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>
8.9 KiB
8.9 KiB
#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
0x8A02016Efloor = three abutting TEXTURED drawn portal polys (polys 1/3/5, surface 0x08000377 → DXT1 tex 0x050026F7,[PortalSide]) → under-hall0x011E(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.33–0.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 (1−d/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)
PortalVisibilityBuilderat 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:
ResolveWithTransitionflips 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
playerRootresolves null (orplayerSeenOutsidedefaults 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.csRenderModernMDIInternal mapsCullMode.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.Buildneeds theplayerInsideCellgate or dungeons will strobe blue-violet. - Flood follows floor-portals DOWNWARD from above (ScenarioC: under-hall
network admitted at down-pitches). Retail's
portal_sideside 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]showsinsideCell=Falseblips 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 inIssue176177FacilityHubFloodReplayTests).- 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).