fix(gameplay): reconcile wield ownership and target facing

Preserve PlayerDescription inventory/equipment ownership across authoritative manifest replacement, make weapon switching and combat/UI consumers read the same canonical object state, and carry the complete outbound player position frame across landblocks.

Route target-facing and mouse-look through the shared MovementManager and MotionInterpreter completion owner. Match retail input aggregation, toggle ordering, turn/sidestep remapping, per-axis hold keys, and synchronous movement publication without render-only heading state.

Initialize the live streaming origin from the first accepted canonical player Position, defer other projections until that origin exists, and retain logical entity identity through hydration.

Advance the project ledger from completed M2 to active M3, synchronize CLAUDE.md/AGENTS.md and durable memory, and record the next cast-lifecycle, spellbook/enchantment, and two-client portal gates.

Co-Authored-By: Codex <noreply@openai.com>
This commit is contained in:
Erik 2026-07-15 08:19:23 +02:00
parent b26f84cc69
commit 7b7ffcd278
36 changed files with 3884 additions and 761 deletions

View file

@ -46,7 +46,7 @@ Copy this block when adding a new issue:
## #217 — Character windows did not receive live 64-bit experience updates
**Status:** IN-PROGRESS — implementation complete; connected visual gate pending
**Status:** DONE — 2026-07-13, connected gate user-confirmed
**Severity:** HIGH
**Filed:** 2026-07-13
**Component:** retained UI / character sheet / net / player state
@ -79,6 +79,9 @@ the value element `0x10000235` is explicitly right-aligned.
right-aligned total and red progress fill; Skills immediately shows the same
server-authoritative unassigned XP available for raises.
**Gate:** Passed in the starter-dungeon item-giving session: earned XP,
right-aligned Total Experience/progress, and Unassigned Experience all updated.
---
## #213 — Retail client commands were sent to ACE as chat text
@ -184,18 +187,19 @@ the combat button and grave key briefly selected Melee before ACE restored
NonCombat, so the character could not enter combat.
**Root cause:** PlayerDescription recorded equipped entries with their equip
mask but no player ownership/container index. Live WieldObject updates did
index the same item under the player. `ToggleLiveCombatMode` reads the player's
ordered contents for retail `GetObjectAtLocation`, so it missed login equipment,
defaulted to Melee, and sent a mode incompatible with ACE's equipped missile
weapon. ACE correctly returned authoritative NonCombat.
mask but no player ownership/container index. The combat-mode lookup therefore
missed login equipment, defaulted to Melee, and sent a mode incompatible with
ACE's equipped missile weapon. ACE correctly returned authoritative NonCombat.
**Resolution:** PlayerDescription equipment now uses the same
contained-by-wielder projection as live WieldObject while preserving its wire
order, equip mask, and layering priority. The production combat planner now
selects Missile for the login-equipped crossbow. The connected gate completed
NonCombat → Missile → NonCombat → Missile, including a Jump press, without a
server rejection.
**Resolution:** PlayerDescription preserves login equipment ownership and the
production combat planner selects Missile for the login-equipped crossbow. A
2026-07-14 retail-conformance refinement also corrected live WieldObject: its
payload is exactly `(itemGuid, equipLocation)`, and confirmation produces
`ContainerId=0`, `WielderId=player`. Equipment consumers now use
`GetEquippedBy`, which unifies that authoritative state with the temporary
optimistic pre-confirm projection instead of treating equipment as backpack
contents. The connected gate completed NonCombat → Missile → NonCombat →
Missile, including a Jump press, without a server rejection.
**Research:** `docs/research/2026-07-11-combat-default-and-parent-event-pseudocode.md`