Files
g4borg 8988b16bee 🤖 Fix proofreading issues in bevy skills
- Fix `ref` keyword used as variable name in code examples
- Fix "retries next tick" → systems continue on normal schedule
- Fix `State::set()` → `NextState::set()` in upgrade skill
- Fix `SceneRoot` → `WorldAssetRoot` for 0.19 consistency
- Fix Replace lifecycle event description (overwritten, not removed)
- Fix grep patterns (quoting, trailing spaces)
- Remove third-party physics/networking content (not Bevy built-ins)
2026-07-07 17:52:20 +02:00

4.1 KiB

0.17 → 0.18

The largest recent transition. Its centerpiece — the Event/Message split — is architectural, not just a rename. Official guide for the long tail: https://bevy.org/learn/migration-guides/0-17-to-0-18/.

The Event/Message split

The old buffered event system was split in two:

Old (≤0.17) New (0.18)
#[derive(Event)] (buffered use) #[derive(Message)]
EventWriter<T> / .send(e) MessageWriter<T> / .write(m)
EventReader<T> MessageReader<T>
Events<T> Messages<T>
on_event::<T>() run condition on_message::<T>()

Event still exists but now means observer-events only (commands.trigger() + On<E> observers, immediate push). This is the transition's biggest trap: a type ported to #[derive(Event)] and written with a MessageWriter won't compile, but a type left as Event with a forgotten reader silently does nothing.

Port rule: every buffered event → Message. Only convert to Event+observer deliberately, during post-migration cleanup, where immediate reaction is actually wanted.

New in 0.18: #[derive(EntityEvent)] with #[event_target] for entity-targeted events, optionally #[entity_event(propagate)] to bubble up ChildOf.

Renames & moves (mechanical)

Old New
remove_child / remove_children / clear_children detach_child / detach_children / detach_all_children
bevy::render::render_resource::ShaderRef bevy::shader::ShaderRef
WinitPlugin::<WakeUp> WinitPlugin (no longer generic)
AmbientLight (single type) GlobalAmbientLight resource + AmbientLight camera component
Camera.target field RenderTarget required component
GltfPlugin use_model_forward_direction convert_coordinates + rotate_scene_entity / rotate_meshes flags

API shape changes

  • Fallible systems: systems may return Result (= Result<(), BevyError>); errors are logged and the system continues running on its normal schedule. Adopt during the bump wherever it deletes unwrap()s cheaply; systematically during cleanup.
  • Mesh accessors became try_* returning Result<_, MeshAccessError>.
  • MaterialPlugin fields prepass_enabled / shadows_enabled became Material trait methods.
  • LoadContext::path() returns AssetPath, not Path; image reinterpret_* methods return Result.
  • Immutable components: #[component(immutable)] available.
  • Input feature gates: mouse, keyboard, gamepad, touch, gestures are now cargo features. Default-on, but builds with default-features = false must list them — otherwise input silently stops arriving.

Semantic shifts (audit, don't just compile)

  • NextState::set() same-state transitions fire. set(Playing) while in Playing now triggers OnExit(Playing) + OnEnter(Playing) (previously a no-op). One-time setup in OnEnter (spawn camera, load level) re-runs. Audit every next_state.set(...) reachable while already in that state; use set_if_neq() where the old behavior is wanted.
  • Material shader bind groups: material bindings are @group(3); @group(2) is the mesh storage buffer. Old custom shaders using @group(2) fail with Storage class Storage doesn't match the shader Uniform. Update all .wgsl material shaders.
  • MouseMotion, MouseWheel and other input streams are Messages now — readers must be MessageReader.

Porting checklist

  1. grep -rn "EventWriter\|EventReader\|on_event\|Events<" — rename to Message equivalents; .send(.write(.
  2. grep -rn "derive(Event)" — decide per type: buffered (→ Message) or observed (stays Event, needs a trigger + observer).
  3. grep -rn "remove_child\|clear_children" — rename to detach_*.
  4. grep -rn "next_state.set\|NextState" — audit same-state re-fire.
  5. grep -rn "@group(2)" --include="*.wgsl" — move material bindings to group 3.
  6. grep -rn "AmbientLight" — split into resource vs camera component usage.
  7. Check Cargo.toml for default-features = false on bevy → add input features.