Jump to content
  • Advertisement
Sign in to follow this  
Dominik2000

Component based game and component communication

This topic is 2087 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,

 

I want to use a component based system in my game. It should have subsystems for logic, and every subsystem has a list of components which stores the data. 

 

The problem is: How to sync the components?

  • Should I have a pointer to another component (Movement subsystem needs position of entity, so its component has a pointer to the position component?)
  • Should I go with a observer pattern, which notifies all other (registered) subsystems, that the position of the entity has changed? Then I need a reference from the movement subsystem to the position subsystem, to get the actual position, because with the notify I only want that the notified subsystem adds a "to-be-processed" entry to it's queue. This should avoid a confuse processing of the entities.

Are there other (better?) approaches?

 

Thank you for your tips!

Share this post


Link to post
Share on other sites
Advertisement

Hi!

 

Im not sure of how your current setup is working, and what a "subsystem" is, but in general a system should act on an entity with one or more component.

For instance, the MovementSystem could move an entity that has a displacement and velocitty component, the RenderSystem could render an entity that has a displacement and appearance component etc. This way the system needs to know about certain components, but the components does not need to know about each other.

 

Look here: http://www.gamedev.net/page/resources/_/technical/game-programming/implementing-component-entity-systems-r3382

 

In some cases I guess components will need to know about each other, I do not have that need yet, so I can not offer you a good answer.

I do however think you should implement some sort of messaging system.

 

Look here: http://www.gamedev.net/page/resources/_/technical/game-programming/case-study-bomberman-mechanics-in-an-entity-component-system-r3159

 

Good luck =)

Edited by AlanSmithee

Share this post


Link to post
Share on other sites

1) Should I have a pointer to another component (Movement subsystem needs position of entity, so its component has a pointer to the position component?)
2) Should I go with a observer pattern, which notifies all other (registered) subsystems, that the position of the entity has changed? Then I need a reference from the movement subsystem to the position subsystem, to get the actual position, because with the notify I only want that the notified subsystem adds a "to-be-processed" entry to it's queue. This should avoid a confuse processing of the entities.

 

Those two bullets seem like solutions to different problems:

 

1) How do I get component X for an entity, given I have component Y for that entity

2) You have code that needs to know when position has changed, how do you set that up?

 

Can you clarify your question?

 

For (2), I would ask, do you really need this?

Edited by phil_t

Share this post


Link to post
Share on other sites

hello.

There should be no right or wrong way to do this as long as the out come is the same.

 

In my carry Object Component I have a owner pointer.

 

this way when I update the carryobjectcom it calls the owner objects virtual functions for Getpos, size and things

to pick up a object this way the component can do its job and not worry about  what values it need to control as the owner does all that with its other components

you just need a common interface for functions the components need to use to do there job.

 

So for my carry objects componet it can move the object to the unit it wants to pick up and when it gets to the target it picks it up.

Share this post


Link to post
Share on other sites

The architecture works like sneftel wrote in this thread:

http://www.gamedev.net/topic/463508-outboard-component-based-entity-system-architecture/

 

Given I have a physics system, a translation system and a position system. The component which stores the position is the position component linked to the position system. My physic and translation system have to change the position component.

It seems to me, that there are two ways:

I can store the position in a vector in the translation component and physics component also, and implement a observer system, to sync, when the position is updated, every other component. (The translation system changes the position -> updates the position component over the position system -> the position component notifies all listeners, to sync the position) That means, that my translation system stores a pointer to the position system, to update the position.

 

I can store a pointer to the position component in every component I need it. That means that I also need a pointer to the position system, to get a pointer to the position component. So I don't need to sync the components manually, but my components depends on other, which I don't like.

 

I like way one  a little bit more, because I have dependencies only on system level. But maybe there are other ways to do this.

phil_t wrote another way, in which he has a sync primitive, which stores two components and after every frame update, updates the position over this primitive.

There are much ways to do this, but maybe there are other pros and cons in my ways, which I don't see.

Share this post


Link to post
Share on other sites

Ok you mean, that one system (for example physics system) knows it's dependency to the position system, and every update the first thing it does, is requesting the position. So there is no need for manually syncing.

 

But one question remains, how to store position in the physics component, or is this not needed? I don't want to store a vector in the physics component also, because of duplicate data. A pointer is ok, but I think it breaks encapsulation, because one component needs to know one other...

Share this post


Link to post
Share on other sites


But one question remains, how to store position in the physics component, or is this not needed? I don't want to store a vector in the physics component also, because of duplicate data. A pointer is ok, but I think it breaks encapsulation, because one component needs to know one other...

A wise man avoids to commit self and says … "it depends" ;)

 

Notice that using an external physics library may require you to copy the placement anyway, and that in both directions. An internal physics solution may read the placement from the spatial sub-system piece by piece on demand, or it may read it in a block and bring it into a format required for an efficient processing (w.r.t. physics). However it is done, the physics system should be able to pull the data (data should IMHO not need to be pushed into the physics sub-system).

Share this post


Link to post
Share on other sites

Well, instead of duplicating components, just extract them by splitting the storage from the systems.

Add some helper template class (component-manager/array/vector/storage/..., whatever you like to call it) that keeps one kind of components and gives search/addition/deletion by id and easy access through iterators.

Then give each system a reference to one or if needed two or more of these.

Then let the systems one after another in a fixed order do their update-work so that they can rely on other systems to have done what was needed before.

Share this post


Link to post
Share on other sites

I think if you want to send data between components, you should have them an anchor to a common root which actually handles sending the information between components.

For example, in my game, I have components bound to individual entities which gives them functionality. I also have some specialized components such as an InputComponent and a RenderComponent. Each component haves a pointer back to it's root entity and my entity has a function called BroadCastMessage( MessageClass data ) which calls the function RecieveMessage( MessageClass data ) for all bound components. All my component has to do is use it's pointer to its root entities to broadcast a message to other components.

My MessageClass is basically this:

struct MessageClass
{
   char* pchName;
   void* pvData;
}

You would use the name to listen for certain events from other components like maybe "UpdateXPos" or something to that effect. Also since I know how a message would be built based on the name, I'll know how to typecast the data to its correct format. Another way you might do it, but it leads to a bit more work, is to use an array of bytes for the data. You would have to break down the data you need to send into individual bytes and then rebuild it up when a component receives it.

 

EDIT
Here's a complete example:

//InputComponent
void KeyPressed( char chKey )
{
   if( chKey == 'w' )
   {
      int iMovement = 10;
      pEntity->BroadcastMessage( MessageClass( "UpdateXPos", &iMovement );
   }
}

//RenderComponent
void RecieveMessage( MessageClass data )
{
   if( strcmp( data.pchName, "UpdateXPos" ) == 0 )
   {
      m_iPosX += *((int*)data.pvData);
   }
}
Edited by PandaDragonThing

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!