docs(render): S4 packet — the ±12 reject's quantifier corrected to retail's (ALL vertices on ONE bounding plane); #464 stair-ladder route

The S4-c1 retail lens caught the lead's paraphrase inverting retail's
predicate (any vertex on any plane vs every vertex on the same plane);
the contract and T2 now state the decomp's four per-plane predicates.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-09-03 21:07:38 +02:00
parent cddd3d236b
commit ad6b0599cc
2 changed files with 87 additions and 12 deletions

View file

@ -131,9 +131,15 @@ seal/punch color-state row from S4-c1 kept or retired per its decision.
- R1 far-Z punch: `DrawPortalPolyInternal` @0x0059bc90's tail writes the - R1 far-Z punch: `DrawPortalPolyInternal` @0x0059bc90's tail writes the
punch depth from the constant with bits `0x3F7FFFEF`. punch depth from the constant with bits `0x3F7FFFEF`.
- R2 the ±12 reject: `0x59BCD60x59BD28` then `0x59BD400x59BD66` compare - R2 the ±12 reject: `0x59BCD60x59BD28` then `0x59BD400x59BD66` compare
each SOURCE vertex's LOCAL `x`/`y` against ±12 BEFORE `xformStart`; any hit each SOURCE vertex's LOCAL `x`/`y` against ±12 BEFORE `xformStart`. The
returns — the whole polygon is dropped (degenerate-input guard, S3 packet QUANTIFIER (S4-c1 round-1 retail lens, 2026-09-03 night — the lead's first
§2). Then `0x59BD700x59BD74`: only false/true-depth SEALS increment the wording here and in T2 was inverted): retail rejects the polygon only when
ALL of its local vertices lie on ONE of the four planes x=+12, x=12,
y=+12, y=12 — a polygon degenerate onto a bounding plane; a polygon with
merely one vertex on such a plane is drawn and counted. Four accumulating
predicates, one per plane, each true only if every vertex satisfied it;
return if any predicate survives (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). counter (modulo 65,536); far punches never do (already ported, S3 §8.2 B2).
`0x59BDBC0x59BDBF`: fewer than 3 CLIPPED vertices submit no fan (after `0x59BDBC0x59BDBF`: fewer than 3 CLIPPED vertices submit no fan (after
the possible increment). the possible increment).
@ -167,12 +173,14 @@ seal/punch color-state row from S4-c1 kept or retired per its decision.
- C1 the ±12 local-input reject ported at the producer that owns the LOCAL - 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 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 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 space before the world transform), as retail's four per-plane predicates:
against +12/12 on every source vertex; a hit drops the whole polygon the polygon is dropped only when EVERY source vertex lies on the same one
BEFORE any counter increment (matches R2's order: reject → transform → of x=+12, x=12, y=+12, y=12 (exact equality), BEFORE any counter
clip → count). If the Ghidra table shows the bound can never be hit by an increment (order: reject → transform → clip → count). A polygon with one
authored portal polygon, the port still lands (it is retail's code) with vertex on a bound is NOT rejected. If the table shows the bound can never
the test proving the reject fires on a synthetic ±12 vertex. 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 all-on-one-
plane polygon and NOT on a one-vertex-on-the-plane polygon.
- C2 no state change for R3: add register row "portal-depth color path: - C2 no state change for R3: add register row "portal-depth color path:
ColorWrite=false instead of retail's zero-alpha SRCALPHA/INVSRCALPHA blend ColorWrite=false instead of retail's zero-alpha SRCALPHA/INVSRCALPHA blend
— identical output, different pipeline state" (an AD row, with the — identical output, different pipeline state" (an AD row, with the
@ -183,9 +191,12 @@ seal/punch color-state row from S4-c1 kept or retired per its decision.
**Tests:** T1 reads `portal_depth.vert`'s punch line and asserts the literal **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`, it carries has bits `0x3F7FFFEF` (a source pin — it FAILS at `d0c981212`,
where the line reads `0.99999988` = `0x3F7FFFFE`; MUTATION: any other where the line reads `0.99999988` = `0x3F7FFFFE`; MUTATION: any other
literal); T2 ±12 reject: a synthetic local polygon with one vertex at literal); T2 ±12 reject (corrected 2026-09-03 night — the lead's first
x = 12 exactly → no punch event and no seal, counter unchanged; the same wording inverted retail's quantifier): a synthetic local polygon with EVERY
polygon at x = 11.999 → punched/sealed; T3 the truth table vertex at x = 12 exactly (degenerate onto the plane) → no punch event and no
seal, counter unchanged; the same polygon with ONE vertex at x = 12 and the
rest inside → punched/sealed and counted; every vertex at x = 11.999 →
punched/sealed; T3 the truth table
(root kind × draw_landscape × outside-view count × previous count) → the (root kind × draw_landscape × outside-view count × previous count) → the
exact event subsequence; T4 two consecutive frames prove the latch crosses 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 frames (frame 1 seals N>0 → frame 2 clears; frame 1 seals 0 → frame 2 does

View file

@ -0,0 +1,64 @@
# #464 reproduction (lead, 2026-09-03 night): the cathedral stair line the
# owner ran down, as a teleport ladder from the top pose to the bottom pose
# in nine steps, facing down the stairs (identity heading = +y, the owner's
# own heading). The chase camera settles behind the player at each step, so
# every frame is the "running down" view without zoom. Screenshots only.
wait world-visible 180000
sleep 4000
command /teleloc F4180113 39.502899 19.589222 181.119247 1.000000 0.000000 0.000000 0.000000
sleep 2000
wait world-visible 60000
sleep 3000
screenshot 464-00-top 15000
command /teleloc F4180113 39.449000 19.959000 180.826000 1.000000 0.000000 0.000000 0.000000
sleep 1500
wait world-visible 60000
sleep 3000
screenshot 464-01 15000
command /teleloc F4180113 39.395000 20.329000 180.533000 1.000000 0.000000 0.000000 0.000000
sleep 1500
wait world-visible 60000
sleep 3000
screenshot 464-02 15000
command /teleloc F4180113 39.341000 20.699000 180.240000 1.000000 0.000000 0.000000 0.000000
sleep 1500
wait world-visible 60000
sleep 3000
screenshot 464-03 15000
command /teleloc F4180113 39.364658 21.293159 179.773422 1.000000 0.000000 0.000000 0.000000
sleep 1500
wait world-visible 60000
sleep 3000
screenshot 464-04-owner-mid 15000
command /teleloc F4180113 39.250000 21.700000 179.450000 1.000000 0.000000 0.000000 0.000000
sleep 1500
wait world-visible 60000
sleep 3000
screenshot 464-05 15000
command /teleloc F4180112 39.180000 22.100000 179.120000 1.000000 0.000000 0.000000 0.000000
sleep 1500
wait world-visible 60000
sleep 3000
screenshot 464-06 15000
command /teleloc F4180112 39.070965 22.549135 178.781418 1.000000 0.000000 0.000000 0.000000
sleep 1500
wait world-visible 60000
sleep 3000
screenshot 464-07-owner-bottom 15000
command /teleloc F4180112 38.999477 23.470444 178.053741 -0.980785 0.000000 0.000000 -0.195090
sleep 1500
wait world-visible 60000
sleep 3000
screenshot 464-08-g2-pose 15000
close-client