• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Dominik2000

Component based game and component communication

32 posts in this topic

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!

0

Share this post


Link to post
Share on other sites

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
1

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
0

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.

0

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.

0

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...

0

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).

1

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.

0

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
1

Share this post


Link to post
Share on other sites

Ok every time I update a physics component, I first ask the position system, for the position of this component. Seems pretty good for me. So I don't have dependencies at component level only, on system level.

 

But now, there is another problem, most rendering engines (like OGRE or Irrlicht, I use Irrlicht) have a scene manager, in which their entities, positions and rotations are stored. This rendering libary is no system it will be initialized in the application class, which also initializes a entity manager (this manager is responsible to initialize the systems, I hope you can imagine this architecture, if not ask).
That means I need a reference to my render libary in my render system, and my render system is responsible for adding the entity also to the render libary, and update the position in the render libary.

 

Is that a good way to go? Or should the render system initialize it's "own" rendering libary? Make this a difference? Maybe several things of Irrlich should initialized in the application and several should initialize the render system???

So much questions!

0

Share this post


Link to post
Share on other sites

First off, don't be afraid to break parts of a process with the entity system into multiple passes.  

 

Our scene (aka map) loader process loads map metadata.  It's during this process where entity IDs get allocated and whatever metadata references components is used to create the necessary components associated to this entity ID.  At this end of this first phase, the entity is in an inactive state and the components which have been allocated are stored in the various owning subsystems but are flagged as pending commits.  (Think relational database here).

 

Once the entity has been constructed either by using a combination of prefab archetype data and map metadata or simply map metadata, the next step must begin.  This next step is an inspection pass where systems or components (depending on your design) can look into an entity and determine what other stuff exists.  If required, references to other systems or components can be obtained and stored.  

 

Do be mindful of using pointers, particularly if they're not weak_ptr types.  At any moment, any outside source could cause a component to be removed from an entity and if you depend on that component, have stored a raw pointer and do not have checks in place to eliminate the reference, this could lead to unexpected behavior.  I generally prefer either the use of a component handle where a handle is converted to a pointer at the time of access or maintain copies of the data; generally of which the later is usually more cache friendly and gives a slightly higher performance depending on your data structures.

 

Assuming that your game doesn't support a concept such as teleport, generally the physics component's position & orientation will be seeded from the transform during the inspection phase.  This is what makes sure the physics simulation starts out synchronized with the entity's transform data.  If the entity has no transform, then you cannot initialize the physics component, and thus it remains "pending" or "inactive".

 

The next step is to activate your entity, at which point all systems are informed and the components which were initialized & synchronized successfully are moved into an active state and thus the system's update process will begin to manage the state for that component & entity.  Either here or in the prior inspection step is where you could allocate whatever subsystem specific data objects that are needed.  For example, a RigidBody for physics, a Collider for the Collision system, your SceneNode and various other renderable aspects in the render system, etc.  

 

The point is once activation has completed, the entity's component state should be ready to be manipulated by any outside source.

 

When you begin to apply movement to your entity, the force/direction get applied to some movement/velocity component.  When the physics system begins to step it's simulation, it takes all entities with a physics component and have a force/velocity and applies those values to the rigid bodies in the simulation and then steps the physics world simulation.  If collisions are detected, then an event can be fired and any system interested in collisions can react.  If no collisions took place and position/orientation were modified, the physics system can emit a position/orientation update message.  The transform system can receive it and update the entity's position/orientation.

 

Here you have two options:

A) have the systems which manage your scene render objects also listen for physics events and update the scene's transform/orientation as well

B) have the transform system emit a second message after having changed the transform.  

 

Now if your game had a teleport system, your transform system, physics system and all those render object systems might register to be notified upon a TeleportationEvent, then they simply update their position/orientation based on the transport system's knowledge of where you left and where to spawn your character perhaps on a new map or in another zone or area of the current map.

 

One thing I will also caution you on is try to avoid leaking system specific data into your components.  I find often that people will create say a Light component, place all the data regarding how to construct a light in the render system and then have the component hold a pointer or some reference to the render system's Light object implementation.  Instead, I prefer the idea of creating some internal data structure storage where the system holds the Light object's implementation pointer and can relate that back to a component of a specific entity.  In some cases it's been more efficient to marry parts of the component's data with the specific systems implementation pointers and store all that in a specific structure and simply iterate those each frame and use a series of events to replicate changes from the components or other system changes to the internal structure the system maintains at set intervals.

 

