diff --git a/docs/ISSUES.md b/docs/ISSUES.md index 49c7c19a..3e6ed8f2 100644 --- a/docs/ISSUES.md +++ b/docs/ISSUES.md @@ -1183,6 +1183,20 @@ walls** in particular. (Symptoms not fully characterized yet: likely walking thr openings that should block / blocking at openings that should pass, and door collision not matching the door's open/closed state.) +**SEAM SHAKE FIXED (same day): the stale `footCenter` in `CheckOtherCells`' +per-cell loop** — the P2 cellar-lip lesson one loop deeper. A mid-loop +other-cell query can MOVE the sphere (the boundary full-hit dispatches +step_sphere_up; the successful climb lifts the foot +0.6 mm and returns +OK), and the remaining cells were then queried with the by-value +pre-climb center — 0.4 mm inside the floor slab, grazing the under-room's +ceiling and firing the chain below. Retail's `check_other_cells` reads the +LIVE `sphere_path.global_sphere` per cell (pc:272717+). Fix: re-read +`footCenter = sp.GlobalSphere[0].Origin` per iteration. All three +`Issue137CorridorSeamReplayTests` repros un-skipped and GREEN; full suites +green. Visual gate pending. (The step 3 "restore clobbers CheckPos" wording +below was the right CLASS but the wrong site — CheckPos was fine; the +stale copy was the loop's captured parameter.) + **GATE 2026-07-06 FAILED — THIRD MECHANISM CHARACTERIZED (the seam shake), deterministic offline repro secured:** with mechanisms 1+2 fixed the dead stop became a SHAKE at cell seams (+ purple floor flashing there — almost diff --git a/src/AcDream.Core/Physics/TransitionTypes.cs b/src/AcDream.Core/Physics/TransitionTypes.cs index cc21a953..20dcdef1 100644 --- a/src/AcDream.Core/Physics/TransitionTypes.cs +++ b/src/AcDream.Core/Physics/TransitionTypes.cs @@ -1804,6 +1804,21 @@ public sealed class Transition { if (cellId == sp.CheckCellId) continue; + // #137 seam shake (2026-07-06): a mid-loop query can MOVE the + // sphere — a Path-5 full hit dispatches step_sphere_up, and a + // successful climb lifts the foot (the 0.6 mm ramp-slab lift at + // the Facility Hub boundaries) yet returns OK, so the loop + // continues. Retail's check_other_cells reads the LIVE + // sphere_path.global_sphere for every cell (each cell's + // find_collisions receives the transition itself, pc:272717+); + // querying the remaining cells with the pre-climb center re-tests + // the boundary ~0.4 mm inside the floor slab and grazes the + // under-room's CEILING (the slab underside) — the neg-poly + // step-up-with-a-downward-normal chain that shook the player at + // every corridor seam. Same lesson as the P2 cellar-lip fix + // (RunCheckOtherCellsAndAdvance's entry refresh), one loop deeper. + footCenter = sp.GlobalSphere[0].Origin; + if ((cellId & 0xFFFFu) < 0x0100u) { var terrainWalkable = engine.SampleTerrainWalkable(footCenter.X, footCenter.Y); diff --git a/tests/AcDream.Core.Tests/Physics/Issue137CorridorSeamReplayTests.cs b/tests/AcDream.Core.Tests/Physics/Issue137CorridorSeamReplayTests.cs index 42d5d28b..ae39eeba 100644 --- a/tests/AcDream.Core.Tests/Physics/Issue137CorridorSeamReplayTests.cs +++ b/tests/AcDream.Core.Tests/Physics/Issue137CorridorSeamReplayTests.cs @@ -168,7 +168,7 @@ public class Issue137CorridorSeamReplayTests /// opposing-normals branch → Collided → revert. Repeat. /// /// - [Fact(Skip = "#137 seam shake — deterministic RED repro; the post-step-up check-pos restore clobbers the lifted position (P2 stale-snapshot class). Un-skip with the fix.")] + [Fact] public void SeamShake_WestBoundary_SnapshotExact_Advances() { var datDir = FindDatDir(); @@ -255,7 +255,7 @@ public class Issue137CorridorSeamReplayTests /// frame (the "shaking at the seam" report). The deeper straddle start is /// what the original replay frame (84.638 → 85.253) didn't cover. /// - [Fact(Skip = "#137 seam shake — deterministic RED repro; the post-step-up check-pos restore clobbers the lifted position (P2 stale-snapshot class). Un-skip with the fix.")] + [Fact] public void SeamCrossing_FromDeepStraddleStart_Advances() { var datDir = FindDatDir(); @@ -285,7 +285,7 @@ public class Issue137CorridorSeamReplayTests $"reversed-movement normal = the 2026-07-06 seam shake."); } - [Fact(Skip = "#137 seam shake — deterministic RED repro; the post-step-up check-pos restore clobbers the lifted position (P2 stale-snapshot class). Un-skip with the fix.")] + [Fact] public void SeamCrossing_DoesNotPersistSyntheticSlidingNormal_AndRunContinues() { var datDir = FindDatDir();