Running the same system in two different states is treated as ambiguous by the scheduler
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
Sorry. I am not sure if this is a bug or it is expected as design.
## Bevy version
0.14
## Relevant system information
| | |
|:--|:--|
| Cargo version | 1.79.0 (ffa9cf99a 2024-06-03) |
| Rust | 1.79.0 (129f3b996 2024-06-10) |
| OS | Fedora 40 |
## What you did
I added a same system to two different states but the app cannot run.
```rust
use bevy::prelude::*;
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, States)]
enum GameState {
#[default]
Menu,
Ingame,
}
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.init_state::()
.add_systems(Update, (a, b.after(a)).run_if(in_state(GameState::Menu)))
.add_systems(Update, a.run_if(in_state(GameState::Ingame)))
.run();
}
fn a() {
println!("a");
}
fn b() {
println!("b");
}
```
## What went wrong
- what were you expecting?
Application run without crash.
- what actually happened?
Application crashes with error:
```
Error when initializing schedule Update: Tried to order against `SystemTypeSet(fn FunctionSystem())` in a schedule that has more than one `SystemTypeSet(fn FunctionSystem())` instance. `SystemTypeSet(fn FunctionSystem())` is a `SystemTypeSet` and cannot be used for ordering if ambiguous. Use a different set without this restriction.
```
I don't know what is ambiguous here. It is very clear that:
* In state `Menu`, run `a`, then run `b`.
* In state `Ingame`, run `a`.
## Additional information
If I add system `a` into only one state, application can run:
This is okay:
```rust
App::new()
.add_plugins(DefaultPlugins)
.init_state::()
.add_systems(Update, (a, b.after(a)).run_if(in_state(GameState::Menu))) // a() is in only one state
.run();
```
This is okay:
```rust
App::new()
.add_plugins(DefaultPlugins)
.init_state::()
.add_systems(Update, a.run_if(in_state(GameState::Ingame))) // a() is in only one state
.run();
```
I know I can use `(a, b).chain()` instead, but somtimes using `after()` is cleaner.
Full error logs
```
2024-07-15T14:18:37.520684Z INFO bevy_render::renderer: AdapterInfo { name: "AMD Radeon RX 6700 XT (RADV NAVI22)", vendor: 4098, device: 29663, device_type: DiscreteGpu, driver: "radv", driver_info: "Mesa 24.1.2", backend: Vulkan }
2024-07-15T14:18:37.715868Z INFO bevy_winit::system: Creating new window "App" (Entity { index: 0, generation: 1 })
thread 'main' panicked at /home/kimtinh/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.14.0/src/schedule/schedule.rs:383:33:
Error when initializing schedule Update: Tried to order against `SystemTypeSet(fn FunctionSystem())` in a schedule that has more than one `SystemTypeSet(fn FunctionSystem())` instance. `SystemTypeSet(fn FunctionSystem())` is a `SystemTypeSet` and cannot be used for ordering if ambiguous. Use a different set without this restriction.
stack backtrace:
0: rust_begin_unwind
at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/std/src/panicking.rs:652:5
1: core::panicking::panic_fmt
at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/panicking.rs:72:14
2: bevy_ecs::schedule::schedule::Schedule::run::{{closure}}
at /home/kimtinh/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.14.0/src/schedule/schedule.rs:383:33
3: core::result::Result::unwrap_or_else
at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/result.rs:1431:23
4: bevy_ecs::schedule::schedule::Schedule::run
at /home/kimtinh/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.14.0/src/schedule/schedule.rs:382:9
5: bevy_ecs::world::World::try_run_schedule::{{closure}}
at /home/kimtinh/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.14.0/src/world/mod.rs:2743:55
6: bevy_ecs::world::World::try_schedule_scope
at /home/kimtinh/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.14.0/src/world/mod.rs:2676:21
7: bevy_ecs::world::World::try_run_schedule
at /home/kimtinh/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.14.0/src/world/mod.rs:2743:9
8: bevy_app::main_schedule::Main::run_main::{{closure}}
at /home/kimtinh/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_app-0.14.0/src/main_schedule.rs:227:25
9: bevy_ecs::world::World::resource_scope
at /home/kimtinh/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.14.0/src/world/mod.rs:1886:22
10: bevy_app::main_schedule::Main::run_main
at /home/kimtinh/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_app-0.14.0/src/main_schedule.rs:225:9
11: core::ops::function::FnMut::call_mut
at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/ops/function.rs:166:5
12: core::ops::function::impls:: for &mut F>::call_mut
at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/ops/function.rs:294:13
13: Out>>::run::call_inner
at /home/kimtinh/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.14.0/src/system/exclusive_function_system.rs:218:21
14: Out>>::run
at /home/kimtinh/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.14.0/src/system/exclusive_function_system.rs:221:17
15: as bevy_ecs::system::system::System>::run::{{closure}}
at /home/kimtinh/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.14.0/src/system/exclusive_function_system.rs:111:23
16: bevy_ecs::world::World::last_change_tick_scope
at /home/kimtinh/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.14.0/src/world/mod.rs:2215:9
17: as bevy_ecs::system::system::System>::run
at /home/kimtinh/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.14.0/src/system/exclusive_function_system.rs:103:9
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!
Process finished with exit code 101
```
Contributor guide
Research direction
Start by reproducing the example against Bevy 0.14, then inspect bevy_ecs/src/schedule/schedule.rs around the reported panic at line 383 and the scheduler's handling of repeated system instances. Use the provided state and ordering setup as the regression case; done means the behavior is clearly defined and the example no longer panics unexpectedly, with relevant scheduler tests updated.
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
- 25/100