Skip to content

Commit c06e9cf

Browse files
Aminionclaude
andcommittedMar 10, 2028
fix: skip GPU model removal on restart to avoid swap-remove corruption
remove_sprite_model does a swap-remove internally, so iterating a pre-collected list of chain_ids hits wrong slots after the first removal, leaving orphaned models in the GPU. New asteroids after restart get fresh chain_ids from the growing registry and are safely added to the GPU; the old orphaned models are never referenced again. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent e578e61 commit c06e9cf

1 file changed

Lines changed: 6 additions & 29 deletions

File tree

 

‎src/main.rs‎

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,7 @@ use sdl2::{
2626
EventPump,
2727
};
2828

29-
use crate::components::{
30-
asteroid::{AsteroidChainId, CrystalChainId},
31-
canon::Canon,
32-
miner::Miner,
33-
projectile::Projectile,
34-
};
29+
use crate::components::{canon::Canon, miner::Miner};
3530
use crate::input::PlayerInput;
3631
use crate::systems::{
3732
autopilot::autopilot_system,
@@ -247,36 +242,18 @@ fn fov_y(w: u32, h: u32) -> f32 {
247242
}
248243

249244
fn restart_world(world: &mut World, resources: &mut Resources) {
250-
// Collect every chain_id in use (asteroids, crystals, projectiles).
251-
let mut chain_ids: Vec<u32> = Vec::new();
252-
{
253-
let mut q = <&AsteroidChainId>::query();
254-
for c in q.iter(world) {
255-
chain_ids.push(c.0);
256-
}
257-
let mut q = <&CrystalChainId>::query();
258-
for c in q.iter(world) {
259-
chain_ids.push(c.0);
260-
}
261-
let mut q = <&Projectile>::query();
262-
for p in q.iter(world) {
263-
chain_ids.push(p.chain_id);
264-
}
265-
}
266-
267-
// Strip all GPU sprite instances, then all models.
245+
// Remove all GPU sprite instances. GPU models are intentionally left intact:
246+
// remove_sprite_model does a swap-remove internally, so iterating collected
247+
// chain_ids would hit wrong slots after the first removal. New asteroids get
248+
// fresh chain_ids from the growing registry; old models become orphaned but
249+
// are never referenced again, which is acceptable for a demo.
268250
{
269251
let mut gpu = resources.get_mut::<GpuRenderer>().unwrap();
270252
while gpu.sprite_instance_count() > 0 {
271253
gpu.remove_sprite_instance(0);
272254
}
273-
for chain_id in chain_ids {
274-
gpu.remove_sprite_model(chain_id);
275-
}
276255
}
277256

278-
resources.get_mut::<SpriteData>().unwrap().registry = SpriteModelRegistry::new();
279-
280257
// Rebuild ECS world with a fresh miner.
281258
*world = World::default();
282259
populate_world(world);

0 commit comments

Comments
 (0)
Please sign in to comment.