Ways to implement a game logic layer into current 2d game architecture

364 views Asked by At

I'm developing a 2d fighting game in c++ (for learning purposes) and I'm having a hard time figuring out how to properly implement game logic. For a quick overview of my current architecture, I have component classes that act as data holders and I have 'systems' which are just functions designed to act on those components. I have a scene class which holds an array of fighters that are currently in game and this scene is passed to individual sub-systems which then can freely act on fighter components, updating fighters state:

//Add a fighter object to array of fighters and set starting position
scene.CreatePlayerFighter(160.0f, 0.0f);
scene.CreateAIFighter(80.0f, 45.0f);

gameWolrd.Init(scene);
Renderer.Init(scene, window);
AI.Init(scene);
//etc...

//Game loop
while (true)
{
    Input.Update(scene);

    Physics.Update(scene);
    AI.Update(scene);
    //etc....

    window.ClearBuffers();

    Renderer.Update(scene, colorShaderProgram);

    window.SwapBuffers();
}

Again, inside each sub-system (Renderer, AI, Input, etc.) all fighter components are being passed into system functions and spit back out with new values which are then inserted back into fighters:

void Physics::Update(Scene& scene)
{
    for (Fighter& fighter : scene.fighters)
    {
        //Update fighter position based on fighter's current velocity which has been set by input
        TransformComponent newFighterPosition = System::MoveFighter(fighter.GetComponent<TransformComponent>(), fighter.GetComponent<VelocityComponent>());

        //Insert new TransformComponent to update fighter's position
        fighter.Insert<TransformComponent>(newFighterPosition);
    }
}

This current architecture has the advantage of being loosley coupled in that I can add and remove systems very easily without effecting the fighter class or it's components directly. The problem is everything is hopelessly serial, as my scene is passed into each sub-system one by one to update fighters. I mention this problem because one of my thoughts to implement a game logic layer was to have higher level classes just call specific game engine system functions directly like physics.MoveFighter(TransformComponent, VelocityComponent, float amountToMove); where I can add additional parameters to give the user at the game logic layer level more control. Of course doing things this way means system functions would be called and invoked in any order the user of the game logic saw fit. Would there be a way to still implement a game logic layer in this way and maybe queue up all calls and reorder them to run correctly within the game engine? Or would there be a better way to try and implement game logic within my current architecture?

1

There are 1 answers

0
A. Knorre On
  1. As I see your goal, you could just store movementFactor field in fighter, and allow to change it from game logic layer. In Physics class delta is then mul-ied by that field. If you use component like system you probably do not want to update components manually, only operate with data.

  2. Logic update order is a complex problem: imagine a chicken falling on an egg. It happens that in the same frame chicken touches the egg and egg is ready to show us new little chick. What should be executed first? That depends on what is updated first: physics or eggs, and on the fact whether reactions apply immediately. The best scenario (most fair usually) would be for them not to apply immediately, but form a stack of objects (components) state changes, for them to be resolved independently after the action phase.

Also make sure you do not want to stick with existing entity system like entityx.