bevyengine / bevyengine/bevy

Change detection of keyboard's resource `ButtonInput` is inconsistent

Open
#13,901 0 comments 0 reactions 0 assignees View on GitHub
A-Input 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

`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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.