Skip to content

Inaccurate Time<Real>, missed FixedUpdate #21229

@dubrowgn

Description

@dubrowgn

Bevy version and features

  • v0.16.1 (main and older versions also look affected; the code is at least several years old)
  • vsync disabled

What you did

While trying to implement a simple frame limiter system using thread::sleep, I noticed Update was running too often compared to FixedUpdate, causing persistent frame stutters.

Analysis

After adding some logging, I discovered the thread was correctly sleeping for the expected e.g. ~15ms, but Time<Real> (and thus all other Time<T>'s) were only moving forward e.g. ~500µs. I tracked Time<Real> updates back to time_system, where I added a line to log the received time:

sys_sleep -
    now: Instant { tv_sec: 5601, tv_nsec: 324402504 }
    Time<Real>: 7.652275701s (delta: 16.982329ms)
sys_sleep - slept 16.334885ms
time_system - received time: Instant { tv_sec: 5601, tv_nsec: 324451814 }
sys_sleep -
    now: Instant { tv_sec: 5601, tv_nsec: 341332892 }
    Time<Real>: 7.652884464s (delta: 608.763µs)

We can see above that actual wall clock time moved forward 16.93ms, but Time<Real> only moved forward 608.763µs.

This leads to FixedUpdate not running, as the requisite amount of time does not appear to have passed. On the next frame, everything catches back up, and FixedUpdate is run twice. Rinse and repeat, causing stutters.

What went wrong

Time<Real> does not track wall clock time. Instead, it consumes timestamps sent from the RenderApp, from render_system in the Render schedule. This causes the main app to consistently lag by the time it takes to process any load between RenderApp Render and main app First. A sleep in this time frame makes the issue more obvious.

Someone here probably knows, but it's not clear from the code why it was designed this way. It seems suspect to me that RenderApp effectively owns Time<Real>, and not the main app. If time really does need to be synchronized in this way, I would have expected it to be the other way around.

Additional information

Potentially related/impacted:

Caused by: #4744

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 behaviorD-ComplexQuite challenging from either a design or technical perspective. Ask for help!S-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