Like a lot of people doing programming for video games, I played a lot of NES games when I was a kid. It has always amazed me how they were able to get so much out of so little, and so I’ve spent a good amount of time over the years dissecting certain games to see how they work. Today I’m starting a series of blog posts in which I want to document what I’ve learned, from a game programmer’s point of view. I’m going to try to focus on how the game systems work at the game/engine level and not at the hardware level (so more like how does this game decide which things it wants to draw on this frame as opposed to how do sprites work on the NES.) I’ll also try to throw in any tidbits about the games that I think are interesting like things that weren’t obvious to me just from playing the game casually or instances of bugs in the game’s logic.
Contra Introduction
The first game that I’m going to write about is Contra on the NES. The remainder of this post will be a short overview of the objects and data that exist in a game of Contra and then subsequent posts will go into more detail about each system the game uses to manipulate its model of the world. The basic model that the game maintains is made up of:
- Player characters
- Player bullets
- Enemies and other objects
- Level data
The player characters are the main heavyweight objects of the game and have lots and lots of code that explicitly deals with them as you might expect. The bullets from player characters are treated differently from every other kind of object in the game for reasons that are probably performance related. We’ll see later on how the player bullets being separated out from the other game objects makes various things the game has to do more efficient. The final class of objects are the enemies which are managed by a simple entity system. This includes the enemies themselves along with enemy bullets and explosions, but also a couple of friendly things like flying power-up balloons and power-ups sitting on the ground. I’ll use the term enemies to refer to all of these things just to have a more descriptive term for them than “objects.” The key feature is that there is code in the game that deals with them abstractly as opposed to the player characters and player bullets which are always manipulated by specialized code.
The tile based level data is the final major part of the game simulation. Contra features standard horizontal levels along with a vertical level and pseudo-3D levels. Levels only support moving forward through them, never backwards. The game maintains a double buffer of tiles that hold collision and visual data for the current screen in the first buffer, while it builds the next screen in the second buffer. We’ll see later on how the level data is organized, how it is updated as you make your way through the levels and how enemies are spawned from it.
Up Next
I have a rough outline of where I’d like to go from here with this series but it’s still very much a work in progress. Topics I have ear marked to talk about include data representations, enemy behavior, scrolling, collision detection, random number generation, player control and other assorted things. I’d love to get feedback about what people might be interested in going forward. You can leave a comment below or reach me on twitter @allan_blomquist
(This is part 1 of a 7 part series – Next)
Tags: Allan Blomquist, Retro Game, Retro Game Internals, Tomorrow Corporation
Sounds like a fascinating series of blog posts. I’m interested to hear how the architecture of some of these old games compares to more modern game development.
Looking forward to more of this! I’m interested game development and how games are put together (both old and new), so I’m sure this will be both helpful and just mentally satisfying to read.
Cool! I’ve been wondering that kind of things for a while. Thanks! 🙂
Oh wow I never thought about this nor can I reverse engineer. Sounds awesome!