Ludum Dare 21
This was my first Ludum Dare, and in fact, my first coding jam of any sort. It was grueling, painful, and ultimately quite satisfying. I learned a lot, and hopefully I can share some of that knowledge for anyone attempting to do this sort of thing in the future.
What was Awesome
Having a (rough) plan!
I went into this with a very broad idea I was excited about (controlling multiple tiny creatures at once). Armed with this constraint, I went into my image editor, created a blank 8×8 texture, and noodled around until I came up with the basic slime sprite. This then spawned further ideas about what to do with these tiny creatures, because after all, why do slimes exist other than to split up into smaller slimes? A half hour later I had two different sizes of slimes with a couple frames of animation for both. This leads to my next point…
Prototyping with real art
Having good, familiar tools
Ludum Dare is NOT the time to dive into a language you’ve never written in before, to use a shiny new unfamiliar library or piece of middleware, or to implement a cutting edge rendering algorithm you read about in a siggraph paper. I do believe it can be done, I’ve seen a few good submissions by people trying out a language for the first time, but you will run into stumbling blocks frequently. These will sap your time and your sanity, as you waste hours googling vague error messages and posting frantically to messageboards at 3 in the morning. I stuck to a toolsuite I knew well, and even still ran into issues and bugs that took far longer to resolve than I’d have liked.
Working with discrete units
As many systems as possible in my game use integer based units. Everything runs at a fixed timestep (there is no deltatime passed into the Tick() functions, and really no concept of elapsed time used anywhere outside of the physics system), actor locations are stored as integer vectors, etc. I found that this kept complexity to a minimum, and made tweaking animation timings, actor placing, and other things a lot easier. This strategy won’t work for most games, but for an 8-bitty 2D game, it’s a real timesaver.
Having awesome friends…
… and making myself accountable to them. I told a bunch of people about my Ludum Dare intentions, to the point where I couldn’t really back down without disappointing people that I respect. While I was in the thick of the competition, I set up a livestream, and a few of them were always watching. It was an awesome feeling to be cheered on while I was working, I honestly don’t think I could have done this without their encouragement.
“Just get it done” mentality
“Just get it done” mentality
Yeah. What was awesome at the start of the project grew into a monolithic block of gnarly, twisted code. Iterating went from a quick line change here and there, to a long slog through pages of code, searching for functions I’d forgotten the names of, and classes that may or may not even exist anymore. The worst example of this backfiring was my “actor factory” code, which of course started as a simple switch() statement, and ended up as a series of gigantic switch() statements full of redundant and copy-pasted code. This is where using an old library of code would have been very handy, as this is something I’ve done “correctly” before, but couldn’t be arsed to do in the short time allotted for the competition.
I vastly underestimated the importance of having good tools for getting new content into my game. My levels were stored as huge grids of text in one of my classes, and I did my editing within Visual Studio’s text editor. Painful, and not great for iteration. Adding a new entity was a multistep process involving creating a new class, editing three different switch statements (ugh), dragging its frames of animation into the project, adding those frames to a giant list of textures, remembering what index in the list those frames were at (UGH), and other minutiae that quickly added up. By the end of the second day, I had fewer levels and entity types than I had planned on, and just didn’t have the energy to add any more. If I were to do this all over again, I would have allotted a bit of time at the start of the second day to cleaning up this mess and streamlining the whole process.
Using a physics solver for character control
Don’t get me wrong. Box2d / Farseer is fantastic for what it is meant for. But what it is meant for is NOT making a character smoothly and reliably run across your level, with finely tuned jump heights and air control, and keyed translation amounts tied to your animations. I spent probably five hours trying to get it to feel decent. I could not even tell you what I did to get it to where it is now. It’s STILL not where I’d like it to be. Plus, the damn slimes have a tendency to get stuck on geometry, to fall through the world, and generally misbehave. Unfortunately I just don’t have experience in writing anything like this, and having a big ole’ pile of slimes naturally fall all over each other was something I didn’t think I could get without a pretty good physics sim running it. I definitely need to find a better way to do character control if I’m going to keep working on this game.
I don’t know if or when I’ll do this again. All told I spent about 30 hours working, wrote a little over 4200 lines of code, created 54 sprites and 11 sound effects, and shipped 7 levels of gameplay. It was incredibly draining, and I still feel like I’m recovering from it. That said, I came out of this with a renewed vigor for game development, and a great amount of appreciation for everyone who undertakes this challenge.
If you like my project or just want to chat, shoot me an email at email@example.com. I’d love to hear your thoughts!
I am going to go pass out in a pile of laundry.