Showing posts with label design. Show all posts
Showing posts with label design. Show all posts

Friday, 12 July 2013

Game Programming Essentials: Groups of Objects

Getting together lots of items at once, be they: enemies, bombs, powerups, particles or even the stars in the background.
If I remember on some of my very old code, I used to have:
int ex1,ey1, ex2,ey2, ex3,ey3; // locations for each enemy
But obviously that doesn’t scale.  And you should be moving onto arrays of sprite or arrays of enemies.
A say ‘should’ because I still see assignments which are handed in which have the “ex1,ey1,ex2,ey2” code in them.  These are the ones which are usually awful code, and get very little marks.
There is no hard & fast rule for how to design your Sprite class, but here are the things that I expect to see:
  • Position (must have)
  • Update & Draw function (must have)
  • IsAlive flag or a life variable (must have, more on that later)
  • Rotation, velocity, acceleration variables (good to have, more on those later)
You will need to be proficient with your game engine & programming language to know how to create this kind of class & manage groups of them.  Some game engines may provide you with a class with most of these features, but you will need to know how to be able to add extra functions/variables if you need it.
Note:
No amount of tutorials can cover every language/ game engine.  As I mentioned at the beginning this is general concepts.  So expect to have to do quite a bit of reading up to match this to your engine.  This set works will for XNA & C++, but might not for your engine.

Simple example: a starfield


Let’s start with a really simple example. A few hundred stars moving across the screen in a continual star field.
To do this we need a lot of stars (Sprites), an array to hold them & an update function to move them across the screen.  Here is the code is pseudo C#:
class Star: Sprite{
  void Update(float dt)
  {
    const Vector2 VELOCITY=new Vector2(-100,0);
    this.Pos += VELOCITY * dt; // move it
    // deal with off screen
    if (this.Pos.x <0)  this.Pos.x+=640; // wrap around
  }
}
List<Star> stars=new List<Stars>();
...
Idiot Warning:
DO NOT COPY THIS CODE IN AND EXPECT IT TO WORK!
We are covering concepts, not exact code.  So you will need to adapt the code to you individual language/game engine.
This is a simple example for a bunch of stars all going in the same direction & a simple wrap around routine to spot when they moved off the screen & put them on the other side.

Sharing Variables: Introducing statics

This starfield code is fine, but what happens if we wanted to change the speed of the starfield?  Answer: we cannot!  Its hard coded into the class.  Many times, that’s fine, but sometimes it might not be.   For example, what it you wanted the stars to move faster/slower when the player speeds up/slows down.  What about if the player starts flying upwards?
So let’s think of an alternative.

  1. Add a public Vector2 Velocity to the Star class, then each star could move at its own speed
  2. Add a public static Vector2 Velocity to the Star class, then all stars could move at the same speed

Now both of these options are good & valid.  The solution is should we use?  Answer, depends upon your real needs.  Remember these posts are about general concepts, not specific solutions.  If there was one fix-all solution, I will tell you.  But there isn’t.  Let’s look at this graphically, it might be a bit clearer:
As you can see: on both cases the star has a position attribute. But in option 2, there is only one velocity attribute which is ‘shared’, while in option 1, each has its own velocity.
For this particular case, I feel that option 2 (the static) is probably more suitable, as this is a single variable to control the movement of all stars at the same time.
So now its just a matter of getting your programming manual & looking up how to implement a static variable in the desired programming language.  Here in pseudo C# is looks like this:
class Star: Sprite
{
  public static Vector2 Velocity=new Vector2(-100,0);
  void Update(float dt)
  {
    this.Pos += Velocity * dt; // move it
    // deal with off screen
    if (this.Pos.x <0)  this.Pos.x+=640; // if off left: wrap around
    // will need to add in the other cases (right, top & bottom) 
  }
}

Collisions & Destructions (Attempt1)

Next item on our topic list is a common topic, collisions & destroying things.  We are going to start with a simple concept, space invaders:
In this case, we will need a list of invaders and a list of bullets (player shots).  I’m going to also assume a list of list of explosions which will nicely animate.
List<Invader> invaders=new List<Invader>();
List<Bullet> bullets=new List<Bullet>();
List<Explosion> explosions=new List<Explosion>();
I will also assume that Invader, Bullet & Explosion are based upon the same Sprite class.
For simplicity: I’m going to put most of my code inside the Game class, rather than the individual classes (its simpler that way).
Lets tackle the most complex bit first, the collisions:

