Jump to content
  • Advertisement
Sign in to follow this  
Dynx

Entity system confusion

This topic is 3722 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everyone, First of all, I possibly read almost all of Entity/Component based system design before I designed my own and truth is, I'm not sure if I learned a lot from those and I got stuck. Either I've been doing really good, or I completely misunderstood the entity system idea. The issues that are making me write this forum post are below: 1. I faced with component dependencies. For example here is the Mesh component constructor:
Mesh( unsigned int entityID, std::string meshName, std::string meshFilename, std::string cmpPosition );

cmpPosition is the name of the Position component which holds the position data. Mesh comp. in the constructor, grabs a pointer to the sibling position component using that name string and retrieves the position data from that component and uses it every frame to update the position of Ogre SceneNode. 1. I came to a point where I had to memorize the names of the components to be able to use the entity. For example in my WorldManager, I have a setActiveCamera function that sets a Camera to active mode. See below.
void WorldManager::setActiveCamera( int viewport, string CameraEntityName, string CameraComponentName, string PositionComponentName )

It's not enough to give the name of the entity as you can see, because an entity keeps pointers to Component (which is a base class that every component derives from). This is what it looks like inside the above function:
//Get the entity
Entity::Entity* entCam = Entity::EntityManager::getInstance().getEntity( CameraEntityName );

//Get it's camera component
Components::Camera* cmpCam  = reinterpret_cast<Components::Camera*>( entCam->getComponent( CameraComponentName ) );

//Get it's position component and save it to update the position of the listener (for sound engine) every frame.
cmpPos_ = reinterpret_cast<Components::Position*>( entCam->getComponent( PositionComponentName ) );

//Use the camera component of the entity to actually set the camera active.
cmpCam->setActive( viewport );
3. If there are no issues up to this point (components being aware of other sibling components), then I'm stuck with inter-component communication. I wrote an event system which works fine, but for instance, for the above example for the Mesh component to update it's position, Position component sends an event of type ( "EntityName" + "Position" ) so that it is unique. Mesh component registers to listen to events of type ( "EntityName" + "Position" ) so that it actually registers to receive position update events only for the entity it's attached to, not all position components in the world. 4. Again if I'm right up to this point, then I have a problem defining an entity. For example here is a simple robot definition: entity robot { mesh robot.mesh } The entity system parses the first line and registers the following tokens under the name "robot". If I wanna create an entity, what I do is this:
EntityManager::getInstance().spawnEntity( "robot", "GoodRobot" );
After that tokens are parsed. So take the first token, "mesh". It's a Mesh component token, so the system creates a Mesh component and uses "robot.mesh" to instantiate it and attaches it to the entity. Now the problem is, mesh was listening to the events of type ( "EntityName" + "Position" ) which is not created so far and won't be. I can't simply make it to look like this: entity robot { position "100 200 300" mesh robot.mesh } ...because an entity definition should be position-free. So how do I add that position component in? I was thinking of when defining a new type of component, adding a list of component dependencies ( a simple list of component name strings ) but then what happens if I change the type name of the component Position for example? Say I do this for a Mesh component constructor: (EGE is the engine's name)
Mesh( unsigned int entityID, std::string meshName, std::string meshFilename, std::string cmpPosition,) : Component( entityID, "EGE_Mesh", Vector<String>{"EGE_Position"} )
What do I do if the Position comp. changes it's type name to "Position" instead of "EGE_Position?" My last question is, have I completely misunderstood the Entity/Component idea? Just any help is appreciated. Thanks.

Share this post


Link to post
Share on other sites
Advertisement
Something Smells but I am not quite able to put my finger on it.

So tell me about your event system. How do I register for messages? Also when you create "goodrobot" it has to exist somewhere why not cue of that.

If you have integer entity ids why are you using strings for entity identification?

If you have a camera entity why do you ask the camera entity for the camera? They should be one and the same. Mostly I think you are over engineering it. An entity should know where it is, if the mesh is apart of the entity then it should be able to query the entity directly.

Share this post


Link to post
Share on other sites
1. This is a playerController entity derives from EventListener. Below is playerController registering for Mouse and Keyboard events in it's constructor:

egeEventManager_->registerEventListener( "EGE_Keyboard", this );
egeEventManager_->registerEventListener( "EGE_Mouse_Moved", this );



The following pure virtual function of EventListener base class gets called by the EventManager:
void PlayerController::receiveEvent( EGE::Event::Event event )



2. When you spawn an entity, it exists in EntityManager, which is basically a simple entity container. You give a name to the entity you're creating but internally, EntintyManager assigns it a unique number too. It is just to be able to reference entities from different places in the application. EntityManager also gets called to update itself from the Engine every frame, and it in turns updates all Entities, which update their own components.

3. Since I am using Ogre3D for scene management and rendering, my Camera component is a wrapper of Ogre::Camera. Camera comp. has these members:


//Ogre handler
Ogre::Camera* ogreCamera_;
Ogre::Root* ogreRoot_;

//Entity system information
Entity::Entity* entity_; //Parent
Components::Position* cmpPos_; //Sibling Position component


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!