Intent
This guide is aimed towards novice programmers and non-programmers alike. If you’ve ever written a game yourself then there’s probably no reason for you to continue reading unless you want to offer some constructive criticism on the content (which I would love to hear).
This guide is intended to give an overview of the basic concepts behind programming a game and more specifically the structure of a game “behind the scenes”. No previous knowledge of programming is assumed. After reading this guide my goal is that:
- If you have some programming skills but have never written a game, you will be able to write a simple game like Pong.
- If you don’t know much (or anything at all) about programming and have always wondered what kind of witchcraft makes a game like StarCraft work, then you will have a much better understanding of this and will be able to write a simple game like Pong should you ever learn programming.
Disclaimer
There is seldom only one way to do things and that is of course also true in this case. For starters, there are several different programming paradigms and within them there are several different programming languages, each with its unique features and ways of doing things. None of this is discussed as focus only lies on general concepts. Though I can say here that I think that object oriented languages are best suited for game programming.
Regarding my background; I am not a professional game developer. I am merely a student with interests in both playing and writing games. Contained herein are just things I have read and things I have learnt from programming my own games. I have done (together with a friend) some simple 2D games, some 2D demos and played around with 3D. Therefore, be critical as you read the material, as you always should be. And again, if you know better, don’t be afraid to say so. I’m writing this because I didn’t see anyone else doing it and I figured there should be some interest (uhm, and yeah, I also want a beta key).
What you need to know
I have talked previously about “programming a game” as well as “writing a game”. The reason why “writing a game” makes sense is because what programming really means is basically writing text in a text editor. In short, if you have a text editor on your computer (yes, you do) you can be a programmer. It’s that easy. Actually, you need something more. The text you have written is understandable from a human point of view, but not from a computer’s. Therefore a compiler, or an interpreter, is used to translate the human readable text into a bunch of instructions consisting of ones and zeros.
In order for a translation to be possible, the program must adhere to a very strict set of rules. These rules vary from language to language. Think of these rules as grammar. If a program does not adhere to these rules it is said to not be syntactically correct. If a program is syntactically correct, it may still not be semantically correct. Semantics are the meaning of the program and this is of course the most important part. For a discussion on syntax and semantics, I will have to refer you to other material (try Wikipedia).
So, how can you try out programming without installing anything at all? By going to this webpage and writing whatever pleases you. Go ahead, try some basic things like 2 + 2 or follow along the tutorial.
The absolute fundamentals
If you know what a flip book is then you already have a good understanding of how a game works. Consider an old cartoon you love; each episode of that cartoon consists of a bunch of frames that when viewed rapidly in succession appear to you as a smooth film.
Now, what are the two core steps that take place when moving from one frame to another? First of all, the previous frame is discarded. Then, the entities in the cartoon are updated (i.e. their positions are changed, they start/stop talking and so on). Finally a new frame is drawn.
From this we isolate two core steps: Update and Draw. This is the building block of any game. Basically, in a game, we use these two steps until the game is turned off. This implies that we indefinitely loop (that is, repeat) these two steps as illustrated below:
![[image loading]](http://www.cs.umu.se/~mikaelo/teamliquid/gameloopsmall.jpg)
The most important step out of these two is the Update step. The Draw step is basically just needed to visualize what’s happening in the game. There is an important distinction between what is seen on the screen and the logic behind it. What’s seen on the screen is just a visual representation of what we’re actually interested in. Also, everything that is updated need not be visible. Think of the camera in Super Mario 64. It has a position and is controllable by you and so needs to be updated constantly, but you never actually see the camera (well, unless you go to the mirror room, but let’s ignore that…).
So the update step will be the focus of the rest of this guide.
Representation
Much in programming is about representing some concrete or abstract concept, like a car or a Dark Templar. How would one go about doing this by writing text in a text editor? Well, let’s think of what a Dark Templar really is. It’s an alien creature capable of moving and damaging other creatures. It has some properties such as health and damage as well as speed. It also has the property of being invisible unless a detector is nearby.
This reveals a lot of new concepts (detectors, invisibility and so on) that we may not know how to represent just yet. But let’s focus on the easy ones. Health can be represented by a positive integer. When the Dark Templar’s health reaches 0, it is dead. This gives us yet another concept: a unit can be alive or dead. This can be represented by a boolean value. A boolean value is either true or false (so if the Dark Templar is alive, the boolean value tracking this should be true). Damage can be represented by an integer as well. A Dark Templar also has a name. This can of course be represented by ordinary text.
In fact, when you dig deep enough, everything (including text mentioned above) can be represented by integers. After all, the computer only uses zeros and ones when it does its work (that is, integers using a base of two).
In addition to properties like health, we also have behaviors. For example, a Dark Templar can attack. It can also move. Two obvious behavioral traits. In programming terms, this would be represented by functions or methods (they mean the same thing). Here is an example of a description of the Attack-method that can relatively easily be translated into code:
“Given another unit, subtract its health points by the damage I deal toward this type of unit given the current conditions.”
By now, you should have a fairly good understanding of how units in a game like StarCraft can be represented when programming. But there are some more properties of a Dark Templar that have not been discussed. For example, a Dark Templar and a Siege Tank are two very different units but they are both units. This seems to imply some form of relationship. How can we represent this?
The most straightforward answer is that we need to think in hierarchies just like we do in other areas of life. Think of the tree of life; it shows that all humans are primates and all primates are animals and so on.
This “is-a” relationship is very powerful. When we are in the update step in StarCraft, we want to update all units (positions, loss of health, regeneration of shields and so on) but we don’t really care what type of unit we are updating. It doesn’t matter whether it’s a Dark Templar or a Siege Tank. It’s enough that it’s a unit. Really, it’s enough to know that it is Updateable. Specific usage of this will be shown in the next section.
In programming terms, we define a “is-a” relationship through inheritance. So we would say that both Dark Templar and Siege Tank inherit from Unit. And when we have done that, we put everything that all units have in common with each other into Unit (health is an obvious example).
I don’t want to make this discussion specific to a certain programming paradigm but I should mention that inheritance is a part of the object-oriented programming paradigm. In object-oriented languages, concepts (such as Dark Templar) are represented in something that is called a class. I do not have space to explain this properly but you can think of a class definition as a recipe for a concept. Perhaps a more StarCraft-oriented explanation will do the trick! In StarCraft, we may build several Dark Templars and they may all be at different positions, with different health etc. However they all have the same abilities. We say that each of our Dark Templars are instantiations of the Dark Templar class definition.
In summary, we can represent properties like health by using simple data types like integers, text and boolean values. We can represent behavior through methods. The concept of a method is fairly simple but would take up too much space to explain in this guide. For this discussion, I think it’s easiest to think of methods as defining behavior. Remember, it doesn’t have to be behavior of a unit like a Dark Templar. A “NetworkConnection” is a concept that can be represented in code and it could have a method/behavior called “CloseConnection” or “OpenConnection”.
Structure
By now, we have a simple game loop that we can follow. We also know how we can represent different concepts using only some basic data types (integers, text and booleans) and methods. We also know how to represent relationships between different entities.
With that, we can finally complete the structure of our game loop and in so doing complete the structure of the game as a whole.
In many games we have a lot of entities that we effectively will treat the same way. It would therefore be convenient if we could store these entities together in a list. And this is precisely what we can, and should, do. A list is just like a list in real life. It contains a bunch of related entries and we can add or remove as well as change entries as we please. In short, we can interact with the entries.
Here is a description of what the game loop may look like:
1. Read input devices.
2. For each game entity in the list of game entities, update it.
3. Update all updateable, non-entity, objects (such as the camera if there is one).
4. Update output devices (that is, draw to the screen, play sounds and so on).
5. Go to step 1.
We haven’t talked about step 1 but basically it just involves checking what buttons the player is currently pushing and so forth. This is important since that information may affect steps 2 and 3. This reveals that game entities will need some form of information in order to update themselves. How can a Dark Templar move if it is unaware of its surroundings? A whole other problem is solving how to share this information (or perhaps find a workaround).
It should be noted that I have not once discussed what constitutes an “entity”. I have also used this term somewhat interchangeably with “unit”. The answer would be that it varies from game to game. If I was to relate the above game loop to StarCraft I would say that all units and critters are game entities. However I would probably further state that all buildings as well as resources are game entities.
It should also be noted that different kinds of games have different kinds of needs. In a game like Pong, why would I ever bother with a list of game entities? In other games, perhaps I would like to organize my entities into more than one list (I could perhaps place all enemies in one list and all allies in another).
With that in mind, the above game loop is a mere skeleton to be extended and revamped as needed. As you think about what should happen each frame in the specific game you’re thinking about, all details and all problems will become evident. As you solve them, the structure of the game loop will emerge as will a lot of other game components that you did not know how to incorporate into your game before (such as a pathfinding component).
How this relates to Pong
So how would one go about implementing a game like Pong? Well, there are two paddles and a ball. These are the three game entities that we need to update each frame. Two of them need information about what keys the players have pressed. The ball just needs to respond to collisions so that it can bounce properly.
We should probably also have a scoreboard that should be drawn every frame, though it will probably not change all too often. Other than that, we just need to draw the borders of the play area.
For the logic, we need to check if the ball has gone off the edge of either side. If so, we change the score and “start over” again.
An Example
I cannot possibly claim to have made a guide about game programming without even having a short snippet of code somewhere. I will therefore show an Update-method I have written for a platform game that I am currently working on. It’s called ShinyShinyBullets and its update method can be found here.
This is written in C# and should be quite understandable to anyone with a basic knowledge of Java. As you can see, the structure is similar to that described earlier. Though this game is far from complete (and I probably won’t have time to complete it this summer because I will be busy working) I don’t expect this method to change much (if at all).
Practical Information
If you’re wondering something along the lines of “well, how do I get an image on the screen?” or “how do I play a sound?” then stop. When programming a game, you never have to re-invent the wheel. You will use tools that provide these features for you. In effect, all you will be saying in your code is: “Load this file; by the way, it’s an image.”
Examples of tools that can be used are SDL and XNA.
But above all, programming skills are needed. In theory, it is possible to program a game with just pen and paper. In fact, this is exactly what I do before I actually do any programming if I have a non-trivial problem. However, in practice it is probably hard or maybe even impossible to do this if you don’t know how to program. Thankfully, there are loads and loads of introductory material on programming available. All of it isn’t good, but if you try hard, you can prevail.
End Note
There are about a million more things I would like to comment on but if I were to do that this would end up being a book. Finally I want to stress again that you shouldn’t take anything written here as the absolute truth. This has been written from my perspective, from how I think about things given my background.