One Game A Month – January Postmortem: PlaneShooter

Introduction

I’ve entered into the One Game a Month party. It’s like Ludum Dare, a challenge to make, and most importantly FINISH, a game in a set amount of time based on a theme. What makes #1GAM unique is you have an entire month and it spans an entire year. They have a thriving Twitter and Google+ group.

I’ve entered strictly for learning purposes and to see if I can actually finish something. Game development is surprisingly very different from application development, and it’s nice to feel really stupid again.

Snynopsis

PlaneShooter, a 1942 clone, was all about the story, improved plane engine & weapon customizations, and taking advantage of improved graphical hardware. You play Kay, the protagonist, who flies a P90 Lightning aircraft modified for cargo. Her Dad, O, a former military pilot, and her battle bandits at their latest town of delivery. They slowly uncover a plot that leads to war with an ending that leads you to the 2nd version of the game.

I really liked how you could personalize even a 1940’s era plane with tech that was available around then, yet still leave room for the fantasy element to give it otherworldly powers.

PlaneShooter Goals

My 2 goals with PlaneShooter was simple: finish a game I’d been working on for 8 months in my spare time, and hopefully learn more about the marketing/business side. I had a bonus goal of finally getting a chance to juice a game, ie polish.

It was basically a 1942 clone with a story behind it with extra side-scrolling levels to help in character and story development. Additionally, you could customize your plane between levels. Finally, the game had on going dialogue either during the game or it would pause at key points.

Actual Results

I didn’t finish.

I managed to get the game 99% there with 2 levels. I did get an intro screen, game play, reasonable interaction, a semblance of scoring, reasonable programmer art, and an end screen.

I had created a script and recorded audio content + sound effects for 8 levels.  I had completed all the mechanics for drag and drop of upgrading your plane. This includes the speed + weapon power adjustments, etc. The achievements were half done, and scoring was 99% there, I just had some persistence challenges I was working through. None of which made it in the game, hah!

The intro screen and end screen were not completed and used the wrong art, but I made them functional to call it a day. All planes had 1 hit points except the bosses which was not planned.

What Went Wrong

I’m still learning, so this is all conjecture.

I believe my story scope added a ton of work. While I believe it made/will make the game actually fun to play, it required a significant amount of audio work man hours, including 4 days of purely just scripting writing. If I removed the entire story element, removed the plane weapon/engine customizations, and focused strictly completing levels + art, I may have had a game that felt more complete. That wasn’t the kind of game I wanted to create, though.

All in all, audio took up 60% of my entire work effort. Music creation, dialogue recording & editing, and sound effects. Whoops. I sure had fun, though.

Conclusion: That level of scope was not something I could complete in a month.

What Went Right

Taking a year old code base with 8 months worth of work and yelling at it, “You’ll be frozen in a month” was a great feeling. Many of us programmers have ideas laying around, dozens of them, that are left unfinished. Some don’t need to be completed, but others… yes. So over all that part really felt good to attempt to get some closure.

Secondly, I learned a ton. I read a lot about game design process, re-opened a lot of the artistic tools I haven’t really used professionally in 10 years (Photoshop, After Effects, Reason, Audition, etc). I got to spend significantly more time in them. Some things I remembered, but others I had to learn while under such a short deadline. I also learned new ways to put them into a workflow.

Third, the processes I did use SEEMED to pan out fine:

  1. think up idea
  2. write it down, sketch it out
  3. write up a list of goals, tasks, and scope
  4. code the things I don’t know
  5. create art & audio
  6. implement
  7. bug test

That general process seemed to work great, and while there were some kinks, it proves that the general way of build games is a lot like software; you do a hybrid approach of Waterfall and Agile, the requirements (heavy on the pen & paper since they are cheap to undo/redo), and then you iterate on 4-7. I think I just put a too huge idea into the process.

Fourth, although not complete, I could taste I was getting close on some things, but I also started to get a better sense of how much work polish actually is. Additionally, some polish you don’t actually know about until you get the idea solid. Sometimes getting the idea solid is an actual prototype WITH assets in it to play with.

Fifth, Corona actually worked with tons of assets and code. As a long time Director/Flash/Flex developer who grew up in tincy runtimes using dynamic languages and learned how much “better” it was to have a mature one with a strongly typed language… it was nice to have success with a non-mature runtime with a loosely typed language, Lua.

Sixth, it was interesting to see where architecture got in the way, and where it didn’t, but more importantly WHEN it was too early to implement. People have written volumes about YAGNI. They’re usually exhausted Java developers who have found a job doing Ruby in a different company with good medical benefits. YAGNI, like all things software, is an on-going learning process. Building things only when you need them is a given, but it’s when is it too early, too late, how much do you build, etc… that’s the challenge.

Seventh, Chris gave us no deadline for January… which allowed me to learn my lesson. Sort of.

Eight, taking a 5 year old and having her do dialogue actually worked out well. We did all 8 levels in one sitting which took about 40 minutes with a few re-takes and 2 glasses of water. I was very impressed with Adobe’s Audition and how quickly I could batch my hundreds of assets all with my effects applied. It’s a bit unstable, though, and I have to reinstall when the audio drivers get corrupted.

Nine, I actually liked most of the code. I suffered from a lot of left over ideas in the code which meant navigating it was a little challenging, but it is starting to be clear which parts of architecture I like and help. I lived and died by my game loop, and since Corona doesn’t have one built in, I was impressed you could build an entire game based on one. That, and Box2D’s collisions were solid.

Ten, creating music went quite well, and the timing was also just luck as well for the crescendo’s to hit when you reach the mini-bosses.

Key Takeaways

Over all, #6 was directly the result with the lack of tooling. While my package names, ways to build classes in Lua, and other architecture patterns were legit, wading through it and modifying it was way more challenging than it is in other languages that have mature tooling and IDE support. This in turn adjusted how much architecture I implemented, where, and when.

For example, yes, long descriptive package names are helpful, prevent you from having to think where things are, and really organize your code. However, in Lua and Sublime… they’re a pain in the ass to navigate and change. Once you want to refactor something, even with unit tests the entire effort is on you; you get no help from the IDE nor runtime what you forgot unless you’ve left asserts with descriptive error messages everywhere. That is a HUGE burden on a developer under a tight deadline.

Additionally, I learned that a lot of the Robotlegs code I borrowed you don’t need in Corona SDK because it has a built in event bus that works fine. You don’t often need to create sequestered event buses, 1 is fine. That and Dependency Injection isn’t worth it merely because the language doesn’t support it; you’re better off just following a convention, much like jury-rigging PureMVC to act like Robotolegs by firing created and destroyed events in the View’s so the framework can add the required Mediators.

I spent 5+ years ensuring I don’t use global variables in my code, and another 5+ years ensuring you don’t create too many Singletons once ActionScript went to a class based language. Now, I’m always using the same 2 globals in my games and they’re really useful and make the code readable. It’s still not good practice, but for quick iterations and speed, they’re legit. Having to pass the same 2 variables into 99% of my classes externally is ridiculous… it got a lot worse with composition. I no longer judge those who use _G intentionally.

Organizing my tasks into Trello quickly pointed out how much work I had left. If I kept tabs on my tasks, I could quickly judge if I was off track (doing the wrong tasks), or if I was going to have too much work. That, however, took a lot of discipline… when the whole reason I’m doing this is for fun.

Conclusion

Feburary: Smaller scope, focus on more levels.

The source code is up on Github. You can install on Android here.