fix(motion): jump direction, AutoPos cadence, backward/strafe wire & anim
Closes a multi-bug knot in player motion outbound + remote inbound,
discovered via cdb live trace of retail (2026-05-01) and follow-up
visual verification.
Outbound (acdream → ACE):
- JumpAction velocity is BODY-LOCAL, not world (per retail
CPhysicsObj::get_local_physics_velocity at 0x00512140 + ACE
Player.HandleActionJump's set_local_velocity call). Was sending
world; observers saw jump rotated by player yaw.
- Capture get_jump_v_z BEFORE LeaveGround() — the latter resets
JumpExtent to 0, after which get_jump_v_z returned 0. Was sending
Z=0 in every JumpAction.
- Backward/strafe-left jumps lost their horizontal velocity because
LeaveGround → get_state_velocity returns zero for non-canonical
motion (faithful to retail's FUN_00528960; retail papers over via
adjust_motion translation, not yet ported). Compute the correct
body-local launch velocity from input directly and push it back
into the body so local prediction matches what we send.
- IsRunning HoldKey was gated on `input.Run && input.Forward`, so
strafe-run and backward-run incorrectly broadcast as walk to
observers — ACE then animated walk + dead-reckoned at walk speed
while server position moved at run speed (visible as observer
lag). Fixed: gate on any active directional axis.
- AutonomousPosition heartbeat 0.2s → 1.0s to match holtburger's
AUTONOMOUS_POSITION_HEARTBEAT_INTERVAL and the ~1Hz observed in
retail trace.
- Heartbeat now fires while in-world regardless of motion state
(matches holtburger + retail's transient_state-based gate, not
motion-based). Pre-fix the at-rest heartbeat was suppressed.
Inbound (ACE → acdream, remote retail player):
- Remote backward walk arrives as cmd=WalkForward + speed=-1.91
(retail's adjust_motion'd form). Two bugs were stacking:
1. AnimationSequencer fast-path returned without updating when
sign(speedMod) flipped while motion stayed equal — kept playing
forward at old positive framerate. Fixed: bypass fast-path on
sign change so the full re-setup runs.
2. GameWindow clamped negative speedMod to 1.0 when stuffing
InterpretedState.ForwardSpeed, making get_state_velocity
produce forward velocity. Fixed: pass speedMod through verbatim
so the dead-reckoning body translates backward.
Issue #38 filed: 30Hz physics tick produces a chase-camera smoothness
regression at 60+ FPS render. Standard render-time interpolation is
the recommended fix (separate phase).
Findings + comparison vs retail/holtburger:
docs/research/2026-05-01-retail-motion-trace/findings.md
docs/research/2026-05-01-retail-motion-trace/fixes.md
TODO: port retail's adjust_motion (FUN_00528010) properly so
get_state_velocity works for all directions natively — would let us
drop the workaround in PlayerMovementController jump path and the
clamp in GameWindow.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
09e013b7bd
commit
17a9ff1158
6 changed files with 691 additions and 22 deletions
|
|
@ -46,6 +46,74 @@ Copy this block when adding a new issue:
|
|||
|
||||
# Active issues
|
||||
|
||||
## #38 — Chase camera + player feel "30 fps" since L.5 physics-tick gate
|
||||
|
||||
**Status:** OPEN
|
||||
**Severity:** MEDIUM (gameplay-feel regression; not a correctness bug)
|
||||
**Filed:** 2026-05-01
|
||||
**Component:** rendering / physics / camera
|
||||
|
||||
**Description:** User reports that running around in third-person /
|
||||
chase camera feels less smooth than it did before the L.5 physics-tick
|
||||
work. FPS counter still reads 60+, but the *motion* of the player
|
||||
character + camera looks like it's updating at ~30 fps.
|
||||
|
||||
**Root cause / status:**
|
||||
|
||||
Almost certainly the L.5 `_physicsAccum` gate in
|
||||
`PlayerMovementController.cs` (lines ~448-456). Retail integrates
|
||||
physics at 30 Hz (`MinQuantum = 1/30 s`); we ported that faithfully so
|
||||
collision behavior matches. Side effect: `_body.Position` only updates
|
||||
on physics ticks, i.e. every 33 ms. Render runs at 60+ Hz but the
|
||||
chase camera follows `_body.Position` directly — so the *visible*
|
||||
position changes in 33 ms steps, even though we render at 60+ FPS.
|
||||
First-person is less affected because the world rotates with Yaw (which
|
||||
*does* update every render frame); third-person is hit hardest because
|
||||
the character itself is the moving thing.
|
||||
|
||||
Retail in 2013 didn't see this because render was also ~30 fps —
|
||||
render rate ≈ physics rate. Our 60+ Hz render exposes the gap.
|
||||
|
||||
Discussion + fix options at the end of `docs/research/2026-05-01-retail-motion-trace/findings.md`
|
||||
("Other things still don't have…" → camera smoothness discussion in
|
||||
chat, not yet captured in the doc — TODO migrate the discussion in).
|
||||
|
||||
Recommended fix: **render-time interpolation between physics ticks**
|
||||
(standard fixed-timestep + interpolated rendering pattern from Quake /
|
||||
Source / Unreal). Snapshot `_prevPhysicsPos` and `_currPhysicsPos` at
|
||||
each tick; render player + camera target at
|
||||
`Lerp(_prev, _curr, _physicsAccum / PhysicsTick)`. Cost: ~33 ms visual
|
||||
latency between input and what you see (matches retail's perceived
|
||||
latency anyway). Network outbound stays on the discrete tick value —
|
||||
no wire change.
|
||||
|
||||
Quick confirmation test before any code change: temporarily set
|
||||
`PhysicsTick` to `1.0/60.0` and see if chase camera feels smooth again.
|
||||
If yes, gate is confirmed cause. (Don't ship that — it'd undo the L.5
|
||||
collision fixes.)
|
||||
|
||||
**Files:**
|
||||
|
||||
- `src/AcDream.App/Input/PlayerMovementController.cs:172` — `PhysicsTick` constant
|
||||
- `src/AcDream.App/Input/PlayerMovementController.cs:448-456` — `_physicsAccum` gate
|
||||
- `src/AcDream.App/Rendering/GameWindow.cs` — wherever player render position + chase camera read `_body.Position`
|
||||
|
||||
**Research:**
|
||||
|
||||
- L.5 background: `memory/project_retail_debugger.md` (the 30 Hz
|
||||
MinQuantum gate, the cdb trace evidence)
|
||||
- Discussed during 2026-05-01 motion-trace work
|
||||
|
||||
**Acceptance:**
|
||||
|
||||
- Chase-camera run-around at 60+ FPS feels as smooth as render rate
|
||||
suggests (no perceptual stepping)
|
||||
- Network outbound (MoveToState / AutonomousPosition cadence + values)
|
||||
unchanged from current behavior
|
||||
- Collision behavior unchanged (the L.5 wedge / steep-roof scenarios
|
||||
still resolve correctly)
|
||||
- Observer view from a parallel retail client unchanged
|
||||
|
||||
## #37 — Humanoid coat doesn't extend up to neck (visible "skin stub" between hair and coat)
|
||||
|
||||
**Status:** OPEN
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue