acdream/docs/research/2026-07-06-176-177-render-pair-investigation.md
Erik b8e9e204ad docs+test #176/#177: 12 mechanisms refuted, apparatus shipped, probe protocol staged
The dungeon render pair (purple seam flash + stair pop-in) resisted
desk root-causing, but the investigation narrowed the space to two
live theories and shipped permanent apparatus:

- Issue176177DungeonSeamInspectionTests: dat truth — corridor floors
  ARE textured drawn PortalSide portal polys; the reciprocal is NoPos;
  the 'stairs' are 0x8A020182's ramp shell (vertical portals, zero
  statics); CellBSP partitions exactly at portal planes; DXT1 textures
  carry zero transparent-mode texels.
- Issue176177FacilityHubFloodReplayTests: production-matched flood
  replays — approach/descent/gaze-sweep/walk all healthy with coherent
  inputs; ScenarioE pins the flood's collapse-to-root sensitivity under
  incoherent (root, eye) pairs.
- Issue176177SeamTransitLagTests: the resolver flips cells within one
  tick-step of the portal plane — the 0.33-0.47m [cell-transit] 'lag'
  in the gate logs is speed*tick quantization, not membership error.

Refuted (do NOT retry — ledger in the research doc): placeholder
texture, reciprocal z-fight, seal z-fight (seals only fire for
OtherCellId==0xFFFF), root/eye incoherence (production camera sweep is
mm-exact at planes), flood bistability, #119-class statics, undefined
DXT mips (both paths decode DXT->RGBA8; the compressed-array branch is
dead code), DXT1 alpha, fog mix (ramp ~538m), lightning leak (flash==0
in production), viewer-light pops (smooth (1-d/range) ramp).

Filed #178 (A8 double-sided shell stopgap still live) and #179
(lightning flash lacks an indoor gate — dormant). The purple can only
be the fog clear color (undrawn pixels) or the outdoor ambient+sun
tint; discrimination needs ONE probe launch (ACDREAM_PROBE_LIGHT +
ACDREAM_PROBE_PVINPUT + ACDREAM_PROBE_CELL) — protocol in
docs/research/2026-07-06-176-177-render-pair-investigation.md.

Suites: Core 2587 / App 719 green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 21:20:03 +02:00

8.9 KiB
Raw Blame History

#176/#177 render pair — investigation ledger (2026-07-06, session 2)

