User report during the #170 gate: pack-melee monsters partly inside each other with slightly stale facings vs retail on the same ACE. Investigation (report-only) pinned two code-grounded causes, both already-tracked R5-V3 scope, fix APPROVED by the user: 1. TS-39 — sticky melee is a no-op: ACE arms melee chases with Sticky (Monster_Navigation.cs:416); retail's arrival hands off to PositionManager::StickTo -> StickyManager::adjust_offset (0x00555430, per-tick 0.3m edge gap + facing tracking); acdream's StickTo/Unstick seams are unbound so attackers freeze at stale arrival poses. 2. Arrival radii are zero: getOwnRadius () => 0f (the R5-V3 pin) and RouteServerMoveTo never sets MovementStruct.Radius/Height — retail/ACE arrive edge-to-edge with setup-derived radii (ACE PhysicsObj.MoveToObject reads the TARGET's PartArray radius/height). Ruled out: the between-snap collision sweep (remotes run full ResolveWithTransition; CollisionExemption keeps creatures collidable). Caveat recorded: ACE has no server-side monster avoidance — acceptance is retail PARITY, not zero overlap. ISSUES #171 filed; handoff docs/research/2026-07-04-171-sticky-melee-handoff.md + pickup docs/research/2026-07-04-171-pickup-prompt.md; memory index updated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
52 lines
3.2 KiB
Markdown
52 lines
3.2 KiB
Markdown
# Pickup prompt — #171 sticky melee / R5-V3 (paste into a fresh session)
|
|
|
|
Read `docs/research/2026-07-04-171-sticky-melee-handoff.md` first — it is the
|
|
SSOT for this task (root causes, retail anchors, approved scope, gotchas).
|
|
Then implement R5-V3.
|
|
|
|
**Context:** #170 (chase slide) is CLOSED — gate passed at `4cad626f`; do not
|
|
reopen that machinery. During its gate the user observed #171: in a pack
|
|
melee, monsters sit partly inside each other with slightly stale facings vs
|
|
retail on the same ACE. Investigated + **fix approved by the user 2026-07-04**.
|
|
|
|
**The two causes (both R5-V3 scope, already register-tracked):**
|
|
1. Sticky melee is a no-op (TS-39): ACE arms melee chases with `Sticky`;
|
|
retail's arrival hands off to `PositionManager::StickTo` →
|
|
`StickyManager::adjust_offset` (0x00555430, per-tick 0.3 m gap + facing
|
|
tracking). Our `MoveToManager.StickTo`/`Unstick` seams are unbound —
|
|
attackers freeze at stale arrival poses.
|
|
2. Arrival radii are zero: `getOwnRadius: () => 0f` (the R5-V3 pin in
|
|
`EnsureRemoteMotionBindings`) + `RouteServerMoveTo` never sets
|
|
`MovementStruct.Radius/Height` — retail/ACE arrive edge-to-edge with
|
|
setup-derived radii (ACE `PhysicsObj.MoveToObject` reads the TARGET's
|
|
PartArray radius/height).
|
|
|
|
**Do, in order:**
|
|
1. Grep the named decomp for `StickyManager::` + `PositionManager::` bodies
|
|
(adjust_offset 0x00555430; per-tick anchors already pinned:
|
|
`PositionManager::adjust_offset` @0x00512d0e inside UpdatePositionInternal,
|
|
`PositionManager::UseTime` @0x005159b3 in UpdateObjectInternal).
|
|
Pseudocode, then port verbatim; cross-check
|
|
`references/ACE/Source/ACE.Server/Physics/Managers/{StickyManager,PositionManager}.cs`.
|
|
Groundwork already in tree: `MoveToMath.CylinderDistanceNoZ` /
|
|
`GlobalToLocalVec` / `NormalizeCheckSmall`; `ConstraintManager` (R5-V1) is
|
|
the port-style reference. Do NOT arm ConstraintManager (#167 separate).
|
|
2. Bind `StickTo`/`UnStick` in `EnsureRemoteMotionBindings` AND the player
|
|
wiring; wire PositionManager into the tick at the retail-matching points.
|
|
3. Thread real cylsphere radii (own from the entity's Setup; target resolved
|
|
at `RouteServerMoveTo`'s MoveToObject branch). Sweep remote + player.
|
|
4. Same-commit register bookkeeping: retire TS-39, update the radius pin.
|
|
5. Extend `RemoteChaseEndToEndHarnessTests` with a sticky scenario (arrive →
|
|
target strafes → follower tracks gap + facing; UnStick on next
|
|
PerformMovement). Harness bodies MUST mirror the live RemoteMotion
|
|
construction (InWorld=true, RemoteWeenie — see RemoteChaseDrainBisectTests).
|
|
6. `dotnet build` + full `dotnet test` green → commit → launch for the user's
|
|
visual gate: pack melee side-by-side vs retail, strafe around the pack;
|
|
attackers should reshuffle + keep facing like retail. Acceptance is retail
|
|
PARITY — some overlap is ACE-server-side and shows on retail too.
|
|
|
|
**Gotchas:** revert-prone remote-motion area — verbatim port, no redesign;
|
|
per-entity probes must print the guid (memory
|
|
`feedback_probe_identity_attribution`); PowerShell Tee logs are UTF-16
|
|
(`tr -d '\000'` before grep); the user manages client lifecycle (graceful
|
|
close); both clients hit the same local ACE (127.0.0.1:9000).
|