2
\$\begingroup\$

I would like to implement entity system in my game and I've got some question about entity system and rendering.

Currently, my renderer got two types of elements:

Current design

  • Mesh : A default renderable with a Material, a Geometry and a Transformable
  • Sprite : A type of mesh with some methods like "flip" and "setRect" methods and a rect member (With an imposed geometry, a quad)

This objects inherit from "Spacial" class.

Questions:

  • How can I handle this two types in an entity system?
  • I'm thinking about using "MeshComponent" and "SpriteComponent", but if I do that, an entity could have a Mesh and a Sprite at the same type, it's look stupid, right?

I thought the idea to have a parent "rendering" component : "RenderableComponent" for "MeshComponent" and "SpriteComponent" but it will be difficult to handle "cast" in the game (ex: did I need to ask entity->getComponent or SpineComponent, …)

Thanks a lot for reading me!

My entity system work like that:

---------------------------------------------------------------------------
Entity* entity = world->createEntity();

MeshComponent* mesh = entity->addComponent<MeshComponent>(material);
mesh->loadFromFile("monkey.obj");

PhysicComponent* physic = entity->addComponent<PhysicComponent>();
physic->setMass(5.4f);
physic->setVelocity( 0.5f, 2.f );
---------------------------------------------------------------------------
class RenderingSystem
{
    private:
        Scene scene;
    public:
        void onEntityAdded( Entity* entity )
        {
            scene.addMesh( entity->getComponent<MeshComponent>() );
        }
}

class PhysicSystem
{
    private:
        World world;
    public:
        void onEntityAdded( Entity* entity )
        {
            world.addBody( entity->getComponent<PhysicComponent>()->getBody() );
        }

        void process( Entity* entity )
        {
            PhysicComponent* physic = entity->getComponent<PhysicComponent>();
        }
}

---------------------------------------------------------------------------
\$\endgroup\$
  • \$\begingroup\$ You're using the words "inherit" a lot when describing your entity system. Entity systems are meant to avoid inheritance. en.wikipedia.org/wiki/Entity_component_system \$\endgroup\$ – josaphatv Oct 17 '13 at 21:25
  • \$\begingroup\$ Yes, That's why I ask how I can do without inheritance with my renderer architecture :/ \$\endgroup\$ – Papi75 Oct 17 '13 at 21:26
  • \$\begingroup\$ What have you done? It doesn't seem like you've started writing your Entity Component System and it doesn't seem like you know what it is. There's no reason for you to spend time implementing something you don't understand. \$\endgroup\$ – josaphatv Oct 17 '13 at 21:31
  • \$\begingroup\$ I've write an entity system, I've edited my message to show how it work ;) \$\endgroup\$ – Papi75 Oct 17 '13 at 21:45
  • \$\begingroup\$ Maybe an entity needs both a mesh and a sprite, why not let your designers decide what to use instead of making programmer-art decisions for them =) The component idea is one of flexibility, and that means being flexible enough to look stupid sometimes. \$\endgroup\$ – Patrick Hughes Oct 17 '13 at 23:59
2
\$\begingroup\$

Different types of renderables are different components. They have different interfaces. They are processed by the rendering system differently.

You don't need to have a strict 1-1 mapping between components and systems. A single system may be responsible for multiple components. Some components may need to register themselves into multiple systems (albeit not usually). Some components may be just data and their "system" might really just be an object factory/allocator.

Consider:

 class RenderSystem {
 public:
     void RegisterComponent(MeshComponent* mesh);
     void RegisterComponent(SpriteComponent* sprite);
     void RegisterComponent(ParticleSystemComponent* particles);
 };

 class MeshComponent : public Component<RenderSystem> { ... };
 class SpriteComponent : public Component<RenderSystem> { ... };
 class ParticleSystemComponent : public Component<RenderSystem> { ... };

Each component has nothing in common. The render system keeps the three different components in three different lists. Optimally rendering a bunch of sprites is different than optimally rendering a bunch of (potentially animated) meshes, but the render system does want to be aware of both and potentially interleave them in some cases.

So far as an entity having a mesh and a sprite at the same time looking stupid, sure it would. That's a data problem, not a C++ problem nor a problem with your architecture. Components allow designers to make all kinds of stupid combinations or leave off components necessary for gameplay. That's a downside to components - your designers need to be vaguely aware of what components are, which components do what, and what combinations make sense for viable gameplay.

\$\endgroup\$
  • \$\begingroup\$ what if two components actually shared some of the behavior and satisfy liskov substitution principle, won't using inheritance in this case make sense even in a component system? \$\endgroup\$ – concept3d Oct 17 '13 at 22:57
  • \$\begingroup\$ inheritance makes plenty of sense at times, sure, but not in the rendering context asked about, imo. \$\endgroup\$ – Sean Middleditch Oct 17 '13 at 23:28

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.