Status: mechanism NOT yet pinned — but the hypothesis space is now razor-thin. Twelve candidate mechanisms refuted by direct evidence (dat dumps, headless replays, production-log analysis, code reads). Every layer that can be checked offline is verified HEALTHY at the anchor cells. The surviving discriminator requires ONE live probe launch (protocol at the bottom — piggyback on the pending #175 door gate).

The issues

  • #176 — purple flashing on dungeon floors at cell seams, camera-angle dependent (Facility Hub).
  • #177 — stairs pop in/out across levels: (a) vanish on the last step running down, (b) invisible looking into the stair room from the corridor, (c) pop into existence on entering.

Anchor-cell dat truth (Issue176177DungeonSeamInspectionTests)

  • Corridor 0x8A02016E floor = three abutting TEXTURED drawn portal polys (polys 1/3/5, surface 0x08000377 → DXT1 tex 0x050026F7, [PortalSide]) → under-hall 0x011E (z=12). Reciprocal ceiling poly = NoPos (not drawn).
  • The "stairs" = a RAMP owned by 0x8A020182 (inclined drawn polys, z 9…6 floor + 6…3 ceiling); 0x0183 = flat lower cell. Connections are VERTICAL wall portals (NOT floor-portals). PortalSide flag asymmetry: 0x0182→0x0183 carries PortalSide; the back-portal does not.
  • Zero StaticObjects in all five anchor cells (no #119-class statics, no torch-bearing stabs → no registered point lights except the viewer fill).
  • CellBSP volumes partition EXACTLY at the portal planes (no overlap zone).
  • All surfaces resolve; DXT1 textures contain zero transparent-mode texels (all 3-color-mode blocks, index 3 never used).

REFUTED mechanisms (each by direct evidence — do NOT retry)

# Hypothesis Killed by
1 Placeholder/missing texture (magenta class) All surfaces resolve; drawn-poly sweep 0 misses
2 Reciprocal portal-poly z-fight Reciprocal is NoPos (never drawn)
3 Seal depth-stamp z-fights the drawn floor-portal Seals fire ONLY for OtherCellId==0xFFFF (GameWindow:11437); a sealed dungeon draws zero seals
4 Root/eye incoherence (viewer root lags the eye across portal planes) Production camera sweep publishes coherent pairs; out-cell flips at x=85.001/88.335 — mm-exact at the planes (gate2 log). The flood DOES collapse to 1 cell under artificially incoherent inputs (ScenarioE pin) — but production inputs are coherent
5 Membership transit lag (0.330.47 m in [cell-transit]) as the render-root lag The resolver flips within one tick-step of the plane in the harness (Issue176177SeamTransitLagTests); the logged "lag" is speed×tick quantization of the PLAYER probe, and the camera root (probe out-cell) is plane-exact
6 Flood bistability at the anchors ScenarioC gaze sweep (2° steps, 4 pitches): 0 one-step drops; ScenarioA stair approach: ramp+lower admitted at all tested eyes/pitches
7 Staircase = EnvCell static culled by viewcone (#119 class) Zero statics in the anchor cells; the stairs are shell geometry
8 Undefined DXT mip levels (compressed arrays skip GenerateMipmap) Both ObjectMeshManager texture paths DECODE DXT→RGBA8 (BcDecoder) — the compressed-array branch of ManagedGLTextureArray is dead WB-heritage code; RGBA8 arrays get real mips
9 DXT1 3-color-mode alpha=0 texels + opaque-pass discard a<0.05 / A2C Block histogram: 0 transparent texels in all Hub floor/wall textures
10 Fog mix toward purple FogColor at distance Fog ramp starts at _nearRadius×192×0.7 ≈ 538 m (radii stay 4/12 in dungeon mode); Hub sightlines ≤ ~100 m → fog term ≡ 0
11 Lightning-flash additive (uFogParams.z × (0.6,0.6,0.75)) leaking indoors WeatherState._flashLevel is 0 in production ("Production never TriggerFlashes") — dormant test hook. (The missing indoor gate is still real debt for when storm strobes ship.)
12 Viewer-light per-cell/per-vertex pops (hard range edge or 8-set membership flips) The point ramp is (1d/range) — smoothly ZERO at the range boundary; set-membership beyond range is a zero-contribution no-op. No torches exist in the Hub cells to churn the 8-cap

VERIFIED-HEALTHY layers (offline pins, keep as regression assets)

  • PortalVisibilityBuilder at the anchors: approach/descent/gaze-sweep/walk scenarios (Issue176177FacilityHubFloodReplayTests) — admissions correct and stable with coherent inputs; the ScenarioE incoherent-input collapse is the sensitivity pin (1-cell flood when root≠eye side).
  • Membership: ResolveWithTransition flips cells within one tick of the portal plane, both directions (Issue176177SeamTransitLagTests).
  • Mesh path: CellMesh.Build (production, GameWindow:7013) draws the textured floor-portal strips; snapshot frustum gate (WbFrustum) is the standard conservative p-vertex test; per-cell AABBs are vertex-derived, 8-corner transformed.
  • Per-instance light sets are truly per-instance (EnvCellRenderer MDI).

SURVIVING theories (need the live discriminator)

  • T-A (ambient flip): any frame where playerRoot resolves null (or playerSeenOutside defaults true) runs the OUTDOOR lighting branch — purple sky ambient + full sun. Sun is directional-from-above → floors (N·L≈1) catch it, walls (N·L≈0) barely → a FLOOR-selective purple-bright flash, temporally lockable to whatever gaps CurrCell/TryGetCell. Desk analysis found no per-frame gap trigger during plain corridor runs (UpdatePlayerCurrCell is stale-beats-null; the registry is stable in AP-36 dungeon mode) — but the branch inputs are exactly probed by [light] insideCell= lines, so one run settles it.
  • T-B (flood with REAL production inputs): my harness feeds synthetic viewProj/eye. If the real per-frame inputs at the artifact moments differ (collided camera pressed into walls near seams, damped-forward gaze), the flood could still misbehave in configurations the sweeps missed. [pv-input] prints the exact inputs + flood count per frame.
  • T-C: unknown-unknown (GPU state, driver, MSAA resolve…). If T-A/T-B both read clean at a flash moment → RenderDoc frame capture next.

Also found (real, filed, not these bugs)

  • A8 double-sided shells stopgap still live: EnvCellRenderer.cs RenderModernMDIInternal maps CullMode.Landblock → CullMode.None ("while the architectural cause is isolated") — all cell shells draw two-sided. Perf + correctness debt; retire under the A7/A8 lighting arc.
  • Lightning indoor gate missing (dormant): when weather strobes ship, SceneLightingUbo.Build needs the playerInsideCell gate or dungeons will strobe blue-violet.
  • Flood follows floor-portals DOWNWARD from above (ScenarioC: under-hall network admitted at down-pitches). Retail's portal_side side test (0x005a59a0: portal_side≠0 → NEGATIVE side only; ==0 → POSITIVE only; IN_PLANE(±0.0002) → refused) appears to refuse this direction, but my plane-sign reading had unresolved contradictions (CCellPortal::UnPack normalizes portal_side at load, 0x0053ba1c/0x0053bc6a). OPEN QUESTION — harmless-looking (extra admitted cells draw below the opaque floor, z-buffer wins) but worth settling when the flood is next touched.

The live probe protocol (piggyback on the #175 door gate launch)

Env (add to the standard launch block):

ACDREAM_PROBE_LIGHT=1      # [light] insideCell/ambient/sun — rate-limited
ACDREAM_PROBE_PVINPUT=1    # [pv-input] one line/frame: exact flood inputs + count
ACDREAM_PROBE_CELL=1       # [cell-transit] timeline anchors

User reproduces in Facility Hub (~2 min): run the corridor across several seams until the purple flash shows; approach the stair room from the corridor, walk in, run down. Then close. Discrimination:

  • Flash moments + [light] shows insideCell=False blips or ambient jumps → T-A confirmed (then root-cause the gap trigger from the same log).
  • [pv-input] flood count drops (e.g. 12→1) at flash/pop moments while [light] stays clean → T-B confirmed (the line carries the exact inputs to replay in Issue176177FacilityHubFloodReplayTests).
  • Stairs invisible while the flood contains 0x0182/0x0183 → draw-side hunt (RenderDoc next); absent → flood-side with the printed inputs.
  • All clean → T-C: RenderDoc frame capture of a flash frame.

Apparatus shipped this session

  • tests/AcDream.Core.Tests/Rendering/Issue176177DungeonSeamInspectionTests.cs — dat truth: portal polys/surfaces/draw verdicts, reciprocal coincidence, stair geometry owner, CellBSP containment, under-hall surface colors, DXT1 alpha histograms.
  • tests/AcDream.App.Tests/Rendering/Issue176177FacilityHubFloodReplayTests.cs — production-matched flood replays: stair approach, descent, gaze sweep, corridor walk, and the ScenarioE incoherent-root sensitivity pin.
  • tests/AcDream.Core.Tests/Physics/Issue176177SeamTransitLagTests.cs — resolver cell-flip position at the seam (plane-exact pin).