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

Rollback time resource during rollback #623

Merged
merged 3 commits into from
Sep 7, 2024

Conversation

nick-e
Copy link
Contributor

@nick-e nick-e commented Sep 4, 2024

Ensure that the Fixed<Time> resource is accurate during a rollback by rollbacking the time resource when a rollback starts and advancing the time after each rollback tick. This is a continuation of #619. This PR takes into account Time<Fixed>'s overstep.

I originally thought that using add_resource_rollback::<Time<Fixed>>() and running the RunFixedMainLoop schedule would be the solution but RunFixedMainLoop requires that the real time clock also progress in order to correctly advance the Time<Fixed> resource.

Fixes #618

@nick-e
Copy link
Contributor Author

nick-e commented Sep 4, 2024

I tested the fix using the replication process found in #618

@@ -1108,10 +1107,10 @@ impl AppComponentExt for App {
}
}

/// Do not use `Time<Fixed>` for `R`. `Time<Fixed>` is already rollbacked.
Copy link
Owner

Choose a reason for hiding this comment

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

This comment probably shouldn't be there, right? This is for users who want to use add_resource_rollback

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated the doc comments to add clarity. Let me know what you think!

@cBournhonesque
Copy link
Owner

Sorry I didn't have time to review in detail, but apparently just using the replication rollback to rollback Time and Time was not enough? We still need to have some ad-hoc logic?

I tested the fix using the replication process found in #618

What were the results? There's no rollbacks anymore?

@oxkitsune
Copy link

oxkitsune commented Sep 5, 2024

This noticeably improved FPS drops I was experiencing during rollback. However there are still rollbacks for me, although those might be related to other things in my project.

@nick-e
Copy link
Contributor Author

nick-e commented Sep 5, 2024

I updated the PR to correctly advance the elapsed time of the fixed time resource during a rollback.

We can't use add_resource_rollback::<Time<Fixed>>::() because we lose Time<Fixed>'s current overstep when the resource rollbacks. We don't care what its overstep was when rollbacked. Overstep is used to determine when FixedMain should tick based on real time. Rollback ticks aren't run in real time.

On top of that, the only way to progress Time<Fixed> with accurate overstep is by running RunFixedMainLoop because overstep is private. The issue with that is the RunFixedMainLoop schedule progresses Time<Fixed> using Time<Virtual> which relies on real time. We would have to keep track of the real time for every tick that needs to be rollbacked, add them up, and apply it to Time<Virtual> before running RunFixedMainLoop. It gets more complicated because Time<Virtual> has max_delta which caps how much time can change and some rollbacks may be farther behind than that.

As a rule of thumb, add_resource_rollback() should only be used for resources that will only be modified by systems run in the FixedMain schedule. This is because rollbacks only run the FixedMain schedule. Time<Fixed> is modified by bevy_time::fixed::run_fixed_main_schedule() which is run outside of the FixedMain schedule. I think it's worth mentioning so I added it into the add_resource_rollback() doc comments.

Testing

I tested this PR by adding the following to client::handle_character_actions() with the avian_3d_character example:

if let Some(ref rb) = rollback {
    if let Some(tick) = rb.get_rollback_tick() {
        info!(
            "    rb-{:?}, delta: {}, elapsed: {}",
            tick,
            time.delta_seconds(),
            time.elapsed_seconds()
        );
    } else {
        info!(
            "not-rb-{:?}, delta: {}, elapsed: {}",
            tick_manager.tick(),
            time.delta_seconds(),
            time.elapsed_seconds()
        );
    }
} else {
    info!(
        "{:?}, delta: {}, elapsed: {}",
        tick_manager.tick(),
        time.delta_seconds(),
        time.elapsed_seconds()
    );
}

This function is only run within a system within the FixedMain schedule.

I set the latency to 100ms and a packet loss of 0.1 in order to incur multi-tick rollbacks. Here are some logs of the avian_3d_character client run with cargo run --release -- client -c 1 without the PR:

2024-09-05T16:03:41.208296Z  INFO avian_3d_character::client: not-rb-Tick(257), delta: 0.015625, elapsed: 3.796875
2024-09-05T16:03:41.224970Z  INFO avian_3d_character::client: not-rb-Tick(258), delta: 0.015625, elapsed: 3.8125
2024-09-05T16:03:41.237516Z  INFO avian_3d_character::client: not-rb-Tick(259), delta: 0.015625, elapsed: 3.828125
2024-09-05T16:03:41.254084Z  INFO avian_3d_character::client: not-rb-Tick(260), delta: 0.015625, elapsed: 3.84375
2024-09-05T16:03:41.270763Z  INFO avian_3d_character::client: not-rb-Tick(261), delta: 0.015625, elapsed: 3.859375
2024-09-05T16:03:41.287490Z  INFO avian_3d_character::client: not-rb-Tick(262), delta: 0.015625, elapsed: 3.875
2024-09-05T16:03:41.299996Z  INFO avian_3d_character::client: not-rb-Tick(263), delta: 0.015625, elapsed: 3.890625
2024-09-05T16:03:41.312512Z  INFO avian_3d_character::client:     rb-Tick(257), delta: 0.004247744, elapsed: 3.9034278 <-- wrong delta; elapsed not rollbacked
2024-09-05T16:03:41.313247Z  INFO avian_3d_character::client:     rb-Tick(258), delta: 0.004247744, elapsed: 3.9034278 <-- elapsed not advancing
2024-09-05T16:03:41.313825Z  INFO avian_3d_character::client:     rb-Tick(259), delta: 0.004247744, elapsed: 3.9034278
2024-09-05T16:03:41.314345Z  INFO avian_3d_character::client:     rb-Tick(260), delta: 0.004247744, elapsed: 3.9034278
2024-09-05T16:03:41.314856Z  INFO avian_3d_character::client:     rb-Tick(261), delta: 0.004247744, elapsed: 3.9034278
2024-09-05T16:03:41.315427Z  INFO avian_3d_character::client:     rb-Tick(262), delta: 0.004247744, elapsed: 3.9034278
2024-09-05T16:03:41.315992Z  INFO avian_3d_character::client:     rb-Tick(263), delta: 0.004247744, elapsed: 3.9034278
2024-09-05T16:03:41.318197Z  INFO avian_3d_character::client: not-rb-Tick(264), delta: 0.015625, elapsed: 3.90625