Collisions Done Badly

At first this might seem like a good idea:
for(int e=0; e< invaders.length; e++)
{
  for(int b=0; b< bullets.length; b++)
  {
    if (bullets[b].CollidesWith(invaders[e])) // bullet hits enemy
    {
      createExplosion(invaders[e].position); // big explosion
      invaders.removeAt(e); // remove the enemy
      bullets.removeAt(b); // remove the bullet 
    }
  }
}
Note: if you are a C++ programmer, it will be delete’ing the objects.
How does this code look? Reasonable?
Well, no its not, this code will probably crash within the first 30 minutes of testing.  Let me give you an example:

  1. Assume 10 enemies & 5 bullets.
  2. The code loops through checking each invader against each enemy
  3. This cycle, bullet 0 hits invader 9, the explosion is created
  4. The code then removes bullet 0, since its an array, all the other bullets are moved up
  5. The code then removes invader 9, the invaders array is now reduced to 9 items long
  6. The cycle now continues to check seeing if bullets 1,2,3 hit enemy 9
  7. BUT: If didn’t check one of the bullets (the one in slot 1, since it got moves to slot 0)
  8. AND: it crashes since there is no enemy 9 anymore as the enemies are 0..8

You can try thinking some creative solutions to this problem.  But the bottom line is this.
If you start adding or removing object from an array while you are looping over the array, sooner or later it will break.
This is a well known programming topic: a quick google on “removing objects from a collection while iterating through it” will give you a lot of hits and a lot of ideas.  But rather than try to fix it, let me present you with a different way to approach the problem.

Detour: Object Pool

Recycling is a good idea, reusing stuff & so on.  But did you know that you can recycle in programming too?
Let me give you an idea:
In our space invaders game, how about we create up the array of 40 or so invaders we need at the start of the game.  While we play the game if an invader gets killed, we just set a ‘dead’ flag on the enemy, but leave it in the array.  When moving invaders we skip the dead ones & obviously we don’t draw them either.  However when the next level begins, or the game restarts, we just need to go through the array cancelling all the invader’s ‘dead’ flags.
Seems quite a reasonable idea, just adding a single flag to it and a few if statements. Now let me expand the idea:
In our space invaders game, they invaders can only have a maximum of 3 bombs on the screen at once (an arbitrary limit).  So we have an array with 3 bomb sprites in it.  Each bomb again has this ‘dead’ flag, and at first, all bombs are marked as being ‘dead’.
Each time an invader decides it wants to drop a bomb: it checks the bomb sprite array to see if there are any bombs marked as ‘dead’.  If it finds one, it sets the bombs location just below itself and marks the bomb as not ‘dead’.  If there are no spare bombs, the invader will have to not drop the bomb yet.
The live bombs will drop down and once it hits the ground it marks itself as ‘dead’ and wait to be reused.
I hope you are starting to get the idea on this idea.  Its known as an ‘object pool’, its not only used in games, but its commonly found in games especially those on low memory requirements.
An expanded idea is instead of having a Boolean ‘alive/dead’ attribute, why not have a ‘life’ attribute.  Many sprites in a game need to be hit many times to be killed, so why not use the ‘life’ attribute to determine if a sprite is alive or dead?  For one-hit-kill sprites, just give them life=1!
Technical Note: 
In XNA on the Xbox 360 and the Window Phone and on many other mobile devices there are often lots of warnings about allocating/deallocating too much memory, as the garbage collectors are get overloaded quite quickly.  Therefore having an object pool helps a lot.
And even if you are programming in C++, by not continually new-ing and delete-ing objects you save yourself a lot of pointer headaches by using an object pool.

Collisions & Destructions (Attempt2)

