Postmortem: Flood of Air

Posted by (twitter: @sowbug)
April 22nd, 2009 9:07 pm

Background and Pre-Compo

My primary goal of this, my first Ludum Dare, was to finish the competition. Nothing more; not to win, not to place, not to show. In fact, someone’s game has to come in last place, and I was totally OK with that game being mine.

There’s something mystical about computer games. Every developer I know has tried to write one. All of us dream of checking out from our dreary jobs after a sleeper hit that we wrote at home over 52 weekends. But though we’ve all tried, none of us ever seem to finish our games. I was tired of being in the slacker group. I wanted to join the cool kids who have finished a real computer game.

I made the final decision to participate a few hours before the theme announcement. My wife’s 9 months pregnant and could go into labor at any moment, so when I first heard of LD a few months ago, I dismissed it as too close to our due date. But by Friday afternoon (Pacific time), it was looking to be a quiet weekend, so I committed. I knew that by Sunday evening I would submit a Ludum Dare entry.

Technical Preparation

At around -2:00 (two hours before the theme announcement), I downloaded an IRC client and joined #ludumdare. I closed all my open projects in Eclipse and created a new blank Pydev project. I made sure I could draw a gray screen in pygame. I promised myself that I’d stick to 2D.

I searched Google for [royalty-free clip art]. Then I read the contest rules for the first time and was horrified to learn that we couldn’t use clip art. You might as well have asked me to sing on American Idol. But hey, level playing field, etc. etc. etc. No biggie.

While waiting for the theme announcement, I read some of the survival guides and prior postmortems. Don’t use LD as an opportunity to learn new technologies. Don’t start coding before you’ve done a little bit of design. Don’t design for lots of content. Don’t get drunk. Don’t pick this weekend to get a new girlfriend. Roger wilco.

First Night

I spent the first few hours of the competition kicking around ideas. Almost every one was too ambitious, mostly requiring level design or lots of cute icons that I couldn’t draw, or else having a bunch of vague “and then the two actors have some sort of conflict” parts that I wasn’t sure would get clearer in the remaining 46 hours. I settled on a dumbed-down Tetris variant.

This was the first decision I made in the competition, and it was probably right for my personal goal, but it doomed any chance my game had of being playable. It was the best briefly-describable game I could think of in the short timeframe. I traded the benefit of simplicity for the chance of creating something interesting.

I wrote a little code and started talking myself out of the Tetris idea. Sensing trouble, I backed away from the keyboard and went to bed.


I woke up hating my design even more. I started typing in more Google searches: [anti tetris], [tetris variants], [inverted tetris]. My web browsing was getting more free-form. Huge warning signs. I pulled back and resolved to get back to my stupid original idea.

Six hours later, I had the core game finished. I added scoring and an in-game tutorial. I also added some animation transitions that were surprisingly effective in helping my focus group (my two kids, ages 4 and 5) understand the cause/effect relationships in the game.

After a dinner break, I made another big decision: either explore gameplay and risk destabilizing the code, or button everything up to guarantee that the entry would be finished. I picked the conservative route and promised to return to gameplay during whatever time was left on Sunday.

This decision hurt, because I knew the submitted game was now very, very likely to be trivial and dull. But last time I checked, game design is hard. Which am I more likely to do in the remaining hours: stick to my strength of writing production-quality code under deadline, or come up with a brilliant flash of creativity?


More buttoning up: gameinfo.xml, readme, license, screenshot, hunt-and-peck testing (which did discover a few obscure but good bugs), py2exe, free-licensed font, and coming up with a suitably dorky name for the game. As expected, these details sucked up a fair amount of time. But damnit, my entry was technically complete in every sense. I’d finished Ludum Dare!

With the remaining time, I implemented two interesting features: a special tile that showed up later in the game and introduced some locality constraints on the board, and various gradients on board components that gave them some visual depth. The gradient code introduced far more CPU usage than I expected, so I spent the last 90 minutes before the 48-hour mark prerendering and caching as much as possible (while flipping through the Git documentation to figure out how to quickly revert to earlier in the day if I had to abort the gradient project to make the deadline).

What I did right

  • Set a realistic initial goal and stuck to it.
  • Wrote solid, conservative code.
  • Added a reasonable level of polish: transitions, cosmetics, in-game tutorial, and compliance with all the LD submission guidelines.
  • Stayed on IRC.
  • Admired without envying the progress of my fellow competitors.
  • Postponed needless risks as long as possible, while tackling necessary risks as early as possible.

What I did wrong

  • Wrote a really crappy game that is wasting LD judges’ time. I didn’t realize that every entrant was expected to judge every other game. That’s a heck of a O(n^2) algorithm, and I’m sorry to be contributing to the polynomial explosion. I wish there were a “submitted for non-consideration” tag, like “finalbutdonotjudge” instead of “final” if you’re entering just to enter, not to compete.
  • The one somewhat fun aspect of the game is the special tile. But I don’t introduce it until 60+ seconds into the game. Unfortunately, from the comments left so far for the game, I am pretty sure that most judges exited before seeing the first special tile. The rule of thumb is to sell the core of your game in 20 seconds, or risk your judges bailing out early. Fixing this wouldn’t have saved the game’s crappiness, but I’m disappointed that I didn’t get this easy part of the game presentation right.
  • Aimed a little too low, even for my first competition. It’s my personal style to value reliability over creativity, but successful gaming is all about taking risk. That’s obviously true in game play, but it’s also very true in the development of indie games. Your audience really doesn’t give a shit how proud you are that you finished your game; that’s a given, or else they wouldn’t be wasting their time playing your unfinished game. So people expect that any finished game will reach a basic level of challenge, and mine definitely failed that test. It was a fine personal goal to finish LD once, but for a second LD, if my game were no more fun than this one, I’d decline to submit it and call my attempt a failure, even if it was technically a complete entry.
  • Didn’t explore every artistic challenge the compo has to offer. I should have tried to draw something. It was fine to use sfxr for my beep-boop sound effects, but at a minimum I should have tried throwing some reverb over the wav files. I avoided injecting any kind of artistic expression into my game, and as a result the game’s not just boring, but also sterile.

3 Responses to “Postmortem: Flood of Air”

  1. Tenoch says:

    Heh don’t worry about O(n^2), I did O(n^3)! Polynomial explosion FTW!

  2. HybridMind says:

    Thanks for sharing your thoughts and experiences in your post mortem. Congrats on finishing… it is important! :) I haven’t tried your game yet but I’ll get to it soon I’m sure. I’ll try and find the special tile too.. 😉

  3. callidus says:

    Another first time LD entrant here, very interesting reading your postmortem. It seems like your process was similar to my own. I also suffer from aiming a little too low and simply focusing on crossing the finish line…. but hey always next time to shine 😉 look forward to you next entry 😀

Leave a Reply

You must be logged in to post a comment.

[cache: storing page]