`mark_dirty_trees` skips live entities after entity-index reuse
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
## Bevy version and features
- Verified against both `0.19.1` and `main`
- Default `multi_threaded` enabled
## What you did, what went wrong
In my project I despawn and then respawn entities in the same frame so scene is consistent with user's input. Occasionally, during testing, I would notice that the mesh at the world origin would render incorrectly, either missing faces or rendering z-fighting faces. I nailed the problem down to the multi-threaded `mark_dirty_trees` code path. I'm currently using `StaticTransformOptimizations::Disabled` as a workaround.
## Additional information
I've prepared a minimal reproduction where this problem can be observed on every run:
https://gist.github.com/tnajdek/e945d7a6f52db525d46d913e12f89873
I believe the visited bitset in `mark_dirty_trees` deduplicates by entity index rather than the full generational Entity. Because `RemovedComponents` can yield stale IDs for despawned entities, a stale ID can set the bit for a live entity that reused its index, causing the live traversal to stop at the leaf without dirtying its parent.
Contributor guide
Research direction
Run the minimal reproduction linked in the issue with default multi_threaded settings, then inspect the multi-threaded mark_dirty_trees path and its visited-bitset handling. The fix is complete when despawn-and-respawn entity-index reuse no longer leaves the live hierarchy undirtied and the reproduction stops showing missing or z-fighting faces.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- game-dev, performance
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100