need help with data oriented design

Started by
22 comments, last by cool mr croc 11 years, 10 months ago
so im still waiting for that eureka moment where i can fully implement what ive learnt about DOD. my problem is although i can understand how to change the collection class into a class containing a collection, i just cant figure out how different collections can interact with each other. say i have a class of balls and a class of bricks and a bat class, in what sort of relationship can their classes have whilst being cache friendly?

please assume ive googled and have been reading/programming for 3 days straight on this topic.
Advertisement
Hmm, I've read a little about the topic myself. I don't think I can answer you flat-out, but maybe my take will give a more concrete basis for discussion.

Assuming you have many bricks, many balls and only one bat, you might have something like the following:

class Balls
{
vector<Point> pos;
vector<Color> color;
vector<double> radius;
};
class Bricks
{
vector<Point> pos;
vector<Color> color;
vector<double> width;
};
class Bat
{
Point pos;
double width;
};


To check for collisions with the bat, you could loop through the pos vector for all Balls and compare with the Bat pos, thereby keeping the cache full of Ball positions. Checking for collisions between the Balls and the Bricks... seems trickier to do efficiently unless you assume the number of Balls is much less than the number of Bricks. You could loop through the Balls pos vector and compare to all Bricks pos vectors, thereby keeping the cache filled with Brick positions. The Balls may lose out cache-wise, but perhaps not a big deal.

From what I gather you have to really work hard at getting your data structure right, because changing rules and/or refactoring is hell.
just seeing it laid out like that is a big help, thanks. cant radius and width be removed from the top 2 classes though, as its the same for all entities? and if so could it be held in an entitiesmanager? something like


enum entityname
{
e_brick = 0;
e_ ball,
}

class entitismanager
{
vector<dimension> the dimensions;
void somefunction()
{
//access vector like
thedimensions[e_brick]...
}
}
i suppose it could be held like


class Balls
{
vector<Point> pos;
vector<Color> color;
vector<double> radius;
};



another question, if the balls struct ends up with the same datatypes as bricks, is it ok to call it entities and have 2 instances in the manager class? i assume it is
Could you maybe define the term "relationship" some more in this context? What kind of interactions should your data have with eachother?
I've always approached Data-oriented design with some care, since it's really easy to work yourself into some nasty problems when trying to convert existing OO code to DO code. Same goes for approaching DO with an OO mindset, and these days a large amount of programmers have the idea of objects nested deeply in their minds.

I've always thought it easier to first of all take a piece of paper and lay out the steps of how to solve a problem in an OO design. After that you can start switching around steps or altering parts of your implementation on paper until you have a system which centers around data instead of code.

You should also consider whether it will actually give you any real benefits to abandon your trusted paradigm in favor of DOD? Are you seeing such a problem with your cache usage that there's no other option than switching over to DOD? From what I've read you'll gain the most from DOD when developing for consoles where you'll meet more hardware limitations

I gets all your texture budgets!

i have no problem with my current projects, im just trying to learn for when im next on a console and im asked to use DOD.

the relationships between the entities are pretty much just collision.
Data oriented design does not prohibit you from using any form of spacial partitioning, so the approach for doing collision would be the same as you would do in any other paradigm.

I had my "eureka-moment" with DOD when it was described to me as being like how you would design a particle system. You have a pool of data which is run through the appropriate chain of systems to get a desired output, just like how you would emit and update particles.

I gets all your texture budgets!

yes i saw an example on here of that, with code.

http://www.gamedev.net/topic/575076-what-is-data-oriented-programming/page__st__20

but it assumes all particles are the same. i cant seem to get my head around how to handle it if the particles are different. perhaps just other vectors holding the differing values, velocity, colour etc?
This is an issue of proper design and layout of data. In a well-designed particle system you shouldn't try to pool together a bunch of different types of particles each with a differing data structure, you should try to design a particle in such a way that it can be used to build many different outcomes while retaining the same base data structure.

I gets all your texture budgets!

The point of DOD is to sort your data so that it's as consistent for as long as it can. If you need to switch states between entities all the time while looping, you're not doing it right. If the bricks and balls differ enough to require an "if ball else if brick" statement, you should definitely split them up and run separately. Think of them as two sets of unrelated particles.

For collisions, you take the required data (width and maybe position) of the objects, rather than the full objects, put them into a lean vector or two and rip through it in a data consistent manner. This opposed to loading a vector with the full fat objects draining cache and having to jump over the data in them that you don't touch anyway.

Where the data differ, you make separate passes. For example, all ball - ball collisions makes one set, all ball - brick in one set, and then run specialized functions for each.

This topic is closed to new replies.

Advertisement