fix(render): harden portal exit handoff
Some checks failed
CI / linux-portable (push) Successful in 3m19s
CI / windows-gate (push) Failing after 6m43s
CI / release (push) Has been skipped

This commit is contained in:
Erik 2026-08-25 17:39:44 +02:00
parent ddbd7e4096
commit 82e4b4cb6d
17 changed files with 896 additions and 119 deletions

View file

@ -1443,7 +1443,9 @@ died there. Distinct from the LU5 UX work.
## #419 — Portal-tunnel rim polygon visible (FOV-coupled) + ring flash at exit (camera dolly vs retail's view-plane animation)
**Status:** OPEN (filed 2026-08-17, user screenshot + FOV experiment).
**Status:** ✅ FIXED / OWNER-ACCEPTED 2026-08-25 — the centered disk, 16:9
faceted outer rim, and destination lower-viewport hole are gone in the live
owner-pak gate.
**Symptom:** the tunnel's low-poly mouth shows as a faceted polygon
silhouette against black, scaling with the Config FOV slider (barely
visible at minimum FOV); a brief ring flash remains at exit even at
@ -1541,6 +1543,69 @@ interior there ⇒ our pipeline, rings there ⇒ shared dat
interpretation); (4) a retail side-by-side screenshot for ground truth
(brightness included). Fix only against that evidence.
**2026-08-25 apparatus closeout:** step (1) is implemented as
`ACDREAM_PROBE_TUNNEL_FREEZE=1` (authored frame 72) or `=N` (frame 2120).
The diagnostic withholds the TAS_TUNNEL transition even after world-ready,
then stops the tunnel sequence and roll at the requested frame and emits one
`[tunnel-freeze] ... state=held` marker. It intentionally prevents placement,
reveal, and login completion until cancellation/process exit; it is a capture
tool, not a shipping behavior or a performance mode. Step (2)'s frozen
RenderDoc capture (`portal-frozen-frame1178.rdc`) confirmed the authored finite
mesh and production portal pass were actually drawing; it did not support a
cull/material/asset substitution. Step (3) was attempted, but ACViewer was not
a trustworthy renderer oracle for this path and was discarded rather than used
as fix evidence. Step (4)'s direct retail capture showed the radial tunnel
field swapping straight to the destination world, with no small centered disk.
**Root cause and final fix (2026-08-25):** the exit defect was a two-part
presentation-boundary error, not tunnel content. First, our outgoing viewport
remained eligible through retail animation-table level 1022 even though paired
initial 40 fps captures appeared to establish level 1013 as the last sample
whose radial field covered the measured center rings; level 1016 and later
exposed a small finite-mesh disk. `TeleportAnimSequencer` initially retired the
outgoing viewport after quantized level 1013. Second,
`LocalPlayerTeleportPresentation.Tick`
published the `WorldFadeIn` terminal projection while the tunnel could still be
visible, and both teleport/login event handlers called the synchronous
destination-release suffix before `ExitTunnel`. A slow suffix could therefore
hold the invalid tunnel/projection combination on screen. The presentation now
hides portal space before publishing any snapshot whose `ShowTunnel` is false,
and both handlers enforce retail's order: hide portal, reveal/release world,
then play `Sound_UI_ExitPortal`. The later `ExitTunnel` call remains idempotent.
**Acceptance evidence:** the 40 fps frame-sequence verifier fails the pre-fix
owner-pak capture on the exact disk (`radial coverage=0.053`). Three consecutive
fixed launches, using `artifacts/owner-gate/acdream-v5.pak` with the installed
DATs and the same ACE login route, swap directly to world and pass at minimum
tail coverage `0.800`, `0.747`, and `0.736`. Focused regressions cover the 1001
table boundary, tunnel-retire-before-view-plane publication, and both
teleport/login host-call orders. No portal mesh, shader, sampler, lighting, or
camera-position change is part of the fix.
**16:9 perimeter correction (2026-08-25):** the center-ring verifier missed
the same mesh boundary crossing the sides of a full-width viewport. The owner
capture and the automated 1280x720 sequence agree: level 1001 is the last
fully covered tunnel sample, level 1006 begins exposing the outer perimeter,
and the old level-1013 handoff can hold the complete faceted rim while the
world viewport is installed. The sequencer cutoff is therefore 1001, still in
the retail quantized table domain, and the gate now measures an unobstructed
left-edge rail in addition to center rings. This changes only which authored
tunnel sample is held for the atomic swap; it does not enlarge or repaint the
mesh.
**Residual found by the owner:** the direct swap still leaves a large blue
lower-viewport region during the first `WorldFadeIn` samples. This is not a
missing tunnel texture and the title's `lb 0/0` is not a terrain-residency
count. The destination is resident; its finite terrain is projected with
`M22=0.001` and `znear=0.1`, so lower-screen ground rays meet the terrain before
the Vulkan near plane and only a thin horizon strip survives. The legacy retail
landscape visibly supplies coverage at this singular endpoint. The modern
renderer adaptation scales the near plane with view-plane distance only while
the world viewport owns `WorldFadeOut`/`WorldFadeIn`; tunnel and ordinary-world
near planes remain unchanged. The lower-viewport coverage gate passes the
owner-pak live capture, and the owner accepted the final in-game transition on
2026-08-25 as "Perfect!".
## #418 — Login world load takes ~27 s: publication advances at a flat 32 blocks/s
**Status:** IN-PROGRESS 2026-08-17 — producer half landed (this commit's
@ -1706,6 +1771,19 @@ attributed to the cold render-thread barrier); portal-hold gate-ready
render-thread upload/registration phase (t≈18 s, concurrent) — budgets
are exonerated three times over.**
**2026-08-25 attribution checkpoint:** `ACDREAM_PROBE_REVEAL_TIMING=1` now
pairs each reveal timing run with low-frequency `[reveal-resource]` snapshots
at begin, readiness edges, one-second progress intervals, and summary. The
snapshots borrow the canonical render owners and report mesh/atlas residency,
global and per-frame upload counts/bytes, buffer/texture/copy work, staging
high-water, mesh-arena capacity/migration, prepared-package probe/read results,
composite backlog, CPU mesh cache, and managed/committed/tracked GPU memory.
Use it with `ACDREAM_FRAME_PROF=1` and
`ACDREAM_FRAME_HISTORY=<csv-path>`; the next cold login comparison can now
distinguish decode/cache fill, upload/staging,
registration/composite debt, arena growth, and process-memory growth without
adding a per-frame diagnostic tax.
## #417 — World ambience keeps playing (and re-firing) on the character-select screen after the in-world logoff
**Status:** ✅ FIXED 2026-08-17 (logout-audio round; fix + tests in the same