From ad6b0599cca3fbf114c7db1219a7fb642360c5eb Mon Sep 17 00:00:00 2001 From: Erik Date: Thu, 3 Sep 2026 21:07:38 +0200 Subject: [PATCH] =?UTF-8?q?docs(render):=20S4=20packet=20=E2=80=94=20the?= =?UTF-8?q?=20=C2=B112=20reject's=20quantifier=20corrected=20to=20retail's?= =?UTF-8?q?=20(ALL=20vertices=20on=20ONE=20bounding=20plane);=20#464=20sta?= =?UTF-8?q?ir-ladder=20route?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../s4-depth-alpha-packet.md | 35 ++++++---- tools/overhaul-selfgate/route-464-stairs.txt | 64 +++++++++++++++++++ 2 files changed, 87 insertions(+), 12 deletions(-) create mode 100644 tools/overhaul-selfgate/route-464-stairs.txt diff --git a/docs/research/2026-09-01-overhaul/s4-depth-alpha-packet.md b/docs/research/2026-09-01-overhaul/s4-depth-alpha-packet.md index 948fa8367..132da2daf 100644 --- a/docs/research/2026-09-01-overhaul/s4-depth-alpha-packet.md +++ b/docs/research/2026-09-01-overhaul/s4-depth-alpha-packet.md @@ -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 punch depth from the constant with bits `0x3F7FFFEF`. - R2 the ±12 reject: `0x59BCD6–0x59BD28` then `0x59BD40–0x59BD66` 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 `0x59BD70–0x59BD74`: only false/true-depth SEALS increment the + each SOURCE vertex's LOCAL `x`/`y` against ±12 BEFORE `xformStart`. The + QUANTIFIER (S4-c1 round-1 retail lens, 2026-09-03 night — the lead's first + 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 `0x59BD70–0x59BD74`: only false/true-depth SEALS increment the counter (modulo 65,536); far punches never do (already ported, S3 §8.2 B2). `0x59BDBC–0x59BDBF`: fewer than 3 CLIPPED vertices submit no fan (after 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 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. + space before the world transform), as retail's four per-plane predicates: + the polygon is dropped only when EVERY source vertex lies on the same one + of x=+12, x=−12, y=+12, y=−12 (exact equality), BEFORE any counter + increment (order: reject → transform → clip → count). A polygon with one + vertex on a bound is NOT rejected. If the 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 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: ColorWrite=false instead of retail's zero-alpha SRCALPHA/INVSRCALPHA blend — 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 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 +literal); T2 ±12 reject (corrected 2026-09-03 night — the lead's first +wording inverted retail's quantifier): a synthetic local polygon with EVERY +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 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 diff --git a/tools/overhaul-selfgate/route-464-stairs.txt b/tools/overhaul-selfgate/route-464-stairs.txt new file mode 100644 index 000000000..764989310 --- /dev/null +++ b/tools/overhaul-selfgate/route-464-stairs.txt @@ -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