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>
3.2 KiB
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):
- Sticky melee is a no-op (TS-39): ACE arms melee chases with
Sticky; retail's arrival hands off toPositionManager::StickTo→StickyManager::adjust_offset(0x00555430, per-tick 0.3 m gap + facing tracking). OurMoveToManager.StickTo/Unstickseams are unbound — attackers freeze at stale arrival poses. - Arrival radii are zero:
getOwnRadius: () => 0f(the R5-V3 pin inEnsureRemoteMotionBindings) +RouteServerMoveTonever setsMovementStruct.Radius/Height— retail/ACE arrive edge-to-edge with setup-derived radii (ACEPhysicsObj.MoveToObjectreads the TARGET's PartArray radius/height).
Do, in order:
- 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-checkreferences/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). - Bind
StickTo/UnStickinEnsureRemoteMotionBindingsAND the player wiring; wire PositionManager into the tick at the retail-matching points. - Thread real cylsphere radii (own from the entity's Setup; target resolved
at
RouteServerMoveTo's MoveToObject branch). Sweep remote + player. - Same-commit register bookkeeping: retire TS-39, update the radius pin.
- Extend
RemoteChaseEndToEndHarnessTestswith 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). dotnet build+ fulldotnet testgreen → 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).