refactor(runtime): own local movement and outbound cadence

Move the canonical local movement controller, body/motion managers, object clock, movement wire data, and MTS/jump/AP sender into AcDream.Runtime. Replace process skill defaults with typed Runtime character options, make graphical and direct commands borrow one autorun owner, retain the construction-time PartArray seam, and include movement in terminal ownership convergence.

Preserve the accepted pre-inbound movement/jump and post-inbound autonomous-position order while moving the exact packet/cadence fixtures into Runtime tests. Add graphical/direct parity, two-instance isolation, teardown, allocation, architecture, and divergence-path coverage.

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Erik 2026-07-26 12:33:53 +02:00
parent 3456dff038
commit aa3f4a60f8
36 changed files with 878 additions and 276 deletions

View file

@ -9,13 +9,15 @@ namespace AcDream.Runtime.Tests.Gameplay;
public sealed class RuntimeGameplayOwnershipTests
{
[Fact]
public void CombinedLedgerConvergesEveryJ4OwnerAndSubscription()
public void CombinedLedgerConvergesEveryGameplayOwnerAndSubscription()
{
using var entities = new RuntimeEntityObjectLifetime();
var inventory = new RuntimeInventoryState(entities);
var character = new RuntimeCharacterState();
var communication = new RuntimeCommunicationState();
var actions = RuntimeActionTestFactory.Create(inventory.Transactions);
var movement = new RuntimeLocalPlayerMovementState();
movement.Execute(RuntimeMovementCommand.ToggleRunLock);
inventory.Shortcuts.Changed += static () => { };
inventory.Shortcuts.Load([new ShortcutEntry(1, 2u, 3u)]);
inventory.ItemMana.OnQueryItemManaResponse(2u, 0.5f, true);
@ -73,7 +75,8 @@ public sealed class RuntimeGameplayOwnershipTests
inventory,
character,
communication,
actions);
actions,
movement);
Assert.False(populated.IsConverged);
Assert.Equal(1, populated.Inventory.ShortcutCount);
@ -86,7 +89,9 @@ public sealed class RuntimeGameplayOwnershipTests
AcDream.Core.Combat.CombatMode.Melee,
populated.Actions.CombatMode);
Assert.Equal(1, populated.Actions.TrackedTargetHealthCount);
Assert.True(populated.Movement.AutoRunActive);
movement.Dispose();
actions.Dispose();
communication.Dispose();
character.Dispose();
@ -98,7 +103,8 @@ public sealed class RuntimeGameplayOwnershipTests
inventory,
character,
communication,
actions);
actions,
movement);
Assert.True(retired.IsConverged);
Assert.Equal(0, retired.Inventory.ShortcutSubscriberCount);
@ -108,13 +114,14 @@ public sealed class RuntimeGameplayOwnershipTests
}
[Fact]
public void BorrowerFailuresCannotStrandAnyJ4OwnerDuringTerminalDisposal()
public void BorrowerFailuresCannotStrandAnyGameplayOwnerDuringTerminalDisposal()
{
using var entities = new RuntimeEntityObjectLifetime();
var inventory = new RuntimeInventoryState(entities);
var character = new RuntimeCharacterState();
var communication = new RuntimeCommunicationState();
var actions = RuntimeActionTestFactory.Create(inventory.Transactions);
var movement = new RuntimeLocalPlayerMovementState();
inventory.ExternalContainers.RequestOpen(0x70000001u);
inventory.ExternalContainers.ApplyViewContents(0x70000001u);
@ -132,6 +139,7 @@ public sealed class RuntimeGameplayOwnershipTests
communication.Chat.OnSystemMessage("failure-isolated event", 0u);
Assert.Equal(1, communication.DispatchFailureCount);
movement.Dispose();
actions.Dispose();
Assert.Throws<AggregateException>(inventory.Dispose);
Assert.Throws<AggregateException>(character.Dispose);
@ -142,7 +150,8 @@ public sealed class RuntimeGameplayOwnershipTests
inventory,
character,
communication,
actions);
actions,
movement);
Assert.True(retired.IsConverged);
Assert.Equal(1, retired.Communication.DispatchFailureCount);