Showing posts with label game. Show all posts
Showing posts with label game. Show all posts

Sunday, 7 October 2012

Video Game in C: using X macros to define game data

As my brother and I recently released our last video game voxel invaders on android and symbian, I though I would share some of the technical details about it. For my the first post I will talk about a quite useful, although rarely used, C trick known as "X macros", and how we can use it to simplify game code.

The code is written in plain C, and the original design was very simple: all the elements of the game are stored in a structure (called obj_t in the code) that looks like that:

struct obj_t { 
    int type;
    float pos[3];
    float speed[3];
    sprite_t *sprite;
    // A lot of other attributes follow...
};

The important attribute of the structure is the first one: int type. This value allows us to differentiate all the kinds of objects in the game (in C++ I would have probably used subclassing instead). We can see it as a pointer to the object class, except that it is not a real pointer but an index on an array of a structure obj_info_t that contains all the information about a type of object (the game equivalent of a C++ class).

file objects.h:

struct obj_info_t {
   const char *sprite_file;
   float initial_speed[3];
   void (*on_hit)();
   // Lot of other attributes...
};

enum {
   PLAYER,
   ENEMY_A,
   ENEMY_B,
   // And so on...
   OBJ_COUNT
};

file objects.c:

obj_info_t obj_infos[] = {
    // PLAYER
    {
        "data/img1.png",  // sprite_file
        {0, 1, 0},        // initial speed
        NULL             // on hit
    },
    // ENEMY_A
    {
        "data/img2.png",  // sprite_file
        {1, 2, 2},        // initial speed
        enemy_a_on_hit    // on hit
    },
    // And so on..
};

By the way, this kind of design was mostly inspired by the code of the original doom game by John Carmack.

The first improvement we can do is to realize that since we are using C98, we can make the array declaration look better using designated initializers:

file objects.c:

obj_info_t obj_infos[] = {
    [PLAYER] = {
        .sprite_file = "data/img1.png",
        .initial_speed = {0, 1, 0},
    },
    [ENEMY_A] = {
        .sprite_file = "data/img2.png",
        .initial_speed = {1, 2, 2},
        .on_hit = enemy_a_on_hit,
    },
    // And so on.
};

See how the code already looks nice and simple. Although this is how our code looked like for a while, at some point we started to get annoyed by a problem with this pattern. The problem is that every time we define a new enemy, we need to modify too files: the file containing the object types enum, and the file containing the object infos array. Beside, since there is no way to separate the array or the enum into several files, those two files got bigger and bigger. This might not seem too bad, but really it is, specially when you have to find the definition of a given object in the thousand of lines of code containing the obj_infos array.

As I mentioned, the original doom engine also used this kind of pattern, and I think the way they overcame this problem was to use a special tool that would automatically generate the C code for both the enum and the array.

In our case I though writing a C generator tool would be overkill. That is where I realized that there is a simple way to have the C preprocessor generates those two parts (enum and global array) for us. Later when I searched for occurrences of this pattern online I found out this is known as "X macros", there is a very comprehensive article about it from Randy Meyers.

The idea behind C macros is to use a C preprocessor macro that, depending on the context, will expand to either the enum part, either the array initializer part.

In our simple case, it would be something like this:

file object_defs.h:

OBJ(PLAYER,
    .sprite_file = "data/img1.png",
    .initial_speed = {0, 1, -},
)

OBJ(ENEMY_A,
    .sprite_file = "data/img2/png",
    .initial_speed = {1, 2, 2},
    .on_hit = enemy_a_on_hit,
)

file object.h:

#define OBJ(name, ...) name,

enum {
    #include "object_defs.h"
}

file objects.c:

#define OBJ(name, ...) [name] = {__VA_ARGS__},

obj_info_t obj_infos[] = {
    #include "object_defs.h"
}

And so, thanks to this trick, we just need to modify the objects_def.h file to add or remove an object type. Both our enum and our global array will be automatically updated by the preprocessor at compile time. As a bonus, this makes it easy to split the object definitions into several files. For that we just need to #include all the needed files instead of just object_defs.h.

Sunday, 23 September 2012

Voxel Invaders : space invader + 3d voxels



This week we (noctua software) released our new video game for android phone: voxel invaders.
This is the sequel of our previous game Retrocosmos, and it follows the same principle (making a fun space invader game for touch screen devices).  Only this time we used 3d voxels (the equivalent of pixels in 3d) for all the graphics.

Voxels based games are starting to appear more and more and are particularly interesting for independent developers because it is much easier to generate a voxel model than a traditional 3d model.

Anyway back to the game:  this has been written almost entirely in C using android ndk, with just a few java code for some of the stuffs the ndk does not allow to do easily (like controlling the device vibrator). I wrote the engine from scratch, using opengl es 2 for the rendering, and some interesting C hacks using macro for the enemies behaviour state machines (maybe I'll do an other post on that an other time).  The good thing about that is that if the game is a success it will be quite easy to port it to other platforms like iOS or symbian.

From a marketing point of view, we did two versions of the game: a free demo and a full paid version.  We have little experience of this kind of approach so I might do a follow up an other time about how much money we made from that.

Here is a video of the gameplay:



Thursday, 22 January 2009

online javascript game, in python

Last time I spoke about pypy, which allow (among other things) to translate python code into other languages.

This week I wrote a small video game (inspired by the famous boulder dash game) in rpython and used pypy to create an online version of the game out of it.

You can play the game here.
The sources can be found here.

The game as it is now is not really fun, but I only wrote it as an example of using pypy.

What I like with this approach is that I can develop in rpython, and even run the game using python interpreter, and only before I publish it use pypy to create the javascript version.

I could also create a C version using the same code for the game engine (only the graphic functions would have to be rewritten for each backends.)

This open the door to a lot of interesting applications.

On a side note, the pypy javascript translation is really not optimised. For example, let's try to guess what this generated function does :

function (){
var v1086,v1087,self_145;
var block = 0;
for(;;){
switch(block){
case 0:
self_144 = this;
self_145 = self_144;
block = 1;
break;
case 1:
v1086 = 'H';
block = 2;
break;
case 2:
return ( v1086 );
}
}
}

I don't want to spoil the fun of figuring this out by giving the answer...

Sunday, 12 October 2008

D programming on Openmoko

Today I decided to start to write a video game for OpenMoko.

I am a little bit disappointed by all the current available games for openmoko (I like action games). And the port of already existing games that I tried all have poor usability because they are not usable with a touchscreen (A touch screen is much more limited than a mouse, cause you can't move the pointer when you don't click)

So anyway, I wanted to write a very simple game where asteroids are falling from space and you have to destroy them by launching missile from the ground. The control is very simple : touch the screen to fire a missile to the pointed position.

I want the code of the game to be very small and simple, yet fast. I started to write it in vala, but after profiling got a little bit frustrated to see that a lot of time was spent getting and setting gobject properties.

I was about to consider cython + python or C++, and then I found that gdc, the gnu D programming language compiler, was available in the debian distribution for openmoko.

I immediately tried to compile my game guisterax, and it worked fine. Of course no way to play it without the keyboard, but that is great anyway.
D would be a perfect language for embedded applications.

Now the problem is that as far as I know it is not possible to compile D sources using openembedded yet, so I may have to use an other language for my game anyway.