GGJ '15 Postmortem

David Stark / Zarkonnen
2015-01-28 07:59
Defeat Screen by Yasmin König

Over the last weekend, I again got to participate in the Global Game Jam. It's a pretty big event here in Zurich, with about 80 participants each year, held in one big ex-factory hall.

Like last year, I worked together with Kaspar Manz, though Kristina Balanc, who did the art for Art Critic, couldn't make it. What made this year different was that we were joined by Jan Graber, a local journalist who wanted to experience the jam from the inside. He would both work on the game and report on it, and if you read German, I recommend his rather more expert coverage. This post, as a postmortem, is going to focus on the good old "what went right, what went wrong" side of things.

So we started out at the beginning of the jam, before the theme was announced, with two participants with a programming focus, and one (Jan) who could contribute writing and audio. This left us rather short of visual talent, so we advertised using a piece of A4 paper stuck to a pillar. This netted us Yasmin König and Simon Füglister, both first-timers to the whole jam thing. Finally, we were joined by Reto Spoerri, bringing us another programmer and leaving the total team size at six.

Once the topic - "What do we do now?" - was announced, we started discussing it, and fairly quickly hit on our core concept: in the final level, after what you thought was the end of the game, you have to go back through everything you just fought through - and the state in which you left things determines just how hard things get. So if you rampaged your way to victory, it would now become very tricky to pick your way back through the devastation. Successfully completing the game would involve learning how set things up on the way out to make the way back easier.

From there on, we hammered out the basic story concept ("Steampunk spaceship is crashing into the sun after a great battle"), visual style, and some ideas for specific mechanics that would allow us to push our concept. Then we all went home to sleep, because we're too old, experienced, and lazy to do the whole "work for 48 hours solid, go insane with bugs caused by sleep deprivation" thing.

The next day, Saturday, was our major chunk of available time, some fourteen hours of game-making. Ideally, by the end of Saturday, we would have a working game that we could then debug and polish on Sunday. (Yes, this is foreshadowing.) We got started creating art, coding the game, designing levels, and composing music. We had agreed to use Unity as a platform both because it was something a lot of us were at least vaguely familiar with, and because we wanted to be able to embed the final result on the newspaper's website.

This is where the first problem cropped up. We had three programmers, but no real way to parallelise tasks. Before anything could really happen in terms of building levels or creating content, the core game had to be set up. Unity, with its reliance on opaque Scene files, made this task very hard to split. So in practice, we ended up with Reto writing the game, Kaspar doing level design on paper, and me making lists of required assets, answering art team questions, and kicking my heels.

Some interesting work came my way when we decided to try creating a dynamic layered soundtrack for the game that could react to different situations. This isn't something Unity supports out of the box, but some asking around pointed me towards Fabric, an advanced audio system that is conveniently free for teams as small as ours. So I got to work learning how to use Fabric, added the library to our project, and wrote some code to tests things.

Unfortunately, this caused problem number two, though we didn't realize it for a long time. We were using Unity 4.6, the latest stable version, and the combination of that with Fabric caused an insidious bug where Unity would silently fail to save anything. So we'd work on a scene, hit save, move on to the next piece of work, and return later to find all the work mysteriously missing.

This prompted a scramble to figure out the cause of our problems, fiddling with project settings (that themselves refused to save), removing bits, recreating the project and re-importing things, googling desperately. After a couple of hours we'd figured it out, and downloaded a patch version of Unity that fixed the problem. Still, we'd lost hours of work, and hours of time, right out of the middle of when we were meant to get the game working.

Once this obstacle was out of the way, things started working more smoothly: with some of the core jump-and-run code done, I set to taking art assets and turning them into prefab objects that could be later assembled into levels. Kaspar started laying out a first test level, Reto continued making the actual game work. Yasmin and Simon heroically cranked out artwork on the basis of whatever random new thing we realized we needed. Jan delivered the music loops, and I got to actually implement our fancy audio system, learning quite a lot about dynamic audio in the process.

Still, by the end of Saturday, we had nothing like an actual game. We were hours behind where we thought we would be.

