Component entity system - Updates and call orders

ptpaterson
  • Component entity system - Updates and call orders ptpaterson

    In order to get components to be able to update every frame (and leave this functionality out of components that don't need to) I got the idea to make an UpdateComponent component. Other components like MovableComponent (which holds velocity) would inherit from the IUpdatable abstract class. This forces MovableComponent to implement an Update(gametime dt) method and another RegisterWithUpdater() that gives UpdateComponent a pointer to the MovableComponent. Many components could do this and then UpdateComponent could call all of their Update(gametime dt) methods without having to care about who or what they are.

    My questions are:

    1. Does this seem like anything that is normal or used by anyone? I cannot find anything on the subject.
    2. How could I maintain an order to the components like physics then position change? Is this even necessary?
    3. What are other ways of insuring that components that should be process every frame are in fact processed?

    EDIT
    I think I will be concidering how to give the entity manager a list of types that are updatable. Then ALL of the components of that type can update rather than managing it per entity (which are just indexes in my system anyway).

    Still. My questions remain valid to me. I don't know if this is reasonabl/normal, or what others tend to do.

    Also, the people at Insomniac are awesome! /EDIT

    Boiled down code for previous example:

    class IUpdatable
    {
    public:
        virtual void Update(float dt) = 0;
    protected:
        virtual void RegisterAsUpdatable() = 0;
    };
    
    class Component
    {
        ...
    };
    
    class MovableComponent: public Component, public IUpdatable
    {
    public:
        ...
        virtual void Update(float dt);
    private:
        ...
        virtual void RegisterWithUpdater();
    };
    
    class UpdateComponent: public Component
    {
    public:
        ...
        void UpdateAll();
        void RegisterUpdatable(Component* component);
        void RemoveUpdatable(Component* component);
    private:
        ...
        std::set<Component*> updatables_;
    };
    

  • One of the primary benefits of a component system is the ability to take advantage of caching patterns - good icache and prediction because you run the same code over and over, good dcache because you can allocate the objects in homogeneous pools and because the vtables, if any, stay hot.

    The way you have structured your components, this advantage disappears completely, and in fact can become a performance liability compared to an inheritance-based system, as you're making far more virtual calls and more objects with vtables.

    What you should be doing is storing pools per type, and iterating each type independently to perform updates.

    Does this seem like anything that is normal or used by anyone? I cannot find anything on the subject.

    It's not as common in large games because it is not advantageous. It's common in plenty of games, but it's not technically interesting, so no one writes about it.

    How could I maintain an order to the components like physics then position change? Is this even necessary?

    Code in languages like C++ has a natural way to order execution: type the statements in that order.

    for (PhysicsComponent *c : physics_components)
        c->update(dt);
    for (PositionComponent *c : position_components)
        c->update(dt);
    

    In reality, that doesn't make sense because no robust physics system is structured that way - you can't update one single physics object. Instead, the code would look more like:

    physics_step();
    for (PositionComponent *c : position_components)
        c->update(dt);
    // Updates the position data from the physics data.
    

  • What you're talking about is reasonable and fairly common, I think. This might give you some more information.

  • I like these approaches:

    Shortly: Avoid keeping update behavior within components. Components are not behavior. Behavior (including updates) can be implemented in some single-instance subsystems. That approach might also help to batch-process similar behaviors for multiple components (maybe using parallel_for or SIMD instructions on component data).

    The IUpdatable idea and Update(gametime dt) method seems a bit too restrictive and introduces additional depencencies. It might be fine if you are not using subsystems approach, but if you do use them, then IUpdatable is a redundant level of hierarchy. After all, the MovingSystem should know that it must update the Location and/or Velocity components directly for all entities which have these components, so there is no need for some intermediate IUpdatable component.

    But you could use Updatable component as a mechanism to skip updating some entities despite of them having Location and/or Velocity components. The Updatable component could have a bool flag which can be set to false and that would signal every Updatable-aware subsystem that this particular entity currently should not be updated (although in such context, Freezable seems to be more appropriate name for the component).

Tags
c++ component-based entity-system
Related questions and answers
  • ) I was thinking about the following: class Entity; class Component { Entity* entity; ... virtual void serialize(filestream, op) = 0; ...} class Sprite : public Component {...}; class Position : public Component {...}; class IA : public Component {... virtual void update() = 0; }; // I don't remember exactly the boost::fusion map syntax right now, sorry. class Entity { int id; // entity id... remove_component(C* c) { components.at<C>() = 0; } void serialize(filestream, op) { /* Serialize all componets*/ } ... }; std::list<Entity*> entity_list; With this design I can get #1

  • Components. 3: Component registers itself in GameSubsystem(s). We know at compile-time that there is a GameSubsystemRenderer, so let's ComponentImageRender will call something like... GameSubsystems) can implement registerComponent(Component*). pro. Components and GameSubystems know nothing about each other. con. In C++ it would look like ugly and slow typeid-switch. Questions: Which approach is better and mostly used in component-based design? What Practice says? Any suggestions about implementation of Approach 4? Thank you.

  • : How the Entity and its sprite interact in my current setup. class Entity { public: void handleEvent(const Event& event); void render(Surface* surf, unsigned long currentTime); // void... it does it like this: void Entity::handleEvent(const Event& event) { // We pass this to the state so it could act upon the data in // the entity in a manner appropriate for the given event. state_->handleEvent(event, this); } That means that I don't really ever need more than one instance of a particular entity state; doing something like entity.setState(new StandState

  • ). If the resource isn't loaded, then the manager will mark the object to be loaded at the next opportunity, (usually at the end of drawing the frame). Note that, although my system does do some reference... ~Resource(); virtual bool load() = 0; virtual bool unload() = 0; virtual size_t getSize() = 0; // Used in determining how much memory is // being used. bool... can't think of a decent scheme to use, or the right data-structures required to quickly manage them. Could someone who has implemented a system like this give an overview of how their's worked

  • : float m_Position[3]; // x, y, z // offset 0, size = 3*sizeof(float) float m_TexCoords[2]; // u, v // offset 3*sizeof(float), size = 2*sizeof(float) float m_Normal[3... in the shader code) for( int n = 0; n < vShaderArgs.size(); n ++) glBindAttribLocation( m_nProgramId, n, vShaderArgs[n].sFieldName.c_str() ); // Create and bind to a vertex array object, which...I'm writing a generic ShaderProgram class that compiles a set of Shader objects, passes args to the shader (like vertex position, vertex normal, tex coords etc), then links the shader components

  • /////////////////////////////////////////////////////////////////////////////////////////////////////////////// class Sprite { private: string name; char symbol; float shield; int location[2]; bool alive; public: ///////////////////// Get and SET all the privates... /////////////////////////////////////////////////////////////////////////////////////////////////////////// class Player : public Sprite { public: Player(string name,int X, int Y, float health){ set_symbol('8... /////////////////////////// void Refresh(int command= ALL, int transition= NONE) { //old_map = new_map; // update the old map for(int r= 0; r< nrows; r++){ move(r,0); addstr

  • every frame to handle input and render etc I call an UpdatePhysics method to update the physics simulation. void GameState::UpdatePhysics(unsigned int TDeltaTime) { World->stepSimulation(TDeltaTime... this on what I had done there, but modifying it to fit with Ogre. It is working but not correctly and I would like some help to understand what it is I am doing wrong. I have a state system and when... physics properties. I know there will be errors here as I get the items colliding with the ground but not with each other properly. So I would appreciate some input on what I am doing wrong. void

  • well... I'm building the animation system of my game engine (the skeletal and skinned animation stuff), and I came to a point where I added so much functionality in the frame and node structures... shader in every node. Other option I was thinking was making some helper functions to deal with the simpler cases, which would set some default parameters and would ask only the most basic ones... for my needs. Ah and I forgot to mention that nodes can have hierarchy, but this is not a problem if the frame data is reduced. The structure instances don't get duplicated unless any value changes. When

  • between frame updates or other problems..... Finally I would like to know how my organization, planning, etc is.. Thanks! my UPDATED, WORKING Code: #include<SFML/Graphics.hpp> #include<... axis. I then implemented this function into my custom mySprite class, more specifically into it's update() function which updates its Position using the above function to calculate its new position... //////////////////////////////// class mySprite : public sf::Sprite { private: float velocity; float angle; public: // all the values needed by the base class sprite(); mySprite

Data information