fix(render): doorway blue-hole — render root clobbered by NPCs (CurrCell per-entity write)
THE doorway flap root cause, found via [flap-cam]/[shell]/[cell-transit] (2026-06-03): the player spawned + stood still in the room (cell 0171, NO [cell-transit] after teleport), yet the render rooted at the vestibule (0170) for all 77,951 frames — drawing only 0170's ~8-triangle shell, the rest = GL clear color = the bluish void. CellGraph.CurrCell IS "the player's cell" (the render root), but it was written by SetCurrAndReturn inside the PER-ENTITY ResolveWithTransition + ResolveCellId — so EVERY NPC wrote it. A Holtburg NPC (0x000F4240) jump-looping near the doorway clobbered the player's render root every tick. Standing still (player makes no resolve calls) the NPC's write wins → stuck blue void; moving, player/NPC writes fight → the flap. This is why the membership pick fix (correct, kept) didn't change the visual — the render root was clobbered regardless. Fix: CurrCell is now written ONLY by the player. New PhysicsEngine.UpdatePlayerCurrCell is called from PlayerMovementController.UpdateCellId — the single player-only chokepoint for CellId (teleport / server snap @ SetPosition + per-frame resolver). Removed the CurrCell write from SetCurrAndReturn (inlined the 2 resolve call sites to sp.CurCellId) and the 4 ResolveCellId sites. NPCs no longer touch the render root. Teleport→UpdateCellId also covers spawn/standing-still (CurrCell = the player's spawn cell immediately). CellGraphMembershipTests rewritten to the new contract (3 tests): UpdatePlayerCurrCell writes the render root; ResolveCellId does NOT (the blue-hole guard); stale-beats-null preserved. Full Core suite: 1295 pass / 5 fail = the documented §10 baseline, zero new breakage. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e5457f9552
commit
79fb6e7c23
3 changed files with 87 additions and 25 deletions
|
|
@ -780,6 +780,15 @@ public sealed class PlayerMovementController
|
|||
$"[cell-transit] 0x{CellId:X8} -> 0x{newCellId:X8} pos=({pos.X:F3},{pos.Y:F3},{pos.Z:F3}) reason={reason}"));
|
||||
}
|
||||
CellId = newCellId;
|
||||
|
||||
// Render root: CellGraph.CurrCell IS "the player's cell" — it roots the indoor render
|
||||
// (GameWindow.OnRender). Set it HERE, the single PLAYER-only chokepoint for CellId
|
||||
// (teleport / server snap @ SetPosition + per-frame resolver), NOT in the per-entity
|
||||
// PhysicsEngine.ResolveWithTransition. That ran for EVERY entity, so a Holtburg NPC
|
||||
// jump-looping near the cottage doorway clobbered the render root every tick → the render
|
||||
// rooted at the NPC's tiny connector cell → only its ~8-tri shell drew, rest = GL clear
|
||||
// color = the cottage doorway "blue-hole" flap (diagnosed 2026-06-03 via [flap-cam]/[shell]).
|
||||
_physics.UpdatePlayerCurrCell(newCellId);
|
||||
}
|
||||
|
||||
public void SetPosition(Vector3 pos, uint cellId)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue