From 40b5d8ce95d9cf306626aed1f354b6aa76a62b94 Mon Sep 17 00:00:00 2001 From: popertots Date: Sat, 21 Mar 2026 19:20:57 +0000 Subject: [PATCH] Fix forrestry --- src/world/generation/forestry.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/world/generation/forestry.rs b/src/world/generation/forestry.rs index a7126b2..a8ba292 100644 --- a/src/world/generation/forestry.rs +++ b/src/world/generation/forestry.rs @@ -280,6 +280,11 @@ pub fn generate_chunk_forrestry( /// Despawned tree entities leave stale entries in `chunk_entity_index`. This is harmless: /// `unload_chunk` calls `despawn()` on each indexed entity, which is a no-op on /// already-despawned entities. +/// +/// # Limitations +/// `TreePart` entities are filtered by the trunk's chunk only. Trees near chunk borders +/// may have canopy leaves stored in an adjacent chunk — those are not removed, leaving +/// orphaned leaf sprites. Acceptable until a multi-chunk felling strategy is implemented. pub fn fell_tree( trunk_pos: IVec3, tree_parts: &Query<(Entity, &TreePart)>, @@ -307,15 +312,14 @@ pub fn fell_tree( // Adjacent tree parts share column positions, so deduplication cuts event count // significantly vs. firing per-tile per-column. let mut dirty_columns: FxHashSet = FxHashSet::default(); + // calculate_visibility traces up arbitrarily deep, so refresh the full column. + // z_total is constant per call — hoist above the loop. + let z_total = crate::world::chunks::Z_BELOW as i32 + crate::world::chunks::Z_ABOVE as i32 + 1; for (entity, tile_pos) in to_remove.iter() { tilemap.remove_fixture(tile_pos); tile_changed.write(TileChangedEvent { pos: *tile_pos }); commands.entity(*entity).despawn(); - // calculate_visibility traces up arbitrarily deep, so refresh the full column. - // Hoist z_depth — constant per call, computed once here. - let z_total = - crate::world::chunks::Z_BELOW as i32 + crate::world::chunks::Z_ABOVE as i32 + 1; for dz in 0..=z_total { for dy in -1..=1i32 { for dx in -1..=1i32 {