6

In game development there is a notion of Entity System which is aiming to simplify the game loop by gaining a flexible architecture. For details see the links below:

http://www.richardlord.net/blog/what-is-an-entity-framework http://shaun.boyblack.co.za/blog/2012/08/04/games-and-entity-systems/

Now I wonder how it is possible to realize automatic Node creation when a Component is added to an Entity in C++? Please tell me the principle of identifying what Nodes can be spawned from a specific Entity, i.e. you should have list of Component and classes that aggregate components. And you should understand what classes can be created with the list of data.

For example I have Components:

class PositionComponent
{
  int m_x;
  int m_y;
  int m_rotation;
};

class VelocityComponent
{
  int m_vX;
  int m_vY;
  int m_vAngular;
};

class RenderableComponent
{
  Sprite m_view;
};

And nodes:

class MoveNode
{
  PositionComponent m_position;
  VelocityComponent m_velocity;
};

class RenderNode
{
  RenderableComponent m_rend;
  PositionComponent m_position;
};

Now if I create an Entity like this:

Entity * e = new Entity;
e.add(new PositionComponent);
e.add(new VelocityComponent);

Then I want to have a code that creates a MoveNode automatically, and if I add also this:

e.add(new RenderableComponent);

Then I want to know that also RenderNode is created. Consequently, when I delete it:

e.remove(new RenderableComponent);

the RenderNode should be deleted. And this process, of course, should not be bind to the specific Nodes and Components I have defined.

How is it possible to realize this in C++?

