From 3b3e42c7991df1b067549908be295d6fc35f00fe Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Thu, 28 May 2026 16:15:13 -0700 Subject: [PATCH 1/2] Don't use ScenePatchInstance for queued scenes --- crates/bevy_scene/src/spawn.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/crates/bevy_scene/src/spawn.rs b/crates/bevy_scene/src/spawn.rs index efb4d94fbc26e..37fce68730218 100644 --- a/crates/bevy_scene/src/spawn.rs +++ b/crates/bevy_scene/src/spawn.rs @@ -196,7 +196,15 @@ impl WorldSceneExt for World { let assets = self.resource::(); let patch = ScenePatch::load(assets, scene); let handle = assets.add(patch); - self.spawn(ScenePatchInstance(handle)) + let mut entity = self.spawn_empty(); + let id = entity.id(); + entity + .resource_mut::() + .scene_entities + .entry(handle) + .or_default() + .push(id); + entity } fn spawn_scene_list( @@ -501,7 +509,12 @@ impl EntityWorldMutSceneExt for EntityWorldMut<'_> { let assets = self.resource::(); let patch = ScenePatch::load(assets, scene); let handle = assets.add(patch); - self.insert(ScenePatchInstance(handle)); + let id = self.id(); + self.resource_mut::() + .scene_entities + .entry(handle) + .or_default() + .push(id); } } From 29d4fd8be70b7651a812dc9e59c83d2c97caf035 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Fri, 29 May 2026 14:38:47 -0700 Subject: [PATCH 2/2] Use QueuedScenes instead of WaitingScenes --- crates/bevy_scene/src/spawn.rs | 60 ++++++++++++++++------------------ 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/crates/bevy_scene/src/spawn.rs b/crates/bevy_scene/src/spawn.rs index 37fce68730218..eac85b446d383 100644 --- a/crates/bevy_scene/src/spawn.rs +++ b/crates/bevy_scene/src/spawn.rs @@ -199,11 +199,9 @@ impl WorldSceneExt for World { let mut entity = self.spawn_empty(); let id = entity.id(); entity - .resource_mut::() - .scene_entities - .entry(handle) - .or_default() - .push(id); + .resource_mut::() + .new_scene_entities + .push((id, handle)); entity } @@ -510,11 +508,9 @@ impl EntityWorldMutSceneExt for EntityWorldMut<'_> { let patch = ScenePatch::load(assets, scene); let handle = assets.add(patch); let id = self.id(); - self.resource_mut::() - .scene_entities - .entry(handle) - .or_default() - .push(id); + self.resource_mut::() + .new_scene_entities + .push((id, handle)); } } @@ -673,7 +669,7 @@ pub fn resolve_scene_patches( /// A [`Resource`] that tracks entities / scenes that have been queued to spawn. #[derive(Resource, Default)] pub struct QueuedScenes { - new_scene_entities: Vec, + new_scene_entities: Vec<(Entity, Handle)>, related_scene_list_spawns: Vec<(RelatedSceneListSpawn, Handle)>, scene_list_spawns: Vec>, } @@ -695,8 +691,13 @@ pub(crate) struct RelatedSceneListSpawn { pub fn on_add_scene_patch_instance( add: On, mut queued_scenes: ResMut, + instances: Query<&ScenePatchInstance>, ) { - queued_scenes.new_scene_entities.push(add.entity); + if let Ok(instance) = instances.get(add.entity) { + queued_scenes + .new_scene_entities + .push((add.entity, instance.0.clone())); + } } /// A system that spawns queued scenes when they are loaded. @@ -708,22 +709,8 @@ pub fn spawn_queued( mut reader: Local>>, mut list_reader: Local>>, ) { - core::mem::swap(&mut *world.resource_mut::(), &mut queued); world.resource_scope(|world, mut list_patches: Mut>| { world.resource_scope(|world, mut waiting: Mut| { - loop { - if queued.is_empty() { - break; - } - queued.spawn_queued( - world, - &mut waiting, - scene_patch_instances, - &mut bundle_scratch, - &list_patches, - ); - } - world.resource_scope(|world, events: Mut>>| { for event in reader.read(&events) { let patches = world.resource::>(); @@ -778,6 +765,20 @@ pub fn spawn_queued( } }, ); + + loop { + core::mem::swap(&mut *world.resource_mut::(), &mut queued); + if queued.is_empty() { + break; + } + queued.spawn_queued( + world, + &mut waiting, + scene_patch_instances, + &mut bundle_scratch, + &list_patches, + ); + } }); }); } @@ -797,12 +798,9 @@ impl QueuedScenes { bundle_scratch: &mut BundleScratch, list_patches: &Assets, ) { - for entity in core::mem::take(&mut self.new_scene_entities) { - let Ok(handle) = scene_patch_instances.get(world, entity).map(|h| &h.0) else { - continue; - }; + for (entity, handle) in core::mem::take(&mut self.new_scene_entities) { let patches = world.resource::>(); - if let Some(resolved) = patches.get(handle).and_then(|p| p.resolved.clone()) { + if let Some(resolved) = patches.get(&handle).and_then(|p| p.resolved.clone()) { let mut entity_mut = world.get_entity_mut(entity).unwrap(); if let Err(err) = resolved.apply(&mut entity_mut, bundle_scratch) { let scene_patch_instance = scene_patch_instances.get(world, entity).unwrap();