0
\$\begingroup\$

I'm implementing a simple "turn based" game where the player sets up a bunch of "actions" on a board and "objects" move on the board and are influences by those actions. The player is no longer involved after setting up the board and just watches the actions play out. Each "turn" of the game loop, a "move right" action will move any objects on its square one square to the right, for example.

My problem is now that each time I run the game loop, all actions are executed as follows:

for(auto& go: gameObjects) {
    go->update();
}

Each of these game objects mutates the world state in its update() method. What I'm seeing now is that when the board is updated by one object, the next one will immediately use that updated board state and perform its action "too soon".

For example: When I place three "move right" actions on the board and run the game loop, the object will be moved three spaces in one "turn" while it should actually take 3 "turns" for the object to move through all 3 of those actions.

How can I delay the board state update until all actions have had their chance to decide what to do? I'm considering two strategies:

  1. Copy the board state for each turn and create a new board state as the result of a turn. This is complicated because all my views are tied to the objects on the board. If I copy the board, I'll have to re-create all views?

  2. Have each action not update the world state, but only return a function which, when executed, will do the update. Once I have all the functions collected, execute them all to update the board.

Any suggestions?

\$\endgroup\$
  • 1
    \$\begingroup\$ I'm not an expert on these kinds of architecture questions. But: if it were me, I would duplicate the world, operate on the copy, then swap the pointer out so the copy is now the real world. If the world is big enough, this may be a horrible solution. \$\endgroup\$ – Almo Jun 24 '17 at 20:29
1
\$\begingroup\$

You can look into Double Buffering Pattern, which was designed specially for object updating in such way that every object has actual information about others, neither the previous nor the future one.

\$\endgroup\$
  • \$\begingroup\$ Thanks for your response, that was my first idea as well. The issue with that is that all my view classes are created with an immutable reference to the GameObject they represent. If I now go and create a new game state, I'll have to somehow update all those references as well or recreate all views each time the game loop runs. Is there a better way to tie views to their GameObjects than having a direct reference to the object the view is supposed to display? \$\endgroup\$ – Gerco Dries Jun 25 '17 at 18:32
  • \$\begingroup\$ @GercoDries I don't actually know that much about your implementation, but maybe you need something like action queue for each object, so every game loop. You pop the action from queue, perform it and next one will be performed only in the next interation. \$\endgroup\$ – German Gorodnev Jun 26 '17 at 16:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.