fix(render) #132: outdoor alpha drains follow retail walk order
Some checks failed
CI / linux-portable (push) Successful in 3m35s
CI / windows-gate (push) Failing after 6m46s
CI / release (push) Has been skipped

Retail draws every cell's objects inside LScape::draw's far-to-near walk
(DrawSortCell @0x005A17C0) and drains the one delayed-alpha list at the
DrawCells boundary AFTER the finished walk (@0x005A4872). Our outdoor
frame drained at the landscape-stage end and then drew punches, interior
shells, cell objects, and ALL dynamics — every one of those opaque
passes overwrote the already-composited flames (the reopened #132
candle class: "the door draws over the candle", creatures at openings).
Depth and barrier A/Bs were no-ops because the eraser is opaque color
painted after the drain.

Two retail-cited ordering corrections, outdoor-node roots only:

1. The stage-boundary drain is skipped and FlushLandscapeAlpha() runs
   after DrawDynamicsLast, where the frame's opaque world depth is
   complete — the one far-to-near list composites over everything,
   exactly like retail's boundary flush relative to its finished walk.
2. Before DrawExitPortalMasks, FlushLandscapeAlphaFartherThan(
   ExitPortalMaskBarrierDistance(...)) drains everything at or beyond
   the nearest cell whose exit-portal mask is about to write far-Z —
   retail DrawBuilding @0x0059F2A0 runs FlushAlphaList(0f) BEFORE its
   portal-only pass, so in the far-to-near walk nothing already drained
   can meet a punched aperture's falsified depth. Without this, the
   first correction let exterior waterfalls z-pass across punched
   apertures whose true landscape depth the punch erased (found live at
   the cathedral gate). Nearer content stays queued and legitimately
   composites in front of punched structures.

Interior roots keep the pre-clear stage-boundary drain unchanged.

User-gated live: Holtburg sign candle whole in front of the sign and
tower door at the aligned pose; cathedral waterfalls contained at every
camera zoom, inside and outside. Register row AP-236 retired (the
walk-order outcome reconstruction is complete; AP-34 remains the
umbrella for the CYpt-sort reconstruction itself). Filed #456 for the
separate occluded-distant-building/creature admission residual this
session diagnosed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-08-29 19:03:35 +02:00
parent 8acb544d44
commit e102fb363e
4 changed files with 148 additions and 3 deletions

View file

@ -39,6 +39,43 @@ confirmed closed by the owner, 11 need a focused live gate, and 43 are safe to
remain closed. See
[`docs/research/2026-08-28-owner-closed-issue-validity-audit.md`](research/2026-08-28-owner-closed-issue-validity-audit.md).
## #456 — Occluded distant buildings/creatures show through structures at raised cameras
**Status:** OPEN — mechanism established 2026-08-29; needs its own slice.
**Severity:** MEDIUM (visual correctness at pulled-out cameras; the long-standing
"camera outside shows buildings behind terrain" residual, now with a mechanism)
**Component:** pview outdoor shell drawing / dynamics distance admission
**Symptom (owner, 2026-08-29, Sanctuary cathedral terrace `0xF4180104`
[31.1, 55.7, 169.8]):** zoom the chase camera out and a building in the next
landblock (the `0xF518` shrine, model `0x01001777` at world (47173, 4741, 130),
317 m away) plus purple creatures appear across the lake where structure/ridge
should hide them; zoom in and they vanish. Verified with the punched-cell probe:
zoomed in (root = EnvCell `0xF4180104`, `visible=1`) the shrine never enters the
frame; zoomed out (root = landcell `0xF4180003`) the per-building flood admits
`0xF5180100`/`0xF5180106` at 316.8 m into the punch/shell pipeline. DAT terrain
profile from the true eye: the sight-line is blocked by a z=160 knoll by only
2.8 m (roof) / 10.3 m (base), and a ~9 m camera raise makes the roofline
geometrically clear — but the screenshots show the WHOLE building, so an
occluder that should cover its lower half is not being drawn.
**Established mechanism candidates (both retail-cited):**
1. Retail `RenderDeviceD3D::DrawBuilding @0x0059F2A0` draws a building's whole
exterior unconditionally in the block walk (`CPhysicsPart::Draw(parts, 0)`);
only the interior flood is portal-gated. Our shell pass draws only
flood-admitted cells' shells, so intervening cathedral pieces whose cells the
flood did not reach leave a hole the shrine shows through (the owner's
original "wall appears transparent though its geometry is present" read).
2. Retail degrades/skips distant objects (`DrawBuilding`'s
`gfxobj[deg_level] != 0` gate; `GfxObjDegradeInfo::get_degrade` off CYpt in
`CPhysicsPart::UpdateViewerDistance @0x0050E030`) and never draws creatures
at 300 m; we draw dynamics and admit look-in structures at unlimited range.
**Prescribed next step:** RenderDoc pixel history on an artifact pixel (which
draw owns it, what should have covered it), then port the missing admission
gates. Full evidence chain in
`C:/Users/erikn/.codex/worktrees/16ee/acdream/docs/research/2026-08-29-cathedral-seam-progress.md`.
## #455 — Clicking an equipped item on the paperdoll does not dequip it
**Status:** OPEN — needs retail investigation BEFORE any implementation.
@ -19612,6 +19649,24 @@ the post-world PView replay is deleted.
**Gate:** both sides — indoors with the opening behind the candle, and
outdoors at the angle that previously erased it.
**2026-08-29 recurrence fixed (register AP-236 retired in the same commit):**
the #451 correction moved outdoor-static flames into the LScape-stage drain,
which reopened this class — every opaque pass after that drain (doors,
creatures, look-in interiors, DynamicsLast) overwrote the already-composited
flames, and depth/barrier A/Bs were no-ops because the eraser is opaque color
painted later. Fix, both halves retail-cited and user-gated live at Holtburg
(candle whole in front of sign + door) and the cathedral (waterfalls
contained at every zoom): (1) an OUTDOOR root skips the stage-boundary drain
and runs `FlushLandscapeAlpha()` after `DrawDynamicsLast` — retail's walk
draws every cell's objects before `PView::DrawCells`' boundary flush
(`DrawSortCell @0x005A17C0`, flush `@0x005A4872`); (2) before
`DrawExitPortalMasks`, a partial drain flushes everything at or beyond the
nearest punched cell (`ExitPortalMaskBarrierDistance`) — retail `DrawBuilding
@0x0059F2A0` runs `FlushAlphaList(0f)` BEFORE its portal-only far-Z pass, so
in the far→near walk nothing already drained can meet a punched aperture's
falsified depth (the waterfall-through-aperture regression the first half
exposed). Interior roots keep the pre-clear stage-boundary drain unchanged.
---
# Recently closed