fix(physics): AD-55 retired — Sledding fast-sled constant is cos(10 deg)

Per docs/research/2026-07-30-ts4-116-oracle-plan.md Addendum (byte-proven
2026-07-30). Raw bytes of CPhysicsObj::calc_friction @ 0x0050ee70's
Sledding fast-sled branch (0x0050ef52-0x0050ef6a):

  d9 86 38 01 00 00   fld  dword [esi+0x138]    ; contact_plane.Normal.Z
  dd 05 28 6b 7c 00   fld  qword [0x007c6b28]   ; = 0.17453292519943295 (10 deg RADIANS)
  d9 ff               fcos                       ; st0 = cos(10 deg) = 0.984807753
  de d9               fcompp

confirm a genuine fcos opcode over a real 10-degrees-in-radians double
literal -- not a BN misdecompile of a raw float load. Retail truly
computes cos(10 deg) ~ 0.9848078 at runtime; ACE's 0.99999536f equals
cos(0.1745 DEGREES) -- the same radian literal evaluated in degree mode,
a proven ACE porting error carried into this port provisionally.

PhysicsBody.calc_friction's Sledding near-flat override now compares
GroundNormal.Z > 0.98480775f (cos 10 deg). Feel impact: retail's 0.2f
fast-sled friction override engages on any ground within 10 degrees of
flat; the old constant engaged only within ~0.175 degrees (never, in
practice).

Tests: two new boundary pins
(calc_friction_sledding_fast_override_engages_at_5_degrees_from_flat /
..._does_not_engage_at_15_degrees_from_flat) construct a tilted
GroundNormal with velocity purely orthogonal to the tilt plane (dot=0
exactly, isolating the Sledding-band friction value from the outer 0.25f
gate and the normal-removal step) and assert the exact pow(1-friction, dt)
decay on each side of the new 10-degree boundary.

Register: AD-55 retired (struck through, retirement note with the byte
decode).

Full AcDream.Core.Tests suite: 4063 passed / 1 skipped, no regressions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-07-30 12:56:26 +02:00
parent 0149220506
commit 252e806804
3 changed files with 75 additions and 14 deletions

View file

@ -642,17 +642,24 @@ public sealed class PhysicsBody
/// GroundedRootMotion_FrictionThreshold_DoesNotHammerLocomotionTests for
/// the regression pin on the root-motion path specifically.
///
/// ⚠️ Constant discrepancy (Ghidra-verify, NOT resolved this pass): the
/// raw decomp's Sledding slope-flatness test literally computes
/// __fcos(0.17453292519943295) (= cos(10°) ≈ 0.984808) and compares
/// against contact_plane.N.z; ACE's port instead compares
/// ContactPlane.Normal.Z &gt; 0.99999536f directly (≈0.175° from flat, NOT
/// 10°) — physically very different tests. Neither hypothesis (a BN
/// misdecompile of a raw float load as __fcos, vs. an independent ACE
/// port error) is confirmed; a live Ghidra decompile of 0050ee70 settles
/// it. 0.99999536f is kept provisionally (least churn — it's what
/// acdream's own prior dead code already had); do not silently resolve
/// this without the Ghidra check. See register row AD-55.
/// AD-55 RESOLVED (Campaign P final physics slice, 2026-07-30; byte
/// decode in docs/research/2026-07-30-ts4-116-oracle-plan.md Addendum).
/// Raw bytes of <c>CPhysicsObj::calc_friction @ 0x0050ee70</c>'s
/// Sledding fast-sled branch (0x0050ef52-0x0050ef6a):
/// <code>
/// d9 86 38 01 00 00 fld dword [esi+0x138] ; contact_plane.Normal.Z
/// dd 05 28 6b 7c 00 fld qword [0x007c6b28] ; = 0.17453292519943295 (10 deg in RADIANS)
/// d9 ff fcos ; st0 = cos(10 deg) = 0.984807753
/// de d9 fcompp
/// </code>
/// This is a genuine <c>fcos</c> opcode over a real 10°-in-radians
/// double literal — not a BN misdecompile of a raw float load. Retail
/// truly computes <c>cos(10°) ≈ 0.9848078</c> at runtime and compares
/// <c>Normal.Z</c> against it. ACE's <c>0.99999536f</c> equals
/// <c>cos(0.1745 DEGREES)</c> — the same radian literal evaluated in
/// degree mode, a proven ACE porting error, not a BN artifact.
/// Replaced with the byte-confirmed <c>0.98480775f</c> (cos 10°).
/// Register row AD-55 retired in the same commit.
/// </summary>
public void calc_friction(float dt, float velocityMag2)
{
@ -674,7 +681,7 @@ public sealed class PhysicsBody
{
if (velocityMag2 < 1.5625f) // 1.25² — slow sled
friction = 1.0f;
else if (velocityMag2 >= 6.25f && GroundNormal.Z > 0.99999536f) // near-flat, Ghidra-verify (see doc comment)
else if (velocityMag2 >= 6.25f && GroundNormal.Z > 0.98480775f) // cos(10°), byte-confirmed (AD-55, see doc comment)
friction = 0.2f;
}