test(physics): AP-157 measured — CylHeight half retired, sorting-sphere half proven collision-unreachable; AD-55 byte-decoded
Some checks are pending
Headless portability / portable-headless (ubuntu-latest) (push) Waiting to run
Headless portability / portable-headless (windows-latest) (push) Waiting to run
Headless portability / linux-graphical (push) Waiting to run
Headless portability / linux-vulkan (push) Waiting to run
Some checks are pending
Headless portability / portable-headless (ubuntu-latest) (push) Waiting to run
Headless portability / portable-headless (windows-latest) (push) Waiting to run
Headless portability / linux-graphical (push) Waiting to run
Headless portability / linux-vulkan (push) Waiting to run
Campaign S S1A, both outcomes the measure-first rule exists for. AP-157's CylHeight half is RETIRED as a non-divergence: retail's own cylsphere overload (CObjCell::find_cell_list @0x0052b9f0) copies localtoglobal(low_pt) + radius per cylsphere, capped at 10, and never reads height — retail collapses a cylsphere to a base-point sphere exactly as acdream does. The sorting-sphere half measured REAL against retail's registration set — 1,812 of 3,343 evaluated Setups (54%) fail containment at 1 mm, worst shortfall 18.135 m — and then PROVEN collision-unreachable: for this branch the flood spheres and the collision-test geometry are the same per-part Sphere list, so every omitted cell is one the entity's test geometry cannot reach, and retail's wider sorting-sphere registrations are narrow-phase rejects on retail too. Fix deferred to the next bake-schema revision rather than performing Slice I3 surgery for zero behavioural delta. The measurement test stays in the tree as the permanent record (population cross-checked against the dispatch test's independently-committed constants: 3,506 = 3,605 - 99). AD-55 is byte-decoded and RESOLVED against our constant: the binary loads qword [0x007c6b28] = pi/18 exactly and executes FCOS — retail's Sledding flatness threshold is cos(10 deg) = 0.984808. Our 0.99999536f is cos(0.17453 DEGREES): the radian literal misread as degrees, which makes the object-friction arm unreachable on real terrain (nothing is flatter than 0.175 deg). Evidence note carries the full instruction listing and the polarity of the test ah,0x41 / jp idiom; the one-line fix + conformance test is S5, queued behind the running implementation slice for build-slot reasons. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
04b794ad7c
commit
52aea775b9
3 changed files with 352 additions and 1 deletions
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,66 @@
|
|||
# AD-55 resolved by byte-decode — the Sledding flatness threshold is cos(10°), and our constant is a unit slip
|
||||
|
||||
**Date:** 2026-08-07 (overnight). **Method:** `reference_pe_byte_decode` — raw
|
||||
bytes from the PDB-paired v11.4186 binary (`check_exe_pdb.py` → MATCH,
|
||||
CodeView GUID `9e847e2f-777c-4bd9-886c-22256bb87f32`), not the decomp text.
|
||||
|
||||
## The question AD-55 filed
|
||||
|
||||
`PhysicsBody.calc_friction`'s Sledding near-flat branch compares
|
||||
`GroundNormal.Z > 0.99999536f` (≈0.175° from flat). The raw decomp of
|
||||
`CPhysicsObj::calc_friction` @0x0050ee70 instead shows
|
||||
`__fcos(0.17453292519943295)` — cos(10°) ≈ 0.984808 — compared against
|
||||
`contact_plane.N.z`. One of the two had to be a decode artifact.
|
||||
|
||||
## The bytes @0x0050ef53 (verbatim from the binary)
|
||||
|
||||
```
|
||||
d9 86 38 01 00 00 fld dword [esi+0x138] ; contact_plane.N.z
|
||||
dd 05 28 6b 7c 00 fld qword [0x007c6b28] ; the constant
|
||||
d9 ff fcos
|
||||
de d9 fcompp ; cos(const) vs N.z
|
||||
df e0 fnstsw ax
|
||||
f6 c4 41 test ah, 0x41
|
||||
7a 0a jp +0x0a ; skip the friction load
|
||||
8b 86 bc 00 00 00 mov eax, [esi+0xbc] ; this->friction
|
||||
89 44 24 04 mov [esp+4], eax
|
||||
d9 44 24 04 fld dword [esp+4]
|
||||
```
|
||||
|
||||
`qword [0x007c6b28]` = **0.17453292519943295 = π/18 exactly** (verified by
|
||||
direct read at the mapped file offset). The binary genuinely executes `FCOS`
|
||||
at runtime — the compiler did not fold it — so the threshold retail compares
|
||||
against `N.z` is **cos(π/18 rad) = cos(10°) = 0.984807753...**.
|
||||
|
||||
## The verdict
|
||||
|
||||
- **The decomp was RIGHT. Our port is wrong.** `0.99999536f` is
|
||||
`cos(0.17453292519943295°)` — the *radian* literal read as *degrees* and
|
||||
run through a degree→radian cosine. A one-character-class unit slip that
|
||||
survived because nothing gates slope feel numerically.
|
||||
- **Felt consequence:** the branch means "on ground flatter than the
|
||||
threshold, use the object's own friction; on steeper ground (while slow —
|
||||
the `arg3 < 6.25` speed² gate at 0x0050ef46 guards this), keep the 0.2
|
||||
sliding friction." With our constant, "flat" requires < 0.175° — real
|
||||
terrain triangles essentially never qualify, so the object-friction arm of
|
||||
Sledding is unreachable in practice and slow movers keep sliding friction
|
||||
on gentle slopes retail treats as flat. Ice-feel in exactly the S4/S5
|
||||
slope-feel family.
|
||||
- **Fix shape (S5):** replace the constant with retail's semantics. Either
|
||||
the folded `0.98480775f` with a comment carrying this evidence, or the
|
||||
exact `MathF.Cos(MathF.PI / 18f)` computed once — prefer the folded
|
||||
constant + comment, matching how AP-7's 0.25f landed. Polarity must be
|
||||
ported from the `test ah,0x41; jp` idiom above, not assumed: the friction
|
||||
load is SKIPPED when the jump is taken (cos(10°) > N.z, i.e. steeper than
|
||||
10°, or unordered), and taken when N.z ≥ cos(10°). Verify our branch's
|
||||
existing polarity against this before changing only the constant.
|
||||
- The speed² gates in the same function — 1.5625 (= 1.25²) at 0x0050ef24 and
|
||||
6.25 (= 2.5²) at 0x0050ef46 — matched our port already at AP-7 and are
|
||||
untouched.
|
||||
|
||||
## Bookkeeping owed at the fix
|
||||
|
||||
Retire AD-55 (the row's open question is now answered against our constant);
|
||||
conformance test pinning `0.98480775f` + the ported polarity; S4/S5's
|
||||
slope-feel session covers the felt change. Until the fix lands, the register
|
||||
row stands corrected by this note.
|
||||
Loading…
Add table
Add a link
Reference in a new issue