15 KiB
Turtle Lib Bevy Upgrade Guide
Goal and Scope
- upgrade path:
bevy0.10.x → 0.16.1 - crates covered:
turtle-lib, example app(s), supporting tooling - audience: maintainers comfortable with Rust & Bevy internals
Dependency Targets
bevy0.10.x → 0.16.1bevy_inspector_egui0.18 → 0.33bevy_tweening0.6→0.13bevy_prototype_lyon0.8 → 0.13
Bevy relevant changes for the turtle-lib crate
0.10 → 0.11
-
Schedule-first API (mandatory): replace all add_system/add_startup_system calls with schedule-scoped add_systems
- In
turtle-lib/src/lib.rs::TurtlePlugin::build:.add_startup_system(setup)→.add_systems(Startup, setup).add_system(keypresses)→.add_systems(Update, keypresses).add_system(component_animator_system::<Path>)→.add_systems(Update, component_animator_system::<Path>).add_system(close_on_esc)→.add_systems(Update, close_on_esc).add_system(draw_lines)→.add_systems(Update, draw_lines)
- Source: 0.10→0.11 “Schedule-First: the new and improved add_systems”
- In
-
Plugin API:
add_plugindeprecated → useadd_plugins(single items or tuples)- In
TurtlePlugin::build:.add_plugin(debug::DebugPlugin)→.add_plugins(debug::DebugPlugin).add_plugin(ShapePlugin)→.add_plugins(ShapePlugin).add_plugin(TweeningPlugin)→.add_plugins(TweeningPlugin)
- Source: 0.10→0.11 “Allow tuples and single plugins in add_plugins, deprecate add_plugin”
- In
-
Window configuration moved from
WindowDescriptortoWindowonWindowPlugin- In
TurtlePlugin::buildreplace:DefaultPlugins.set(WindowPlugin { window: WindowDescriptor { title, width, height, present_mode, ..Default::default() }, ..default() })- with
DefaultPlugins.set(WindowPlugin { primary_window: Some(Window { title, resolution: (width, height).into(), present_mode, ..default() }), ..default() })
- Notes: PresentMode variants are unchanged here; title now takes
Stringvia.into(); width/height becomeresolution. - Source: Bevy 0.11 window API (examples/docs)
- In
-
Events must derive Event
- In
turtle-lib/src/events.rs: add#[derive(Event)]toDrawingStartedEvent. - Ensure
app.add_event::<DrawingStartedEvent>()remains inTurtlePlugin::build. - Source: 0.10→0.11 “Require #[derive(Event)] on all Events”
- In
-
Reflect derives:
FromReflectis auto-derived by#[derive(Reflect)]- In
turtle-lib/src/commands.rs, many enums/structs derive bothReflectandFromReflect. - You can remove explicit
FromReflectderives unless you provide a manual impl; if you keep a manual impl, disable auto via#[reflect(from_reflect = false)]. - Source: 0.10→0.11 “FromReflect Ergonomics Implementation”
- In
0.11 → 0.12
-
EventReader API rename:
iter()→read()- In
turtle-lib/src/lib.rs::draw_lineschange:for _ev in query_event.iter() { ... }→for _ev in query_event.read() { ... }
- Also,
&mut EventReaderno longer implementsIntoIterator; prefer.read(). - Source: 0.11→0.12 “Refactor EventReader::iter to read” and “Remove IntoIterator impl for &mut EventReader”
- In
-
Unified
configure_setsAPI (FYI only)- If you later configure system sets, prefer
app.configure_sets(ScheduleLabel, …). Turtle-lib doesn’t currently call this, so no change. - Source: 0.11→0.12 “Replace IntoSystemSetConfig with IntoSystemSetConfigs” and “Unified configure_sets API”
- If you later configure system sets, prefer
-
Present mode/Window tweaks (FYI only)
PresentMode::Fifostill valid; an additionalFifoRelaxedvariant exists—no change required.- Hot reloading workflow changed to feature flag
bevy/file_watcher; turtle-lib doesn’t configureAssetPlugin, so no change. - Source: 0.11→0.12 windowing and assets notes
0.12 → 0.13
-
Scheduling and plugin API are unchanged from 0.12 for turtle-lib
- Existing schedule-first usage and
add_pluginscontinue to work. No changes needed inTurtlePlugin::buildfor scheduling semantics.
- Existing schedule-first usage and
-
WindowPlugin: primary window field naming consistency
- If you already use the 0.11+ style (recommended earlier):
WindowPlugin { primary_window: Some(Window { title, resolution, present_mode, ..default() }), ..default() }continues to be the correct pattern.
- If any code still uses
WindowPlugin { window: WindowDescriptor { .. } }, migrate per 0.10→0.11 notes above (crate currently usesWindowDescriptorand needs that migration anyway).
- If you already use the 0.11+ style (recommended earlier):
-
Camera clear color configuration remains valid
Camera2dBundle { camera_2d: Camera2d { clear_color: ClearColorConfig::Custom(Color::BEIGE) }, ..default() }remains correct. No change needed.
-
Input API is stable
Res<Input<KeyCode>>andkeys.just_pressed(KeyCode::W)continue to work without changes.
-
Events ergonomics (carry-over from 0.11)
- Ensure custom events derive
#[derive(Event)]and are registered withapp.add_event::<T>(). This remains required and stable in 0.13. EventReader::read()introduced in 0.12 continues to be the correct method in 0.13; preferfor ev in reader.read()over the removediter().
- Ensure custom events derive
-
Bevy Inspector Egui (debug) still uses plugin as-is
WorldInspectorPlugincontinues to be added viaadd_pluginsin debug builds; no API change affectingturtle-libat this hop.
0.13 → 0.14
-
Color API refinements (no code change needed for current usage)
- Named colors like
Color::BEIGE,Color::MIDNIGHT_BLUE,Color::BLACKremain valid. No renames impactingturtle-libin this hop. - Type-safe color constructors improved, but we don’t currently construct custom colors beyond constants.
- Named colors like
-
Windowing migrated to winit 0.30 (FYI)
- No direct use of backend-specific window APIs in
turtle-lib; existingWindow { title, resolution, present_mode }remains valid. - If examples or downstream apps interact with window events, check their migrations separately; not applicable in this crate.
- No direct use of backend-specific window APIs in
-
Events are always updated in minimal apps (FYI)
- Bevy 0.14 guarantees events update even in minimal setups;
turtle-libalready usesDefaultPluginsand explicitadd_event::<DrawingStartedEvent>()so no action required.
- Bevy 0.14 guarantees events update even in minimal setups;
-
Scheduling/UI/Camera
Camera2dBundlestays stable in this hop; our use ofClearColorConfig::Custom(Color::BEIGE)continues to be correct.close_on_escremains available viabevy::window::close_on_escwith the same call pattern.
0.14 → 0.15
-
Query::single family migrated to
Single(N/A)turtle-libdoes not callQuery::single()/single_mut(); no migration needed here.
-
State-scoped events (FYI)
- 0.15 introduces state-scoped events;
turtle-libuses a globalDrawingStartedEventand doesn’t scope events to states. No change required.
- 0.15 introduces state-scoped events;
-
Color, camera, and window remain compatible
- Existing use of
Color::BEIGE,Camera2dBundle, andWindow { resolution, present_mode }remains valid; no API renames affecting our code in this hop.
- Existing use of
-
Scheduling order clarifications (FYI)
- 0.15 tightened ambiguities in system ordering;
turtle-libdoesn’t rely on ambiguous ordering between systems, and uses default sets. No action needed.
- 0.15 tightened ambiguities in system ordering;
0.15 → 0.16
-
ECS Relationships replace
Parent/Children(N/A)turtle-libdoesn’t use hierarchy components directly; no migration required.
-
Improved spawn ergonomics (N/A)
- The new
children!/related!helpers don’t affect current code; we spawn via bundles without parent-child APIs.
- The new
-
Unified ECS error handling (optional)
- Systems and commands can return
Resultin 0.16+.turtle-libsystems currently return(). You may adoptResultfor clearer error paths later, but no change is required to compile.
- Systems and commands can return
-
Window/Input/Camera remain compatible
close_on_esc,Input<KeyCode>,Camera2dBundle, andClearColorConfig::Custom(Color::BEIGE)continue to work. No API renames in these areas affecting current usage.
-
Tweening and Lyon plugins
- API incompatibilities, if any, are tracked in their dedicated sections below. No direct Bevy-0.16-specific change required in our calls (
Animator,Tween,Path).
- API incompatibilities, if any, are tracked in their dedicated sections below. No direct Bevy-0.16-specific change required in our calls (
Bevy_inspector_egui relevant changes for the turtle-lib crate
src: https://github.com/jakobhellermann/bevy-inspector-egui/blob/main/docs/CHANGELOG.md src: https://github.com/jakobhellermann/bevy-inspector-egui/blob/main/docs/MIGRATION_GUIDE_0.15_0.16.md
-
Version alignment across Bevy upgrades
- 0.12 → 0.13: use bevy_inspector_egui ≥ 0.21 (changelog shows 0.21 updated to Bevy 0.12; 0.23 to Bevy 0.13). Our target path ends at 0.33 for Bevy 0.16.
- 0.14: use ≥ 0.25 (changelog: 0.25.0 updated to Bevy 0.14).
- 0.15: use ≥ 0.28 (changelog: 0.28.0 updated to Bevy 0.15).
- 0.16: use ≥ 0.31 (changelog: 0.31.0 updated to Bevy 0.16). Latest at time of writing is 0.33.x.
-
WorldInspectorPlugin path and construction (0.15 → 0.16)
- The old
WorldInspectorPluginmoved tobevy_inspector_egui::quick::WorldInspectorPlugin. - In
turtle-lib/src/debug.rs, ensure we import fromquick:use bevy_inspector_egui::quick::WorldInspectorPlugin;
- Continue to add it conditionally in debug:
app.add_plugins(WorldInspectorPlugin);(useadd_plugins, notadd_plugin).
- The removed
WorldInspectorParamsis not used in this crate, so no action is required.
- The old
-
Reflect-driven inspector (0.15 → 0.16 rewrite)
- The inspector is centered on
Reflectand type registration. We already register types we care about (TurtleColors,TurtleCommands). No additional registration is necessary for using the world inspector itself. - If we later add per-resource inspectors (e.g.,
ResourceInspectorPlugin<T>), deriveReflectforTand callapp.register_type::<T>().
- The inspector is centered on
-
Schedules/ambiguity fixes in quick plugins
- The crate’s quick plugins run in their own schedule to avoid system ambiguity since ~0.25. No overrides needed by
turtle-lib.
- The crate’s quick plugins run in their own schedule to avoid system ambiguity since ~0.25. No overrides needed by
-
Known guardrails
- 0.18.4 added a guard for missing
PrimaryWindow; our app defines a primary window viaDefaultPlugins.set(WindowPlugin { … }), so the inspector will work in debug.
- 0.18.4 added a guard for missing
Bevy_tweening relevant changes for the turtle-lib crate
src: https://github.com/djeedai/bevy_tweening/blob/main/CHANGELOG.md
-
Version alignment with Bevy
- Bevy 0.10 → bevy_tweening 0.7
- Bevy 0.11 → bevy_tweening 0.8
- Bevy 0.12 → bevy_tweening 0.9
- Bevy 0.13 → bevy_tweening 0.10
- Bevy 0.14 → bevy_tweening 0.11
- Bevy 0.15 → bevy_tweening 0.12
- Bevy 0.16 → bevy_tweening 0.13
-
Custom Lens signature change (bevy_tweening 0.11 for Bevy 0.14)
- Impacted files:
turtle-lib/src/drawing/animation/line_lens.rs,turtle-lib/src/drawing/animation/circle_lens.rs. - Update
Lens<T>::lerp(&mut self, target: &mut T, ratio: f32)→Lens<T>::lerp(&mut self, target: &mut dyn Targetable<T>, ratio: f32). - Code using
targetcan remain unchanged becausedyn Targetable<T>implementsDefer/DeferMutand derefs like&mut T. - This change is required when moving to Bevy 0.14 (bevy_tweening 0.11+) and remains compatible up to 0.13.
- Impacted files:
-
EaseFunction source update (bevy_tweening 0.12 for Bevy 0.15)
interpolation::EaseFunctionwas replaced bybevy_math::EaseFunctionand re-exported by bevy_tweening.- Our code imports
bevy_tweening::EaseFunction, which continues to work. Alternatively, importbevy_math::EaseFunctiondirectly.
-
Animator systems and Path animations
- Continue adding
TweeningPluginto the app. - Continue registering
component_animator_system::<Path>inUpdateto animateAnimator<Path>(still required up to bevy_tweening 0.13). - Note: The removal of
component_animator_systemis planned in a future bevy_tweening 0.14 (unreleased at the time of writing) and does not apply to our 0.13 target.
- Continue adding
-
Completion events
TweenCompletedevent remains available through 0.13. Our use of.with_completed_event(state.segment_index() as u64)is valid up to 0.13.- If migrating beyond 0.13 later, the API changes (no
user_data, new event types) will require adjustments; out of scope for Bevy 0.16 + bevy_tweening 0.13.
-
Bevy 0.12 EventReader change applies here too
- When listening to
TweenCompleted, useEventReader<TweenCompleted>::read()(notiter()), as documented in the Bevy 0.11→0.12 section above.
- When listening to
Bevy_prototype_lyon relevant changes for the turtle-lib crate
src: https://github.com/Nilirad/bevy_prototype_lyon/blob/master/CHANGELOG.md
-
Version alignment with Bevy
- Bevy 0.10 → lyon 0.8
- Bevy 0.11 → lyon 0.9
- Bevy 0.12 → lyon 0.10
- Bevy 0.13 → lyon 0.11
- Bevy 0.14 → lyon 0.12
- Bevy 0.15 → lyon 0.13
- Bevy 0.16 → lyon 0.14
-
0.8: Fill/Stroke rename
FillMode/StrokeModerenamed toFill/Strokeand became Components.- In
turtle-lib/src/turtle_bundle.rs, if still using the old names, update:DrawMode::Outlined { fill_mode: FillMode::color(c), outline_mode: StrokeMode::new(c2, w) }- to the current API for your target lyon version (≤0.13 still supports DrawMode; in 0.14 see below).
-
0.13:
ShapeBundlecomposition change (FYI)- Deprecated
SpatialBundlewas removed fromShapeBundle;TransformandVisibilityare added separately internally. - We construct shapes via
GeometryBuilder::build_as(...)returningShapeBundle; we don’t access its fields—no code change required.
- Deprecated
-
0.14 (Bevy 0.16): Major API rework affecting turtle-lib
- Path component renamed to
Shape;Shapenow includes fill and stroke data. FillandStrokeare no longerComponents; they’re part ofShapedata.GeometryBuilderandPathBuilderremoved. UseShapeBuilderandShapePath:- Build shapes:
ShapeBuilder::with(&geometry).fill(color).stroke((color, width)).build(). ShapePathnow implementsGeometryand replaces directPathBuilderusage.
- Build shapes:
ShapeBundleis deprecated and no longer exported fromprelude.
Impacted code and migration sketch for 0.14:
- Imports in
turtle-lib/src/lib.rsand lenses:- Replace
use bevy_prototype_lyon::prelude::{Path, ShapePlugin};withuse bevy_prototype_lyon::prelude::{Shape, ShapePath, ShapeBuilder, ShapePlugin};
- Replace
- Animator and systems:
Animator<Path>→Animator<Shape>component_animator_system::<Path>→component_animator_system::<Shape>
- Lenses (
drawing/animation/line_lens.rs,circle_lens.rs):impl Lens<Path> for ...→impl Lens<Shape> for ...- Replace
PathBuilderusage with creating/updating aShapePathgeometry and attaching it to theShapetarget per the new API.
- Spawn/build (
turtle_bundle.rs):- Replace
GeometryBuilder::build_as(&shapes::turtle(), DrawMode::Outlined { ... }, Transform::IDENTITY)andShapeBundle - with
ShapeBuilder::with(&shapes::turtle()).fill(Color::MIDNIGHT_BLUE).stroke((Color::BLACK, 1.0)).build().
- Replace
- Path component renamed to
Notes:
- If you stop at lyon 0.13 (Bevy 0.15), you don’t need the 0.14 rework yet. If you upgrade to Bevy 0.16, adopt lyon 0.14 and apply the above migrations.