Skip to content

1-frame-lag for Res<Time> updates when using UpdateMode::Reactive #20412

@vladbat00

Description

@vladbat00

Bevy version

0.16.1

Relevant system information

MacOS Sequoia 15.5

What you did

use bevy::log;
use bevy::prelude::*;
use bevy::winit::WinitSettings;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        // Power-saving reactive rendering for applications.
        .insert_resource(WinitSettings::desktop_app())
        .add_systems(Update, repro_system)
        .run();
}

fn repro_system(time: Res<Time>) {
    log::info!("{} {}", time.delta_secs(), time.elapsed_secs_f64());
}

What went wrong

I'll attach the output of the system here.

Started the app:

2025-08-04T09:49:18.070990Z  INFO bevy_time_repro: 0 0
2025-08-04T09:49:18.158590Z  INFO bevy_time_repro: 0.093625665 0.093625667
2025-08-04T09:49:19.377771Z  INFO bevy_time_repro: 0.25 0.343625667

... trimmed out some entries where I was just moving my cursor

After this line I stopped moving the cursor and my app started updating once in 5 seconds (all the following entries weren't cut out or modified):

2025-08-04T09:49:23.068283Z  INFO bevy_time_repro: 0.028938208 0.76564425

Here you can see from the timestamp that the first update indeed happens in 5 seconds,
but both time.delta_secs and elapsed_secs_f64 are outdated:

2025-08-04T09:49:28.070137Z  INFO bevy_time_repro: 0.029651623 0.795295875

Also, notice how it's again an update after 5 second but the delta_secs value is 0.25 for whatever reason, while 5.0 is expected (I couldn't reproduce that in my other apps). But at least here we we've received some large time diffs.

2025-08-04T09:49:33.072285Z  INFO bevy_time_repro: 0.25 1.045295875
2025-08-04T09:49:38.079530Z  INFO bevy_time_repro: 0.25 1.2952958749999999

Additional information

This bugs causes some weird issues with bevy_egui: vladbat00/bevy_egui#352.
For context, Egui has a timeout where it discards "ButtonUp" events for pointers if the time delta is larger than 0.8.

And since time updates suffer from the 1-frame-lag bug, a lot of events are discarded in the reactive mode (because Bevy often reports 1s+ diff between two calls elapsed_secs_f64 in sequential frames, where the actual time diff is much shorter).

My guess is that it's caused by the fact that time updates are sent via TimeSender only after we render (see render_system). But we also need the time to be updated once we wake up the app due to winit updates.

No idea what causes the weird 0.25 values for delta_secs though.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-TimeInvolves time keeping and reportingA-WindowingPlatform-agnostic interface layer to run your app inC-BugAn unexpected or incorrect behaviorS-Needs-DesignThis issue requires design work to think about how it would best be accomplished

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions