bevyengine / bevyengine/bevy

DynamicScene.write_to_world panics on partial updates involving hierarchies

Open
#6,702 1 comment 3 reactions 0 assignees View on GitHub
A-Scenes C-Bug
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

## Bevy version

Bevy 0.9.0

## What you did

For a simple explanation, suppose I have a world entity with parent/child components. I want to update its transform component with a `DynamicScene` using a previously initialized `EntityMap` that maps the entity from the dynamic scene to the world. The dynamic scene only contains this transform component. When I do `DynamicScene.write_to_world`, bevy panics.

This is **NOT** related to issue #6573, and was also there in Bevy 0.8.1.

As a side note, the error handling seems incorrect, It unwraps/panics instead of returning Result.
https://github.com/bevyengine/bevy/blob/e0c3c6d16693c86843159007b4688f1408064275/crates/bevy_scene/src/dynamic_scene.rs#L100

## What went wrong

### what were you expecting?

I expect `write_to_world` to only update the components that are included within the `DynamicScene`.

I also expect that in case of an error, the function will return Result and will not panic.

### what actually happened?

`DynamicScene` panics on `write_to_world` due to remapping the valid references in child/parent components.

If an entity is present in the EntityMap, its child/parent entities are remapped on every call regardless of whether the entity is present in the DynamicScene that we are inserting into the world. Basically, when the entity is already present in the world with the correct parents/children, this code tries to remap already valid values (provided that the entity mapping is present in the EntityMap).

## Additional information

I am trying to do real-time network scene updates by transferring updated components only. First I transfer the whole world as a serialized dynamic scene which initializes EntityMap that I store. In later updates, I only transfer updated components and reuse the EntityMap. I use write_to_world to directly to update the world. Looking at the implementation, write_to_world was made to be able to update existing entities.

Remapping happens here: https://github.com/bevyengine/bevy/blob/e0c3c6d16693c86843159007b4688f1408064275/crates/bevy_scene/src/dynamic_scene.rs#L99

For all entities in the EntityMap: https://github.com/bevyengine/bevy/blob/e0c3c6d16693c86843159007b4688f1408064275/crates/bevy_ecs/src/reflect.rs#L426

The actual error is generated here: https://github.com/bevyengine/bevy/blob/e0c3c6d16693c86843159007b4688f1408064275/crates/bevy_hierarchy/src/components/children.rs#L26

## Examples

A simplified example that breaks right away: https://pastebin.com/5qkcHnsZ
More verbose example to play with: https://pastebin.com/WRDD7rqc
Discussion on discord: https://discord.com/channels/691052431525675048/1043155921217523752/1043155921217523752

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.