docs(issues): close #77 in ISSUES.md (closed by 3be7000)

Moves #77 from Active to Recently closed with the resolution writeup
(both halves — walk-vs-run misclassification + velocity-leak in
turn-in-place — plus the decomp anchors and verification record).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-18 09:34:54 +02:00
parent 3be700020b
commit 6c4f6be1b4

View file

@ -46,88 +46,6 @@ Copy this block when adding a new issue:
# Active issues # Active issues
## #77 — Auto-walk doesn't engage at walking range; pickup at walking range overshoots and snaps back
**Status:** OPEN
**Severity:** MEDIUM (M1-deferred polish; visible during normal play, doesn't block any phase)
**Filed:** 2026-05-16
**Component:** physics / auto-walk / `PlayerMovementController.DriveServerAutoWalk`
**Description:** Two related visual bugs observed during Step 2 (`0b25df5`)
visual verification at Holtburg. Both involve the close-range branch of
the server-driven auto-walk path (Phase B.6 / closed-issue #75 territory).
**Bug A — NPC at walking range never auto-walks:**
- User clicks on an NPC (e.g. Royal Guard `0x7A9B46AE`) when the player
is in "walking range" — far enough that retail would walk a short
distance, not close enough to immediately Use.
- The client's `WorldPicker` returns `WithinUseRadius=false`, so
`OnInputAction.UseSelected` defers the Use and would expect ACE's
`MoveToObject` to drive the player to the NPC.
- ACE sends back `UpdateMotion` with the auto-walk command — observed in
the log as `OnLiveMotionUpdated: guid=0x5000000A stance=0 cmd=0x0005
speed=-1.84` immediately after each `[B.4b] use guid=...` outbound.
- But the local player doesn't visibly move. Repeated clicks (the trace
shows seq 81 → 87 → 90 → 96 → 105 → 141 → 146 → 159 → 163 → 169 → 173
→ 177 against the same Royal Guard) produce the same response every
time without movement.
**Bug B — Pickup at walking range runs/overshoots/snaps back:**
- User presses F on a ground item while in "walking range" of it.
- Player RUNS (not walks) toward the target.
- Overshoots the item, then "blips back" to the correct position before
the pickup actually fires.
- The pickup completes (item ends up in inventory), but the visual is
jarring — clearly the walk/run threshold misclassifies the close-range
case, then ACE's position-correction snaps the player back.
**Root cause / status:** Unknown. Likely in one of:
- `PlayerMovementController.DriveServerAutoWalk` — engagement condition
(does it activate on negative speed? on cmd=0x0005?)
- Walk/run distance threshold (CLAUDE.md notes 1.0m as the corrected
threshold from Phase B.6, but the `runRate` / `cmd` derivation may
miscalculate at close range)
- Inbound `UpdateMotion` parser — the `speed=-1.84` is suspicious; if
retail sends the magnitude positive with direction encoded elsewhere,
the sign may be a sign-extension bug
**Step 2 refactor (`0b25df5`) is NOT a cause** — confirmed by diff scope:
`src/AcDream.App/Input/PlayerMovementController.cs`,
`src/AcDream.Core/Physics/PhysicsEngine.cs`, and
`src/AcDream.Core.Net/Messages/UpdateMotion.cs` were untouched. Both bugs
exist on the pre-Step-2 branch (eda936d / 32423c2 / main); the close
visual scrutiny during Step 2 verification just made them obvious.
**Trace evidence (from `launch.log` of task `b01zkw68w`, Step 2 verification):**
```
[B.4b] use guid=0x7A9B46AE seq=159 ← outbound Use
OnLiveMotionUpdated: guid=0x5000000A stance=61 cmd=0x speed= ← player → NonCombat
OnLiveMotionUpdated: guid=0x7A9B46AE stance=61 cmd=0x0003 speed= ← NPC turns to face
OnLiveMotionUpdated: guid=0x7A9B46AE stance=61 cmd=0x speed=
OnLiveMotionUpdated: guid=0x5000000A stance=0 cmd=0x0005 speed=-1.84 ← ACE's MoveToObject for player (NOT followed)
OnLiveMotionUpdated: guid=0x5000000A stance=0 cmd=0x speed=
```
**Files (where the investigation should start):**
- `src/AcDream.App/Input/PlayerMovementController.cs``DriveServerAutoWalk`,
walk/run threshold, runRate derivation
- `src/AcDream.Core.Net/Messages/UpdateMotion.cs` — speed sign-extension
- Phase B.6 spec: `docs/superpowers/specs/2026-05-14-phase-b6-design.md`
**Research:** Recommend an `ACDREAM_PROBE_AUTOWALK=1` trace run capturing
the player's body state every frame between Use-outbound and arrival,
correlated with the inbound `UpdateMotion`. The probe already exists in
`PhysicsDiagnostics` from Phase B.6 work — should produce the per-frame
evidence needed without a fresh investigation tool.
**Acceptance:**
- Click NPC at walking range → player walks (not runs) directly to NPC,
Use fires on arrival, NPC dialogue appears.
- Press F on ground item at walking range → player walks (not runs) the
short distance, no overshoot, no blip-back, item enters inventory.
---
## #76 — [DONE 2026-05-16 · `0b25df5`] LiveSessionController extraction (Step 2) regresses interaction + chat outbound ## #76 — [DONE 2026-05-16 · `0b25df5`] LiveSessionController extraction (Step 2) regresses interaction + chat outbound
**Status:** DONE **Status:** DONE
@ -2645,6 +2563,69 @@ Unverified. The likely culprits, ranked by suspected probability:
# Recently closed # Recently closed
## #77 — [DONE 2026-05-18 · 3be7000] Auto-walk doesn't engage at walking range; pickup at walking range overshoots and snaps back
**Closed:** 2026-05-18
**Commit:** `3be7000` — fix(physics): close #77 — auto-walk honors ACE CanCharge bit; zero velocity in turn-in-place
**Component:** physics / `PlayerMovementController` / `GameWindow.OnLiveMotionUpdated` / `CreateObject.ServerMotionState`
**Resolution.** Two coupled bugs sharing a root in
`PlayerMovementController.DriveServerAutoWalk` + `BeginServerAutoWalk`.
1. **Walk-vs-run misclassification (the user-visible "always runs at walk range" half).**
`BeginServerAutoWalk` decided `_autoWalkInitiallyRunning = (initialDist
distanceToObject) >= 1.0f`, forcing run at any chase past ~1.6 m.
ACE's wire-level walk-vs-run answer is the MovementParameters
**CanCharge** bit (0x10), which `Creature.SetWalkRunThreshold`
sets when server-side player→target distance ≥ `WalkRunThreshold/2`
(= 7.5 m default). Retail's `MovementParameters::get_command`
(decomp `0x0052aa00`, `acclient_2013_pseudo_c.txt:307946+`) gates
the run path on CanCharge first; the inner walk_run_threshold
check practically always walks given ACE's 15 m default. The
hardcoded 1.0 m threshold pushed run into the 3-5 m walk-range the
user reported should walk.
2. **Velocity leak in turn-in-place phase (the user-visible "overshoots
and snaps back" half).** When the auto-walked body crossed the
destination, `desiredYaw` flipped ~180°, `walkAligned` dropped to
false, and the `if (!moveForward) return true;` branch returned
without zeroing body velocity. The body kept the prior frame's
running velocity (`RunAnimSpeed × runRate ≈ 11 m/s`) and slid 4-5 m
past the target before the turn-around rotation completed.
**Changes:**
- `CreateObject.ServerMotionState.CanCharge`: new bool prop reading
bit 0x10 of `MoveToParameters`. Cross-ref ACE
`MovementParams.CanCharge = 0x10`.
- `PlayerMovementController.BeginServerAutoWalk`: replaces the unused
`walkRunThreshold` parameter with `bool canCharge`; sets
`_autoWalkInitiallyRunning = canCharge`.
- `PlayerMovementController.DriveServerAutoWalk` turn-in-place branch:
calls `_motion.DoMotion(Ready, 1.0)` and zeros body horizontal
velocity (preserving Z for gravity). No-op for initial-turn with a
stationary body; fixes overshoot-recovery and settling cases.
- `GameWindow.OnLiveMotionUpdated`: passes
`update.MotionState.CanCharge` through; `[autowalk-begin]` trace
now shows `canCharge=` instead of `walkRunThresh=`.
- `GameWindow.InstallSpeculativeTurnToTarget`: predicts ACE's
CanCharge from local distance using ACE's exact 7.5 m rule, so the
speculative install agrees with the wire-triggered overwrite that
arrives moments later.
**Verification.** Build green; all targeted test projects pass cleanly
(Core.Net 294/294, UI.Abstractions 419/419, App 10/10; Core 1073 passed
/ 8 pre-existing failures unchanged). Visual-verified at Holtburg
2026-05-18: walk-range NPC click walks + Use fires + dialogue appears,
walk-range F-key pickup walks + no overshoot + item enters inventory,
far-range pickup (8-10 m+) still runs.
**Lesson archived:** `memory/feedback_autowalk_cancharge_bit.md`. When
ACE already encodes a decision on the wire (CanCharge IS the walk-vs-run
answer), relay it — don't reinvent the bucket with a locally-computed
threshold.
---
## #56 — [DONE 2026-05-12 · 8735c39] `ParticleHookSink` ignores `CreateParticleHook.PartIndex`; multi-emitter scripts collapse to entity root ## #56 — [DONE 2026-05-12 · 8735c39] `ParticleHookSink` ignores `CreateParticleHook.PartIndex`; multi-emitter scripts collapse to entity root
**Closed:** 2026-05-12 **Closed:** 2026-05-12