docs(physics): L.3c attempt — friction threshold investigation, deferred

Tried bumping calc_friction's gate from `dot >= 0f` to `dot >= 0.25f`
per retail acclient_2013_pseudo_c.txt:276705. Build green but
PlayerMovementControllerTests immediately showed forward motion
dropping from ~3m to ~0.16m over a 1-second simulated walk —
friction now hammers active locomotion in our architecture.

Root cause is deeper than a single threshold. Retail line 276702 has
a state-flag check (`(this->state & ...) == 0`) gating the friction
block that the decompile renders as a corrupted string and we didn't
fully characterize. Best read: retail skips this friction block while
locomotion is actively driving velocity, applying it only to residual
motion after locomotion stops. acdream's controller sets velocity
once per frame from input, then UpdatePhysicsInternal substeps friction
through it — at 0.25 threshold the substep compounding eats most of
the velocity before integration completes.

Reverting to the previous behavior (0.0 threshold). Filing the proper
investigation as L.3c-followup: needs to read retail's `(this->state &
...)` flag at acclient_2013_pseudo_c.txt:276702, identify whether
it gates on an active-locomotion bit, and either honor that gate or
restructure acdream's per-frame locomotion → integration ordering so
friction fires only on residual velocity.

Tests: 1491 still pass after revert.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-04-30 09:46:42 +02:00
parent 851e88364d
commit 1abb699c68

View file

@ -280,6 +280,16 @@ public sealed class PhysicsBody
///
/// Cross-checked with ACE PhysicsObj.calc_friction which uses 0.25f as
/// the threshold instead; the decompile uses 0.0. We match the decompile.
///
/// L.3c attempt (2026-04-30, REVERTED): tried bumping to 0.25f per
/// retail acclient_2013_pseudo_c.txt:276705. Build green but
/// PlayerMovementControllerTests showed forward locomotion dropping
/// from ~3m/s to ~0.16m/s — friction now hammers normal walking.
/// Retail's friction block is gated by an additional state check at
/// line 276702 (`(this->state & ...) == 0`) that we didn't decode
/// fully; locomotion is probably skipped from the friction path
/// while actively walking. Filed as L.3c-followup; keeping the
/// matching-the-decompile-as-read 0.0 threshold for now.
/// </summary>
public void calc_friction(float dt, float velocityMag2)
{