Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I can't seem to find a nice explanation of the Data Oriented Design for a generic zombie game (it's just an example, pretty common example).

Could you make an example of the Data Oriented Design on creating a generic zombie class? Is the following good?

Zombie list class:

class ZombieList {
    GLuint vbo; // generic zombie vertex model
    std::vector<color>;    // object default color
    std::vector<texture>;  // objects textures
    std::vector<vector3D>; // objects positions
public:
    unsigned int create(); // return object id
    void move(unsigned int objId, vector3D offset);
    void rotate(unsigned int objId, float angle);
    void setColor(unsigned int objId, color c);
    void setPosition(unsigned int objId, color c);
    void setTexture(unsigned int, unsigned int);
    ...
    void update(Player*); // move towards player, attack if near
}

Example:

Player p;

Zombielist zl;
unsigned int first = zl.create();
zl.setPosition(first, vector3D(50, 50));
zl.setTexture(first, texture("zombie1.png"));
...

while (running) { // main loop
    ...
    zl.update(&p);
    zl.draw(); // draw every zombie
}

Or would creating a generic World container that contains every action from bite(zombieId, playerId) to moveTo(playerId, vector) to createPlayer() to shoot(playerId, vector) to face(radians)/face(vector); and contains:

std::vector<zombie>
std::vector<player>
...
std::vector<mapchunk>
...
std::vector<vbobufferid> player_run_animation;
...

be a good example?

Whats the proper way to organize a game with DOD?

share|improve this question

2 Answers 2

up vote 7 down vote accepted

There is no such thing as a "game with DOD". Firstable, that buzz-word is a bit fuzzy, because each system is designed data-oriented. Each program works on a set of data and makes certain transformations to it. Impossible to do that without orienting the design towards the data. So it's not mutually exclusive with "normal" design, but adds constraints in memory layout and the way memory is accessed respectively.

The idea behind DOD is to pack and group data belonging to one functionality closer together in a continious memory block, in order to have less cache misses, getting rid of virtual functions and vtables, easier parallelization, no (or minimal) random memory accesses and to write code for highly optimized processors like the Cell's SPUs in the PS3 with its limited memory resources, optimizing memory access and DMAs to and from it's main memory.

This does not simply mean to change everything from "Array-of-Structures" (AoS) to "Structure of Arrays" (SoA) like shown in the examples here. It can also mean mixing both and to interleave and pack data belonging to one functionality closely together, like for instance "position" and "velocity" to avoid jumping in memory for the integration of the position.

However, pure DOD systems are very hard to implement, as each pointer access is a violation of that pure concept, as you don't access a continious memory block anymore, but doing random memory accesses by dereferencing a pointer. This is particularily important for writing code for the SPU when moving for instance a particle system from the CPU to the SPU, but in the normal daily game development it is not important. It's a way to optimize sub-functionality, not to write games with it (yet, as Noels article explains).

Mike Acton from Insomniac Games has a lot of intesting material related to this topic, you can find some of his stuff here as well as Noel's articles, both highly recommended.

share|improve this answer

I have been searching for a good example of this aswell, but with limited resouces on the net and no one to tell me how to do it properly, i did it with the following implementation. (it might not be the best, but it follows the basic idea)

Object
   //Basic data
   Vector3* Position;
   Vector3* Rotation;
   Vector3* Scale;



Car : Object
    float* acceleration;
    Object* GetObjectData();
    //invoke the updateCars, to update all cars.
    void    UpdateCar() { UpdateCars(Postion, Rotation, Scale);

    //Update all your objects in a big loop.
    void    UpdateCars(vector3* Position, vector3* Rotation, Vector3* scale);

So the implementation is more or less like this : You have an base object class, which holds all common data. When your car class get constructed, you specify what amount of data you want to pool up, and therefor have enough memory for all the objects.

from there you can offcourse add identifiers or what ever feels nessecary for your implementation. but i tried this on a simpler game, and it workt pretty neat.

It´s not that far away from your design either, and frankly i dont know any more efficent way to do this.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.