I’ve been in hibernation for the last few weeks putting the finishing touches on my first iPhone game – but now I’m back, since the game is finally on the App Store!
For the curious, the game is called Math Ninja and is an educational iPhone game designed to make practicing addition, multiplication, division, and subtraction fun. It’s actually based on the How To Make A Simple iPhone Game with Cocos2D Tutorial Series from this site, and the art was done by my lovely wife!
Anyway, in the process I learned a ton of lessons about making games that I thought you guys might find interesting. So here’s what I learned from the whole experience!
1. It’s OK to Rewrite
The first time I wrote Math Ninja, the code was pretty bad. Spectacularly bad, I might say. I was new to Cocos2D, so made a lot of rookie mistakes, and had designed the app as I was writing it, so the organization was pretty ugly and full of hacks.
So I had a dilemna halfway through the project – should I wrap up the game as-is, figuring the end user would never know the difference anyway? Or should I rewrite it from scratch now that I knew what I was doing better – and add some improvements along the way?
There’s actually a lot of debate on this subject. Joel on Software calls rewriting software from scratch the single worst strategic mistake that any software company could make.
I debated the subject for a while, and finally decided to go with the rewrite – mainly for self-satisfaction and learning sake. The rewrite took me about half as long as it took me to write Math Ninja the first time, so was quite time intensive. So was it worth it?
In this case, definitely. I think it was worth it for the following reasons:
- In general, the game rested on a much firmer foundation, making it much easier to add new features.
- During the rewrite, I refactored the level design logic out into an easy configuration file, which was made the game design much easier (more below).
- During the rewrite, I put more thought into how to store and save game state, which made loading and saving much easier.
- During the rewrite, I put more thought into game performance, making the app more responsive.
- And perhaps most importantly, I was personally much happier with the results and can be proud of it (instead of feeling slightly guilty!) :]
I think my key takeaway from this is when you are learning a new library or way of constructing software, the first time through you’re going to make a ton of mistakes. You can refactor along the way, but with games you are constantly changing things until you figure out what is fun.
So it’s very difficult to maintain the pace of constant refactoring (for cleanliness) with constant refactoring (for fun), while at the same time learning a new library (at least for me). So rewriting let me get additional development speed during the “prototype” phase in tradeoff for additional development time later (to rewrite).
In the future, I think it would be even more useful to make a prototype in a language more suited for rapid development (such as perhaps Flash or Cocos2d Python) to get the game design elements worked out, then switch over to Cocos2D-iPhone when the game design look solid/fun.
2. Make Game Design Easy As Possible
The first time I wrote Math Ninja, the game design was literally hard-coded into my game. To change the health of monsters required changing a number in the constructor of the Monster class. To change the monsters that spawned in a level required writing some code in a function. And so on for weapons, story elements, etc.
It wasn’t hard to tweak these settings, but the amount of switching between files/lines of code necessary to effect a change added up – and subconciously, made me not want to change certain game design elements out of laziness.
This is a bad thing. In order to feel complete freedom to change the game design elements such as monster stats, level spawns, etc., editing those needs to be as easy as possible.
So in the rewrite, I pulled all of the definitions for monsters, levels, story, etc. out into an easily tweakable XML file. I started to build a WPF editor for the XML file, but then I realized that editing the XML by hand was much easier and faster than any editor could be and just stuck with the XML.
Of all the changes I made, making the game design aspects so easy to tweak was probably the most important. Here’s why:
- Since changing game design aspects was so easy, I felt free to make any changes required to make the game more fun/balanced.
- Testing was much easier. I could easily create levels to spawn certain monsters or combinations I was working on.
- There was a clean separation between game design aspects and programming aspects. This helped me mentally get in the right “state of mind” for each task – which feel very different for me!
3. However, Game Design Is Still Hard
The other thing I learned was no matter how easy you make it to tweak your game design, coming up with a good design is still incredibly hard and time consuming work.
I don’t even know how many times I changed the effects, damage, and upgrade paths of the various weapons in the game, or played each level in various difficulties with varioius weapon choices.
At first I felt strangely guilty even spending all this time on game design. To me as a programmer, spending so much time on the game design felt like “playing” or “goofing off” when I really should be coding :]
But then I realized that logically, getting the game design right was probably the most important aspect – after all, that is what makes the game fun – so was worth the time.
I realize I still have a lot to learn from game design. I think experienced game designers use a lot more math and spreadsheets than I did, calculating average DPS, max damage possible per time frame, etc. to figure out the right damage for weapons/upgrades/etc.
Being a beginner, the only way I knew how to do it was by iterating, iterating, iterating until something good came out. It worked (at least I hope so) – but just took a lot more time and hair pulling!