As far as to your last question regarding the rendering library, there is really no set way.  I generally code against a set of interfaces and so my engine's framework is much like that of CryEngine where an IRenderer interface is exposed that gives you access to the 3D rendering library.  This class initializes the library, allows me to attach it to a specific window handle to begin rendering, exposes a render method, has support to restart the 3D library, exposes the scene graph, etc.  I simply have the engine framework construct the Renderer class during startup.  I leave the application class responsible for being a thin wrapper around the framework and exposing a series of listener methods and such which can be overwritten based on application needs such as OnActionEvent(), OnKeyEvent(), OnMouseEvent(), OnPreUpdate(), OnUpdateFixed(), OnUpdate(), and OnPreRender(), etc.

 

Feel free to ask any questions, hopefully it gives you a clearer idea.  Just remember that the entity system is an abstraction layer that sits way above the underlying systems in the engine.  It's basically the system or systems which designers in AAA titles interact with in the editors to create these elaborate games.  What happens at the physics, rendering, and other various low-level systems are well below the entity framework but are influenced by "inputs" given to the components.

EDIT:
One thing I forgot to mention above is that once an entity has been activated and you add/remove components from the entity, those changes are once again considered "pending".  This means that another inspection/activation process must be performed on the entity to allow various systems/components to determine whether or not the entity's state continues to satisfy the requirements of some systems and if not cleanup the existing data if it exists and treat the component as though it was just created but couldn't be initialized due to missing dependencies.

Edited by crancran
1

Share this post


Link to post
Share on other sites

Wow, thank you very much for this long explanation, that made much things clearer.

 

I think, I will use a observer pattern event system on the component, which notifies on value change (position changed) some systems. But instead, of switch to the notified system, and process the event, I only add the entity to a queue, and in the next update the entity will be processed.

 

I like the two pass approach very much, and think, it will be implemented in this way! Also the component handler idea is good, but I think, this will be done in the system base class. My other systems make a positionSystem->getPosition(entityId), and the getPosition method will check if the component exists, so the check will be on data access. Thank you!

 

You talk about low level systems and components. I must confess that I don't know exactly how the architecture above the "low level" systems look like. I thought that I have my components -> systems -> one entity manager -> application. But this is wrong or? My application class would startup and initialize the entity manager, render libary, ai libary and such things. The entity manager gives the pointer to the systems. Do I need another level of "high level" systems? Don't know how the common way is.

 

EDIT:

Do you have a addEntity, removeEntity,... methods in your rendering libary also, so you only have the references to the rendering engine only in your libary class?

Edited by Dominik2000
0

Share this post


Link to post
Share on other sites

I think, I will use a observer pattern event system on the component, which notifies on value change (position changed) some systems. But instead, of switch to the notified system, and process the event, I only add the entity to a queue, and in the next update the entity will be processed.

 

Your framework should be capable of support both queued events (asynchronous delayed delivery) and immediate events (synchronous delivery).  Depending on the context of the event that occurred, you can determine which makes the most logical sense.  There are often systems that run after other systems and if the prior systems emit an event that the subsequent systems are interested in, delaying it by queuing it up only attributes to having what is commonly called frame lag.

 

You talk about low level systems and components. I must confess that I don't know exactly how the architecture above the "low level" systems look like. I thought that I have my components -> systems -> one entity manager -> application. But this is wrong or? My application class would startup and initialize the entity manager, render libary, ai libary and such things. The entity manager gives the pointer to the systems. Do I need another level of "high level" systems? Don't know how the common way is.

 

One of the worse things you can succumb to is over engineering things.  There is no real right or wrong way to do it.  If you took various game engines and compared their sources, while you'll find some commonalities between how they separate certain things, they generally are coupled in very different ways that made sense to the developers or architects for those projects.

 

If you think about a car engine or a computer for a moment; there are a multitude of pieces that come together to make the final product.  Those pieces are generally put together in a specific order and some pieces rely on other pieces to exist and expose some "connection" or "joint" in order to apply the next piece, right?  A software program of any kind follow similar practices.

 

I generally separate the engine into several low-level building blocks such as Audio, AI, Graphics, Input, Memory, Networking, Physics, Platform/IO, UI, and others.  

 

If we take Audio for example, I might decide to use some third-party audio library such as FMOD or OpenAL  I then generally create several classes that wrap the library and expose an API that should I opt to change the third-party library to another, it would have minimal impact. This is where coding to Interfaces rather than implementation can really make a significant difference.  At this point, we've created the base low-level things necessary for audio.  

 

The next step is to build on this low-level audio framework and expose various aspects in a plug-n-play type of fashion.  This is where the entity framework & components behind to come into play.  So I develop a set of components such as an AudioEmitterComponent which is responsible for emitting various sounds along with an AudioListenerComponent that listens tongue.png.  Depending on your needs, you might find a few other type of components you might want to expose with various attributes for the audio system but you get the idea.

 

