fix(render): Phase A8 — normalize _buildingRegistries key (RR7.2 root cause)

Second visual-gate probe data: [envcells]/[buildings] firing 3711 times
each (indoor branch FIRED), but [stencil]=0 and [draworder]=2x (only
Steps 3+4, no Steps 1+2+5). [buildings] sample:
  camCell=0xA9B40143 camBldgs=[] otherBldgs=109 totalKnown=110

The registry HAS 110 buildings loaded but lookup returns empty. Root
cause: storage key mismatch. lb.LandblockId encodes 0xXXYY_FFFF (low 16
bits = 0xFFFF for the landblock's own LandBlockInfo dat id), while the
runtime lookup at the gate derives 0xXXYY_0000 via cellId & 0xFFFF0000u.
Same bug RR7.2 (`efe3520`, reverted by `9aaae02`) tried to fix — landed
here properly:

- Storage key now `lb.LandblockId & 0xFFFF0000u` (was lb.LandblockId).
- Both RemoveLandblock callbacks use `id & 0xFFFF0000u` to match.

Build green.

After this fix, [buildings] should show camBldgs=[0x1] (or similar)
when the player is inside a cottage, [envcells] cells/tris should be
non-zero, and the [stencil] / [draworder] step 1 + 2 + 5 should fire.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-27 15:20:27 +02:00
parent 0fc6003c2a
commit 5d41876ba6

View file

@ -1870,7 +1870,7 @@ public sealed class GameWindow : IDisposable
_terrain?.RemoveLandblock(id);
_physicsEngine.RemoveLandblock(id);
_cellVisibility.RemoveLandblock((id >> 16) & 0xFFFFu);
_buildingRegistries.Remove(id); // Phase A8
_buildingRegistries.Remove(id & 0xFFFF0000u); // Phase A8 (key normalization fix 2026-05-28)
_envCellRenderer?.RemoveLandblock(id); // Phase A8
});
// A.5 T22.5: apply max-completions from resolved quality.
@ -5907,7 +5907,18 @@ public sealed class GameWindow : IDisposable
if (!lbStampCells.ContainsKey(c.CellId))
lbStampCells[c.CellId] = c;
}
_buildingRegistries[lb.LandblockId] =
// FIX 2026-05-28: normalize storage key to the cell-prefix
// convention (`landblockId & 0xFFFF0000u`). The lb.LandblockId
// field encodes 0xXXYY_FFFF (low 16 bits = 0xFFFF for the
// landblock's own LandBlockInfo dat id), but the runtime
// lookup at line ~7110 derives the key from a cell id via
// `cellId & 0xFFFF0000u` which yields 0xXXYY_0000. Storage
// and lookup must agree. Mask both sides to the upper-16
// form so the registry resolves correctly. This is the same
// bug the RR7.2 commit (`efe3520`, reverted by `9aaae02`)
// tried to fix; landing it here in the data-flow layer.
uint regKey = lb.LandblockId & 0xFFFF0000u;
_buildingRegistries[regKey] =
AcDream.App.Rendering.Wb.BuildingLoader.Build(
lbInfo, lb.LandblockId, lbStampCells);
}
@ -9036,7 +9047,7 @@ public sealed class GameWindow : IDisposable
_terrain?.RemoveLandblock(id);
_physicsEngine.RemoveLandblock(id);
_cellVisibility.RemoveLandblock((id >> 16) & 0xFFFFu);
_buildingRegistries.Remove(id); // Phase A8
_buildingRegistries.Remove(id & 0xFFFF0000u); // Phase A8 (key normalization fix 2026-05-28)
_envCellRenderer?.RemoveLandblock(id); // Phase A8
});
_streamingController.MaxCompletionsPerFrame = newResolved.MaxCompletionsPerFrame;