Commit graph

16 commits

Author SHA1 Message Date
Erik
3cf6bcc219 #119 decisive probe: ACDREAM_DUMP_ENTITY one-shot entity dump (H-A/H-B/H-C discriminator)
The broken-state log (user-session-capture2.log) shows meshMissing=0 /
entSeen==entDrawn WHILE broken stairs are on screen - the staircase is
DRAWN WRONG, not missing. This probe discriminates the three live
hypotheses in ONE launch (handoff 2026-06-11 s4):

- HYDRATE dump (GameWindow.BuildInteriorEntitiesForStreaming): per-part
  placement-frame translations + dropped-part accounting at the MOMENT
  MeshRefs are constructed. H-A (SetupMesh.Flatten identity fallback /
  silent gfx-null part drops under degraded dat reads) shows here as
  zero translations or built<43.
- DRAW dump (WbDrawDispatcher, first tuple per entity): live MeshRefs
  translation summary + per-part loaded flags + Tier-1 classification
  cache state (batch count + RestPose translation summary), re-emitted
  compactly on signature change. H-B (partial/stale cached batch set)
  shows as correct translations + odd batch count.
- WALK-REJECT lines (rate-limited): attributes 'entity never reaches
  the draw loop' to the specific gate (visibleCellIds/frustum).
- Correct everything -> H-C (draw-side compose), instrument next.

Targets: ACDREAM_DUMP_ENTITY=0x020003F2,0x020005D8 (the 43-part spiral
staircase Setup + the wall barrels; H-A predicts the user's 'barrel' IS
the collapsed staircase). Probe is inert when the env var is unset.
Parser in RenderingDiagnostics (diagnostic-owner pattern) + 5 unit tests.

Suites: App 242+1skip / Core 1427+2skip / UI 420 / Net 294.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 21:01:08 +02:00
Erik
a974504e6e #119-residual: [viewer] capture probe - the capture half of the tower capture-replay loop
One line per change of (root cell, flood size, OutsideView polys, player
cell), with the projection eye at mm precision on every line
(ACDREAM_PROBE_VIEWER=1, print-on-change, silent while stable). The
tower-ascent harness replays the captured production (eye, root) pairs
deterministically - replacing the synthetic helix that proved unphysical
in the roof-lip band (the real collided camera may never reach it).

Suites: App 238+1skip, Core 1422+2skip, UI 420, Net 294.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 18:41:05 +02:00
Erik
6cba95047c BR-2 task 1: phantom-site probe (ACDREAM_PROBE_PHANTOM)
The BR-1 pre-check left the #113 phantom residual with two surviving
suspects, both cell-side: (a) flood-admitted cells whose shell draws with
a pass-all slice (NoClipSlice fallback when the assembler handed no slot,
or an assembler slot-0 scissor-fallback slice), and (b) cell entity
buckets drawn unclipped + un-viewcone'd by design.

[phantom-shell]: per shell-pass cell, print-on-change - clip-enable
state, slot presence, every drawn slice's slot + plane count with
PASS-ALL flagged. [phantom-objs]: per object-list cell, print-on-change
- entity bucket size. Env-gated ACDREAM_PROBE_PHANTOM=1, zero cost off,
throwaway (strip when the phantom closes).

Repro protocol: launch with the probe on, stand at the hall bisect spot
(world ~216,-108 looking at the AAB3 meeting hall west face) where the
phantom is visible, read which mechanism fires for stair cells
0xAAB30100..0x106. Shells pass-all -> BR-2/BR-3 close it; statics ->
BR-5 closes it.

Build green; App suite green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 06:27:44 +02:00
Erik
c78720127a fix(render): #105 white indoor walls — restore WB's per-frame staged-texture flush dropped in the N.4/O-T4 extraction
Root cause: TextureAtlasManager.AddTexture only STAGES texture content (PBO
write + ManagedGLTextureArray._pendingUpdates); the actual TexSubImage3D
copies + mipmap regeneration happen in ProcessDirtyUpdates, which WB drives
once per frame via ObjectMeshManager.GenerateMipmaps() from its render loop
(WB GameScene.cs:975, just before the opaque pass). GameScene is the file we
replaced with GameWindow, so the call site was silently dropped — staged
updates only reached the GPU as a side effect of PBO growth (UpdateLayerInternal
flushes pending updates before orphaning the PBO). Every layer staged after an
array's LAST growth kept undefined TexStorage3D content behind a valid,
resident bindless sampler handle: white/garbage walls, zh==0, dat tripwires
silent — exactly the #105 signature. Only ObjectRenderBatch.BindlessTextureHandle
consumers are affected (EnvCellRenderer cell shells = indoor walls); entities
resolve via TextureCache (immediate TexImage2D) and terrain via TerrainAtlas
(immediate GenerateMipmap), which is why only indoor walls ever struck.

Fix: WbMeshAdapter.Tick() now calls _meshManager.GenerateMipmaps() after the
staged-upload drain — Tick runs before all draw passes (GameWindow OnRender),
the exact WB-equivalent position.

Evidence (ACDREAM_PROBE_TEXFLUSH=1 apparatus, kept env-gated):
- pre-fix (texflush-prefix.log): pending updates climb 0->48->...->142 and
  park at 126 across 34/34 atlas arrays at standstill, forever (19 heartbeats);
  brief dips only at PBO-growth crossings — the broken contract live.
- post-fix (texflush-postfix.log): every line after=0 — staged updates drain
  the same frame, all 34 arrays clean.

Intermittency explained: background decode-completion order shuffles which
textures land in the never-flushed tail; whether a visible wall samples one is
per-run luck. Also explains the #110 correlation: znear=0.1 makes close-up
geometry newly visible -> more prepare/upload pressure indoors -> bigger tail
-> higher strike probability. The near plane is mechanism-innocent (re-land
follows as its own commit).

Baseline maintained: App 223 / UI 420 / Net 294 / Core 1377 green + 4
pre-existing #99-era failures + 1 skip; CornerFloodReplayTests (5) and
CameraCornerSealReplayTests (2) gates green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 12:10:00 +02:00
Erik
682cba36f1 diag(render): §4 flap [clip-route] probe — slot routing + clip-buffer content + landscape scissor
The decisive probe between the two surviving suspects from the 2026-06-09
building-flood-merge handoff (docs/research/2026-06-09-flap-outdoor-fullworld-
building-flood-merge-handoff.md section 1), gated by ACDREAM_PROBE_CLIPROUTE=1,
all print-on-change:

- [clip-route] (RetailPViewRenderer.DrawLandscapeThroughOutsideView): the
  outside slice slot + NDC AABB + planes, the CellIdToSlot routing table, the
  region-SSBO bytes DECODED at the routed slot, and the terrain-UBO head —
  captured after SetTerrainClip + UploadClipFrame + SetClipRouting, i.e.
  exactly what the landscape draws consume. Pins/refutes suspect (b) and the
  slot-repack half of suspect (a).
- [clip-route-disp] (WbDrawDispatcher.Draw, routed draws only): per-slot
  instance histogram exactly as staged for binding=3 plus the count of
  entities dropped by ResolveSlotForFrame CULL. Pins/refutes the
  instance-routing half of suspect (a).
- [clip-route-scis] (GameWindow.DrawRetailPViewLandscapeSlice): the ACTUAL GL
  scissor enable + box read back right after BeginDoorwayScissor — the whole
  landscape pass (sky + terrain + outdoor entities + player) draws inside this
  box, so a doorway-sized box here IS the full-world kill by construction.

Code-reading findings recorded while building the probe: the landscape pass is
scissored to slice.NdcAabb end-to-end (GameWindow.cs DrawRetailPViewLandscapeSlice),
and ResolveEntitySlot CULLs server entities with null ParentCellId while routing
is active — both now directly observable under the probe.

Throwaway apparatus — strip once §4 ships.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 08:37:09 +02:00
Erik
fafe5d66e8 diag(render): §4 flap apparatus — eye-vs-terrain field + GL-state tripwire
Two probe additions from the §4 outdoor full-world flap investigation
(world turns to fog-tinted clear color at specific outdoor spots;
strobes then holds; camera rotation recovers; forward-walk triggers):

- [pv-input] gains terrZ=/eyeAbove= (terrain height under the camera
  eye) — used to REFUTE the buried-eye hypothesis (eyeAbove stayed
  +1.6..2.1 m through every held-flap block).
