bevyengine / bevyengine/bevy

Time-keeping broken with `UpdateMode::Reactive` (X11 and WASM)

Open
#14,682 3 comments 0 reactions 0 assignees View on GitHub
A-Time A-Windowing C-Bug S-Needs-Investigation
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 16h
Merged PRs (30d)
171

Description

## Bevy version

Bevy 0.14.1 and main

X11 adapter: `AdapterInfo { name: "NVIDIA GeForce RTX 2060", vendor: 4318, device: 7817, device_type: DiscreteGpu, driver: "NVIDIA", driver_info: "555.58.02", backend: Vulkan }`
WASM adapter:`AdapterInfo { name: "NVIDIA GeForce GTX 980, or similar", vendor: 4318, device: 0, device_type: Other, driver: "WebGL", driver_info: "2.0", backend: Gl }`

Happens on native X11, and WASM (Firefox and Chrome)

## What you did

Run this example:
```rust
use std::time::Duration;

use bevy::{
input::common_conditions::input_just_pressed,
prelude::*,
winit::{UpdateMode, WinitSettings},
};

fn main() {
App::new()
.add_plugins(DefaultPlugins.build())
.add_systems(Startup, |mut cmds: Commands| {
cmds.spawn(Camera2dBundle::default());
})
.add_systems(
Update,
(run, switch.run_if(input_just_pressed(KeyCode::KeyU))).chain(),
)
.run();
}

fn switch(mut settings: ResMut) {
settings.focused_mode = match settings.focused_mode {
UpdateMode::Continuous => {
info!("Switching to continuous!");
UpdateMode::reactive(Duration::from_secs(1))
}
UpdateMode::Reactive { .. } => {
info!("Switching to reactive!");
UpdateMode::Continuous
}
};
settings.unfocused_mode = settings.focused_mode;
}

fn run(time: Res

## What went wrong

- Initially, `delta_time` is consistent
- The circle revolves at 1 revolution per second.
- Press U, to switch to reactive mode
- Now the delta_time increases every frame, until it caps off at 0.25s
- As a result, the circle moves around instead of appearing roughly in the same place (what you would expect if the app updates ~every second)
- Press U again, to switch back to continuous mode
- The next frame has a low delta_time, as expected BUT
- The following frame gets a strange lag spike at 0.25s, making the circle briefly appear in another position before going back to rotating normally.

## Additional information

X11 logs

```
2024-08-09T15:29:24.328881Z INFO update_mode_switch: 0.006974337 Continuous
2024-08-09T15:29:24.335733Z INFO update_mode_switch: 0.006931047 Continuous
2024-08-09T15:29:24.342786Z INFO update_mode_switch: 0.006965437 Continuous
2024-08-09T15:29:24.342826Z INFO update_mode_switch: Switching to reactive!
2024-08-09T15:29:24.349579Z INFO update_mode_switch: 0.006900987 Reactive { wait: 1s, react_to_device_events: true, react_to_user_events: true, react_to_window_events: true }
2024-08-09T15:29:24.422030Z INFO update_mode_switch: 0.006958497 Reactive { wait: 1s, react_to_device_events: true, react_to_user_events: true, react_to_window_events: true }
2024-08-09T15:29:25.342941Z INFO update_mode_switch: 0.006940747 Reactive { wait: 1s, react_to_device_events: true, react_to_user_events: true, react_to_window_events: true }
2024-08-09T15:29:26.343144Z INFO update_mode_switch: 0.05999414 Reactive { wait: 1s, react_to_device_events: true, react_to_user_events: true, react_to_window_events: true }
2024-08-09T15:29:27.343763Z INFO update_mode_switch: 0.25 Reactive { wait: 1s, react_to_device_events: true, react_to_user_events: true, react_to_window_events: true }
2024-08-09T15:29:28.343784Z INFO update_mode_switch: 0.25 Reactive { wait: 1s, react_to_device_events: true, react_to_user_events: true, react_to_window_events: true }
2024-08-09T15:29:29.343866Z INFO update_mode_switch: 0.25 Reactive { wait: 1s, react_to_device_events: true, react_to_user_events: true, react_to_window_events: true }
2024-08-09T15:29:29.812715Z INFO update_mode_switch: 0.25 Reactive { wait: 1s, react_to_device_events: true, react_to_user_events: true, react_to_window_events: true }
2024-08-09T15:29:29.812754Z INFO update_mode_switch: Switching to continuous!
2024-08-09T15:29:29.813895Z INFO update_mode_switch: 0.25 Continuous
2024-08-09T15:29:29.814938Z INFO update_mode_switch: 0.25 Continuous
2024-08-09T15:29:29.815371Z INFO update_mode_switch: 0.00067504 Continuous
2024-08-09T15:29:29.816060Z INFO update_mode_switch: 0.001055621 Continuous
2024-08-09T15:29:29.816653Z INFO update_mode_switch: 0.000581371 Continuous
2024-08-09T15:29:29.817327Z INFO update_mode_switch: 0.00066637 Continuous
2024-08-09T15:29:29.817929Z INFO update_mode_switch: 0.000625411 Continuous
```

X11 logs (different run showing a single normal continuous frame in between the freaky 0.25s frames)

```
2024-08-09T15:37:07.687200Z INFO update_mode_switch: 0.006944937 Continuous
2024-08-09T15:37:07.694232Z INFO update_mode_switch: 0.006939317 Continuous
2024-08-09T15:37:07.701115Z INFO update_mode_switch: 0.006946427 Continuous
2024-08-09T15:37:07.701148Z INFO update_mode_switch: Switching to reactive!
2024-08-09T15:37:07.708097Z INFO update_mode_switch: 0.006948797 Reactive { wait: 1s, react_to_device_events: true, react_to_user_events: true, react_to_window_events: true }
2024-08-09T15:37:07.809416Z INFO update_mode_switch: 0.006945327 Reactive { wait: 1s, react_to_device_events: true, react_to_user_events: true, react_to_window_events: true }
2024-08-09T15:37:08.532579Z INFO update_mode_switch: 0.006942567 Reactive { wait: 1s, react_to_device_events: true, react_to_user_events: true, react_to_window_events: true }
2024-08-09T15:37:08.532621Z INFO update_mode_switch: Switching to continuous!
2024-08-09T15:37:08.533378Z INFO update_mode_switch: 0.08901965 Continuous
2024-08-09T15:37:08.534797Z INFO update_mode_switch: 0.25 Continuous
2024-08-09T15:37:08.535216Z INFO update_mode_switch: 0.000840611 Continuous
2024-08-09T15:37:08.535908Z INFO update_mode_switch: 0.00076325 Continuous
2024-08-09T15:37:08.536541Z INFO update_mode_switch: 0.000646981 Continuous
2024-08-09T15:37:08.537180Z INFO update_mode_switch: 0.000634641 Continuous
```

WASM logs

```
INFO examples/window/update_mode_switch.rs:27 Switching to reactive! wasm_example.js:435:21
INFO examples/window/update_mode_switch.rs:39 0.006 Reactive { wait: 1s, react_to_device_events: true, react_to_user_events: true, react_to_window_events: true } wasm_example.js:435:21
INFO examples/window/update_mode_switch.rs:39 0.008 Reactive { wait: 1s, react_to_device_events: true, react_to_user_events: true, react_to_window_events: true } wasm_example.js:435:21
INFO examples/window/update_mode_switch.rs:39 0.082 Reactive { wait: 1s, react_to_device_events: true, react_to_user_events: true, react_to_window_events: true } wasm_example.js:435:21
INFO examples/window/update_mode_switch.rs:39 0.25 Reactive { wait: 1s, react_to_device_events: true, react_to_user_events: true, react_to_window_events: true } 8 wasm_example.js:435:21
INFO examples/window/update_mode_switch.rs:31 Switching to continuous! wasm_example.js:435:21
INFO examples/window/update_mode_switch.rs:39 0.25 Continuous wasm_example.js:435:21
INFO examples/window/update_mode_switch.rs:39 0.002 Continuous wasm_example.js:435:21
INFO examples/window/update_mode_switch.rs:39 0.013 Continuous wasm_example.js:435:21
INFO examples/window/update_mode_switch.rs:39 0.008 Continuous wasm_example.js:435:21
INFO examples/window/update_mode_switch.rs:39 0.012 Continuous wasm_example.js:435:21
```

Contributor guide

Open the contributing guide

Research direction

Start by running examples/window/update_mode_switch.rs on X11 or WASM and compare the logged Time delta values while toggling UpdateMode. Then trace the UpdateMode and WinitSettings handling involved in the example. Done means reactive updates no longer accumulate to 0.25 seconds and switching back to continuous mode does not produce a spurious lag frame.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
game-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.