-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
DynamicScenes contain invalid Entity references #4793
Description
Bevy version
Commit hash: 15acd6f (post v0.7.0)
Bug description
Minimal example
Details
use bevy::{ecs::entity::EntityMap, prelude::*};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_startup_system(save_scene_system)
.run();
}
#[derive(Resource)]
pub struct StoredScene(Option<DynamicScene>);
fn save_scene_system(world: &mut World) {
let mut scene_world = World::new();
// Uncomment the following lines to cause the bug!
let child = scene_world.spawn(()).id();
scene_world.despawn(child);
let child = scene_world.spawn(()).id();
scene_world.spawn(()).push_children(&[child]);
let type_registry = world.resource::<AppTypeRegistry>();
let scene = DynamicScene::from_world(&scene_world, type_registry);
println!("{}", scene.serialize_ron(type_registry).unwrap());
scene
.write_to_world(world, &mut EntityMap::default())
.unwrap();
}When applying DynamicScenes to a world using write_to_world, the operation will sometimes panic.
(more specifically, it will crash if the DynamicScene was created from any entities with a generation != 0 which belong to a hierarchy)
Cause
DynamicScenes store entities without their generation, which makes sense because the simple ids are transiently unique.
However, Entitys stored in components (such as Parent or Children) still contain the generation.
This means that upon applying the DynamicScene, the mapping phase of write_to_world will try to map the "generationful" Entitys and will fail to find them in the map (because the map only has a 0-generation for its keys).
Important note
OUTDATED
I believe most people never encounter this problem, because DynamicScenes are mainly used alongside serialization, and serialization of an Entity strips it of its generation already. (I didn't find where in the codebase but it's what I deduce)
UPDATE:
The workaround above no longer works as per #6194
Proposed fix
OUTDATED
I believe we would simply need to add a prior mapping phase in DynamicScene::from_world to strip the generation of all Entitys contained in components.
I will file a PR soon. Nevermind, I am not well-enough versed in the deep arts of reflection
UPDATE:
Since the arguments in #6194 are convincing that serializing the generation is useful, I think we need another solution.
Possibly, storing the generation in the DynamicScenes