The Sledding constant has been the byte-confirmed cos(10 deg) = 0.98480775f in production since252e8068(2026-07-30), which also struck the register row. Five hours latera8a7d64b— reverting the UNRELATED TS-4 commit5e2be19b— restored this file's older hunk and resurrected the un-struck row text while leaving the code fixed. The zombie row then cost tonight's session a full duplicate byte-derivation: the stale row said 0.99999536f was live, so the binary was re-read to prove what 252e8068's own commit message already contained verbatim. Tonight's derivation note is corrected to what it actually is — an independent confirmation of the week-old fix — and S5 collapses to this bookkeeping: no code change, no feel gate owed; the user has been playing on the fixed constant for a week. Process rule filed to memory (feedback_register_revert_resurrection): after any revert whose diff touches the register, re-verify EVERY row in the touched hunks; and before acting on a row's 'our code does X' claim, grep the cited file for the claimed expression first. AD section 51 -> 50 active rows. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
80 lines
4.2 KiB
Markdown
80 lines
4.2 KiB
Markdown
# AD-55 byte-decode — independent confirmation of a fix that already shipped (VERDICT CORRECTED)
|
|
|
|
**CORRECTION, same night:** this note's original verdict — "our port is wrong"
|
|
— was STALE. The production code has carried the byte-confirmed `0.98480775f`
|
|
since `252e8068` (2026-07-30), whose commit message contains this exact
|
|
instruction listing. The register row was retired in that commit and then
|
|
**resurrected by `a8a7d64b`**, a revert of the unrelated TS-4 commit whose
|
|
register hunk restored the older row text. This note's derivation was
|
|
performed against that zombie row; it stands as an INDEPENDENT confirmation
|
|
of the 2026-07-30 result (identical bytes, identical constant, identical
|
|
conclusion) and as the measured cost of a register row surviving its own
|
|
retirement. No code change is needed; no feel gate is owed — the user has
|
|
been playing on the fixed constant for a week.
|
|
|
|
*Original note below, its evidence valid, its verdict superseded.*
|
|
|
|
**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.
|