acdream/docs/research/2026-05-16-session-handoff.md
Erik 5d79dd3b88 docs: session handoff 2026-05-16
Captures M1 landing, Phase B.6 architectural details, new rules
(no-workarounds, no-demo-videos, graceful-shutdown), M2 next steps,
and test baselines for fresh-session pickup.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 17:53:11 +02:00

5.9 KiB

Session handoff — 2026-05-16

What landed this session

M1 — "Walkable + clickable world" — LANDED on main at fb92122.

All four M1 demo targets work end-to-end retail-faithfully:

  1. Walk through Holtburg without getting stuck (L.2 collision)
  2. Open the inn door (B.4c)
  3. Click an NPC and see dialogue (B.4b + Phase B.6)
  4. Pick up an item from the ground (B.5 + Phase B.6)

Main branch history (newest first)

SHA Title
fb92122 milestone: M1 landed; flip "currently working toward" to M2
d640ed7 feat(retail): Phase B.6 — server-driven auto-walk done right
b5da17d feat(retail): Commit B — retail-faithful AP cadence + screen-rect picker
e2bc3a9 (base — docs(CLAUDE.md): document Ghidra MCP + WireMCP availability)

Phase B.6 (today's big landing) — what it actually did

Replaced the chain of Commit-B workarounds that compensated for ACE's MoveToChain getting cancelled by a leaked user-MoveToState packet during inbound auto-walk. The fix was architectural:

  • ApplyAutoWalkOverlay → DriveServerAutoWalk — auto-walk drives the body's velocity + motion state + animation cycle DIRECTLY from the wire-supplied path data. No player-input synthesis. Mirrors retail's MovementManager::PerformMovement case 6 (decomp 0x00524440) which never touches the user-input pipeline during server-controlled auto-walk.
  • Wire-layer guard retained at GameWindow.cs:6419 as a semantic statement (user-MoveToState packets are for user-driven motion intent), NOT as the band-aid the deleted 500ms grace period was.
  • Walk/run threshold = 1.0m (matches user-observed retail behaviour; ACE's wire-default 15.0f is ignored — overridden in BeginServerAutoWalk via const RetailWalkRunThresholdMeters). Formula from decomp 0x0052aa00 MovementParameters::get_command: running = (initialDist - distance_to_object) >= threshold, one-shot at chain start.
  • Animation cycle plumbed for moving-forward (RunForward/WalkForward) AND turn-first phase (TurnLeft/TurnRight via _autoWalkTurnDirectionThisFrame).
  • Pickup gate corrected to check BF_STUCK (acclient.h:6435, bit 0x4) — signs (pwd=0x14) blocked; spell components (pwd=0x10) allowed.
  • R-key dispatches by target type — creature → SendUse, pickupable → SendPickUp, useable → SendUse, else toast.
  • AP cadence reverted to retail's two-branch ShouldSendPositionEvent gate (acclient_2013_pseudo_c.txt:700233-700285). Effective rates: 0 Hz idle, ~1 Hz smooth motion, per-event on cell/plane changes, 0 Hz airborne. ApproxPlaneEqual helper added.

Issues closed: #63, #69, #74, #75. Full diff was 1316 insertions / 199 deletions across 6 files.

New rules / preferences captured this session

  1. No workarounds without explicit approval. CLAUDE.md "How to operate" section + feedback memory at memory/feedback_no_workarounds.md. Band-aids, grace periods, suppression flags, retry loops all forbidden unless the user explicitly approves or it's a deliberate new-feature design. User quote: "we should have no workarounds unless I say so or we want a different feature."

  2. No milestone demo videos. CLAUDE.md "milestone discipline" rule #3 + feedback memory at memory/feedback_no_demo_videos.md. Milestones land via text-only artifacts — pin a writeup in 2026-05-12-milestones.md, flip the freeze list, advance the CLAUDE.md "currently working toward" line. User quote: "pointless of recording videos, for what purpose?"

  3. Graceful client shutdown via CloseMainWindow. CLAUDE.md "Logout-before-reconnect" section. Stop-Process is a hard kill — leaves ACE's session marked logged-in for ~3+ min before timeout. The graceful path runs the client's shutdown hook so the logout packet reaches ACE.

M2 — "Kill a drudge" — the next milestone

Demo scenario: Equip a sword, walk to a drudge, swing, see damage in chat, watch the swing animation, drudge dies and drops loot, pick up the loot, open inventory and see it.

Phases in dependency order:

  1. L.1b — command router + motion-state cleanup (prereq for L.1c)
  2. L.1c — combat animation wiring (draw/sheath, attack swings by stance/power/height, hit reactions, evades)
  3. F.3 — combat math + damage flow (mostly ACE-side; client surfaces results)
  4. F.5a — visible-at-login dev panels (Attributes / Skills / Equipped / Inventory list, minimal ImGui surfaces, retail-skin deferred to M5)
  5. F.2 — polished Inventory panel reading ItemRepository (data already exists in F.2 base; M2 ships the visual surface)

First concrete step: L.1b scope. I haven't read L.1b's spec or roadmap entry — that's the first action of the next session.

Open issues worth tracking

After this session's closures, the M1-deferred / post-M1 backlog is:

  • #61 — AnimationSequencer link→cycle frame-0 flash on door swing. LOW (visual polish).
  • #64 — Local-player pickup animation does not render. LOW (observers see it).
  • #70 — Triangle apex/size DAT sprite. LOW (target indicator final polish).
  • #71 — WorldPicker Stage B polygon refine. LOW (Stage A sufficient).
  • #72 — cdb probe to confirm omega.z = π/2 base rate. LOW (research).
  • #73 — Retail-message centralization. Per-feature, ongoing.

None block M2. All M7 polish.

Test baseline

  • Core.Net: 294/294
  • Core: 1073/1081 (8 pre-existing Physics failures — BSPStepUp + MotionInterpreter; unchanged baseline)
  • Visual-verified end-to-end on 2026-05-16

Environment reminders

  • ACE running locally on 127.0.0.1:9000 (testaccount / testpassword / +Acdream at 0x5000000A).
  • DAT directory: %USERPROFILE%\Documents\Asheron's Call.
  • Worktree branch claude/vigilant-golick-9433e1 has the full 20-commit Phase B.6 history if you want to see how it got built; main has one squashed commit (d640ed7).
  • WorldBuilder submodule needs git submodule update --init references/WorldBuilder when working in a fresh worktree.