Migration Guide: v0.7 to v0.8
This guide covers breaking changes and new features when upgrading from godot-bevy 0.7.x to 0.8.0.
Table of Contents
- Opt-in Plugin System (Breaking Change)
- GodotSignals Resource (Breaking Change)
- BevyBundle Enhanced Property Mapping (New Feature)
Opt-in Plugin System (Breaking Change)
What Changed
In v0.8.0, godot-bevy has adopted Bevy's philosophy of opt-in plugins. This gives users granular control over which features are included in their build.
Breaking Change: GodotPlugin
now only includes minimal core functionality by default (basic scene tree access and assets). Automatic entity creation and other features must be explicitly opted-in.
Migration Path
The quickest migration is to use GodotDefaultPlugins
for the old behavior, but we recommend adding only the plugins you need.
Option 1: Quick Migration (Old Behavior)
Replace the #[bevy_app]
macro usage with explicit plugin registration:
Before (v0.7.x):
#![allow(unused)] fn main() { #[bevy_app] fn build_app(app: &mut App) { // GodotPlugin automatically included all features: // - Automatic entity creation for scene tree nodes // - Transform synchronization // - Collision detection // - Signal handling // - Input events // - Audio system app.add_systems(Update, my_game_systems); } }
After (v0.8.0) - Quick Fix:
#![allow(unused)] fn main() { #[bevy_app] fn build_app(app: &mut App) { // Add all features like before app.add_plugins(GodotDefaultPlugins); app.add_systems(Update, my_game_systems); } }
Option 2: Recommended - Add Only What You Need
Pure ECS game (transforms + basic features):
#![allow(unused)] fn main() { #[bevy_app] fn build_app(app: &mut App) { app.add_plugins(GodotSceneTreeMirroringPlugin { add_transforms: true, }) .add_plugins(GodotTransformSyncPlugin::default()) // OneWay sync .add_plugins(GodotAudioPlugin); // Audio system app.add_systems(Update, my_game_systems); } }
Platformer (no transform conflicts):
#![allow(unused)] fn main() { #[bevy_app] fn build_app(app: &mut App) { app.add_plugins(GodotSceneTreeMirroringPlugin { add_transforms: false, // Use Godot physics instead }) .add_plugins(GodotCollisionsPlugin) // Collision detection .add_plugins(GodotAudioPlugin) // Audio system .add_plugins(GodotSignalsPlugin); // UI signals app.add_systems(Update, my_game_systems); } }
Full-featured game:
#![allow(unused)] fn main() { #[bevy_app] fn build_app(app: &mut App) { app.add_plugins(GodotDefaultPlugins); // Everything app.add_systems(Update, my_game_systems); } }
Available Plugins
Core (Always Included):
GodotCorePlugins
- Basic scene tree access, assets, basic setup (automatically included by#[bevy_app]
)
Scene Tree Plugins:
GodotSceneTreeRefPlugin
- Basic scene tree access (included inGodotCorePlugins
)GodotSceneTreeEventsPlugin
- Monitor scene tree changes without creating entitiesGodotSceneTreeMirroringPlugin
- Auto-create entities for scene nodes (equivalent to v0.7.x behavior)
Optional Feature Plugins:
GodotTransformSyncPlugin
- Add if you want to move/position nodes from Bevy systemsGodotAudioPlugin
- Add if you want to play sounds and music from Bevy systemsGodotSignalsPlugin
- Add if you want to respond to Godot signals (button clicks, etc.) in Bevy systemsGodotCollisionsPlugin
- Add if you want to detect collisions and physics events in Bevy systemsGodotInputEventPlugin
- Add if you want to handle input from Godot in Bevy systemsBevyInputBridgePlugin
- Add if you prefer Bevy's input API (auto-includesGodotInputEventPlugin
)GodotPackedScenePlugin
- Add if you want to spawn scenes dynamically from Bevy systems
Convenience Bundles:
GodotDefaultPlugins
- All plugins enabled (equivalent to old v0.7.x behavior)
Plugin Dependencies
Some plugins automatically include their dependencies:
GodotSceneTreeMirroringPlugin
automatically includesGodotSceneTreeEventsPlugin
BevyInputBridgePlugin
automatically includesGodotInputEventPlugin
Benefits of the New System
- Smaller binaries - Only compile what you use
- Better performance - Skip unused systems
- Clearer dependencies - Explicit about what your game needs
- Future-proof - Easy to add new optional features
Migration Checklist
-
Quick fix: Add
app.add_plugins(GodotDefaultPlugins)
to yourbuild_app
function -
Optimization: Replace
GodotDefaultPlugins
with only the specific plugins you need - Test: Ensure all features work correctly with your plugin selection
- Consider: Whether you can disable some features (e.g., transform sync for physics games)
GodotSignals Resource (Breaking Change)
What Changed
In v0.8.0, the signal connection system has been significantly simplified and improved:
New GodotSignals
SystemParam: Signal connections are now handled through a dedicated GodotSignals
resource
Migration Path
The main change is switching from the standalone connect_godot_signal
function to the new GodotSignals
SystemParam.
Before (v0.7.x)
#![allow(unused)] fn main() { use godot_bevy::prelude::*; fn connect_signals( mut scene_tree: SceneTreeRef, ) { if let Some(root) = scene_tree.get().get_root() { if let Some(button) = root.try_get_node_as::<Button>("UI/MyButton") { let mut handle = GodotNodeHandle::from_instance_id(button.instance_id()); // Old function signature required SceneTreeRef parameter connect_godot_signal(&mut handle, "pressed", &mut scene_tree); } } } }
After (v0.8.0)
#![allow(unused)] fn main() { use godot_bevy::prelude::*; fn connect_signals( mut scene_tree: SceneTreeRef, signals: GodotSignals, // ← New SystemParam ) { if let Some(root) = scene_tree.get().get_root() { if let Some(button) = root.try_get_node_as::<Button>("UI/MyButton") { let mut handle = GodotNodeHandle::from_instance_id(button.instance_id()); // New simplified API signals.connect(&mut handle, "pressed"); } } } }
Breaking Changes
- Function signature changed:
connect_godot_signal
no longer requiresSceneTreeRef
parameter - New SystemParam required: Add
GodotSignals
parameter to systems that connect signals - Recommended API change: Use
signals.connect()
instead of directconnect_godot_signal()
calls
Migration Checklist
-
Add
GodotSignals
parameter to systems that connect signals -
Replace
connect_godot_signal(&mut handle, signal_name, &mut scene_tree)
withsignals.connect(&mut handle, signal_name)
-
Remove unused
SceneTreeRef
parameters if they were only used for signal connections - Test that all signal connections work correctly with the new system
Summary
The v0.8.0 signal system simplifies signal connections while improving performance. The main migration step is:
- Add
GodotSignals
parameter to systems that connect signals - Replace
connect_godot_signal(&mut handle, signal, &mut scene_tree)
withsignals.connect(&mut handle, signal)
- Remove unused
SceneTreeRef
parameters
The signal event handling (EventReader<GodotSignal>
) remains unchanged, so only the connection setup needs to be updated.
BevyBundle Enhanced Property Mapping (New Feature)
What's New
In v0.8.0, the BevyBundle
macro has been significantly enhanced with more flexible property mapping options:
- Struct Component Mapping: Map multiple Godot properties to fields in a struct component
- Transform Functions: Apply transformation functions to convert values during mapping
- Improved Syntax: More intuitive syntax for single and multi-field mappings
New Mapping Options
Struct Component Mapping
You can now map multiple Godot properties to fields in a struct component:
#![allow(unused)] fn main() { #[derive(Component)] struct Stats { health: f32, mana: f32, stamina: f32, } #[derive(GodotClass, BevyBundle)] #[class(base=CharacterBody2D)] #[bevy_bundle((Player), (Stats { health: max_health, mana: max_mana, stamina: max_stamina }))] pub struct PlayerCharacter { base: Base<CharacterBody2D>, #[export] max_health: f32, #[export] max_mana: f32, #[export] max_stamina: f32, } }
Transform Functions
Apply transformation functions to convert Godot values before assigning to components:
#![allow(unused)] fn main() { fn percentage_to_fraction(value: f32) -> f32 { value / 100.0 } #[derive(GodotClass, BevyBundle)] #[class(base=Node2D)] #[bevy_bundle((Enemy), (Health: health_percentage))] pub struct Enemy { base: Base<Node2D>, #[export] #[bundle(transform_with = "percentage_to_fraction")] health_percentage: f32, // Editor shows 0-100, component gets 0.0-1.0 } }
Backwards Compatibility
All existing v0.7.x BevyBundle
syntax remains fully supported:
#![allow(unused)] fn main() { // Still works in v0.8.0 #[bevy_bundle((Player), (Health: max_health))] }
Benefits
- Better Component Design: Create struct components that group related data
- Editor-Friendly Values: Use transform functions to convert between editor-friendly and system-friendly values
- Type Safety: All mappings are verified at compile time
- Flexibility: Mix and match different mapping styles as needed
For complete documentation on the new features, see the Custom Node Markers section.