Narek
  • 38,779
  • 79
  • 233
  • 389
  • Did you really mean to tag [tag:entity-framework] for what's described there, or is the link you have given a different pair of shoes? – πάντα ῥεῖ Jan 19 '14 at 20:36
  • This frameworks are called Entity Frameworks. But I guess there is a framework, called like that. If it is so, then oops! :) – Narek Jan 20 '14 at 07:06
  • The tag's wiki entry explicitly refers to ADO .NET, doubt you're really referring to this here. May be better just to remove the tag, to reach a broader audience for your question. – πάντα ῥεῖ Jan 20 '14 at 08:16
  • 1
    well i do not see any benefit from this approach it actually complicate things but it can be done (virtual component must have pointers or list of pointers to any possible subcomponent and the presence can be detected by nonzero address or some flag. but opretion with such classes is horrible !!! – Spektre Jan 20 '14 at 10:02

1 Answers1

17

I am slightly confused, since it appears to mix concepts. I will try to shed some light on the two concepts.

Entity & Component

The entity component system is quite common in game engines, for example Unity implements it quite visibly. It tries to address the issue that simple inheritance does not work well in many cases, such as mixing rendering and collision information; is a Collidable also a Renderable? And since multiple inheritance is a scary thing for many and not supported in many languages, the only way out of this is the Entity/Component design. (Actually not the only solution, but that is a different issue.)

The design for entity component is quite simple, you have a class Entity that takes multiple objects of type Component. There will be multiple components that "do" something, like a MeshRenderer, TriMeshCollision or RigidBodyMotion. As stated in the articles, the actual logic does not need to be implemented in the components themselves. The component just "flags" the entity for specific logic. It makes sense to delegate the actual work to be done in a tight loop in a system, maybe even in a different thread, but more to that later.

Then the actual entity is composed. There are two basic ways to do this, in code or in data.

For example you compose objects in code that represent one "real world" object; the object of type Goblin exists and it is derived from the class Entity. The constructor from Goblin will then create all components and register them on itself. Inheritance is now only done for high level logic, for example the FastGoblin is derived from Goblin and only has a different material and speed setting.

The second way to create objects is through data, that is you have some form of object description language. (Take something in XML or JSON) This will then create in a factory method something based on a given template in that is defined in this object description language.

Node Based Work Scheduling

It may make sense to have objects that are fully defined, but the logic not being executed. Think about objects on the server or in the editor. On the server you do not want the rendering code to be in the way. So the basic approach is to create components that contain no data. The problem to solve is, how do you efficiently get things done without iterating through the entire scene each frame and typecasting the objects around?

What your second link describes is basically a botched version of Designing the Framework of a Parallel Game Engine

There needs to be a way to schedule the work in an efficient way. The proposed solution is to have "nodes" that each do a specific task. The nodes are then scheduled, by submitting them to either a work scheduler or a specific system.

Take for example rendering. You have an entity and it has a MeshRenderer component. This component will create a RenderNode and submit it to the RenderSystem. Then when it is time to render the frame the RenderSystem will simply iterate over each RenderNode and call its display method. In the display method the actual rendering is done.

Alternatively the system, engine or entity can create nodes based on specific component configurations. Take for example physics. The Entity has the TriMeshCollision and RigidBodyMovement components. The PhysicsSystem seeing this configuration creates a RigidBodyNode that takes the two components as inputs and thus implements rigid body motion. Should the entity only have a TriMeshCollision component the PhysicsSystem would then create a StaticColliderNode to implement the behavior.

But like the construction mechanic for components from data, the nodes can also be created and attached to the entity through a factory function. This can be part of either the object definition or a rule based system.

Mapping this design into C++ should be straight forward. The rather difficult bit is to figure out a way how the different bits get connected; for example, how the MeshRenderer gets access to the RenderSystem so it can submit its RenderNode. But this can be solved with a singleton (shudder) or by passing a Game/Engine object around at the construction of the Entity or Component.

Is this good design?

But the issue I want to address here is: Is this good design?

I have troubles with your second link (Games And Entity Systems), since I think the design will fall flat on its nose quite quickly. This is true for other aspects like physics, but this will become quite inefficient when considering modern 3D rendering.

When you need to organize the scene spatially to efficiently cull hidden objects, organize the objects into batches for lighting and reduce resource switching then the entire "list of nodes" concepts is moot since you need a separate organisational structure anyway.

At this point you can let the components "talk" directly to the systems and each system has its own unique specific API that is fit for its specific purpose. The requirements of rendering, sound and input are each significantly different and tying to cram them into on API is futile.

See Also

rioki
  • 5,988
  • 5
  • 32
  • 55
  • Thank you for detailed analysis, but I have asked here how to implement the automatic node creation in c++ for Entity Systems. I guess this does not answer my question. Or did I miss something? – Narek Jan 20 '14 at 15:06
  • Does this not solve your problem: "You have an entity and it has a MeshRenderer component. This component will create a RenderNode and submit it to the RenderSystem." There is nothing automatic, the node is bound to the component in that they two belong sort of together. The component will simply create the node, for example with new. – rioki Jan 20 '14 at 15:09
  • A Node should be a composition of multiple components in general. In this case I don't understand how the Component can create a Node. – Narek Jan 20 '14 at 15:25
  • I reread the relevant section of "Games And Entity Systems" and in that case basically you need to affix the node "from the outside". This would be done in the derived class, i.e. Goblin, or the factory method. An entity is defined not only by the component but the nodes. Alternatively either systems or the engine can detect specific component compositions and generate the appropriate nodes. (I will amend the answer to reflect this.) – rioki Jan 20 '14 at 15:31
  • The idea is that the Engine should detect and create appropriate nodes. But How it can be done in C++, this is my question :) – Narek Jan 20 '14 at 15:34
  • I don't think that each specific system should create the nodes and add it to the engine. I think this work should do the engine itself, so that we could rely on the process on Framework code. I mean if we create an Entity System framework, the framework should take care of Node creation and not the framework user who create specific Systems. What you think? – Narek Jan 20 '14 at 19:40
  • Whatever suites your need. There is not one definite answer... I personally think the Entity/Component in general and the "Games And Entity Systems" in specific are over-engineering the problem. There are approaches are more compacter and more efficient than that. – rioki Jan 22 '14 at 12:36
  • rioki please tell me an example of other approach. I need to read them, please! – Narek Jan 23 '14 at 12:05
  • 2
    Model-View-Controller, Document-View, Scene-Graph, Binary-Space-Partition are some search terms you can feed into Google. It basically boils down to plain old software engineering, the underlying architectural problems are no different from a word processor than a game engine. Start building something small and simple and then scale that up where it starts to hurt. Over engineering a problem is never a good idea. – rioki Jan 26 '14 at 11:19
  • Thank you so much, about MVC I know, but the other I will investigate with pleasure. – Narek Jan 26 '14 at 12:07