You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In **Bevy 0.10** we introduced [ECS Schedule V3](/news/bevy-0-10/#ecs-schedule-v3), which _vastly_ improved the capabilities of Bevy ECS system scheduling: scheduler API ergonomics, system chaining, the ability to run exclusive systems and apply deferred system operations at any point in a schedule, a single unified schedule, configurable System Sets, run conditions, and a better State system.
25
+
26
+
However it pretty quickly became clear that the new system still had some areas to improve:
27
+
28
+
***Base Sets were hard to understand and error prone**: What _is_ a Base Set? When do I use them? Why do they exist? Why is my ordering implicitly invalid due to incompatible Base Set ordering? Why do some schedules have a default Base Set while others don't? [Base Sets were confusing!](https://github.com/bevyengine/bevy/pull/8079#base-set-confusion)
29
+
***There were too many ways to schedule a System**: We've accumulated too many scheduling APIs. As of Bevy **0.10**, we had [_SIX_ different ways to add a system to the "startup" schedule](https://github.com/bevyengine/bevy/pull/8079#unify-system-apis). Thats too many ways!
30
+
***Too much implicit configuration**: There were both default Schedules and default Base Sets. In some cases systems had default schedules or default base sets, but in other cases they didn't! [A system's schedule and configuration should be explicit and clear](https://github.com/bevyengine/bevy/pull/8079#schedule-should-be-clear).
31
+
***Adding Systems to Schedules wasn't ergonomic**: Things like `add_system(foo.in_schedule(CoreSchedule::Startup))` were not fun to type or read. We created special-case helpers, such as `add_startup_system(foo)`, but [this required more internal code, user-defined schedules didn't benefit from the special casing, and it completely hid the `CoreSchedule::Startup` symbol!](https://github.com/bevyengine/bevy/pull/8079#ergonomic-system-adding).
32
+
33
+
### Unraveling the Complexity
34
+
35
+
If your eyes started to glaze over as you tried to wrap your head around this, or phrases like "implicitly added to the `Update` Base Set" filled you with dread ... don't worry. After [a lot of careful thought](https://github.com/bevyengine/bevy/pull/8079) we've unraveled the complexity and built something clear and simple.
36
+
37
+
In **Bevy 0.11** the "scheduling mental model" is _much_ simpler thanks to **Schedule-First ECS APIs**:
38
+
39
+
```rust
40
+
app
41
+
.add_systems(Startup, (a, b))
42
+
.add_systems(Update, (c, d, e))
43
+
.add_systems(FixedUpdate, (f, g))
44
+
.add_systems(PostUpdate, h)
45
+
.add_systems(OnEnter(AppState::Menu), enter_menu)
46
+
.add_systems(OnExit(AppState::Menu), exit_menu)
47
+
```
48
+
49
+
***There is _exactly_ one way to schedule systems**
50
+
* Call `add_systems`, state the schedule name, and specify one or more systems
51
+
***Base Sets have been entirely removed in favor of Schedules, which have friendly / short names**
52
+
* Ex: The `CoreSet::Update` Base Set has become `Update`
53
+
***There is no implicit or implied configuration**
54
+
* Default Schedules and default Base Sets don't exist
55
+
***The syntax is easy on the eyes and ergonomic**
56
+
* Schedules are first so they "line up" when formatted
57
+
58
+
<details>
59
+
<summary>To compare, expand this to see what it used to be!</summary>
60
+
61
+
```rust
62
+
app
63
+
// Startup system variant 1.
64
+
// Has an implied default StartupSet::Startup base set
65
+
// Has an implied CoreSchedule::Startup schedule
66
+
.add_startup_systems((a, b))
67
+
// Startup system variant 2.
68
+
// Has an implied default StartupSet::Startup base set
69
+
// Has an implied CoreSchedule::Startup schedule
70
+
.add_systems((a, b).on_startup())
71
+
// Startup system variant 3.
72
+
// Has an implied default StartupSet::Startup base set
It is now possible to infinitely nest tuples of systems in a `.add_systems` call!
115
+
116
+
```rust
117
+
app.add_systems(Update, (
118
+
(a, (b, c, d, e), f),
119
+
(g, h),
120
+
i
121
+
))
122
+
```
123
+
124
+
At first glance, this might not seem very useful. But in combination with per-tuple configuration, it allows you to easily and cleanly express schedules:
0 commit comments