This blog will look at that learning curve.
There's a great article here on gamedev which talks about how you should forget about trying to write the next great MMORPG and instead try to write Pong just to build your skill set. Coincidentally enough, my first game project was essentially a Pong game as well. I call it "Planet Ball".
The concept is simple. The 2 players each control a planet. The planets can accelerate in whatever direction they move their controller and they have a brake key which will slow the planet down quickly. There are small asteroids of a matching color. Every time a player captures a planet of a matching color they get 10 points. If they capture their opponent's asteroid they lose 5 points. If the planets bump into each other both players lose 2 points.
Let's look at what bits of code need to be written just to do this simple game:
- A game loop which can handle the update, render, paint sequence and maintain a consistant number of frames per second.
- A double buffering painting system.
- A series of Entity classes (essentially sprites) such as (base class) Entity, MoveableEntity, ControllableEntity etc.
- Collision detection
- A score system.
- A timer event system to start and stop the game
- A system to assign key strokes to an entity action.
- If I want a title page then I need a way to define each scene (Title, game play, config, credits, etc) and a scene manager to know which scene plays in what order.
- I need sound when objects collide and for background music.
Even this simple game can become overwhelming. As it turns out, I wrote the game twice, and for reasons to be explained in the future, I'm about to write it a 3rd time. But lets start with the first iteration.
I code in Java at work so I'm most familiar with that language. So I bought the book "Killer java game programming" by Andrew Davison, I read the preview of the book on O'Reilly's web site and I liked the way he went into detail on the timing of the game loop. For example, I had no idea that the standard Java call System.currentTimeMillis() is only accurate to about 50 milliseconds. That only gives you a granularity of about 20 frames per second. You need to use getNanoTime and then divide by 1000000 to get accurate milliseconds.
I chose my weapons and started to code. Everything I used was free:
Java jdk to compile and build
Eclipse editor to write code
Gimp to create images
XMind to keep track of task and ideas
NMind to design class diagrams
I wrote the first version of the game and it worked. But the code was too tightly integrated. The paint command in the game loop knew too much about the specifics of the objects, the planets, the score text and so on. A better design would be to have the engine be completely agnostic as to what the game is. Are planets colliding or are bullets hitting a target? It shouldn't care. My code was far too knowledgable about the specific game. If I wanted to write a breakout style game next I couldn't reuse much of my code, I'd have to refactor too much. I should be able to have a single jar file with the engine code in it and then have my game specific code simply reuse that jar.
So I threw the first draft away and started again.
In extreme programming this is called a technology spike. A technology spike is when there's an aspect of the project which you don't know how to do. So you build a prototype to learn how to do it. But that prototype is never very optimal because as you're writing it you're learning. So once it's built you throw it away and write it again now that you understand the problem better.
In the next blog I'll talk about the second version of the game and what I learned from it's design.