#Save entities as scene

15 messages ยท Page 1 of 1 (latest)

scarlet valve
#

Hello everyone,

im currently trying to save some entities to a scene. I looked at the scene example but that left some questions unanswered.
Primarily: do I always have to save every entity in a world?
Can I only save some entities (for example: from one or multiple queries). Or can I have multiple "active" worlds at the same time (for example, a editor would have 2 worlds, one for the editor itself (UI and stuff) and one for the currently open scene).

I also ran into some problems while playing around with the example. Here I try to save or load a world based on a index/number. I removed the world parameter from the system and instead use the AppTypeRegistry-Resource (it was the only thing that the example needed) as well as my on resources and stuff.
However It always crashes at let serialized_scene = scene.serialize_ron(&type_registry).unwrap(); with the following error:

Any guidance / resources on this topic are appreciated.

#
called `Result::unwrap()` on an `Err` value: Message("Type 'std::sync::Arc<bevy_asset::handle::StrongHandle>' did not register ReflectSerialize")
pale cipher
#

don't know about multiple worlds, but here's my save system:

fn save_scene(world: &mut World) {
    let mut save_events = world.resource_mut::<Events<SaveCommand>>();
    let events: Vec<SaveCommand> = save_events.drain().collect();
    for event in events {
        let name = event.0.to_string();
        let mut query = world.query_filtered::<Entity, With<Save>>();
        let scene = DynamicSceneBuilder::from_world(world)
            .allow::<Col>()
            .allow::<Transform>()
            .allow::<Op>()
            .allow::<Number>()
            .allow::<Arr>()
            .allow::<Save>()
            .allow::<Order>()
            .allow::<BlackHole>()
            .allow::<WhiteHole>()
            .allow::<Holes>()
            .allow::<Vertices>()
            .allow::<Targets>()
            .allow_resource::<DefaultDrawColor>()
            .allow_resource::<DefaultDrawVerts>()
            .allow_resource::<HighlightColor>()
            .allow_resource::<ConnectionColor>()
            .allow_resource::<ConnectionWidth>()
            .allow_resource::<ClearColor>()
            .allow_resource::<CommandColor>()
            .allow_resource::<TextSize>()
            .allow_resource::<Version>()
            .extract_entities(query.iter(world))
            .extract_resources()
            .build();
        let type_registry = world.resource::<AppTypeRegistry>();
        let serialized_scene = scene.serialize_ron(type_registry).unwrap();

        #[cfg(not(target_arch = "wasm32"))]
        IoTaskPool::get()
            .spawn(async move {
                File::create(format!("assets/{}", name))
                    .and_then(|mut file| file.write(serialized_scene.as_bytes()))
                    .expect("Error while writing scene to file");
            })
            .detach();
    }
}
#

i'm using the DynamicSceneBuilder, it extracts the entities in the query for a marker component Save, and i only allow the components needed in those entities

#

you have to make sure all those types are registered, using .register_type on the app

scarlet valve
#

Thank you very much for the code.
What types exactly do I have to register? All components that I want to save? Does that also include the default rust components? Because I don't have any own components (except 2 resources) in the project.

pale cipher
#

yeah, your resources and components. you don't have to do that for primitive rust types. but sometimes if you have special things like:

.register_type::<(i8, i8)>()

one of my components has a field of type (i8, i8)

#

i think i also ran into that when i had a component that had a Vec<Vec<>> inside it

scarlet valve
#

Alright. I think I found the problem. I tried my code with just a transform and that works. SpriteBundle contains a Handle<Image>. Based on the error Message I think I cant save a Handle.

pale cipher
#

oh yeah, you probably don't want to save a handle in your scene file

scarlet valve
#

Do you know How I can could get around this?

pale cipher
#

i don't know if this is ideal for games, but i save components that contain all the info needed to respawn the entities as they were. so for example instead of saving a 2d mesh (i can't do that), i have transform, vertices, and color components, and when loading the scene i read those values and generate a mesh and insert it to that entity, so now it has an identical mesh

scarlet valve
#

Alright, so I just have to do a little bit of pre and post processing when storing and loading. Thanks.

pale cipher
#

yeah, good luck ๐Ÿ’š

novel jolt