Ok, back to our collision problem we hit earlier.  Let’s use the object pool concept & assume the Sprite class has an ‘isAlive’ attribute which we can use in our game.
Let’s have a look how the code has changed.
for(int e=0; e< invaders.length; e++)
{
  if (!invaders[e].isAlive) continue; // ignore dead invader
  for(int b=0; b< bullets.length; b++)
  {
    if (!bullets[b].isAlive) continue; // ignore dead bullets
    if (bullets[b].CollidesWith(invaders[e])) // bullet hits enemy
    {
      createExplosion(invaders[e].position); // big explosion
      invaders[e].isAlive=false; // enemy is dead
      bullets[b].isAlive=false; // bullet is dead too
    }
  }
}
Other than the additional checking for alive objects, the code is generally much neater.
Note on naming: 
Do you notice that I named my loop variables e and b, not x,y or i,j?
There is a simple reason for this.  What happens if I try accessing bullets[e]?
Answer: it crashes quite quickly.  There are probably only a few bullets in the array, but e was used to index the invaders & probably goes up to 40.  Therefore in this case, I always use a clear loop variable name so I know which is which.
Alternatively you can use an iterator or a foreach, if your programming language supports it.

Other odds & ends

This is a quick wrap up, since we have covered all the main topics.  But here are a few things to consider:
  • Keep your eyes open for common sprite attributes & specific sprite attributes
    • In my examples above: position & isAlive are common to all
      • As it the CollidesWith() function
    • But the Velocity attribute might or might not be a common
    • Think carefully before adding to the base class, but go ahead and add new stuff to the derived class
      • Sometimes I see students adding strange features to the base class, because they don’t know how to use the derived class or manage up-casting & down-casting. (If you don’t know what that means, do look it up)
  • My example above ran with a single Boolean for isAlive, but it could so easily have been an integer variable:
class Sprite
{
  int life;
  bool isAlive(){return life>0;}
  void Destroy(){life=0;}
  void Damage(int amount){life-=amount;}
  ...
}
  • Then we can have the invader injured by a bullet using:
    if (bullets[b].CollidesWith(invaders[e])) // bullet hits enemy
    {
      invaders[e].Damage(5); // damage invader
      bullets[b].Destroy(); // remove bullet
      if (!invaders[e].isAlive()) // its just died
        createExplosion(invaders[e].position); // big explosion
    }
  • Be careful with object pool sizes:
    • The more objects you put in the pool, the more you can have active at once. But the more memory it takes, (having a large pool of dead objects does take a little CPU, but not much) 
    • Ask yourself, do you really need 1000 enemies ‘just in case’?
    • Also remember that it is possible that all pool members might be busy, so always check for it. Eg.
