Post-Game, Pre-Judgment Postmortem.
So it's been a few weeks now and judging ends in about 5 hours so I figure it's about time to write up a postmortem. This will (a) let me get this down now after some time has passed but still remember what went down during the week and (b) make the most recent post regarding my game not about how buggy it is.So Sunday rolls around and I figure I should at least look at the themes to see if there was anything I liked. I had a great idea for "Bat Cave" and a pretty good idea for "Secret Identity". I had nothing for "Nemesis" but I liked the sound of the word: Nemesis. I think I rated it third. So it won. Yay! Then I found I had no idea what sort of Nemesis themed game to make. None. I annoyed people for the next day or so by randomly shouting "Nemesis" in disgust.
Then on Monday night, I had an idea. The nemesis is Grey Goo and it's coming to eat everything. I wanted it to be unstoppable. The only way to survive was to leave behind turrets (which would be devoured too). Like a free form turret defense game. I wanted you to feel a little bad about leaving people behind so you didn't just power through the levels.
The core of the game is the goo spreading. I started off with an overly complicated CFD system that was waaaay to slow for the game loop. Beautiful, but slow. I backed off that idea and went to simple 2D convolution for goo growth. This was good, but still a little slow. So finally, I moved the goo growth to its own process (go-go multiprocessing) and sent a scaled down version of the map to it via a Queue. when it was done with the computation, it would send back the results. That worked well but had two problems.
- If you set off a bomb in the goo while a growth calculation was underway, the explosion would get overwritten in the next cycle. I solved this by tagging each computation with a transaction number and invalidating all previous results when a bomb goes off.
- If you are on a very fast machine, the computations will run very fast and you will be murdered. A lot. I didn't notice this until the very end and didn't have time to fix it correctly. Instead, I just exposed a player speed option on the menu. If you are on a newer machine (Intel i7 grade) you will want to turn up your speed or you will die.
About three days were spent just getting the mechanics down. By Thursday, I had obstructions and most of the powers working correctly. However, I was running low of sleep. By the wee hours of the morning I was trying more and more esoteric code to do dimple things... and failing. The next day I solved all of the previous night problems in about an hour. Sleep helps.
On Friday, I basically had the game down but with nothing else. You ran from the goo and made it to the end or got eaten. Then you were dumped back to the console with some debugging information. I jabbed in an endgame (the terrain turns to stars) and started bludgeoning the massive pile of spaghetti code into something I could wrap. Then menus and instructions came together quickly. Doing this, however, introduced a bug into the final product that I didn't catch until after the competition had ended.
Instead of having all of the game constants jabbed at the top of the main game module, I moved them off to another module (config.py) so that the menu and instruction screens could access them. I missed one place in the game loop where it it calls:
hud.followers -= POWERS[action].cost
instead of:
hud.followers -= config.POWERS[action].cost
Classy. Also, I forgot to upload my logging version of the code, so I couldn't really help anyone who had a problem running the game.
Next Time:
I hope everyone enjoys (or at least, can run) my game. The competition was awesome this year and I'm looking forward to digging through the source code of a few of my favourite games.
On Friday, I basically had the game down but with nothing else. You ran from the goo and made it to the end or got eaten. Then you were dumped back to the console with some debugging information. I jabbed in an endgame (the terrain turns to stars) and started bludgeoning the massive pile of spaghetti code into something I could wrap. Then menus and instructions came together quickly. Doing this, however, introduced a bug into the final product that I didn't catch until after the competition had ended.
Instead of having all of the game constants jabbed at the top of the main game module, I moved them off to another module (config.py) so that the menu and instruction screens could access them. I missed one place in the game loop where it it calls:
hud.followers -= POWERS[action].cost
instead of:
hud.followers -= config.POWERS[action].cost
Classy. Also, I forgot to upload my logging version of the code, so I couldn't really help anyone who had a problem running the game.
Next Time:
- Get some help chasing down game assets. I'm no artist or composer so I trolled around looking for publicly released (CC licensed) sound and tiles. This took a long time that could have been better spent working on the game. Next time I'm roping someone else into the team to help with this.
- Have some idea what the finished product is going to look like before jumping in. It was hours of work untwisting my existing code so that I could add something as simple as a menu. Once done, the code looked much better (not great, but better) and was easier to use. Should have started here but I didn't want to end up with a great start menu and no game.
- After playing through all of the games that finished I was blown away by the sound in few games. I loved the voice acting in The Sea of Good and Bad and the effects in Möbius Freak. Next year I'm tracking down my friends with a sound recorder. :)
I hope everyone enjoys (or at least, can run) my game. The competition was awesome this year and I'm looking forward to digging through the source code of a few of my favourite games.