1
\$\begingroup\$

Whilst working on examples and upgrades for my C++ Entity System, something randomly caught the attention of my mind, by surprise: duplicate data. What I'm referring to is how an entity system that uses other libraries (e.g. Ogre3D, SFML, etc.), which already store some information about your entities, handles storing information in custom components.

The Problem:

Say you have two define component types, called: Position component (which holds the location of an Entity) and Velocitycomponent (which holds how fast an Entity is moving, and the direction it is moving toward). And of course, you have a Movement system, which moves entities with a Position and Velocity component attached to it. Now... here comes the tricky part, how would you store the Position component effectively/efficiently, so that you do not duplicate data? By duplication of data, this is what I mean (this is a simple example): a Sprite object typically has it's own x/y position (take for example, SFML's Sprite class), therefore if I had a Position component with it's own x/y values, then I would be duplicating data, would I not? I thought about using pointers/references* in a Position component, but that doesn't really work out if I want to save entities to files.

*Yes, I do know that sizeof(float) == sizeof(float*), but sizeof(vec2/3) != sizeof(vec2/3*). This doesn't really seem much of a problem at first: but what if I had bigger objects to store, such as:

A Mesh:

How would I store a Mesh effectively in a component? I was thinking of just storing a string to where the mesh data was located, but then I thought, what if it's not in a file? How do I resolve that? I also thought to store the raw data in the component, but if I use a 3rd party graphics library (such as Ogre3D or Irrlicht), then I require to actually create the Mesh data via another object.

So, the summed up question is: what's the best way to reduce duplicate data, using an Entity System design, in your game?

Would I have to re-make everything from scratch so that it just "fits" in my entity-system? I'd prefer not to do that, especially if I decide to change the design pattern that I use to make games.

\$\endgroup\$
0

1 Answer 1

4
\$\begingroup\$

It's typical than an Entity System will duplicate some data.

Some solutions I've seen is that the Position component contains a transform representing the world position & orientation of the entity. The renderable component has a reference to the position component, as does the physics component. In other designs, the renderable system and physics systems connect to signal emitters on the transform component or register for some event/message notification when the position is modified.

When such a signal/callback/notification fires, the renderable and physics components both update their internal state by copying the vector from the position component.

By duplicating the data, you eliminate coupling, can avoid using pointers which often can be a source of bugs if a dangling pointer isn't cleaned up and has some benefits to potential running various updates in parallel without contention (ie: can run physics while rendering allowing physics to update the position but the rendering can render to the old location until its safe for the renderable to update its position value).

Also keep in mind that you may be creating the position component first. If you expect your position component to have a scene node or sprite position pointer but you haven't created the renderable component yet to allocate a scene node or a sprite component to create a sprite object, then you have no pointer you can yet reference. Now you've imposed a dependency order needed on creating & adding components to entities. I generally prefer to avoid this and have some dependency check system in place when adding components that allow them to link up as they need in a special init phase for an entity.

Lastly, there is nothing stopping you from creating a Mesh component that allows you to

  • Specify the filename for the mesh to load and use.
  • Specify the data buffer needed to render the mesh

Whatever code examines the mesh components can check to see what values were provided and based on them, decide how to decode the component data for rendering.

In our engine, we have the ability to specify a list of skins that a mesh can use. By selecting a particular skin, the appropriate mesh is rendered. For mesh components where there is only one skin, the list simply has a single value. If we need something specialized, we have a choice: new component or modify an existing component if it makes sense to do so.

\$\endgroup\$
2
  • \$\begingroup\$ Hm, perhaps duplicating data is not that bad of an issue. Just a little more complicated than expected. \$\endgroup\$ Jan 12, 2013 at 10:05
  • \$\begingroup\$ @Miguel Duplicating data isn't necessarily bad if there a logical reason to do so. Entity Systems, depending on how you organize your game loop, usually play really nice with parallism ideas when things are adequately decoupled that you can minimize or avoid the need to use any synchronization concepts between each parallel thread of execution. This is where duplicating data can really help and you simply define specific sync points where you replicate the data between components/systems where needed. \$\endgroup\$
    – Naros
    Jan 12, 2013 at 22:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .