Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing game loop rebuild race condition #496

Merged
merged 4 commits into from
Mar 12, 2023

Conversation

davesmith00000
Copy link
Member

Related to #495.

@davesmith00000 davesmith00000 self-assigned this Mar 11, 2023
@davesmith00000
Copy link
Member Author

Reminder to self:
So far I've improved things a bit. The dreaded rebuild function call now happens at the end of a frame based on a new internal system event.

Testing it out in the Roguelike game, it doesn't lose as much state as it did, but it still needs to be better. I think the trick will be essentially 'locking' the game until the rebuild is complete and then carrying on, or something along those lines. Still, that will be easier to achieve with the work done so far.

@davesmith00000 davesmith00000 changed the title WIP: Rebuild loop race condition Fixing game loop rebuild race condition Mar 12, 2023
@davesmith00000 davesmith00000 requested a review from a team March 12, 2023 09:18
@davesmith00000 davesmith00000 marked this pull request as ready for review March 12, 2023 09:18
@davesmith00000
Copy link
Member Author

This version not works correctly in the Roguelike game. This change is pretty gnarly.

The backstory is that when I originally put in the dynamic asset loading I needed a way to dynamically rebuild the game loop, and the things that it uses like the texture atlases. For some reason, in a moment of madness, I decided to just do the OO thing and propagate a function call that would all some code to call all the way back to the engine and tell it to do the rebuild - relying on single-threading to save me. And it did until just recently.

However the recent work to improve the performance of the frame-limiter now means that frame ticks are divorced from frame execution. So what was happening was:

  1. Frame starts.
  2. Somewhere mid-frame the message occurs that says the asset load finish, do the rebuild.
  3. The rebuild captures the current state and starts the rebuild.
  4. ...but in the mean time the current frame finishes and one or two more are processed moving the model state on.
  5. The rebuild completes and overwrites the state, and hopes you haven't noticed.
  6. The game is expecting the model to be in a more advanced state and weird things happen.

This solution is still not brilliant, and I feel like I'm reach the point where rebuilding the core is probably what needs to happen - but that's a job for another day.

How the fix works is that I've swapped the propagated rebuild loop function call for a new IndigoSystemEvent that currently only supports rebuilds but could be handy for other things. At the end of the frame, any events of that type are filtered out and queued inside the GameLoop. When the next frame starts it checks a) if the frame is locked, and b) if there are any system events to deal with.

If there are system events, they are processes instead of running the normal frame. The rebuild action when invoked, tells the game loop to lock and unlocks it when it's finished. This means we capture any events, but process nothing while the engine rebuilds.

The result is that we drop a frame or too and see the game pause, but the state is intact and correct.

@davesmith00000 davesmith00000 merged commit 6d72567 into main Mar 12, 2023
@davesmith00000 davesmith00000 deleted the issue/495/rebuild-loop-race-condition branch March 12, 2023 21:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant