An atomic save/load system for Bevy Game Engine.
https://github.com/Zeenobit/bevy_atomic_save.git
An atomic save/load system for Bevy.
Use Moonshine Save instead (crates.io) for Bevy 0.10 compatibility.
With the latest version of Bevy, it is possible to save the state of a world into a DynamicScene (see example). While this approach is useful for scene management and editting, it's not practical to use the same approach for saving and loading the game state.
In most typical cases, a game needs to save only a minimal subset of the world to be able to resume its state from disk. Visual and aesthetic elements of the game such as UI, models, sprites, cameras, or logic systems do not need to be serialized as they are usually initialized during game start.
This crate solves this problem by providing a framework for marking entities which need to be saved and loaded, along with functions to save/load these entities into and from disk.
SavePlugin is added to your App.use bevy_atomic_save::SavePlugin;
...
app.add_plugin(SavePlugin);
Save component. This may either be a Bundle, or inserted like a regular component. Entities marked for save should have components which derive Reflect. Any component which does not derive Reflect is not saved.use bevy::prelude::*;
use bevy_atomic_save::Save;
#[derive(Bundle)]
struct PlayerBundle {
/* ... Serializable Player Data ... */
save: Save,
}
SaveWorld via a &mut World or &mut Commands.use bevy::prelude::*;
use bevy_atomic_save::SaveWorld;
fn trigger_save(mut commands: Commands) {
commands.save("world.ron");
}
Unload.use bevy::prelude::*;
use bevy_atomic_save::Unload;
#[derive(Bundle)]
struct PlayerModelBundle {
/* ... Player Transform, Mesh, Sprite, etc. ... */
unload: Unload,
}
LoadWorld via a &mut World or &mut Commands.Save or Unload components. Finally, new entities are spawned and SaveStage::PostLoad begins.
use bevy::prelude::*;
use bevy_atomic_save::LoadWorld;
fn trigger_load(mut commands: Commands) {
commands.load("world.ron");
}
SaveStage::PostLoad.SaveStage::PostLoad.FromLoaded trait for any components which reference entities, and then registering those components in your app using RegisterLoaded../examples/pawn.rs for a concrete example on how to do this.
Alternatively, this can also be done manually by adding a system to SaveStage::PostLoad and reading the Loaded resource directly.use bevy::prelude::*;
use bevy_atomic_save::{FromLoaded, RegisterLoaded};
#[derive(Component)]
struct SomeEntity(Entity);
impl FromLoaded for SomeEntity {
fn from_loaded(&mut self, loaded: &Loaded) {
self.0.from_loaded(loaded);
}
}
...
app.register_loaded::<SomeEntity>();
DynamicScene in Bevy does not save Resource items. To save/load resources, it is recommended to spawn your saved resources as entities with a Save component. This also gives you control over exactly which resources should be saved.
Parent and Children), which would need to update their references during SaveStage::PostLoad. This crate does NOT provide this functionality. In most cases, you shouldn't need to save such components, as they typically belong to scene entities which may be spawned from loaded game data.
SaveWorld::dump for details.
The only difference between a dump and a save request is that a dump saves all entities, as opposed to save which only saves entities with a Save component.
The result of a dump should not be loaded, as it can result in duplicate entities afterwards.