The final step to polish off the Audio framework is to expose a series of system classes that are responsible for managing various aspects of audio.  We generally first create a plethora of systems that handle a very specific aspect of audio.  For example, a system that maintains a continual but non-overlapping playback of audio clips based on events dispatched from the combat system.  We have an audio system responsible for zone ambient music so that as a player transitions from one zone to another, the ambient sound from the prior zone fades out and the new zone fades in.  Once we have all those building blocks for the various plethora of audio concepts we want, we begin to see where those systems can be refactored into a common system or smaller number of systems that perhaps does a multitude of things within each one.  It might also lead us down a path to expose a new component for specific purposes and expose it through a custom audio system.

 

Anywho, the point here is to start at the lowest level and build atop of the previous layer.  If you treat creating your game in layers, you'll start to understand how easy it becomes to change things when you want because you've applied sufficient abstraction to do so and decoupled things in a way that supports continual change and maintenance of your codebase without necessarily throwing it away and starting over.  Now don't expect all this overnight of course, this comes with many years of trial and error.  So don't hesitate to throw things away and start fresh if you believe the design is flawed and could be made better.  Iterative programming will lead to better code with time smile.png.

 

TLDR; You wrap your third party library with a set of classes and then you wrap those classes with the entity systems that operate on components.  By manipulating components from the outside in turn influences how the entity system manipulates the internal third party libraries such as OpenAL/FMOD/OGRE/etc.  I use the term wrap lightly in this context because generally some framework allocates your OpenAL/FMOD/OGRE wrapper and then passes the wrapper class reference to your entity systems and then interact with the third party library through your wrapper.  Make sense?

Edited by crancran
1

Share this post


Link to post
Share on other sites
Yes it makes sense, you described it very well and detailed.


I don't exactly understand what you mean at your last sentences about a wrapper. Given I have a render system which has initialized my irenderer interface. Behind the interface is OGRE as rendering libary. OGRE has it's own entity and scene node classes. Now I create a wrapper class for these two classes where I store... What? The ogre scenenode and entity? I don't think so, because of the dependencies. Only the mesh and position, and then at the system update the irenderer interface has a setposition method which takes the position maps it in a ogre vector and move it. My render libary Claes is responsible for storing scene node and entity.
0

Share this post


Link to post
Share on other sites

Yes it makes sense, you described it very well and detailed.


I don't exactly understand what you mean at your last sentences about a wrapper. Given I have a render system which has initialized my irenderer interface. Behind the interface is OGRE as rendering libary. OGRE has it's own entity and scene node classes. Now I create a wrapper class for these two classes where I store... What? The ogre scenenode and entity? I don't think so, because of the dependencies. Only the mesh and position, and then at the system update the irenderer interface has a setposition method which takes the position maps it in a ogre vector and move it. My render libary Claes is responsible for storing scene node and entity.

 

What I mean by wrapper is a class that knows how to startup OGRE, shutdown OGRE and exposes a set of methods for doing various activities with OGRE.  What you can do is rather than return the Ogre::Entity or Ogre::Mesh objects, you simply expose a set of methods that take the identifiers for those objects, look up their pointers and manipulate them.  Doing so avoids leaking the OGRE objects to the other parts of the engine and keeps it self contained.

 

Of course, there is nothing bad with allowing Ogre's objects to be exposed to your engine if you want, but I generally prefer the former because it enforces a sense of decoupling between implementation and functionality. Some might argue this is highly subjective.

Edited by crancran
0

Share this post


Link to post
Share on other sites

If I have a render system and a render interface, as you described, does the render system have only one component where the render interface pointer is stored? What stores the component in a render system, maybe I could store the mesh string, and the name of the entity?

 

I think, that I have to ensure that the render system runs after each other system, how can I do that? I want the game class to loop trough every system and make an update, but the render system should be the last, because if it run before the position system, it would not move the entity...

 

My way is after all other systems, the render system, get the new position of the entity and sets it in the graphic engine, over my graphic interface api, I think this is a very good way. Are there other improvements, which I can do?

0

Share this post


Link to post
Share on other sites

Whats so difficult in just calling it last when you need it to be called last? I think its easier to just write a function that calls the system updates in the correct order, than making a loop to handle them generically only to then having to create some complicated dependency checking to make that possible.

0

Share this post


Link to post
Share on other sites

