storing the game state

Started by
2 comments, last by Inferiarum 10 years, 11 months ago

Hello everyone,

So I was thinking about how to store the game state for all entities. Let's say we have two properties, position and velocity. If each entity has the same properties we can just store those in flat arrays (I hope my pseudo-code is understandable)

Array<Vec3> pos

Array<Vec3> vel

and then if we integrate the positions we can simply do

for ix = 1 to lenth(pos) do

pos[ix] = pos[ix] + vel[ix]

end

which is also very fast. Now what if not every entity has the velocity property? We only have to update entities that have a velocity, but we also need to know the position of the entity. One straightforward solution would be to assign unique identifiers to the entities and store every property in a map or dictionary,

Map<EntId, Vec3> pos

Map<EntId, Vec3> vel

which could be iterated over similarly,

for each (id, v) in vel do

pos[id] = pos[id] + v

end

however this is kind of slow (about 100 times slower in my benchmark with 1000 entities). And I think I remember reading something here on the forum where someone gave the advice not to store everything in maps like this.

So I know about these entity component systems, and what I am doing here is actually very similar, but I do not really want to use some kind of framework. I am totally happy with storing the whole game state in global variables. I already have some ideas on how to approach this, but none of them seem really elegant. I would be happy to hear some opinions.

Advertisement

If you are worried about performance of maps, then use an array of structures - store all properties in one structure and use a separate boolean flag (or enum) to indicate what kind of entity it is.

If the entities have different purpose, then you do need a separate type / structure for each. If there are some common properties (as e.g. position), then go for Inheritance (if it makes sense - don't create inheritance hierarchy if all you have are just those 2 properties - that'd be an overkill).

The code, however, will be much more readable, if you have separate types and handle those 2 entities in its separate for () cycles.

After all, with different properties, they have different behavior - and you do want to separate that in code.

VladR My 3rd person action RPG on GreenLight: http://steamcommunity.com/sharedfiles/filedetails/?id=92951596

however this is kind of slow (about 100 times slower in my benchmark with 1000 entities). And I think I remember reading something here on the forum where someone gave the advice not to store everything in maps like this.

Did you do your performance test in debug or release mode (if you are visual studio, otherwise with or without optimizations)? Under "real world" testing conditions, both methods should be almost identically fast - in fact, method 2 will be slower, but for 1000 entities, it should be no more than a few nanoseconds.

Also note that again, in a real game, you'll have so much more calculations going on, that straigth iterating through entities and/or their components isn't going to count in any way. For example, I have 10 different systems that all have to iterate through their own component - composition list. I'm also currently unoptimized, as this list needs to be recreated every frame. And still, with 1000 entities, the cost for iteration is > ~1.0% in release mode.

Then again, I'm not storing my components in any maps. I store my entities in a flat array (c++ vector) and iterate through them. Each entities stores pointers to its own components, again in a vector. When iterating, I use a bitmask to identify entities with certain components that I want to update, and access those components directly from the entity. If you are after performance, this is probably the best way to go.

Then again, I'm not storing my components in any maps. I store my entities in a flat array (c++ vector) and iterate through them. Each entities stores pointers to its own components, again in a vector. When iterating, I use a bitmask to identify entities with certain components that I want to update, and access those components directly from the entity. If you are after performance, this is probably the best way to go.

After some thought I decided to store all game state components in flat arrays with equal size. That is, I basically allocate all components (or at least pointers to the components) for all entities. I guess I could add an array of bitmasks to generate lists for the update functions like you suggested.

For now, in each function that updates the game state, I iterate through all indices and skip those that are not used at the moment (indicated by another boolean game state component) and those for which not all necessary components are present (indicated by NULL pointers or equivalent zero values).

This lets me write my gameplay code pretty straightforward without any indirections.

This topic is closed to new replies.

Advertisement