Over a week after completing my Ludum Dare entry, I think I’m finally ready to write up a postmortem. I needed that time, because the project wore me out. I’m not even sure I felt like I worked that aggressively, but I think my awareness of the deadline magnified the sense of exhaustion. It was my first game jam, though. Maybe next time I’ll be a bit better adapted to the experience.
What Went Well
What Went Poorly
Let me first describe the development process. The theme was to be released at 20:00 local time Friday evening. I spent the day leading up to that time working on a quick space shooter a la Asteroids. It had been a while since I had done an action-based game which I thought would be a likely candidate for the jam, and I wanted to get some practice with CreateJS, the framework I planned on using. It didn’t get anywhere close to complete (you can see the result here), but it did give me a proper game loop and an opportunity to work through a few hangups I had with loading sprites instead of depending entirely on vector graphics. Since Joshua Skelton had offered to provide art, I wanted to make sure I’d be prepared to make use of it.
Once the theme was announce (“You only get one.”), Joshua and I brainstormed for about a half an hour. The theme was rather tricky. (I’m pretty sure I voted against it earlier.) Joshua had recommended that we decide on something early, get a prototype as quickly as possible, and spend the rest of the jam polishing. That was an intimidating prospect, I’ll admit. But it also made a lot of sense, so we chose to do a platformer with two different mechanics that could be swapped once during each level. (For prototyping, we chose to just do two different types of platforms, one passable and one impassable, with the intention of choose more interesting mechanics later.) Within two hours I had this, a limited prototype with gravity and running on a platform. Another hour and a half later, I had a this prototype which contained the entire core of running, jumping, two platform types, and the inversion mechanic. I finished up Friday with a late night prototype containing polish to the physics, screen scrolling so that we could have wide levels, and the addition of a ground platform that you couldn’t ever fall through, and which was unaffected by inversion. We were off to a good start I felt, with two and a half days left for polish!
Saturday’s first prototype saw the addition of level design through ASCII art, death and respawn, and further improved physics and feel. I then ditched the simplistic passable/impassable platforms and worked up the next version that included a speed-boost platform and a high-friction platform that you can only stand on for a second before it becomes impassable for a second. The third prototype of the day added enemies and projectiles. The enemies came in two varieties that also swapped behavior when the inversion was triggered. At this point, I was definitely happy with the progress, but was also realizing that what I had Friday had not been anywhere close to complete and ready for polish. Most of the work on Saturday was additional necessary mechanics.
Sunday started off with me trying to truly get a complete game available, so that I could really get on with the polish in earnest. The afternoon’s prototype added a win condition, multiple levels, proper game flow, and a timer so that you could compare runs. In the evening, I received and integrated the first round of graphics from Joshua (as well as a tutorial level with help text in the background), followed a second round of additional and updated graphics. But the addition of new mechanics wasn’t entirely behind me. Late Sunday night’s version included life hearts (no more insta-death), a player weapon, and life/bullet pickups throughout the level.
Monday brought with it the deadline for the game jam at 20:00 local time. Now it was truly crunch time, and I had so many ideas, both for polish and for features. I prioritized sound and music. Learning SoundJS was actually a breeze, but getting my electronic drum kit hooked up to my computer and configured for recording was more obnoxious than I expected. Lack of appropriate cables was the biggest impediment. That and poor recording equipment (that is, my motherboard’s integrated sound) resulted in a noisy recording and the inability to play with a metronome without recording the metronome. Fortunately, Audacity was satisfactorily able to remove the noise. But for the metronome, I just had to depend on my own poor sense of timing. Once recorded, I had to learn how to use Audacity enough to get a proper loopable track. For sound effects, I decided to just grab the recommended sfxr to generate sounds, and that worked without a hitch. But after creating all this audio, I realized that my game took some time to load, but didn’t provide any feedback while loading. Thus it was time for a loading screen. And then the music drove me crazy, so I also added mute buttons. (Maybe that’s a sign that I should have left out the music altogether, hah!) This brought me to prototype #11.
With two hours to go, I couldn’t resist the addition of another feature that I had been wanting to implement in some form or another for a while: Forcing the player to complete the level at a particular vertical location, in order to enable vertical levels. I didn’t have time to actually implement a proper doorway, but I did manage to force them to exit the right side of the screen at or above a specific height specified in the level design, and added the ability to place an arrow sign sprite in the level to help indicate where to exit. The loading time was also slowing me down, and I kept muting the music anyway, so I rearranged things to have a version with all audio, a version with just sound effects, and one with no sound at all.
I then quickly whipped up a vertical level with my newly added feature and arrow signs, and included a final level that my friend Josh Grondski quickly created after he came home from work, resulting in the final version of Inversionaut (no music, no sound).
What Went Well
Friday Preparation: I found my warmup exercise to be incredibly valuable.
Small and Frequent Iteration: Each feature I added was visible and testable quickly, which kept the energy and the motivation up, as well as giving me quick feedback on how well everything worked or didn’t.
Having an Artist: I might’ve been able to create some passable art with a stale style, but not in 72 hours. Joshua was able to provide nice and distinctive art while I could concentrate on the stuff I was much more skilled and efficient at.
Deadlines: Not just the final 72 hour deadline, but also the vaguely defined deadlines throughout the jam, just based on my estimate of what needed to get done and how quickly. I have a bad habit of over-engineering, and these deadlines helped me to focus on writing code that gets the job done, without it needing to be flexible enough to do twenty other irrelevant jobs.
What Went Poorly
Mental Exhaustion: I think I let the tight deadline and the excitement and intimidation get to me.
No Feature Freeze: I kept adding features up through the very last hour. My optimism that the Friday night progress would allow lots of polish for the rest of the jam was premature.
Uninspiring Theme Mechanic: I wasn’t a big fan of the theme, and my brain kind of went blank trying to figure out how to satisfy it. The end result was probably harmed by my lack of enthusiasm.
Not Completely Prepared: I didn’t have sufficient knowledge of all the relevant tools ahead of time. I learned SoundJS, sfxr, Audacity, and recording my drums on the fly; I also researched third party physics libraries a bit Saturday before deciding I’d burn too much time learning how to use it and reworking what I already had to integrate well with a different system.
It was a good experience, and I learned a lot. I got some practice avoiding over-engineering, and hopefully slightly improved my ability to estimate development times of various features. I definitely plan to do more game jams in the future, and perhaps they will go a bit more smoothly over time.