void createExplosion(Vector2 position) // big explosion
{
  // look for spare explosion
  Sprite spare=null;
  foreach(Sprite s in explosions)
  {
    if (!s.isAlive)
    {
      spare=s;
      break;
    }
  }
  // VITAL: check to make sure there is a spare
  if (spare==null) return; // no spares
  ... // do whatever you need
    • Clever programmers will spot the foreach loop & recognise that it could be moved to a function
    • Really clever programmers will realise it can be make into a template/generic function
  • Learn how to tell when it’s better to use two lists of sprites, or combine them into a single list of sprites.
    • I don’t have a good ruling on this one.  Having a list of different types of sprites is what polymorphism is all about isn’t it?  The trouble is that taken too far can cause so much complexity, that it’s easier to separate them.
    • Generally though, it often keep my sprites apart

Conclusion

Although I didn’t touch the 3D sprites, the concepts for both these are exactly the same.  Its all about managing the groups of objects.
Hope this helps get you thinking along the right tracks.
Mark

Monday, 8 July 2013

Game Programming Essentials: Motion of Objects

First topic: making stuff move, obvious stuff.

When I first started making stuff move I tried the following:

for(int x=0;x<640;x+=10)
  draw_enemy(x,20);

But it quickly became obvious that this kind of idea won’t work.


Quite quickly you find out about the game loop:


while(!game_over)
{
  move_everything();
  draw_everything();
}

Which clears matters up and you figure out what you need to do.






Tip:
For those programming XNA: those are the Update() and Draw() functions.
For Unity3D & Flash: its you don’t usually see the Draw() function, you just have a script attached to a sprite/game object, which is in charge of transforming the object.
But generally its the same kind of code.


 


Simple position based movement


So we usually end up with some code to move our player which looks a little like this:



Sprite player;
...
const float SPEED=10;
if (KeyDown(LEFT))
  player.x-=SPEED;
if (KeyDown(RIGHT))
  player.x+=SPEED;
if (KeyDown(UP))
  player.y-=SPEED;
if (KeyDown(DOWN))
  player.y+=SPEED;

And this works just fine.






Tip: Dealing with variable frame rates

Many game engines (especially the 3D ones), are variable frame rate. That means that they might run 30-60 frames per second depending upon how much drawing has to be done. To overcome this variableness (you don’t want your player running twice as fast on some machines), you will include the delta time (amount of time elapsed between two frames) included in the computation:



if (KeyDown(DOWN))
  player.y+=SPEED * deltaTime;


You will need to look in your game engines documentation to check what delta time is in your code.


 

Simple velocity based movement


The next thing we think about it usually how to make a bullet/bomb/car move at a fixed speed in a direction. Normally we end up with code like this:



Sprite bullet;
...
const float SPEED=10;
bullet.y= -SPEED * deltaTime; // -SPEED as its going up

Any this works provided all bullets/bombs/cars go in the same direction, but usually that’s not the case. Therefore we need to have a velocity variable added to our Sprite class (I’m going to assume its vx & vy for simplicity). And our code becomes:



Sprite bullet;
const float SPEED=10;
bullet.vx=0; // not moving left/right
bullet.vy= -SPEED; // moving up
...
bullet.x = bullet.x + bullet.vx * deltaTime; // move by vx
bullet.y = bullet.y + bullet.vy * deltaTime; // move by vy

Does this look familiar to you? How about this?

image

This is the standard equations of motion (https://en.wikipedia.org/wiki/Equations_of_motion) or from your O-level/high-school physics text book.

Look at equation [2], and the code above:



bullet.x = 0 + bullet.vx * deltaTime; // move by vx
s = ut + ½ 0 t2 [2]
// Simplify:
bullet.x = bullet.vx * deltaTime; // move by vx
s = u * t

Guess what? The physics stuff which you studied because you had to pass the physics paper is actually used in your game.








Comment: vx,vy verses vel.x, vel.y

You might be using a game engine with a Vector2 or similar so instead of:



bullet.x = bullet.vx * deltaTime; // move by vx
bullet.y = bullet.vy * deltaTime; // move by vy


You have:



bullet.pos.x = bullet.vel.x * deltaTime; // move by vx
bullet.pos.y = bullet.vel.y * deltaTime; // move by vy


Or even:



bullet.pos = bullet.vel * deltaTime; // move by vel

The concept is the same, it’s just a matter of fitting it to the syntax/game engine.

Remember, I’m selling concepts here, not exact code.

 


Comment: 1D/2D/3D

All my examples here are 2D based (x,y), but the code work 100% the same for 3D (x,y,z) or even for 1D (if you wanted that). If there is anything which is different between 2D & 3D, I will mention it.


 


Adding acceleration to our velocity based movement


Well if the physics stuff works with our velocity routines, we could also add in the acceleration routines. Lets assume the sprite class has an ax, ay for acceleration:



Sprite bullet;
const float SPEED=10;
const float GRAVITY=2;
bullet.vx=0; // not moving left/right
bullet.vy= -SPEED; // moving up
bullet.ax=0; // no acceleration
bullet.ay=GRAVITY; // gravity is down
...
bullet.vx += bullet.ax * deltaTime; // apply acceleration
bullet.vy += bullet.ay * deltaTime; // apply acceleration
bullet.x += bullet.vx * deltaTime; // apply velocity
bullet.y += bullet.vy * deltaTime; // apply velocity

Any there we have it. We launch our bullet, it goes up in the air, and then down again.

 






Comment: Gravity is not always 9.8

I’m sure a few of you looked at the code & said ‘gravity is not 2, its 9.8’. Sorry you are wrong. Gravity on earth is 9.8m/s, but this is not earth, this is a computer game. Our unit of measurement is not meters, its pixels (or some other abstract unit). You will need to fiddle with your SPEED/GRAVITY values until they are the right amount for your game.


 

Adding direction to our velocity based movement


Ok, so a bullet up/down is rather boring, you probably want some kind of directional aiming (like a cannon trajectory), like this:

image

OK, well dust off your maths textbooks & answer me the following question:

image

“But Sir, this is maths!” I hear the cry.

Yes it is! Just like the physics we did earlier!

So get over it & solve it.

...

A bit of head scratching and sin/cosine laws later and we get:






vx = vel cos(elev)

vy = vel sin(elev)


Looking back over our code from earlier we could make the following changes:



const float GRAVITY=2;
const float VELOCITY=5;
const float ELEVATION=PI/2;
// bullet.vx=0; // not moving left/right
bullet.vx=VELOCITY * cos(ELEVATION); 
// bullet.vy= -SPEED; // moving up
bullet.vy=VELOCITY * sin(ELEVATION);

...

And ‘hey presto’, we have a moving object flying on a nice trajectory. All of a sudden all these math classes seem to have some use Smile

 

Next Step: Space Flight


How much new stuff do you think you need to learn to move on to asteroids?

image

Well, pretty much nothing new. It’s just a matter of applying it in a slightly different context.

So here is our basic idea:

The player has a position, a velocity and a rotation. When the press the forward key, it will generate a thrust (acceleration) in whichever direction the player is facing right now. The original asteroids game often did not include a deceleration (drag), but we can add it in later if we chose to.

So here is our basic code:



Sprite player;
const float SPEED=10, TURN_SPEED=PI/2;
player.position=...; // set initial position
player.angle=0; // no angle
player.velocity=Vector2(0,0); // no velocity
...
if (KeyDown(LEFT)) player.angle-=TURN_SPEED * deltaTime;
if (KeyDown(RIGHT)) player.angle+=TURN_SPEED * deltaTime;
if (KeyDown(THRUST))
{
  Vector2 accel;
  accel.x= SPEED * sin(player.angle);
  accel.y= SPEED * cos(player.angle);
  player.velocity += accel * deltaTime;
}
player.position += player.velocity * deltaTime;

 






Comment: Introducing Vector2

I’m getting a little tired of x+= vx; y+= vy; So I’m going to assume some kind of class (Vector2) which holds an X & Y parameter that supports the basic arithmetic operation (+ - * /). Otherwise this code is going to get more and more tedious.


Take note how, when the player presses thrust the velocity changes. But the movement happens regardless of whether the player is thrusting or not. This means that once the player begins moving, they will never stop. The player can only stop if they deliberately turn to face the opposite direction and thrust to stop themselves. This is accurate physics, but not necessarily good for our game.






Comment: Accuracy vs Playability

A key thing to remember in all games is we are aiming for fun, not realism. When I used to play counter-strike in the LAN shop & used to get annoyed at the expert players who would jump out of second floor windows, shooting as they fell & kill me. Or the players who would be continually jumping all over the place while shooting me.
Is it accurate to allow players to jump out of windows without issues? Of course not, but this is an example of where accuracy of the physics is ignored for the benefit of the game.


 

Adding a slowdown: Drag


Now back on topic: lets add in some kind of friction to slow the player down. Actually without some kind of drag it would be possible for the player to reach infinite speed, since they can accelerate forever in one direction. The drag also allows the player who doesn’t press a key to eventually come to a stop. It’s actually quite simple to do:



Sprite player;
const float SPEED=10, TURN_SPEED=PI/2, DRAG=0.01f;
...
if (KeyDown(THRUST))
{
  ...
}
player.velocity -= player.velocity * DRAG * deltaTime; // drag
player.position += player.velocity * deltaTime; // move player

The basic idea here is that, there will always be a bit of drag to slow the player down. The drag is proportional to the players speed. If the drag is 1/10 that’s quite a bit of friction & it will slow down fast. If its 1/1000 that’s very little and will only slow eventually. If the friction is 0.5 or even 1.0, then the object will hardly move at all.

I think the top speed should be SPEED/DRAG, but check it in your game to see how it works & adjust the factors to fit your need.

 

Conclusion


That’s our basic movement. It was only 2D, but the 3D version is just the same. That’s enough for basic gameplay.

Happy Coding:

Mark

Game Programming Essentials: Overview

Hello All,
Today, I’m beginning a series of articles to try to scratch an itch which has been occurring this semester in my game programming classes. The following are questions from my students:
image
image
image
image

image

All the above questions are in effect the same kind of question:
  • “How do I write my game?”
  • “How do I organise my game code?”
  • “How do I code up the game logic?”
Despite the last question saying its a DirectX question, its a more general, more fundamental question than that.  All these questions could be asked for any kind of game in any programming language.

So, here is what this series will be about:
  • Basic game programming techniques:
    • Not graphics, not networking, just the basics
  • No particular language:
    • General bias to C++/C#/Java syntax
    • But its mainly pseudo code
  • No working examples, just idea snippets
    • You will have to convert them to your own programming language/game engine
  • Common ideas, but trying to give as many applications as possible:
    • The same code for a homing missile could be misused to a simple RTS movement
That’s this idea, let’s get coding:

Mark

Friday, 25 January 2013

The easy way to make reports

The problem

Working on my project I have a tendency of generating up lots of data logs.  These things might be players score each time they play it, or how active someone has been while exercising in front of a Kinect.

Either way, its a lot of data & it generally looks like this:

image

I happen to like logging data in comma separated variable format (CSV), as it’s easy to generate, quite easy to read in. And as an added bonus, I can load it into Excel and look at it as a nice graph.

The only real issue: is it’s a bit tedious loading up Excel to have a look at all the data. I’m not sure what my users will think about doing this all the time. But since I didn’t have a better solution & I don’t want to spend weeks building up a GUI front end just to look at some logs, so I left it as is.

An Idea

A couple of days back I was looking at Devmag.org and I found:

And these caught my eye.   The articles are all about writing logs in html to make them easier to visualise. But my logs are all in text format, designed to be easily machine readable/writeable, but not suitable for human reading.

But rather than go back & redesign all my logging code to output html, I decided to write a simple program to read the logfiles & output nice looking html.

The result

Have a look, nice well laid out data.  The appearance is all due to CSS’s, so it’s easy to change the appearance.  The tables are actually filter-able and can be sorted based upon each field thanks to http://www.javascripttoolbox.com/lib/table/

image

And I can have nice effective graphs thanks to http://bluff.jcoglan.com/

image

Conclusion

It was only a day’s worth of C# coding to convert my log files into html.  And that included the time to find suitable JavaScript libraries to do the nice presentation for me.
I can see that this will be used again to make nice looking reports.

Tuesday, 19 June 2012

Game Design Thoughts

The problem:

In my teaching of game programming, I watch students come up with game ideas, try to build them and then fail.  I see some fail because they are lazy and just don’t work at the project, I see others fail because though they have good ideas; they cannot translate those ideas into code.  My concern is those who have the capability, but cannot express the kind of game they want to build, or who express the ideas poorly and miss out important bits of the concept.
I have just finished reading ‘Unity 3D Game Development by Example’ by Ryan Henson Creighton.  The book is fair (but I’m sure some of it is out of date by now), but it has a great concept on the design and keeping the game simple.  So I will borrow some concepts from there and try to string it together into a coherent whole.
I’m writing this to my students and developers who are in a team of 5 or less people and are trying to get something out in a few weeks-months

How not to do it:


(or just go to the original http://www.youtube.com/watch?v=3hMYF2CRFRo and skip to 6:03)


“My game will be like quake <or some other game>, just better!”
  • Brain Dead!
  • Define ‘better’?
  • And if ‘better’ means ‘more weapons, more monsters, more levels, more ...’, then you must be even more brain dead!
“My game will be like Diablo, but with only 2 classes each with 5 special abilities, 5 monsters, 1 level, 3 quests...”
  • This may look better, but it’s still impossible.
  • Ask yourself the following questions:
    • How much effort does it take to design(think up) 5 types of monster?
    • How much effort does it take to design(think up) 50 types of monster?
    • How much effort does it take to draw/animate 5 types of monster?
    • How much effort does it take to draw/animate 50 types of monster?
    • How much effort does it take to program 5 types of monster?
    • How much effort does it take to program 50 types of monster?
  • For the designing and drawing, it will take about 10 times as long to do 50 types of monsters as it will for 5, but for programming, the difference is minimal because of code reuse.
  • However the amount of effort to implement the monster system is a lot. Once it’s in, adding new monsters is easy.
  • Now look at the idea again: you realise that from the programmer’s perspective, it’s got almost as much code as the full game.  Reducing the amount of monsters/quests/classes has not made it any easier.
“My game will be based upon this barbarian. In the beginning his parents and entire village will be killed by raiders and he will escape, vowing revenge and then he will journey across the wilderness and meet up with...”
  • This is not a game, this is a story.
  • Back stories add colour and mood to your game, but they cannot replace the main game mechanic.
  • The early games like space invaders, pong & pacman did not need a story.
  • But they did have gameplay, and your game must have that too.

So what do we need?

Ok, for a while I will park all the content (story, levels, graphics, etc...) off to one side and ask yourself the following questions.  Each answer should be a few sentences, a paragraph at most:
  • What is the game mechanic? How does the game physically function? How to you play the game?
  • What are the main features of the game? What are the technical items which will need to be implemented?
  • Which is the most important feature to making your game interesting/fun/special? (If your answer is ‘Storyline’, then this means that your gameplay must be totally generic and boring)
  • What is the goal of the game? Does the game have an end, or does it just go on forever?  (When answering this question, keep it short and sweet, don’t use the 50 page background story.)
Once you have this, you can talk about the appearance of the game (its skin) and all the rest of the content.

A couple of examples:

Let’s have a couple of simple examples so we are clear on this:

Pong

The one true game.  It’s ancient, yes, but it’s easy to describe.
  • Main Game Mechanic: 2 players, each controlling a bat and bouncing a ball between each other
  • Features:
    • 2 Paddles/Bats
    • Ball, which bounces off the wall & bats
    • Score when ball goes off the screen
    • Win/lose condition
  • Most important feature: The bats & the ball, without it the game is just nothing
  • Goal: First player to X points wins (it is 15 or 21 points, I cannot remember)

PacMan

Another old game.
  • Main Game Mechanic: Player runs around the maze, eating objects and avoiding the ghosts
  • Features:
    • Player which moves about
    • Maze with wrap around
    • Items to eat
    • Bonus items (fruit) to eat for extra score
    • Ghosts which patrol and then start chasing you
    • Player killed when ghost catches it
    • Power pills which turn the ghosts blue, and allows the player to eat them
    • New level when all the items are eaten
    • Three lives
  • Most important feature: It’s the running around the maze with the ghosts chasing you all the way. That what makes the game fun.
  • Goal: After each level the next level is a little harder, no final goal. Losing when you run out of lives

Serious Sam

For those who don’t know, go and look it up on YouTube (http://www.youtube.com/watch?v=uOgnIKjtKyE). It’s an FPS game which doesn’t take itself seriously and requires a 3-4 digit body count every level.
  • Main Game Mechanic: It’s an FPS! Player runs around a level, sometimes having to avoid traps or jump over gaps & stuff, but mainly just shooting bucket loads of monsters
  • Features:
    • FPS Player movement
    • Large 3D maps
    • Moving platforms, doors, triggers, traps & such like
    • Weapons (pistols, shotguns, mini-guns, sniper rifles, rocket launchers, lasers, flame throwers, cannons, etc...)
    • Smart bomb (yes, that’s right, an FPS with a smart bomb!)
    • Items to pickup (health, armour, weapons, ammo)
    • Bad guys which chase after the player
    • Bad guys which shoot at the player
    • Bad guys which kamikaze into the player
    • Boss bad guy’s the size of tower blocks!
    • Scoring
    • Load/save game
    • Plus quite a few other bits I missed...
  • Most important feature: The thing that makes this game most fun is the ludicrous amount of bad guys which you end up mowing down each level
  • Goal: There is a tiny back story, but basically its reaching the end of each level, killing everything in your path

Conclusion

Coming up with a game idea is one thing.  Being able to describe it for others and then break it down into features to be implemented is another.  I hope that this has helped a bit in getting you to think a bit about describing the technical aspects of your game.

Happy Designing, before the coding,
Mark :-)