docs(render): define OH1 retail world contract

This commit is contained in:
Erik 2026-09-01 19:33:15 +02:00
parent 5cd4fd2c71
commit 5d907ae9ad
7 changed files with 2040 additions and 39 deletions

View file

@ -1089,49 +1089,63 @@ devtools, and screenshots; then closes the GPU-flight transaction in
---
## Render Pipeline (SSOT — current accepted state)
## Render Pipeline (SSOT — current implementation state; OVERHAUL active)
> The modern path (Phase N.5, mandatory) is
> `WbDrawDispatcher` (entities) + `EnvCellRenderer` (indoor cell shells) +
> `TerrainModernRenderer` (terrain), fed by the unified PView stack. This is the
> authoritative current draw model; the 2026-05-31 reset handoff is historical.
**One visibility owner.** `RetailFrameWalk`, driven once per frame by
`WalkFrameDriver.Collect`, is the production authority for rooting, portal
recursion, visible cells/buildings, per-view admission, and draw order. Its root
is the collided camera/viewer cell or retail's synthetic outdoor cell; the
player's current cell separately owns sunlight and indoor lighting. A null root
exists only for login/debug/streaming-gap fallback frames. The classes named
`RetailPViewRenderer` and `RetailPViewPassExecutor` remain composition/pass
facades around that one walk; they do not build a second visibility product.
`PortalVisibilityBuilder` is retained only by tests and research diagnostics and
has no production caller. `CellVisibility` does not decide frame visibility.
**Walk owner and current reconstruction boundary.** `RetailFrameWalk`, driven
once per frame by `WalkFrameDriver.Collect`, is the production authority for
rooting and portal recursion. Its root is the collided camera/viewer cell or
retail's synthetic outdoor cell; the player's current cell separately owns
sunlight and indoor lighting. A null root exists only for login/debug/streaming-
gap fallback frames. `RetailPViewRenderer` and `RetailPViewPassExecutor` are
composition/pass facades, and `PortalVisibilityBuilder` has no production
caller. This does **not** yet mean the complete world graph has one owner:
`WalkProductionWorldData` still reconstructs frame buckets from scene records,
AABBs, and aggregate shadow-owner cells. Campaign OVERHAUL OH3 replaces that
boundary with one canonical published cell graph and typed render/physics
membership transaction.
**Current draw discipline.** The walk records one ordered event stream for
landscape cells, building portals, EnvCell shells, statics, dynamics, particles,
depth boundaries, and alpha barriers. `WalkFrameDriver` replays those events in
retail order through the Vulkan leaf renderers. Interior roots preserve retail's
conditional depth clear and true-depth exit seals; the synthetic outdoor root
retains world depth and stamps far-Z entry punches. World translucents and scene
particles share `RetailAlphaQueue` and drain at the walk's exact barriers.
Private portal/paperdoll viewports and retained UI execute only after the world
stream finishes. Projectiles are ordinary live-entity draws, never a separate
global pass.
**Current draw discipline and known non-retail order.** The walk records an
ordered event stream for landscape cells, building portals, EnvCell shells,
statics, dynamics, particles, depth boundaries, and alpha barriers, then
`WalkFrameDriver` replays it through the Vulkan leaves. Private portal/
paperdoll viewports and retained UI execute after the world stream, and
projectiles remain ordinary live-entity draws. Three current details are
explicit Campaign OVERHAUL divergences, not accepted retail contracts:
**Portal-slice clipping is part of admission, not a later approximation.** Each
walk visit retains the exact authored pixel-space portal polygon. The frame
adapter converts it once to a Vulkan GPU clip slot, and the cell shell, statics,
and dynamics admitted by that visit draw through that same slot. A content
drawing sphere may reject a slice before submission, but an accepted slice
never emits the whole mesh unclipped. The same cell can therefore draw more
than once through distinct apertures, exactly as retail's `viewconeCheck` plus
`portal_view` loop requires. Particles remain unclipped at submission because
retail contains them positionally through owner-cell ordering, opaque depth,
and alpha barriers. The complete visibility answer is the union of the walk's
visited EnvCells and visited landscape land cells. EnvCell batch preparation
consumes only the former; particle, light, and shadow visibility consume the
union. Omitting the landscape half disables every outdoor emitter even though
its owner still reaches the draw stream.
- terrain is staged before all per-cell building/object turns instead of
retail's `DrawLandCell` then `DrawSortCell` interleave for each land cell;
- depth clear/seal events are emitted for zero-outside-view roots and do not
consume retail's persistent previous-call `uint16 portalsDrawnCount` gate;
- `RetailAlphaQueue` distance-sorts one shared queue, whereas retail owns two
FIFO mesh lists and drains clip before alpha at exact barriers.
The exact target and evidence are recorded in
`docs/research/2026-09-01-overhaul/oh1-retail-world-contract.md`; OH5, OH6, and
OH7 own these cutovers.
**Retail view admission is not general mesh clipping.** A walk visit retains
the authored portal polygon and its installed view planes. Retail uses those
planes for `viewconeCheck`-style sphere admission. For an ordinary built part,
the first accepted view submits the complete eligible mesh and stamps the
part; later views are suppressed by that stamp. A built EnvCell shell is also
drawn complete once per render stamp. The local player deliberately bypasses
the ordinary inner part-stamp gate and may submit whole for more than one
admitted cell/view. Actual polygon clipping belongs to portal clip/punch/seal
geometry (`PView::GetClip` / `DrawPortalPolyInternal`), not normal built shells
or objects. The current `PortalDepthMaskRenderer` GPU `gl_ClipDistance` route
therefore remains an OH6 portal-fan approximation. The current ordinary-part
classifier is a materially aligned candidate and OH4 must protect it while
removing only contradictory view/admission residue.
The walk's visited EnvCells and landscape land cells still form different
typed inputs. Outdoor particle, light, and shadow consumers must borrow the
landscape half rather than infer visibility from aggregate owner ids; OH8 owns
that final consumer cutover.
WorldBuilder contributes DAT decoding, mesh preparation, residency, and Vulkan
batch mechanics only; it makes no visibility or ordering decision. Forced merge
@ -1141,9 +1155,9 @@ inside a leaf may still use order-preserving MDI merging.
Retail anchors are `SmartBox::RenderNormalMode @ 0x00453AA0`,
`PView::DrawInside @ 0x005A5860`, `PView::DrawCells @ 0x005A4840`,
`LScape::draw @ 0x00506330`, `D3DPolyRender::FlushAlphaList @ 0x0059D2E0`,
and `SceneTool::EndFrame @ 0x0043FB30`. The deliberate modern/PView
adaptations are audited in the retail divergence register; Slice 7 changes
their ownership only, not their behavior.
and `SceneTool::EndFrame @ 0x0043FB30`. The active OVERHAUL plan is
`docs/plans/2026-09-01-campaign-overhaul-world-solidity.md`; it replaces prior
claims of exactness only at each reviewed slice gate.
### Streaming publication ownership