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

Ensure Rollback Order is Stable After Rollback #82

Merged
merged 2 commits into from
Oct 31, 2023

Conversation

bushrat011899
Copy link
Contributor

Objective

If a Rollback entity is spawned, then rollback causes that entity to no longer be spawned (or vice versa), the generation of that Entity will be different across clients that did/not rollback. Because Entity derives its PartialOrd, the generation value changes the order of the entities, and likewise for Rollback. Any code relying on a stable ordering of Rollback components will then likely desync.

This should not happen!

Solution

  • I've removed the PartialOrd and Ord implementations for Rollback, since they are not stable across clients, and therefore using them is a footgun waiting to happen.
  • Simplified RollbackOrdered::push to simply stack the values in the order AddRollbackCommand is called. I believe this ordering is stable across clients so it can be used.
  • Implemented Clone for RollbackOrdered and added it to the rollback schedule to account for Rollback entities de/spawned during rollback.
  • Added a default checksum plugin that will ensure the number of active Rollback entities, and the total number spawned Rollback entities is a part of the checksum. These are cheap since both are single len() calls.

Notes

I've tested rebasing #78 onto this PR and from my testing, all desync issues are resolved. At a minimum, the frequency of desync issues is so drastically reduced that I was not able to replicate them no matter how randomly and quickly I switched peers/inputs.

If the de/spawning of a `Rollback` entity is rolled back, we must ensure the `RollbackOrdered` resource reflects that.

I've also added an `EntityChecksumPlugin` which will flag if clients desync on the number of active `Rollback` entities, or the total number ever spawned.
Because Entity derives it's ordering, the generation value will change the order drastically. Unfortunately, Bevy will pick a different generation during rollback, destroying ordering.

`RollbackOrdered` is now the only way to get a stable ordering for `Rollback`.
@bushrat011899 bushrat011899 mentioned this pull request Oct 31, 2023
3 tasks
Copy link
Collaborator

@johanhelsing johanhelsing left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! I'm not seeing any desyncs in #78 anymore either. Would be really nice to have a unit test for this, but also really nice to get it in quickly so main isn't broken :P

Comment on lines +11 to 12
#[derive(Component, Hash, PartialEq, Eq, Clone, Copy, Debug)]
pub struct Rollback(Entity);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aaaah. I totally forgot about #58, and thought we we're still using "rollback ids"

@gschup gschup merged commit 78abe4e into gschup:main Oct 31, 2023
1 check passed
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.

3 participants