- [gl-state] (ACDREAM_PROBE_GLSTATE=1): snapshots the GL fixed-function
  state entering the world passes (depth, blend, cull, scissor + box,
  viewport, FBO, color/clip masks, glGetError), printing on change.
  Delivered the frame-exact flap-onset marker: the leftover scissor box
  flips from full-screen to a drifting 9x21 px doorway footprint at the
  exact frame the nearby building flood merges in (pv-input flood 1->5).

Both probes are gated and zero-cost when off. Strip with the rest of
the §4 apparatus when the flap ships.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 08:18:26 +02:00
Erik
687040ba52 feat(render-diag): add ACDREAM_PROBE_PORTAL_CHURN flag for the bounded-propagation pin
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 12:49:17 +02:00
Erik
d6aa526dd3 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>
2026-06-08 09:16:12 +02:00
Erik
1405dd8e90 feat(render): indoor render WORKS — terminating portal flood + every-cell seal + look-in FPS
Checkpoint of the unified retail-faithful indoor render. The two-week HANG/grey is fixed and the
interior seals (live-verified by the user). Commits the session render-rewrite foundation together
with the fixes that made it functional.

- HANG fix: PortalVisibilityBuilder.Build portal flood did not terminate (the faithful ProjectToClip
  near-side clip drifts per round, defeating the CellView dedup; the BFS had no bound after U.2a removed
  MaxReprocessPerCell). Fix = drift-tolerant snapped/canonical CellView.Add dedup (PortalView.cs) plus
  restored MaxReprocessPerCell=16 bounded re-enqueue (PortalVisibilityBuilder.cs). Re-enqueue is kept
  (load-bearing for late-slice propagation, Build_ViewGrowthAfterDoneCell_PropagatesNewSlicesToExit);
  only its count is capped. CellViewDedupTests added.
- Seal (DrawCells Task 2): RetailPViewRenderer.DrawEnvCellShells draws EVERY visible cell via
  IndoorDrawPlan.ShellPass (was gated on the ClipFrameAssembler slot filter, leaving slot-less cells grey).
- Look-in FPS: GameWindow exterior look-in candidates limited to the player landblock +-1 (was all ~81
  loaded LBs iterated every outdoor frame). No behaviour change (far cells were >48m, already culled).

