I'm trying to figure out how to integrate entity component systems with scene graphs in a web game / application. The problem is of course that ECS and scene graphs are very different in nature. They are designed to solve different problems and in many ways contradict each other.

Actually, to be more precise, I’m looking for a way to introduce hierarchical relationships in an ECS architecture. If that involves a scene graph remains to be seen.

What would be a good, conventional way to handle hierarchical relationships in an ECS?

In my application entities on their own are nothing more than IDs. Components are containers of data that stores a reference to the corresponding entity ID. Components are stored outside of the entities. Systems loop through entities and check if they have the relevant components. At least this is how it stands right now.

So far I have come up with the following alternatives:

  1. Hierarchical entities, aka "scene graph with components": Store hierarchical relationships in entities. Turn entities into node objects that hold hierarchical data and possibly other types of data that is typical for nodes. Traverse the scene graph as usual and look up the relevant components for each node.
  2. Hierarchical components: Store hierarchical relationships in components, e.g. childComponent, parentComponent. One or more systems will use these components to traverse the hierarchy and operate on entities (or rather components belonging to entities) in the correct order.
  3. Clear separation: Keep the ECS and the scene graph entirely separate and focused on different tasks. The ECS is focused on gameplay logic while the scene graph handles transformations and rendering. I don’t know if this level of separation is possible.
  4. Separate but synchronized: Keep the ECS and the scene graph separate but synchronized. Have each entity with a certain set of components (position, transformations, etc) correspond to a node in the scene graph. Since both systems work on the same data they will need to be synchronized in some way.
  • 2
    \$\begingroup\$ You may be interested in this earlier Q&A: Dealing with more complex entities in an ECS architecture. \$\endgroup\$
    – DMGregory
    Aug 1, 2023 at 11:36
  • \$\begingroup\$ Thank you @DMGregory ! If I understand correctly, you begin by sorting the entities in order of parent ID. Then you loop through the entities starting with the lowest ID (-1 for root entities). By doing so you ensure that parents are always processed before their children. You don't even have to rely on recursion. The parent ID in the transform component (or parent component if you prefer) allows you to quickly look up the parent. \$\endgroup\$
    – Candleout
    Aug 1, 2023 at 13:21
  • \$\begingroup\$ @DMGregory One potential drawback I see is that you can't easily turn off whole "branches" of entities. Even if you skip one entity, you will still loop through its children and their children and so on. Would be interesting to hear your thoughts on how to deal with this. \$\endgroup\$
    – Candleout
    Aug 1, 2023 at 16:46
  • \$\begingroup\$ I think you can. You can propagate down the "isEnabledInHierarchy" flag from parent to children to grandchildren in a linear scan, in the same manner as you propagate world transformation changes. It's an extra operation, but usually a somewhat infrequent one (most objects don't change state every frame), and probably wouldn't add substantial overhead to the transformation update. If you want a more thorough disabling, I sketch an approach in this answer to get them out of the iteration path entirely. \$\endgroup\$
    – DMGregory
    Aug 1, 2023 at 17:48
  • \$\begingroup\$ Thank you @DMGregory. I think the first method seems like a reasonable approach, at least to start with. I will look into the second approach as well. \$\endgroup\$
    – Candleout
    Aug 3, 2023 at 7:29


You must log in to answer this question.

Browse other questions tagged .