AgentStack
SKILL verified MIT Self-run

Bevy Ecs Systems

skill-chrisgliddon-bevy-skills-bevy-ecs-systems · by chrisgliddon

Use when deriving `SystemParam`, grouping with `SystemSet`, gating execution with `.run_if(on_message::<M>())` / `in_state(...)` / `resource_exists::<R>`, ordering with `.before`/`.after`/`.chain()`, or removing systems at runtime with `remove_systems_in_set` (new in 0.18). Covers Bevy 0.18 system params, sets, and run conditions.

No reviews yet
0 installs
12 views
0.0% view→install

Install

$ agentstack add skill-chrisgliddon-bevy-skills-bevy-ecs-systems

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Bevy Ecs Systems? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Bevy 0.18 — ECS Systems (params, sets, run conditions)

When to use this skill

  • Bundling related state into a single system parameter via #[derive(SystemParam)].
  • Grouping systems into a SystemSet so callers can order against the whole group.
  • Gating systems with run conditions (run_if, on_message, in_state, resource_exists, any_with_component).
  • Hooking into state transitions with OnEnter(S) / OnExit(S) / OnTransition { from, to }.
  • Hot-removing systems at runtime (e.g. tearing down a debug overlay) with remove_systems_in_set.
  • Hitting ScheduleBuildError ambiguity panics — the executor no longer guesses.

Canonical pattern

use bevy::ecs::system::SystemParam;
use bevy::prelude::*;

#[derive(SystemSet, Hash, PartialEq, Eq, Clone, Debug)]
enum GameLoop { Input, Simulate, Render }

#[derive(States, Default, Hash, PartialEq, Eq, Clone, Debug)]
enum AppState { #[default] Loading, Playing }

#[derive(Resource, Default)]
struct Score(u32);

#[derive(Message)]
struct GoalScored { team: u8 }

// Composite param: pass one argument, get four.
// 'w = world borrow; 's = system-local state borrow.
#[derive(SystemParam)]
struct GameCtx {
    time:  Res,
    score: ResMut,
    goals: MessageReader,
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .init_resource::()
        .add_message::()
        .init_state::()
        .configure_sets(Update, (GameLoop::Input, GameLoop::Simulate, GameLoop::Render).chain())
        // State schedule: fires once when entering Playing.
        .add_systems(OnEnter(AppState::Playing), spawn_level)
        // State schedule: fires once when leaving Playing.
        .add_systems(OnExit(AppState::Playing), despawn_level)
        .add_systems(Update, read_input.in_set(GameLoop::Input))
        .add_systems(
            Update,
            tally_goals
                .in_set(GameLoop::Simulate)
                .run_if(on_message::),
        )
        .add_systems(Update, draw_hud.in_set(GameLoop::Render))
        .run();
}

#[derive(Component)]
struct LevelEntity;

fn spawn_level(mut commands: Commands) {
    commands.spawn((LevelEntity, Name::new("level")));
}

fn despawn_level(mut commands: Commands, query: Query>) {
    for e in &query { commands.entity(e).despawn(); }
}

fn read_input(mut writer: MessageWriter) {
    writer.write(GoalScored { team: 0 });
}

fn tally_goals(mut ctx: GameCtx) {
    let _ = ctx.time.delta_secs();
    for goal in ctx.goals.read() {
        ctx.score.0 += 1;
        info!("team {} scored, total {}", goal.team, ctx.score.0);
    }
}

fn draw_hud(score: Res) { let _ = score.0; }

Run condition cheat sheet

| Built-in | Triggers when | |---|---| | on_message:: | The Messages buffer has unread items. | | resource_exists:: | Resource R is in the World. | | resource_changed:: | R was mutated this tick. | | in_state(MyState::X) | Current State equals X. | | state_changed:: | The state changed this tick. | | any_with_component:: | At least one entity has C. |

Combine with .and() / .or(): run_if(in_state(GameState::Playing).and(resource_exists::())).

Topics

| Topic | Reference | |---|---| | #[derive(SystemParam)], 'w/'s lifetimes, Local, Commands deferred apply | [references/system-params.md](references/system-params.md) | | #[derive(SystemSet)] requirements, .in_set, .configure_sets, .chain() | [references/system-sets.md](references/system-sets.md) | | Every built-in condition, .and()/.or()/not(), custom conditions, cost rule | [references/run-conditions.md](references/run-conditions.md) | | OnEnter(S) / OnExit(S) / OnTransition, NextState, set_if_neq | [references/state-schedules.md](references/state-schedules.md) | | .before, .after, .chain(), .ambiguous_with, debugging ambiguity errors | [references/ordering.md](references/ordering.md) | | remove_systems_in_set, ScheduleCleanupPolicy, 3-arg vs 4-arg receivers, side-effect limits | [references/runtime-removal.md](references/runtime-removal.md) |

Gotchas (0.18)

  • SimpleExecutor is gone. Any ambiguity between systems sharing data is now a build-time error. Fix with .before, .after, .chain(), or .ambiguous_with(other) (explicit accept). See [references/ordering.md](references/ordering.md).
  • MessageReader / MessageWriter, not EventReader / EventWriter. Renamed in 0.17. Trait derive is #[derive(Message)]; registrar is app.add_message::().
  • next_state.set(S) always fires OnExit/OnEnter in 0.18. Use set_if_neq for the old behaviour. See [references/state-schedules.md](references/state-schedules.md).
  • Schedules::remove_systems_in_set takes 4 args in 0.18 (schedule_label, set, world, ScheduleCleanupPolicy); Schedule::remove_systems_in_set takes 3. See [references/runtime-removal.md](references/runtime-removal.md).

See also

  • bevy-core-concepts — which schedule (Startup, Update, FixedUpdate) to add a system to.
  • bevy-ecs-queries — query is one of many SystemParams; Changed / Added filters.
  • bevy-ecs-components — defining the Component types your systems act on.
  • bevy-migration-0-17-to-0-18 — full Message/Event rename, MaterialPlugin changes.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.