Remaining dominant issue = the FLAP at transitions: viewer-cell metastability (render roots at the
camera-eye cell, which oscillates outdoor-indoor as the 3rd-person boom drifts across the doorway,
confirmed in render-sig). SEPARATE fix, NOT the DrawCells port. Full handoff + flap fix plan + tracked
follow-ups (#78 terrain, look-in-from-inside, look-in FPS, L-spotlight):
docs/research/2026-06-07-indoor-render-session-handoff.md.

Baselines: build 0 err; App.Tests 210/210; Core.Tests 1331 pass / 4 fail (pre-existing) / 1 skip.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 10:14:43 +02:00
Erik
2b7f5a16c6 fix(render): branch inside/outside on is_player_outside, not the camera cell (PARTIAL)
Retail SmartBox::RenderNormalMode (0x453aa0:92665) branches DrawInside vs the
outdoor LScape::draw on is_player_outside (the PLAYER's cell, 0x451e80), then
roots DrawInside at the VIEWER cell. acdream keyed the whole branch off the
camera cell (clipRoot = visibility.CameraCell), so a 3rd-person chase camera
lagging in a doorway AFTER the player stepped outside took the DrawInside path
rooted at the threshold cell, where the exit-portal flood degenerates: grey
world + entities-through-walls. Now ShouldRenderIndoor(playerCellId,
viewerCellResolved) gates the branch on the player; the DrawInside root stays
the viewer cell (handoff invariant preserved).

SCOPE / HONESTY: this REDUCES the player-OUTSIDE doorway grey (visual-confirmed
reduced a lot) but does NOT fix the deeper symptom: when the player is in one
interior cell (cellar 0174) and the camera is in another (room 0171), the flood
roots at the camera cell and does NOT seal the player's cell, so the cellar
floor / interior walls drop to grey. That is the KNOWN R1-completion problem
(2026-06-05 Residual A handoff + 2026-06-02 design doc section 3: a
SHELL-SEALING / wrong-flood-root bug), not this branch.

Tests: Core 1331p / 4f (documented) / 1s, App 187p, build green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 17:02:09 +02:00
Erik
0013819fa1 docs(render): ARCHITECTURE RESET — indoor render is a 3-gate patchwork; handoff + unified-PView target
A week on the indoor render (Phase U.4 → U.4c → 2026-05-31) fixed the flap but
produced NO shippable progress: walls/ceiling don't seal, outdoor terrain is
visible from inside (#78), the enclosure reads grey/transparent. Root cause is
ARCHITECTURAL, not a bug.

Evidence this session (direct, via the new [shell] probe + screenshots) RULED OUT
every subsystem except the gating architecture: the interior cell shells render
fine (geometry/texture/opaque/depth all correct, zh=0 tr=0); the visibility
traversal computes correct sets + non-empty portal clips; cull mode is fine; the
camera/eye thread was a detour. The residual is that OUTDOOR geometry is not gated
to portal openings when indoors, and acdream enforces visibility THREE inconsistent
ways (TerrainClipMode / per-cell shell clip / entity ParentCellId filter with an
outdoor-stab bypass) instead of retail's ONE PView gate.

This commit is the reset handoff + documentation, not a code fix:
- docs/research/2026-05-31-render-architecture-reset-handoff.md — canonical: honest
  state, evidence ledger (ruled-out / do-not-repeat), the mapped 3-gate patchwork,
  the retail PView target (one traversal → one gate for ALL geometry), the reset
  mission, and a copy-paste pickup prompt.
- docs/architecture/acdream-architecture.md — new "Render Pipeline" SSOT section
  (current divergence + unified-PView target + the one rule: compute visibility
  once, enforce it once). (Doc has pre-existing corruption below this section —
  flagged for separate cleanup.)
- Apparatus: ACDREAM_PROBE_SHELL → [shell] (EnvCellRenderer per-cell prepared/drawn
  geometry + flags) added to RenderingDiagnostics + EnvCellRenderer. Throwaway.
- docs/superpowers/specs/2026-05-31-camera-collision-indoor-engagement-design.md —
  spec for e099b4c (camera collision; now parked as orthogonal to the seam).

Next session: STOP point-fixing; do the architecture reset to a single PView gate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 21:35:55 +02:00
Erik
1d47ede007 diag(render): Phase U.4c — ACDREAM_PROBE_FLAP per-frame convergence probe
Per-frame (not cell-change-throttled, so it catches the flicker at a stable root):
[flap] line from the builder — root cell's per-portal side-test D + traverse/cull +
NDC projection, plus OutsideView poly count + visible-cell count; localEye exposes
when the eye has crossed an interior portal plane. Paired [flap-cam] line from the
draw site — FindCameraCell resolution branch (CameraCellResolution enum, new),
eyeInRoot AABB flag (stale-root signal), eye + player worldpos, and the frame's
TerrainMode/OutdoorVisible outcome. Disambiguates side-cull vs empty-projection vs
stale-root. Inert when off (gated). Throwaway apparatus to converge the flap fix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 10:44:37 +02:00
Erik
0b125830fe feat(render): Phase U.2d — ACDREAM_PROBE_VIS visibility probe in RenderingDiagnostics
Add the durable per-frame visibility probe apparatus that #103 lacked, so
the Phase U portal-visibility builder can be validated on live frames before
any GL/visual work.

EmitVis(rootCellId, visibleCells, outsidePolyCount, outsidePlaneCount,
perCellPlaneCounts, scissorFallbacks) prints ONE concise [vis] line gated on
root-cell CHANGE (private _lastVisRootCellId tracker; no-op when the root is
unchanged or ProbeVisibilityEnabled is false — one bool compare per frame when
off). Line format:
  [vis] root=0x… cells=N ids=[…] outside(polys=…,planes=…) percell=[0x…:N,…] fallbacks=…

Reuses the existing Phase A8 ProbeVisibilityEnabled flag (env ACDREAM_PROBE_VIS,
already DebugPanel-mirrored via DebugVM.ProbeVisibility) rather than adding a
parallel owner — Code Structure Rule 5 (one diagnostic owner per subsystem).
Property doc repurposed from the abandoned A8 two-pipe stencil semantics to the
Phase U unified pipeline.

Decoupling note: RenderingDiagnostics lives in AcDream.Core, which must not
reference AcDream.App (Code Structure Rule 2). The plan's EmitVis signature took
an App-layer CellView; this lands the equivalent as pre-computed primitives
(outsidePolyCount + outsidePlaneCount) so the owner stays in Core. The U.4a call
site supplies OutsideView.Polygons.Count and the OutsideView ClipPlaneSet.Count.

TDD: 3 new tests in RenderingDiagnosticsVisibilityTests (no-op when disabled,
fires-once-per-new-root + suppressed-on-unchanged, env-default contract), each
self-contained via internal ResetVisibilityProbeForTests + Console.Out capture
to avoid the documented static-leak flakiness. Core suite +3 tests, no new
failures (flaky physics/input static-leak set unchanged at 16, untouched area).

Courtesy: removed the dangling RenderInsideOutAcdream comment reference (deleted
in U.1) + the AcDream.App.Rendering.Wb doc cref (a Core→App layer inversion).

The emit SITE wiring (per-frame call from the render loop) lands in U.4a; this
task lands only the owner members + formatter + test. GameWindow untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 17:11:02 +02:00
Erik
8532c84f57 feat(render): Phase A8 Wave 5 — probe trail ([envcells]/[stencil]/[draworder]/[buildings])
Probe emitters wired (replaces the Task 8 stubs). All gated on
ACDREAM_PROBE_VIS=1 (everything) or ACDREAM_PROBE_ENVCELL=1
([envcells] only):

- [envcells] frame=N cells=N tris=N ourBldgs=N otherBldgs=N filterCnt=N
  Fires once per Render call inside RenderInsideOutAcdream Step 3.
  Reads CellsRendered + TrianglesDrawn from EnvCellRenderer.Stats.

- [stencil] op={mark|punch} bld=0xHHHHHHHH verts=N
  Fires after every IndoorCellStencilPipeline.RenderBuildingStencilMask
  call (Steps 1, 2, 5a, 5b, 5d) — surfaces LastStencil* probe fields
  added in Wave 1's Task 7 extension.

- [draworder] frame=N step=Xy stencil={on|off} depthFn=0xHHH depthMask={true|false}
  Fires at each step boundary (entry to Step 1/2/3/4/5{a,b,c,d}).
  Reads live GL state via glGetInteger so divergence between assumed
  vs actual state is immediately visible.

- [buildings] camCell=0xHHHHHHHH camBldgs=[0x1,0x2,...] otherBldgs=N totalKnown=N
  Fires once per indoor frame at the top of RenderInsideOutAcdream.
  totalKnown sums BuildingRegistry.Count across all loaded landblocks.

Per-frame counter _phaseA8DrawOrderFrame incremented once per render
tick after the existing [vis] probe block (line 7104).

New env-var flag ACDREAM_PROBE_ENVCELL in RenderingDiagnostics +
ProbeEnvCellEnabled property (true OR ProbeVisibilityEnabled).

Mandatory acceptance criteria (process rule "no visual-gate launch
without probe data first") to check FROM the log BEFORE asking the
user for visual verification:
  - [buildings] camBldgs=[0x...] non-empty when inside a cottage
  - [envcells] cells>=1 tris>=1 filterCnt>=1 for at least one indoor frame
  - [stencil] op=mark verts>0 fires per camera-building
  - [draworder] shows the full Step 1 → 2 → 3 → 4 → 5{a,b,c,d} cycle

Build green. 82/82 App.Tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 15:14:45 +02:00
Erik
6577c0a21c feat(render): Phase A8 — RenderingDiagnostics.ProbeVisibilityEnabled
Adds the ACDREAM_PROBE_VIS=1 env-var-toggleable flag for the indoor-cell
visibility culling pipeline (#78). Mirrors the existing ProbeIndoor*
pattern. DebugVM checkbox follows.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 07:47:56 +02:00
Erik
6b0230be43 feat(rendering): Task 1 — RenderingDiagnostics static class
Five indoor-cell probe flags (ProbeIndoorWalk/Lookup/Upload/Xform/Cull)
+ IndoorAll master cascade, seeded from ACDREAM_PROBE_INDOOR_* env vars.
Mirrors L.2a PhysicsDiagnostics pattern exactly. IsEnvCellId helper for
call-site filtering (low-16 ≥ 0x0100 = EnvCell). Zero warnings.

Spec: docs/superpowers/specs/2026-05-19-indoor-cell-rendering-fix-design.md
Plan task 1: docs/superpowers/plans/2026-05-19-indoor-cell-rendering-phase1-diagnostics.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 11:24:38 +02:00