Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
82 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

Breaking it Down

The whole idea behind incremental development is to keep the time between compiles as short as possible. You want to take small baby steps for two reasons:

  • Theoretically, the less code you add to the existing structure the less chance of bugs and errors popping up with the next compile. This is, of course, not always true – there will still be times when the errors stack up no matter what. Even so, this can become a rare event if the amount of new code added between compiles is reduced.
  • When the errors do pop up, they're a lot easier to get rid of when you know exactly what was added since the last stable build of the project. The more you add, the easier it is to lose track of things as they tend to become spread out. This is why when adding new code it should be an encapsulated module or something where the code is localized for easy debugging.

Reading the above two points, we can begin to define the term "baby steps" into something workable. Obviously incremental development emphasizes constant compiles, but the problem is deciding when to compile. Obviously you don't want to spend half of your total development time compiling the project, even if it can drastically reduce errors. There is a point where incremental development can actually become time inefficient, and that's when you spend more time compiling than coding or debugging.

Another thing to consider when deciding build points is that when you compile the project, you want the new build to run and actually do something on top of the old build. Don't do a compile just to debug a routine that isn't even called yet in the execution. Wait until you've added a whole game function. For example, if you had a space game, you might compile to simply display the player's ship. Then you would code in all the weapons programming and then compile to test and debug the shooting of the lasers. You wouldn't compile the project until you were able to actually shoot the lasers. For example, compiling to display the guns themselves would be a waste – they should have been shown with the ship the first time or you should have waited until the lasers could fire. Just showing weapons adds nothing of testable value to the previous build.

With this is mind, it's a lot easier to decide when to compile. Keep in mind these guidelines:

  • If you are adding an entirely new game object, you may want to break the object down into smaller pieces. For example, a space ship would be broken down into its display, movement, weapons, shields, etc. if possible. Compile, test, and debug each of these pieces not separately, but on top of each other.
  • The amount of new code to add depends on its localization. If the new code is spread out over many files, you should not add too much. If the code is localized to a single file, more is acceptable. The whole point is to make it easier to determine where you screwed up when the errors come marching in.
  • It's important to plan out your entire build order, rather than take it as it comes. This is because it makes no sense to compile and test weapons when you can't even see the game object that's shooting them. Make sure each additional compile builds onto the previous compiles.
  • You should always have a playable version of the project on hand as a previous build. This is good because it's a stable version you can fall back onto when things get hairy, you always have something to show to impatient clients, and as a visual aid to other team members, it's priceless. Don't do a compile that adds nothing to the playability.

If you need an example, I made a small Asteroids demo in SDL. It didn't do much except display a ship that moved and rotated and fired a laser that did nothing, and asteroids were careening around and there was a parallax star field effect. This was my first project in SDL and it only took me three days, a few hours each day, to get this far. Here was my build order:

#Build 1:

  • Initialize SDL

  • Create full screen app

  • set transparency key (black)
  • exit on ESC keypress

#Build 2:

  • enable file stream
  • create image data file
  • read in test image

#Build 3:

  • modify image data file for interface elements
  • load in interface elements (radar screen, status indicators, etc)
  • properly display interface elements

#Build 4:

  • create Vector class (see vector.cpp/vector.h)

#Build 5:

  • Starfield class, Builds 1-3 (see starfield.h/starfield.cpp)

#Build 6:

  • Asteroid class, Builds 1-3 (see rock.cpp/rock.h)

#Build 7:

  • Player class, Builds 1-4 (see player.cpp/player.h)

This was taken from the main source file, and only progresses up to the game's current state – there are actually 20 main builds but, as you can see, each game object has its own builds assigned to it. Here's an excerpt from the Starfield class source:

#Build 1:

  • create (draw) starfield layer

#Build 2:

  • allow more than one starfield layer

#Build 3:

  • animate starfields (using arrow keys to simulate player movement)

I would like you to notice Build 3. Even though at this time there was no player ship to be seen on the screen, the build still called for implementation of the arrow keys to simulate player movement. It's important to realize that you shouldn't have to mix up the building of objects because of dependencies. This is discussed more in the next section.

On average, each of these builds created about 5-10 errors. Debugging was as tedious as ever, but was made easier by the fact that I knew what code to look at for mistakes. The hardest part of debugging is knowing where to start, where to look. When you know where the new code is, it can greatly simplify the problem.





Putting it Together

Contents
  Introduction
  Breaking it Down
  Putting it Together

  Printable version
  Discuss this article