diag(render/physics): flap root-caused to physics rest µm-jitter; refute prior diagnoses
Apparatus + handoff for the indoor flap. Confirmed (primary evidence): the flap is the portal-flood clip being µm-sensitive at the threshold, driven by a ~1-8µm jitter in the player RenderPosition (physics resting position not bit-stable; Lerp surfaces it). REFUTES the 2026-06-07 see-through/EnvCell/outdoor-node diagnosis (ModelId GfxObj 0x01000A2B IS the solid exterior) AND an enqueue-once attempt (retail propagates late slices via AddToCell; the existing PropagatesNewSlicesToExit test caught it; reverted). Adds: Build determinism test, A8CellAudit gfxobj dump, [pv-input] 6dp probe + [render-sig] outRoot/bshell fields. No functional fix shipped. Next: higher-precision physics rest trace -> port retail kill_velocity/contact rest-stability. Canonical: docs/research/2026-06-08-flap-rootcause-physics-rest-handoff.md Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d0b65c4170
commit
d6aa526dd3
6 changed files with 300 additions and 1 deletions
|
|
@ -58,6 +58,38 @@ public class PortalVisibilityBuilderTests
|
|||
$"OutsideView width {outsideWidth} should be a sliver, far less than full window {windowOnlyWidth}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Build_IsDeterministic_IdenticalInputsGiveIdenticalVisibleSet()
|
||||
{
|
||||
// Flap root-cause apparatus (2026-06-07): the live threshold flap shows OrderedVisibleCells
|
||||
// flipping 2<->6 at an eye+player identical to cm. Build is a pure static function with
|
||||
// all-fresh per-call state, so identical inputs MUST yield an identical visible set. If this
|
||||
// FAILS, the flap is a determinism bug INSIDE Build; if it PASSES (expected), the live flip is
|
||||
// sub-cm INPUT jitter and the fix must make membership robust, not Build deterministic.
|
||||
// Exercises the re-enqueue fixpoint via a diamond: 0x0004 is reached from BOTH 0x0002 and 0x0003.
|
||||
var cam = Cell(0x0001,
|
||||
new CellPortalInfo(0x0002, 0, 0, 0),
|
||||
new CellPortalInfo(0x0003, 1, 0, 0));
|
||||
cam.PortalPolygons.Add(QuadX(-0.6f, -0.05f, -3f)); // left -> 0002
|
||||
cam.PortalPolygons.Add(QuadX(0.05f, 0.6f, -3f)); // right -> 0003
|
||||
var left = Cell(0x0002, new CellPortalInfo(0x0004, 0, 0, 0));
|
||||
left.PortalPolygons.Add(QuadX(-0.6f, -0.05f, -6f));
|
||||
var right = Cell(0x0003, new CellPortalInfo(0x0004, 0, 0, 0));
|
||||
right.PortalPolygons.Add(QuadX(0.05f, 0.6f, -6f));
|
||||
var back = Cell(0x0004, new CellPortalInfo(0xFFFF, 0, 0, 0));
|
||||
back.PortalPolygons.Add(QuadX(-0.6f, 0.6f, -9f));
|
||||
var all = new Dictionary<uint, LoadedCell>
|
||||
{ [0x0001] = cam, [0x0002] = left, [0x0003] = right, [0x0004] = back };
|
||||
|
||||
var a = Build(cam, all);
|
||||
var b = Build(cam, all);
|
||||
|
||||
Assert.Equal(a.OrderedVisibleCells, b.OrderedVisibleCells);
|
||||
Assert.Equal(
|
||||
a.CellViews.Keys.OrderBy(k => k).ToArray(),
|
||||
b.CellViews.Keys.OrderBy(k => k).ToArray());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Build_EyeStandingInInteriorPortal_FloodsNeighbour()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue