-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Description
Bevy version and features
- version: 0.16.1 but i believe the issue still persists
- no features
What you did
using the bevy remote protocol, if i try to bevy/spawn
or bevy/insert
on a Component and do not derive Deserialize
and reflect Deserialize
it gets an error
here's the report i came up with
BRP Issue: Components with only Reflect
cannot be spawned/inserted
The Problem
In Bevy 0.16.1, components that only derive Reflect
(without Serialize
/Deserialize
) fail to spawn via BRP with the error:
Unknown component type: `bevy_reflect::DynamicStruct`
Root Cause Analysis
When process_remote_spawn_request
receives a spawn request:
-
deserialize_components
creates aTypedReflectDeserializer
and callsdeserialize()
-
The deserializer checks for:
ReflectDeserialize
(requires#[derive(Deserialize)]
+#[reflect(Deserialize)]
)ReflectDeserializeWithRegistry
(requires manual registration)
-
Without these traits, it falls back to
deserialize_struct()
which creates aDynamicStruct
- a generic container that knows it represents the actual type viaset_represented_type()
-
This
DynamicStruct
is passed toinsert_reflected_components
which calls:get_reflect_component(type_registry, reflected.reflect_type_path())
-
The bug:
reflect_type_path()
onDynamicStruct
returns"bevy_reflect::DynamicStruct"
(fromimpl_type_path!
macro) instead of the represented type's path -
get_reflect_component
fails because"bevy_reflect::DynamicStruct"
isn't registered as a component
The Fix
In insert_reflected_components
, check for a represented type first:
fn insert_reflected_components(
type_registry: &TypeRegistry,
mut entity_world_mut: EntityWorldMut,
reflect_components: Vec<Box<dyn PartialReflect>>,
) -> AnyhowResult<()> {
for reflected in reflect_components {
let type_path = if let Some(represented_type_info) = reflected.get_represented_type_info() {
represented_type_info.type_path() // Use the actual component type
} else {
reflected.reflect_type_path() // Fallback for non-dynamic types
};
let reflect_component = get_reflect_component(type_registry, type_path)?;
reflect_component.insert(&mut entity_world_mut, &*reflected, type_registry);
}
Ok(())
}
Verification
I've tested this fix on Bevy 0.16.1 and confirmed it works - components with only Reflect
can now be successfully spawned and inserted via BRP.
Help requested
I'm not a bevy contributor and i don't know the rules - mostly i'm concerned while that this is just a few lines of code to fix in an existing function i want to make sure that it's the right few lines of code. Not being a bevy_remote or bevy_reflect developer I would love it if someone who was could look at this issue and fix it correctly.
It's a big issue for me and I would love it if it this could make it into 17 as a bug fix.