fix(G.3): pin dungeon collapse to the cell's landblock, not the position-derived one (#133)
"The dungeon is broken" — the collapse was unloading the REAL dungeon. A dungeon's EnvCells sit at arbitrary "ocean" world coords with negative cell-local Y (snap showed pos=(58.9,-69.6) in cell 0x00070133), so the observer landblock _liveCenterY + floor(pp.Y/192) = 7 + floor(-69.6/192) = 7 + (-1) = 6 lands one row off. The collapse pinned to 0x0006 and unloaded 0x0007 — the real dungeon — which nulled CurrCell (the cell no longer existed) and left the player floating in outdoor-lit empty space (lb 1/1 @ ~1585 fps, but the wrong landblock). This is the Bug-A negative-local-coordinate class. Fix: when inside a dungeon, pin the collapse to the cell's OWN landblock (CurrCell.Id >> 16), never the position-derived observer landblock — the cell id is the authoritative landblock for ocean-placed dungeon geometry. Also hardened the hysteresis so a transient CurrCell flicker can't thrash: - Re-collapse when insideDungeon at a DIFFERENT landblock (multi-landblock dungeon). - Expand only on a DISTANT move (Chebyshev > 1) — a real exit teleports far from the ocean-grid block; the off-by-one flicker is always an ADJACENT (±1) landblock, so it now HOLDS the collapse instead of expanding. - SweepCollapsed always preserves _collapsedCenter (the true dungeon landblock), never the per-frame observer landblock. Build green; 59 streaming tests green (flicker regression test updated to the realistic adjacent off-by-one). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d9e7dd65e9
commit
2561918a70
3 changed files with 52 additions and 18 deletions
|
|
@ -6892,10 +6892,23 @@ public sealed class GameWindow : IDisposable
|
|||
// and keep their surrounding terrain.
|
||||
// Mirrors the playerInsideCell computation below (CurrCell → registry
|
||||
// LoadedCell.SeenOutside): true only for a sealed indoor cell.
|
||||
bool insideDungeon =
|
||||
_physicsEngine.DataCache?.CellGraph.CurrCell is AcDream.Core.World.Cells.EnvCell pcEnv
|
||||
bool insideDungeon = false;
|
||||
if (_physicsEngine.DataCache?.CellGraph.CurrCell is AcDream.Core.World.Cells.EnvCell pcEnv
|
||||
&& _cellVisibility.TryGetCell(pcEnv.Id, out var pcReg)
|
||||
&& pcReg is { SeenOutside: false };
|
||||
&& pcReg is { SeenOutside: false })
|
||||
{
|
||||
insideDungeon = true;
|
||||
// Pin the collapse to the cell's OWN landblock (cell id high 16 bits),
|
||||
// NOT the position-derived observer landblock. A dungeon's EnvCells sit
|
||||
// at arbitrary world coords (the "ocean" placement) with negative local
|
||||
// offsets, so floor(pp.Y/192) lands one landblock off — which collapses
|
||||
// onto the WRONG landblock and unloads the real dungeon, nulling CurrCell
|
||||
// and breaking the render (the Bug-A coordinate class). The cell id is the
|
||||
// authoritative landblock.
|
||||
uint cellLb = pcEnv.Id >> 16;
|
||||
observerCx = (int)((cellLb >> 8) & 0xFFu);
|
||||
observerCy = (int)(cellLb & 0xFFu);
|
||||
}
|
||||
_streamingController.Tick(observerCx, observerCy, insideDungeon);
|
||||
|
||||
// Re-inject persistent entities rescued from unloaded landblocks
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue