Handling Updates to Components

Started by
5 comments, last by crancran 12 years, 5 months ago
I am using a component-based approach for my game entities and I am pondering the implications of my update loop, particularly whether others tend to iterate over all components of a specific subsystem each frame (or on some set interval of frames for specific systems) or does your component system manage two different lists, one which holds all component pointers and the other which holds pointers to only those which were updated during the last game loop, allowing you to only need to iterate a smaller number of components if only a few changed. I am concerned about performance, in the case where I have a number of systems, each iterating over many components which have had no change from the prior frame. Is that typical and is my worry about performance unwarranted?
Advertisement
I think you are premature optimizing.
Just iterate over all components in the sub system for now.
One day if you really find it's the performance bottleneck, just rewrite the iterating and list maintenance part of the sub system. It should be not difficult because all sub systems should share the same logic and code.

And I hardly think it will become a performance issue. I would spend my time on optimizing render engine, physical engine, etc, which are more apparently able to become performance issue.

https://www.kbasm.com -- My personal website

https://github.com/wqking/eventpp  eventpp -- C++ library for event dispatcher and callback list

https://github.com/cpgf/cpgf  cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.

...allowing you to only need to iterate a smaller number of components if only a few changed. I am concerned about performance, in the case where I have a number of systems, each iterating over many components which have had no change from the prior frame.
Can you explain this a bit more -- perhaps give a use-case?


How can a component "not change" without being updated? If you don't update a component, then it won't change... which means you shouldn't update it (because it didn't change), so then it definitely won't change because it's not being updated?

How can a component "not change" without being updated? If you don't update a component, then it won't change... which means you shouldn't update it (because it didn't change), so then it definitely won't change because it's not being updated?


It depends on his tech design.
Some components may be changed by events, not the update loop.

https://www.kbasm.com -- My personal website

https://github.com/wqking/eventpp  eventpp -- C++ library for event dispatcher and callback list

https://github.com/cpgf/cpgf  cpgf library -- free C++ open source library for reflection, serialization, script binding, callbacks, and meta data for OpenGL Box2D, SFML and Irrlicht.


[quote name='Hodgman' timestamp='1321587755' post='4885204']
How can a component "not change" without being updated? If you don't update a component, then it won't change... which means you shouldn't update it (because it didn't change), so then it definitely won't change because it's not being updated?


It depends on his tech design.
Some components may be changed by events, not the update loop.
[/quote]

My initial thought was that a subsystem maintains two lists, one for all components and another as a set that was the map key values for the components that are considered "dirty" because they've been updated. But then it dawned on me that maybe when events fire and my component system handles those events, I may not necessarily want to actually "apply" the change but rather just capture the change and then update during the update() method call.

But my original thoughts surrounded the idea I could have 10000 components for example and only 10 of them have been modified or being frequently modified. Rather than iterate all 10000 each loop, I could just iterate those 10 instead. But when you think about the cost to insert/remove from this "dirty" list or the iterate a key in the set, find it in the component list by key and then process the changes, I may just be better off doing a full iteration.

I suppose it is somewhat premature optimization, but when working solely off event-driven mechanics, I just wanted to make sure I am not shooting myself in the foot with a particular approach. Now if only I can grasp how to layout my renderable components properly .. meshes, lights, planes, etc -- all being renderables yet requiring some aspect of OGRE. I'm finding OGRE dabbled in more places than it should in my design which leads me to think I've done something wrong.
I'm dealing with value components and behavior components. A value component is just a storage and hence has no update by itself. It requires a behavior component if it should be updated. So only behavior components need to be run for update.

E.g. a PlacementComponent allocates a Placement in the SpatialServices sub-system when being instantiated. The belonging entity counts to the static geometry so far. When a valid Parenting behavior is added then there is a possibility at al for the SpatialServices to run an update on the Placement through the Parenting.

Although this naturally divides up the scene into non-updatable and updatable parts, the updatable part is just "potentially dynamic". E.g. a Parenting need not to be run for update if neither the linked parental Placement nor the local Placement argument has changed. Such a situation can be handled using a dirty-mark mechanism. However, I don't do so at the moment. Instead I try to homogenize the sub-systems so that a fast processing is possible, and run the entire pool of behaviors.

For inter-component dependencies between components of distinct sub-systems one can define the simulation loop so that sub-sequent sub-systems (or at least phases of its update) can rely on that previous sub-systems has completed their update. E.g. graphical rendering relies on that all Placements are up-to-date and all animations, skinning, morphing, ... has been run so that the meshes are up-to-date, too. The skinning itself had relied on that that the skeleton was up-to-date, and so on. Look e.g. at this article by Gregory Jason on partitioning a simulation loop.

E.g. a PlacementComponent allocates a Placement in the SpatialServices sub-system when being instantiated. The belonging entity counts to the static geometry so far. When a valid Parenting behavior is added then there is a possibility at al for the SpatialServices to run an update on the Placement through the Parenting.

Although this naturally divides up the scene into non-updatable and updatable parts, the updatable part is just "potentially dynamic". E.g. a Parenting need not to be run for update if neither the linked parental Placement nor the local Placement argument has changed. Such a situation can be handled using a dirty-mark mechanism. However, I don't do so at the moment. Instead I try to homogenize the sub-systems so that a fast processing is possible, and run the entire pool of behaviors.

That's an interesting concept.

For inter-component dependencies between components of distinct sub-systems one can define the simulation loop so that sub-sequent sub-systems (or at least phases of its update) can rely on that previous sub-systems has completed their update. E.g. graphical rendering relies on that all Placements are up-to-date and all animations, skinning, morphing, ... has been run so that the meshes are up-to-date, too. The skinning itself had relied on that that the skeleton was up-to-date, and so on. Look e.g. at this article by Gregory Jason on partitioning a simulation loop.

I understand that aspect. What I have read a lot of times is that many favor the 1 system to 1 component approach. So for example, I have several reasons a component may need a scene node, that could be a mesh, plane, light, particle, etc. I basically broke that out to a Render Component. But if I create a mesh subsystem, a plane subsystem, etc then I end up with all these child subsystems dependent upon portions of ogre that I was initially treating to keep in the render subsystem. Rather than using singletons, my options are 1) these render extension subsystems are started internally by the render subsystem (which I don't like because some of these could be "game specific" for things like name plates, etc) or I redesign the graphics subsystem to offer an interface to OGRE and then all my subsystems basically are created in the engine's startup by being passed values from methods on the graphics subsystem.



This topic is closed to new replies.

Advertisement