Change detection of keyboard's resource `ButtonInput` is inconsistent
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
## Bevy version
`0.14.0-rc.3`
## \[Optional\] Relevant system information
```
SystemInfo { os: "Windows 11 Enterprise", kernel: "22631", cpu: "AMD Ryzen 9 5900X 12-Core Processor", core_count: "12", memory: "63.9 GiB" }
```
```
AdapterInfo { name: "NVIDIA GeForce GTX 1080", vendor: 4318, device: 7040, device_type: DiscreteGpu, driver: "NVIDIA", driver_info: "555.99", backend: Vulkan }
```
## What you did
Let's have this code:
```rust
use bevy::prelude::*;
fn main() -> AppExit {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Update, print_kb)
.run()
}
fn print_kb(keyboard_input: Res>) {
if !keyboard_input.is_changed() {
return;
}
info!("{:?}", keyboard_input);
}
```
## What went wrong
1. Pressing a key, let's use `A`, will print that it was pressed into console:
```
2024-06-17T20:34:15.673541Z INFO vbr: Res(ButtonInput { pressed: {KeyA}, just_pressed: {KeyA}, just_released: {} })
2024-06-17T20:34:16.183702Z INFO vbr: Res(ButtonInput { pressed: {KeyA}, just_pressed: {}, just_released: {} })
2024-06-17T20:34:16.211731Z INFO vbr: Res(ButtonInput { pressed: {KeyA}, just_pressed: {}, just_released: {} })
...
```
2. Pressing second key, let's use `S`, will print both of them into console:
```
...
2024-06-17T20:35:12.589514Z INFO vbr: Res(ButtonInput { pressed: {KeyA, KeyS}, just_pressed: {KeyS}, just_released: {} })
2024-06-17T20:35:13.084898Z INFO vbr: Res(ButtonInput { pressed: {KeyA, KeyS}, just_pressed: {}, just_released: {} })
2024-06-17T20:35:13.113489Z INFO vbr: Res(ButtonInput { pressed: {KeyA, KeyS}, just_pressed: {}, just_released: {} })
...
```
3. Then after releasing the first key `A` the second key `S` will be printing:
```
...
2024-06-17T20:38:03.982794Z INFO vbr: Res(ButtonInput { pressed: {KeyS}, just_pressed: {}, just_released: {KeyA} })
2024-06-17T20:38:04.478926Z INFO vbr: Res(ButtonInput { pressed: {KeyS}, just_pressed: {}, just_released: {} })
2024-06-17T20:38:04.507727Z INFO vbr: Res(ButtonInput { pressed: {KeyS}, just_pressed: {}, just_released: {} })
...
```
Point 1 to 3 work as expected BUT should we change the order of keys in 3rd point - second key `S` will be released before first key `A` - then we will not see additional printing of key `A`:
```
...
2024-06-17T20:42:33.649980Z INFO vbr: Res(ButtonInput { pressed: {KeyA, KeyS}, just_pressed: {}, just_released: {} })
2024-06-17T20:42:33.678286Z INFO vbr: Res(ButtonInput { pressed: {KeyA}, just_pressed: {}, just_released: {KeyS} })
```
The same behaviour as observed in 3rd point should happen and we should see printing of `ButtonInput` resource into console but it does not happen.
Just because we changed the order of released keys should not result in different behaviour of change detection.
## Additional information
.
Contributor guide
Research direction
Start with the minimal Rust example and the print_kb system, focusing on the ButtonInput resource and its is_changed() behavior. Reproduce the two key-release orders described in the issue, then trace how ButtonInput is updated. Done means change detection behaves consistently regardless of which pressed key is released first, with coverage for both orders.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- game-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100