I have handled this by using a seperate store for components rather than storing them in the entities or systems themselves. The systems operate on the stores themselves. Now I don't worry about a post movement update to copy the position to the physics components or a pre physics update to grab the current postion and transform. As the data exists seperately from the system. So my components are not coupled, and neither are the systems. The systems that need access to components will contain references to the stores for those components. Every problem can be handled by another layer of abstratction is a motto that I see to live and die by more and more.

1

Share this post


Link to post
Share on other sites


I think, that I have to ensure that the render system runs after each other system, how can I do that? I want the game class to loop trough every system and make an update, but the render system should be the last, because if it run before the position system, it would not move the entity...

 

It's absolutely essential that your systems run in a predetermined order. So definitely factor that functionality that into your design.

1

Share this post


Link to post
Share on other sites


If I have a render system and a render interface, as you described, does the render system have only one component where the render interface pointer is stored? What stores the component in a render system, maybe I could store the mesh string, and the name of the entity?
 
I think, that I have to ensure that the render system runs after each other system, how can I do that? I want the game class to loop trough every system and make an update, but the render system should be the last, because if it run before the position system, it would not move the entity...
 
My way is after all other systems, the render system, get the new position of the entity and sets it in the graphic engine, over my graphic interface api, I think this is a very good way. Are there other improvements, which I can do?

The update order of all of the sub-systems in the game loop must be defined and fix. It makes no sense to delay input more than necessary. It makes no sense to let collision detection work if a subsequent call to the animation system will change the position in an arbitrary way again. And so on … The ordering may go as far as to divide updates into several steps just to ensure that things are done correct. Please have a read of this book excerpt about game engine architecture by Jason Gregory; IMHO it is a good lecture to learn about organizing the game loop (I don't say that you should copy his architecture; just see how things may depend and draw your conclusions from that).

1

Share this post


Link to post
Share on other sites

If I have a render system and a render interface, as you described, does the render system have only one component where the render interface pointer is stored? What stores the component in a render system, maybe I could store the mesh string, and the name of the entity?

 

It ultimately depends on your design needs really.  I've seen some component hierarchies where Component gets derived into a Renderable and then that class is further derived into various types of renderables for things such as Lights, Terrain, Meshes, and numerous other render system specific objects.  But that's only one way to approach it.  

 

Now how components are associated to various subsystems is somewhat dependent upon taste.  Some might prefer to combine all the 3D renderables into a single system that updates them in a predefined order, but in my opinion that is skirting the lines of not following the SoC and SRP rules of programming.  I tend to prefer splitting them into their own various subsystems and have them interact with the low-level 3D render system.

 

As far as where components are stored, we follow a similar concept like Burnt_Fyr where components are stored in various arrays that are external the systems.  This helps in a number of ways because we actually treat each concrete component like it's a database table of sorts where each property of the component is basically considered a column in the said table.  

 

In some systems, its optimal enough for them to use the component database directly each frame and perform whatever updates are need but for others a more optimal iteration process is necessary.  For those, we generally use another layer of abstraction where the system has some internal structs and we replicate the necessary information in conjunction with events triggering state changes to keep the update loop's impact minimized.

 

I think, that I have to ensure that the render system runs after each other system, how can I do that? I want the game class to loop trough every system and make an update, but the render system should be the last, because if it run before the position system, it would not move the entity...

 

As others have said, update order really should be deterministic because it will otherwise be a source of significant pain points and subtle bugs.  If you're looking to create a somewhat flexible solution and trade a tad bit of performance for it, you can very easily use the observer pattern in conjunction with either a priority system or a combinataion of priority and listener buckets.

bool Framework::AddFrameworkListener(IFrameworkListener* listener, int queue = eListenerQuueDefault, int priority = 0 /* default */)
{
  /* lookup queue */
  /* add listener to the specific queue, ordered by priority */
}

void Framework::Update(float dt)
{
  /* at specific stage */
  auto& listeners = mListenerQueues[eListenerQueueStage1];
  std::for_each(listeners.begin(), listeners.end(), [=](IFrameworkListener* l) {
    l->OnStage1(/* pass whatever */);
  });
  ...
}

The benefit here is that a framework listener can register a listener class for one, several, or even all queues based on how the listener gets registered.  Various exposed listener API methods can be exposed to make registration easier.

 

In our engine, we use an augmented flavor of the above approach to keep the framework plug-and-play and to be able to inject code into the main loop at any point, even before core framework systems if needed.  

Edited by crancran
1

Share this post


Link to post
Share on other sites

crancran, can you elaborate on your listener stuff? What kind of code would register as a listener? What are you talking about when you mention queues?

 

There should be a series of systems (in an explicit order) that get updated one after the other. I'm trying to figure out how your listener/queue stuff fits into that.

1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0