acdream/tests/AcDream.Core.Tests
Erik dccd700991 feat(physics): R5-V5 — MovementManager facade owns each entity's interp+moveto pair
Structural capstone of the R5 movement-manager arc; zero behavior change.

Retail MovementManager (acclient.h /* 3463 */, 16 bytes / four pointers)
gives every CPhysicsObj ONE owner for its motion_interpreter +
moveto_manager. acdream carried them as loose per-entity objects wired by
hand at three sites. This slice:

- New src/AcDream.Core/Physics/Motion/MovementManager.cs — owns
  MotionInterpreter + lazy MoveToManager (MakeMoveToManager 0x00524000 via
  a MoveToFactory closure, the acdream stand-in for the physics_obj/
  weenie_obj backpointers) + the relays with retail call shapes:
  PerformMovement 0x005240d0 (types 1-5 -> minterp, 6-9 ->
  MakeMoveToManager + moveto, (type-1)>8 -> 0x47), UseTime 0x005242f0
  (moveto only), HitGround 0x00524300 (minterp FIRST then moveto),
  HandleExitWorld 0x00524350 (minterp only), CancelMoveTo 0x005241b0,
  HandleUpdateTarget 0x00524790, IsMovingTo 0x00524260.
- RemoteMotion.Movement + PlayerMovementController.Movement hold the ONE
  facade; Motion/MoveTo become child views so the comment-dense call sites
  read unchanged. The three wiring sites (EnsureRemoteMotionBindings,
  EnterPlayerModeNow, the chase harness — same commit per the mirror rule)
  construct through MoveToFactory + MakeMoveToManager(), preserving the
  pre-facade eager timing (side-effect-free ctor = unobservable either way).
- Relay call sites repointed: both remote landing HitGround pairs + the
  player landing pair, despawn HandleExitWorld, TickRemoteMoveTo + the
  player Update UseTime, RouteServerMoveTo (takes the facade; routes via
  the retail PerformMovement dispatch), InstallSpeculativeTurnToTarget,
  host HandleUpdateTarget/InterruptCurrentMovement closures (retail
  CPhysicsObj::HandleUpdateTarget @0x00512bf0 fan head + the TS-36
  interrupt chain, now the literal facade relays).
- NOT absorbed per the slice spec: unpack_movement stays App
  (RouteServerMoveTo + UM heads; Core.Net types stay out of Core.Physics);
  TS-42 per-tick order untouched (R6); #170/#171 gate-passed machinery
  untouched. PerformMovement's set_active(1) head not re-asserted (spawn
  asserts Active; status quo — no new register row).
- Register: TS-41/TS-42 source wording freshened to the facade shape;
  AD-36 retire note corrected (facade half closed; residue = entities
  that never get a RemoteMotion). No new rows.
- Conformance: 15 new MovementManagerTests pin the dispatch table, lazy
  create, relay targets/order, null tolerance. Suite 4052 green; the
  183-case/funnel/moveto/chase/sticky suites UNMODIFIED (harness
  construction mirrors production, test bodies untouched).

Decomp: docs/research/2026-07-03-r5-managers/r5-movementmanager-decomp.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 11:12:19 +02:00
..
Allegiance feat(allegiance): Phase H.2 AllegianceRequests + AllegianceTree model 2026-04-18 17:17:45 +02:00
Audio feat(audio): Phase E.2 OpenAL engine + SoundTable cookbook + hook wiring 2026-04-18 16:38:26 +02:00
Chat fix(chat): /help client-side handler + System dedup + ThatIsNotAValidCommand template 2026-04-25 21:22:07 +02:00
Combat fix(combat): #159 — derive CombatAnimationMotionCommands from the DRW enum 2026-07-04 09:08:11 +02:00
Conformance chore: strip throwaway dense-town FPS profiling apparatus (plan Task 5) 2026-06-24 00:10:00 +02:00
Fixtures feat(L.2g-S2a): CMotionInterp inbound funnel in Core + live-retail conformance harness (DEV-1 core) 2026-07-02 18:50:09 +02:00
Input fix(R4): #161 remote landing stuck in falling pose - apply-pass params decode 2026-07-03 17:00:03 +02:00
Items fix(D.2b): wield is ContainerId-based — drop the WielderId write (code review) 2026-06-22 22:15:18 +02:00
Lighting test(lighting): lock the bake contract on golden torches (A7 Fix D oracle) 2026-06-18 17:26:52 +02:00
Meshing fix(render): hide editor-only placement markers in dungeons — port retail's degrade-to-nothing (#136) 2026-06-14 19:03:08 +02:00
Physics feat(physics): R5-V5 — MovementManager facade owns each entity's interp+moveto pair 2026-07-05 11:12:19 +02:00
Player feat(player): #5 PlayerDescription parser — Stam/Mana via attribute block 2026-04-25 16:42:24 +02:00
Plugins feat(D.2b): IUiRegistry plugin UI surface + buffered drain into UiHost 2026-06-14 17:46:37 +02:00
Rendering refactor(physics #145): Slice 1 — rename Frame->CellFrame to avoid DatReaderWriter.Types.Frame collision 2026-06-21 10:34:36 +02:00
Selection test(picker): Cluster A #86 — screen-rect cell-occlusion tests 2026-05-19 14:56:51 +02:00
Spells fix(player): EnchantmentMask bit fix + Vitae key=0 + absolute Vitals overlay 2026-04-25 18:15:20 +02:00
Streaming fix(streaming): recover the player from the pending bucket — invisible-player / world-not-loading bug 2026-07-03 22:03:44 +02:00
Terrain fix #108-residual (root cause): terrain drew DOUBLE-SIDED - port retail landPolysDraw eye-side gate as terrain backface cull 2026-06-12 22:05:31 +02:00
Textures fix(textures): DecodeSolidColor null-safe against null ColorValue 2026-06-14 14:36:07 +02:00
Ui fix(retail): rotation rate, useability gate, retail toast strings 2026-05-16 12:17:54 +02:00
Vfx fix(vfx #56): ParticleHookSink applies CreateParticleHook.PartIndex transform 2026-05-11 23:57:20 +02:00
World feat(streaming): PhysicsDatBundle on LoadedLandblock (datLock fix scaffold) 2026-06-23 09:31:26 +02:00
AcDream.Core.Tests.csproj test: fix PhysicsResolveCapture/PhysicsDiagnostics static-leak isolation 2026-06-02 15:20:24 +02:00
SmokeTest.cs chore: phase 1 — add Core, Abstractions, App, Tests projects 2026-04-10 09:22:33 +02:00
xunit.runner.json test: fix PhysicsResolveCapture/PhysicsDiagnostics static-leak isolation 2026-06-02 15:20:24 +02:00