Skip to content

Run individual SystemSets in Schedules#21893

Open
ItsDoot wants to merge 9 commits intobevyengine:mainfrom
ItsDoot:schedule/run-subgraph
Open

Run individual SystemSets in Schedules#21893
ItsDoot wants to merge 9 commits intobevyengine:mainfrom
ItsDoot:schedule/run-subgraph

Conversation

@ItsDoot
Copy link
Contributor

@ItsDoot ItsDoot commented Nov 20, 2025

Objective

Bevy users occasionally ask for the ability to run specific SystemSets in a Schedule, commonly for unit testing behaviors. Beyond that, this functionality brings us closer to turning our Update, PostUpdate, etc schedules into system sets by giving system sets a power that previously only schedules had: the ability to be executed.

Solution

  • Added a new parameter to SystemExecutor::run: subgraph: Option<SystemSetKey>
    • If Some, the provided SystemSetKey is used to fetch a bitset of the systems that are part of the set (including transitively), which is used to filter the SystemExecutor to execute only those systems.
    • If None, the SystemExecutor functions as previously.
  • Added SystemSchedule::systems_in_set which holds a sparse mapping of system sets to bitsets of the systems part of that set.
    • This map is filled lazily upon the first time a system set is executed.
  • Added Schedule::run_system_set which invokes SystemExecutor::run with the given system set.
  • Added World/Commands::run_system_set/try_run_system_set which invokes Schedule::run_system_set.

Note: Schedule::run_system_set is not re-entrant.

Testing

  • Added two new tests, one for single-threaded and one for multi-threaded.
  • Added new doctests.
  • Added new benchmarks.

Future work

  • Make slotmap::SparseSecondaryMap work under alloc rather than std, so we can replace SystemSchedule::systems_in_sets's HashMap with it.

Showcase

You can now run a specific system set within a schedule without executing the entire
schedule! This is particularly useful for testing, debugging, or selectively running
parts of your game logic, all without needing to factor features out into separate
schedules:

use bevy::prelude::*;

#[derive(SystemSet, Clone, Copy, PartialEq, Eq, Debug, Hash)]
enum GameSystems {
    Physics,
    Combat,
    UI,
}

fn physics_system() { /* ... */ }
fn combat_system() { /* ... */ }
fn ui_system() { /* ... */ }

let mut schedule = Schedule::default();
schedule.add_systems((
    physics_system.in_set(GameSystems::Physics),
    combat_system.in_set(GameSystems::Combat),
    ui_system.in_set(GameSystems::UI),
));

let mut world = World::new();

// Run only the physics systems
schedule.run_system_set(&mut world, GameSystems::Physics);

// Run only the combat systems
schedule.run_system_set(&mut world, GameSystems::Combat);

// You can also run system sets from the World or via Commands:
world.run_system_set(MySchedule, MySet);
commands.run_system_set(MySchedule, MySet);

@ItsDoot ItsDoot added C-Feature A new feature, making something new possible A-ECS Entities, components, systems, and events M-Release-Note Work that should be called out in the blog due to impact D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Nov 20, 2025
@ItsDoot ItsDoot mentioned this pull request Nov 20, 2025
9 tasks
@janhohenheim
Copy link
Member

I don't feel qualified to review the code per-se, but I want to express my support for this PR. Yeeting schedules would be lovely, and this looks like a great step in this direction :)

Copy link
Contributor

@cBournhonesque cBournhonesque left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great!
I've always wanted this functionality; I actually an old PR that did the same for system-stepping: #13219

I also want to blur the distinction between Schedules and SystemSet; as for me schedules are basically a big system-set and it can be confusing to have both concepts

Copy link
Contributor

@cBournhonesque cBournhonesque left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Can we add one test where a system is added/removed?

Copy link
Contributor

@hymm hymm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like somewhat niche functionality as running part of a schedule seems like a footgun outside of unit tests. But the added complexity and perf hit is not too significant so I'm fine with adding this. Just have a few nits.

Indirectly contributes to #16432
Indirectly contributes to #9792
schedules into system sets by giving system sets a power that previously only schedules had: the ability to be executed.

I don't understand how this pr contributes to these. Seems mostly orthogonal to me.

@ItsDoot ItsDoot force-pushed the schedule/run-subgraph branch from fd2c28d to edff0a7 Compare December 3, 2025 06:09
@janhohenheim
Copy link
Member

@hymm if we want to remove schedules and replace them with system sets, we need a way to replace run_schedule with run_system_set, which currently does not exist yet.

@ItsDoot
Copy link
Contributor Author

ItsDoot commented Dec 8, 2025

Yea I expect that if we eventually merge First/PreUpdate/Update/PostUpdate/Last into one schedule, the difficulty of setting up testing for individual behaviors will be a bit annoying without the ability to run individual system sets. This basically lets you slice Worlds by system behavior rather than needing to handcraft Worlds for each behavior you want to test.

@alice-i-cecile alice-i-cecile added the X-Contentious There are nontrivial implications that should be thought through label Dec 8, 2025
@alice-i-cecile
Copy link
Member

Marked as contentious: on its own, this is niche and not too controversial.

The broader plan of unifying all of the Main schedule and returning to base sets is very controversial though, and will need a working group.

@cart cart added this to ECS Feb 17, 2026
@github-project-automation github-project-automation bot moved this to Needs SME Triage in ECS Feb 17, 2026
@alice-i-cecile
Copy link
Member

@ItsDoot, can you resolve merge conflicts? Then I'll get back to you with a review.

@alice-i-cecile alice-i-cecile moved this from Needs SME Triage to SME Triaged in ECS Feb 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-ECS Entities, components, systems, and events C-Feature A new feature, making something new possible D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes M-Release-Note Work that should be called out in the blog due to impact S-Needs-Review Needs reviewer attention (from anyone!) to move forward X-Contentious There are nontrivial implications that should be thought through

Projects

Status: SME Triaged

Development

Successfully merging this pull request may close these issues.

Introduce an app::run_system_set() function

5 participants