Here are some logs with the PR:

2024-09-05T16:00:26.780969Z  INFO avian_3d_character::client: not-rb-Tick(129), delta: 0.015625, elapsed: 1.828125
2024-09-05T16:00:26.792864Z  INFO avian_3d_character::client: not-rb-Tick(130), delta: 0.015625, elapsed: 1.84375
2024-09-05T16:00:26.809763Z  INFO avian_3d_character::client: not-rb-Tick(131), delta: 0.015625, elapsed: 1.859375
2024-09-05T16:00:26.826218Z  INFO avian_3d_character::client: not-rb-Tick(132), delta: 0.015625, elapsed: 1.875
2024-09-05T16:00:26.838714Z  INFO avian_3d_character::client: not-rb-Tick(133), delta: 0.015625, elapsed: 1.890625
2024-09-05T16:00:26.855291Z  INFO avian_3d_character::client: not-rb-Tick(134), delta: 0.015625, elapsed: 1.90625
2024-09-05T16:00:26.871923Z  INFO avian_3d_character::client: not-rb-Tick(135), delta: 0.015625, elapsed: 1.921875
2024-09-05T16:00:26.880931Z  INFO avian_3d_character::client:     rb-Tick(129), delta: 0.015625, elapsed: 1.828125 <-- correct delta; elapsed rollbacked
2024-09-05T16:00:26.881672Z  INFO avian_3d_character::client:     rb-Tick(130), delta: 0.015625, elapsed: 1.84375  <-- elapsed advancing correctly
2024-09-05T16:00:26.882308Z  INFO avian_3d_character::client:     rb-Tick(131), delta: 0.015625, elapsed: 1.859375
2024-09-05T16:00:26.882863Z  INFO avian_3d_character::client:     rb-Tick(132), delta: 0.015625, elapsed: 1.875
2024-09-05T16:00:26.883419Z  INFO avian_3d_character::client:     rb-Tick(133), delta: 0.015625, elapsed: 1.890625
2024-09-05T16:00:26.883931Z  INFO avian_3d_character::client:     rb-Tick(134), delta: 0.015625, elapsed: 1.90625
2024-09-05T16:00:26.884464Z  INFO avian_3d_character::client:     rb-Tick(135), delta: 0.015625, elapsed: 1.921875
2024-09-05T16:00:26.888542Z  INFO avian_3d_character::client: not-rb-Tick(136), delta: 0.015625, elapsed: 1.9375

There are still constant rollbacks. Still looking into that.

@nick-e
Copy link
Contributor Author

nick-e commented Sep 5, 2024

I added a test for verifying that the time resource is accurate during a rollback. I can confirm that the test fails without this PR.


// Set the rollback tick's generic time resource to the fixed time
// resource that was just advanced.
*world.resource_mut::<Time>() = world.resource::<Time<Fixed>>().as_generic();
Copy link
Owner

Choose a reason for hiding this comment

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

Why do we want to also rollback the non-fixed-time Time?

Copy link
Contributor Author

@nick-e nick-e Sep 7, 2024

Choose a reason for hiding this comment

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

Time is not a non-fixed time but instead a time without a "context". It could represent fixed time or some other kind of time like Time<Virtual>. It's my understanding that systems within the FixedMain schedule should be safe to assume that the value of the generic Time resource they retrieve via Res<Time> represents the Time<Fixed> resource.

@cBournhonesque
Copy link
Owner

Thanks for the explanation on why rollbacking Time + running RunFixedMainLoop wouldn't work.
I also appreciate the tests and the logs!

I'm convinced by this PR, making sure that Time was handled correctly during rollback was something I had completely overlooked!

I left a couple comments but otherwise I think it's ready to merge. Thanks for the awesome work!

@cBournhonesque cBournhonesque merged commit a7dd781 into cBournhonesque:main Sep 7, 2024
4 of 5 checks passed
@nick-e nick-e deleted the time-rollback branch September 17, 2024 20:45
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.

Incorrect time resource value during rollbacks
3 participants