0
\$\begingroup\$

I've read some articles about Entity Component System and I like this idea of "entities" having lots of "components" to define them, so I tried to implement it. Here is an simple overview of what i've got so far:

I've a template class that will hold a list for each component type that exit Component Collection Template

That allows me to have a collection of components by its type enter image description here

Which is good because in memory components will be contiguous enter image description here

Then I've a component manager that hold all these collections and allows me to retrieve a collection at any time enter image description here

Also, each entity keeps tack of all components it has with a bitset

So in the final result, each index of all component containers belongs to an entity

enter image description here

I know that this causes a problem than, not all entities have all components, so it causes a waste of space... But for now, I can (saldy) live with it

enter image description here

But the real issue for me here is that some components will have same data, and if each entity have a component for that data, this data will be duplicated unnecessary

enter image description here

Even worst, it would require OpenGL to have different objects in memory that are exactly equal and having to enable those objects and disable them many times is not desirable at all.

I've been scratching my head to figure out a solution for this issue but I can't find any. Could someone give me an advice please?

If you've read this far, Thank You!

\$\endgroup\$
  • \$\begingroup\$ Pointer to the data, or have a class that wraps the VBO, and only gives a reference to it for each element. Note you don't need to use entity component systems for every element of your game, and if your entity component system is making it more difficult to make your project you're doing it wrong, or it doesn't belong in your project. \$\endgroup\$ – whn Feb 2 '18 at 14:27
  • \$\begingroup\$ Entity Component System solves a lot of problems and most of articles about this pattern/principle show some basic implementation giving the idea that it is easy to implement, so I decided to try it out, but it seems that it is not that trivial as "they" say. \$\endgroup\$ – Vadimz Feb 2 '18 at 14:49
  • 1
    \$\begingroup\$ Entity component systems solve one specific problem that spawns a lot of issues, they do not solve a lot of problems. ECS is meant to solve adding uncapped number of effects, features, aspects, etc.. to "entities" in your game with out having to make entity classes specific to each of those combinations of components. If you have a very large or wide hard to maintain class hierarchy, and the number of entities isn't the largest performance cost, ECS system is a potential solution. It is not a general tool for every game. In RPGs it can make sense, but in counter strike or starcraft? No. \$\endgroup\$ – whn Feb 2 '18 at 14:58
2
\$\begingroup\$

When you have a large amount of data shared between multiple game entities, then the component representing that data might be a good candidate for the flyweight pattern. Your Mesh component shouldn't include the full mesh data. It should only have a reference to which mesh asset is used to represent that entity (in an OpenGL-based graphic engine, this could just be the ID of the vertex buffer object), plus any entity-specific metadata which is relevant to how that mesh is applied to this particular entity. The mesh assets themselves should be stored in an own data structure separated from the entities.

Now you might be skeptical about what this means for memory locality when the mesh data is no longer close to the rest of the entity. But you need to ask yourself: if the data is shared, how often will you actually access it? Remember that you can not manipulate it while processing a specific entity, because that manipulation would also affect all other entities. There are also very few reasons I could think of to regularly access the actual mesh data. Your rendering system will just require the VBO id and the model matrix derived from your Transform component.

The only thing I could think of which could make use of the actual mesh data is collision detection, and in that case you should not use the high detail meshes used for the graphical representation. Performance will force you to use a low-detail mesh which would be small enough that data duplication isn't that much of an issue anymore.

\$\endgroup\$
  • \$\begingroup\$ Oh man, I completely forgot about flyweight pattern... I've read about it long time ago. Well, one level of indirection, at this stage, wouldn't hurt too much. Thank you! You're awesome ;) \$\endgroup\$ – Vadimz Feb 2 '18 at 14:42
0
\$\begingroup\$

Each of your ComponentCollection might have different constraints or ways to optimize data storage, so I would relax the design of the base class.
By doing so, the template-based ComponentCollection could be one implementation of the base class, used for standard component types, while your Mesh collection could store data with another structure, more appropriate to share meshes among different entities.

\$\endgroup\$
  • \$\begingroup\$ Hmmm I see, but the problem here is that I would need to hard code ech ComponentCollection for each component that I create. My ComponentManager class manages all ComponentCollections, this means that I just need to write a component and then add it to the entity, the ComponentManager will manage its Collection. Thank you anyway, who knows, perhaps I will need to write some more specific Collections... Thank you. \$\endgroup\$ – Vadimz Feb 2 '18 at 14:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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