AgentStack
SKILL verified MIT Self-run

Bevy Migration 0 17 To 0 18

skill-chrisgliddon-bevy-skills-bevy-migration-0-17-to-0-18 · by chrisgliddon

Use when upgrading from Bevy 0.17 to Bevy 0.18, when an LLM writes `EventReader`/`EventWriter`/`Trigger<E>` instead of `MessageReader`/`MessageWriter`/`On<E>`, when `mesh.insert_attribute` fails to compile, when `AmbientLight` no longer works as a resource, or when `Camera { target: ... }` errors on the `target` field. Index of every breaking 0.17→0.18 change.

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

Install

$ agentstack add skill-chrisgliddon-bevy-skills-bevy-migration-0-17-to-0-18

✓ 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 Migration 0 17 To 0 18? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Bevy 0.17 → 0.18 — Migration cheat sheet

Released 2026-01-13. Apply top-down — earlier items break later builds if skipped.

When to use this skill

  • Compiler errors after a bevy = "0.17"bevy = "0.18" bump.
  • LLM emits 0.17-era API names from training data.
  • Auditing a PR for hidden 0.18-incompatible patterns.
  • Hot-fixing a downstream crate that hasn't shipped 0.18 yet.

The renames you'll hit first

Observers: TriggerOn

// 0.18 (also 0.17)
fn on_hit(on: On) { let _e = on.event(); }

Buffered events: EventMessage

// 0.18
#[derive(Message)] struct Tick;
// app.add_message::();
fn read(mut reader: MessageReader) { for _ in reader.read() {} }
fn write(mut w: MessageWriter) { w.write(Tick); }

Event is now reserved for observed, entity-targeted events (#[derive(EntityEvent)]).

Camera { target: ... }RenderTarget component

// 0.18
commands.spawn((Camera3d::default(), RenderTarget::Image(handle.into())));

AmbientLight is no longer a resource

// 0.18: global default
app.insert_resource(GlobalAmbientLight { brightness: 2000.0, ..default() });
// Per-camera override:
commands.spawn((Camera3d::default(), AmbientLight { brightness: 5000.0, ..default() }));

MaterialPlugin config moved to trait methods

// 0.18
impl Material for M {
    fn enable_prepass() -> bool { false }
    fn enable_shadows() -> bool { false }
}
app.add_plugins(MaterialPlugin::::default());

AsBindGroup::label() is now required

impl AsBindGroup for MyMaterial {
    fn label() -> &'static str { "MyMaterial" }
}

AssetLoader must #[derive(TypePath)]

#[derive(TypePath)]
struct MyLoader;
impl AssetLoader for MyLoader { /* ... */ }

Mesh::insert_attribute is panicky — prefer try_insert_attribute

// 0.18 safe form — returns Result
mesh.try_insert_attribute(Mesh::ATTRIBUTE_POSITION, positions)?;

State::set always triggers a transition

// 0.18: always fires OnExit + OnEnter. Guard with:
next_state.set_if_neq(GameState::Playing);

glTF coordinate conversion replaced

// 0.18
GltfPlugin {
    convert_coordinates: GltfConvertCoordinates {
        rotate_scene_entity: true,
        rotate_meshes: true,
    },
    ..default()
}

Schedule executor

SimpleExecutor was removed. Schedules now panic on undeclared ambiguities. Add .before(), .after(), .chain(), .in_set(...), or .ambiguous_with(...). See [references/schedule-renames.md](references/schedule-renames.md) for ScheduleBuildError variant renames.

Topics

| Topic | Reference | |---|---| | On, MessageReader/MessageWriter, Entity::index, tick moves, Resource 'static, reflect syntax, hierarchy helpers | [references/ecs-renames.md](references/ecs-renames.md) | | RenderTarget component, GlobalAmbientLight, MaterialPlugin, AsBindGroup::label, gizmos, bevy_gizmos_render split | [references/render-renames.md](references/render-renames.md) | | AssetLoader + TypePath, LoadContext::asset_path, asset_bytes reader pattern, AssetSource channel, try_insert_attribute | [references/asset-renames.md](references/asset-renames.md) | | SimpleExecutor removal, ScheduleBuildError variants, State::set always-fires, or combinator, glTF coordinates | [references/schedule-renames.md](references/schedule-renames.md) | | animationgltf_animation, picking-backend renames, documentationreflect_documentation, input opt-in | [references/cargo-feature-renames.md](references/cargo-feature-renames.md) |

Gotchas

  • bevy_gizmos was split. Render-side code now lives in bevy_gizmos_render. Update import paths if you used internals.
  • Resource no longer allows non-'static lifetimes. A Resource with a borrowed field will fail to compile.
  • Reflect attribute syntax tightened. Only #[reflect(...)] (parens) is accepted; brace/bracket forms are rejected.
  • AnimationTarget split into two components. Use (AnimationTargetId(id), AnimatedBy(player)).
  • Atmosphere now references a Handle — what was a flat struct is now indirect.

See also

  • bevy-migration-0-18-to-0-19 — the next release's rename catalogue.
  • bevy-core-concepts — schedule executor change in detail.
  • bevy-cargo-features — feature rename table.
  • bevy-ecs-systemsMessage/MessageReader/MessageWriter ergonomics.

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.