At the start of Sunday, we entered that traditional phase of game jams known as "what can we do in the remaining few hours so that we get an actual game out of this?" We cut down our content ambitions to a single longish level in five stages, ditched the second character we wanted to introduce, rewrote the story to make some vague sense of it all, and got to creating the level stages, with Kaspar laying them out and me going over them to make them prettier with background deco.

Then we got to the final few hours, with Kaspar and Reto getting the dynamic level loading to behave and fixing camera follow issues, while I added a repairable console pouring out smoke so there was something for the player to do at the end of the level. On Saturday, we had trouble finding work for programmers. Now the situation was reversed, with the programmers hacking madly and the artists bored, as anything they produced now would be too late to make the final cut.

In particular, we'd realized too late that the object artwork had no margins of empty pixels around it, which meant that there would be intermittent visual artefacts as the texture mapping wrapped around, showing pixels from the far side of the picture at the edges. Yasmin and Simon actually fixed this and sent us updated graphics, but I worried so much about breaking something in the final minutes that I didn't put them in.

We packaged everything up for submission, and the upload went through at five o'clock exact. We had won at Global Game Jam!

What went right

  • Good coordination between the assets and programming halves of the team. A frequent disappointment with GGJ is that a huge amount of assets get cranked out that end up never being used in-game. Because we derived the assets we needed from the elements and mechanics we wanted, and created a prioritized list right from the start, we ended up with very little wasted work.
  • We had a strong core concept and matching narration. Of course, we lacked the time to execute it as well as we might have liked, but it gave our project some "first principles" we could check against to keep from getting lost.
  • Having something like a decent night's sleep both nights definitely helped, and it's something I will keep on doing in future jams. We managed to recover from data loss and weird bugs and were able to put together and push out the game in the final few hours because we were still mentally functioning. I dread having to fix problems I caused while sleep-deprived while still being sleep-deprived, and I'm glad I didn't have to do that.
  • It's really great having a team member who does audio, instead of adding sound as a last-minute afterthought.
  • GitHub continues being an excellent site for coordinating work - at least as long as the Internet works!

What went wrong

  • There's a whole bunch of little details about what game assets have to be like that Kaspar, Reto and I would've known about but failed to communicate at the start: images with margins, audio normalized to 0 DB (Unity can easily make sounds quieter, but not louder). We ended up with not enough time and brain cycles to fix these things, and the result is a game that just looks and sounds worse than it could have if we'd spent a few minutes communicating these things at the start.
  • It was probably a mistake to use the latest version of Unity rather than a slightly older and more mature one. I said some choice things about Unity on Twitter during the jam, and I continue to be of two minds about it - something I will expand on in a later post.
  • Three programmers are probably just plain too many if you don't have a clear plan for how to use them in parallel. Two programmers is the optimal number, because it lets you pair when things get tough. Though I clearly did contribute to the game, and enjoyed myself and learned things, I feel like I spent more time chatting to people than actually writing code. I only really got the proper mad game jam rush right at the end of the process, when we were all working on getting things fixed and ready.
  • In a similar vein, we were probably too egalitarian about our organization, and got very close to a situation where everyone worked in a little silo with no overall plan. Nominating someone to more explicitly manage the team, making sure that everyone's got something to do and work is done on the most important things first, would likely help. Also, you inevitably end up having to cut a whole lot of features and content that you really wanted to put in, but there's temptation to ignore the need to make cuts in a coherent way. Our game would have been fine without dynamic music, without springy physics-based platforms, without that one enemy that splits in half when you jump on it. It really needed better sound mixing, more consistent controls, and a fast way to make interesting level geometry that wasn't just stacking boxes.

What to do next time

  • If GGJ continues being a Unity-fest, I'll want to spend some time before the jam starts refamiliarizing myself with it, so that I can hit the ground running.
  • Along with clearly defining a list of basic assets, also clearly define what they should be like.
  • Aim for two programmers in the team, unless there's a clearly defined separate set of things for additional ones to do.
  • Even if it's initially painful, pick a manager. Note that this doesn't mean "declare myself in charge". I don't need to be in charge, I just want there to be someone who is.
  • To mitigate hurt feelings in terms of whose pet feature gets cut, we could use planning poker or something similar to generate priorities.