bevyengine / bevyengine/bevy

Running the same system in two different states is treated as ambiguous by the scheduler

Open
#14,335 1 comment 0 reactions 0 assignees View on GitHub
A-ECS A-States C-Bug D-Complex S-Needs-Design
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

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.