docs(render): S4 packet — S4-c1 contract draft; the far-punch constant is NOT retail's (0x3F7FFFFE vs 0x3F7FFFEF)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-09-03 18:28:00 +02:00
parent e6f5a156b7
commit 5bc4b36879

View file

@ -124,6 +124,80 @@ already removed from `portal_depth.vert` (verify nothing else carries them).
Register: AP-34 retired; any row describing the distance sort retired; the
seal/punch color-state row from S4-c1 kept or retired per its decision.
## 6. S4-c1 contract (lead draft, 2026-09-03 evening — dispatch after the S3 review closes; re-locate every owner)
**Retail facts (verified in the decomp / the Ghidra arbitration table of
`oh1-depth-lifecycle.md`):**
- R1 far-Z punch: `DrawPortalPolyInternal` @0x0059bc90's tail writes the
punch depth from the constant with bits `0x3F7FFFEF`.
- R2 the ±12 reject: `0x59BCD60x59BD28` then `0x59BD400x59BD66` compare
each SOURCE vertex's LOCAL `x`/`y` against ±12 BEFORE `xformStart`; any hit
returns — the whole polygon is dropped (degenerate-input guard, S3 packet
§2). Then `0x59BD700x59BD74`: only false/true-depth SEALS increment the
counter (modulo 65,536); far punches never do (already ported, S3 §8.2 B2).
`0x59BDBC0x59BDBF`: fewer than 3 CLIPPED vertices submit no fan (after
the possible increment).
- R3 portal-depth state: depth test ALWAYS, depth write on, no cull; color
writes ENABLED with `SRCALPHA/INVSRCALPHA` and source alpha 0 (a no-op
blend); no stencil.
**Current acdream (at `d0c981212`):**
- `portal_depth.vert:53` `clipPos.z = clipPos.w * 0.99999988;` — the decimal
literal is 1 2⁻²³ = bits `0x3F7FFFFE`; retail's constant `0x3F7FFFEF` is
0.99999898672… — FIFTEEN ULPs nearer the camera (lead's bit check,
2026-09-03: `SingleToInt32Bits(0.99999988f) == 0x3F7FFFFE`). The depth
spec's "**wrong constant**" row is right. C0 below fixes it; T1 pins it.
- No ±12 reject anywhere on the punch/seal producers
(`WalkFrameDriver.OnPunchGeometry` @ the walk's punch event;
`RetailPViewRenderer.DrawWalkExitPortalMasks`); the clipped-count <3 gate
exists as the `vertices.Length < 3` early return in `DrawWalkPunchFan`.
- `PortalDepthMaskRenderer.Rhi.cs`: `GpuCompareOp.Always`, depth write on,
`Blend = GpuBlendMode.None`, `ColorWrite = false` — pixel-identical to R3
(a zero-alpha blend changes no color), state-different.
**Behavior change (small):**
- C0 the far-punch constant: `portal_depth.vert` takes retail's exact bits
(`uintBitsToFloat(0x3F7FFFEFu)`, comment citing `DrawPortalPolyInternal`
@0x0059bc90's tail), the SPIR-V is recompiled and `VulkanShaderManifestTests`
re-pinned. Visible effect: the far punch lands 15 ULPs nearer than
before — at 24-bit depth that is the difference between "at the far plane"
and "one step in front of it", which is exactly the retail relationship the
seals (true depth) and the interior repaint rely on; any capture pose whose
`PM` lines show `mode=1` punches is the regression check.
- C1 the ±12 local-input reject ported at the producer that owns the LOCAL
polygon (the walk's punch-event producer for punch fans; the exit-seal
enumeration for seals — both read the dat portal polygon in cell-local
space before the world transform), as an exact equality test on x and y
against +12/12 on every source vertex; a hit drops the whole polygon
BEFORE any counter increment (matches R2's order: reject → transform →
clip → count). If the Ghidra table shows the bound can never be hit by an
authored portal polygon, the port still lands (it is retail's code) with
the test proving the reject fires on a synthetic ±12 vertex.
- C2 no state change for R3: add register row "portal-depth color path:
ColorWrite=false instead of retail's zero-alpha SRCALPHA/INVSRCALPHA blend
— identical output, different pipeline state" (an AD row, with the
citation), unless the reviewer prefers the exact blend attachment; the
lead's default is the row (zero-risk, honest).
- C3 the truth-table theory and the two-frame latch test (§2 above).
**Tests:** T1 reads `portal_depth.vert`'s punch line and asserts the literal
it carries has bits `0x3F7FFFEF` (a source pin — it FAILS at `d0c981212`,
where the line reads `0.99999988` = `0x3F7FFFFE`; MUTATION: any other
literal); T2 ±12 reject: a synthetic local polygon with one vertex at
x = 12 exactly → no punch event and no seal, counter unchanged; the same
polygon at x = 11.999 → punched/sealed; T3 the truth table
(root kind × draw_landscape × outside-view count × previous count) → the
exact event subsequence; T4 two consecutive frames prove the latch crosses
frames (frame 1 seals N>0 → frame 2 clears; frame 1 seals 0 → frame 2 does
not clear); T5 multiple look-ins never touch the root latch. Mutation checks
for every new pin, texts inline in the commit body.
**Gates:** build 0 warnings; hermetic green; InstalledDat the four known;
depth-event transcript unchanged at the four capture poses (the `PM`/`PC`
lines of the alpha-depth captures — S4-c1 changes no event unless a ±12
polygon exists in a captured pose, in which case the transcript is the
proof); the lead's four-pose self-gate with validation on (zero errors).
## 5. Open questions to settle before dispatch
- SETTLED (2026-09-03): the walk's `SC` turn is `IWalkEventSink.OnSortCellTurn`