fix #137 (seam shake): CheckOtherCells queried remaining cells at a stale pre-climb center
The P2 cellar-lip lesson one loop deeper. CheckOtherCells takes footCenter by value and used it for every cell in the loop — but a mid-loop query can MOVE the sphere: at the Facility Hub cell boundaries the neighbor's ramp floor full-hits, step_sphere_up climbs the foot +0.6mm and returns OK, and the loop continued querying the REMAINING cells (including the under-room, portal-ring-3) at the pre-climb height — 0.4mm inside the double-faced floor slab, grazing its underside (the under-room's ceiling) within the near-miss window. That dispatched a neg-poly step-up with a DOWNWARD normal, whose failure funneled into slide_sphere's opposing branch -> synthetic reversed-movement collision -> Collided -> revert, every frame: the seam shake (and, pre-mechanism-2-fix, the original absorbing wedge's entry). Retail check_other_cells reads the LIVE sphere_path.global_sphere for every cell (each cell's find_collisions receives the transition itself, pc:272717+). Fix: re-read footCenter = sp.GlobalSphere[0].Origin at the top of each loop iteration. All three Issue137CorridorSeamReplayTests repros un-skipped: the snapshot-exact west-boundary crossing (capture tick 4101), the east deep-straddle, and the clean-run lifecycle all GREEN. Full suites: Core 2556 / App 713 / UI 425 / Net 385, 0 failures. Visual gate pending: corridor run + the purple seam flashing re-check (expected to be the render exposing the same per-frame oscillation). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
660f3458ac
commit
d4869154d2
3 changed files with 32 additions and 3 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ public class Issue137CorridorSeamReplayTests
|
|||
/// opposing-normals branch → Collided → revert. Repeat.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[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.
|
||||
/// </summary>
|
||||
[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();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue