refactor(physics): delete legacy PhysicsEngine.Resolve/ResolvePlacement/HasCellSurface (C5a, AP-1/AD-1)
Member-wise deletion of the three legacy resolver members named in docs/research/2026-08-05-c5a-contract.md: PhysicsEngine.Resolve, PhysicsEngine.HasCellSurface, and PhysicsEngine.ResolvePlacement. An exhaustive receiver census over src/ found zero production callers of any of the three — every production placement writer already reaches the canonical PhysicsEngine.SetPosition transaction exclusively through RuntimeSetPositionState (three call sites total). The deletion is purely member-wise: IsSpawnCellReady and AdjustPosition, which shared the same source region as the deleted members, are preserved byte-identical — every remaining production caller of either (including PhysicsCameraCollisionProbe, AdjustPosition's sole surviving production caller) is unaffected. Companion changes: - PlayerMovementController's 3-argument SetPosition test overload is renamed to SeedPlacementForTest (internal) and CommitPreparedPosition is deleted; 83 call sites across 19 test files were mechanically renamed to match. - Seven pinned test dispositions from the contract are executed: 3.1 (PhysicsEngineTests.cs: 11 legacy-resolver tests deleted, 6 ResolveWithTransition tests kept), 3.2/3.3/3.4 (re-point to canonical SetPosition, with TransitionScratchDifferentialTests.cs additionally gaining positive IsCommitted assertions after each bitwise comparison so the differential proves a placement actually committed, not just that two possibly-uncommitted results match), 3.5 (Runtime rename), and 3.6 (PlayerMovementPlacementTransactionTests.cs rewritten — its xmldoc now states plainly that the render-root publish moved to RuntimeSetPositionState.cs, but the sticky-release relocation claim was false and is retracted; this disposition's coverage loss is the sticky release path, not silently absorbed elsewhere). - Stale `PhysicsEngine.Resolve`/`Resolve` doc citations in CellTransit.cs, PlayerMovementController.cs, and HeadlessSessionWorldProjection.cs are corrected to name the surviving canonical entry points by symbol (SetPosition, AdjustSetPosition/AdjustPosition, ResolveWithTransition) rather than fragile line numbers. Retires AP-1 and AD-1 in docs/architecture/retail-divergence-register.md: both rows described production zero-delta placement routing remaining on the legacy resolver pending the Slice 4B2/4B route cutover; that resolver no longer exists, so the condition each row tracked is now structurally false rather than merely narrowed. AP-145 (routed through the prior commit) and this commit's AP-1/AD-1 together bring the section counts to 101 AP / 47 AD active rows. Builds on the AP-145 fix (previous commit) — this commit's staged tree was independently rebuilt and its four suites independently rerun on top of that commit before this commit was created, in addition to the combined rebuild/rerun below. Full-solution build: 0 errors (21 pre-existing warnings, all unrelated). Suite results (combined tree): Core 4270/4271 passed (1 skip; the single DatSoundCacheTests concurrent-decode-dedup failure is a known load-sensitive race, confirmed passing standalone and unrelated to this change), Runtime 1176/1176, Headless 86/86, App 4132/4135 (3 skips). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
f8e55ba5e4
commit
6921a02744
34 changed files with 508 additions and 946 deletions
|
|
@ -15,7 +15,7 @@ public sealed class LocalPlayerProjectionControllerTests
|
|||
Quaternion.CreateFromAxisAngle(Vector3.UnitX, 0.7f)
|
||||
* Quaternion.CreateFromAxisAngle(Vector3.UnitY, -0.4f));
|
||||
var movement = new PlayerMovementController(new PhysicsEngine());
|
||||
movement.SetPosition(Vector3.Zero, cellId, Vector3.Zero);
|
||||
movement.SeedPlacementForTest(Vector3.Zero, cellId, Vector3.Zero);
|
||||
movement.SetBodyOrientation(complete);
|
||||
var entity = new WorldEntity
|
||||
{
|
||||
|
|
@ -53,7 +53,7 @@ public sealed class LocalPlayerProjectionControllerTests
|
|||
{
|
||||
const uint cellId = 0x02020001u;
|
||||
var movement = new PlayerMovementController(new PhysicsEngine());
|
||||
movement.SetPosition(new Vector3(12f, 8f, 3f), cellId, Vector3.Zero);
|
||||
movement.SeedPlacementForTest(new Vector3(12f, 8f, 3f), cellId, Vector3.Zero);
|
||||
var entity = new WorldEntity
|
||||
{
|
||||
Id = 8u,
|
||||
|
|
@ -88,7 +88,7 @@ public sealed class LocalPlayerProjectionControllerTests
|
|||
{
|
||||
const uint cellId = 0x02020001u;
|
||||
var movement = new PlayerMovementController(new PhysicsEngine());
|
||||
movement.SetPosition(new Vector3(12f, 8f, 3f), cellId, Vector3.Zero);
|
||||
movement.SeedPlacementForTest(new Vector3(12f, 8f, 3f), cellId, Vector3.Zero);
|
||||
var entity = new WorldEntity
|
||||
{
|
||||
Id = 9u,
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ public sealed class MouseLookControllerTests
|
|||
worldOffsetX: 0f,
|
||||
worldOffsetY: 0f);
|
||||
var controller = new PlayerMovementController(engine);
|
||||
controller.SetPosition(new Vector3(96f, 96f, 50f), 0x0001u);
|
||||
controller.SeedPlacementForTest(new Vector3(96f, 96f, 50f), 0x0001u, new Vector3(96f, 96f, 50f));
|
||||
return controller;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,8 +15,47 @@ public sealed class PlayerMovementPlacementTransactionTests
|
|||
private const uint PriorCell = 0x0101_0101u;
|
||||
private const uint DestinationCell = 0x0101_0102u;
|
||||
|
||||
/// <summary>
|
||||
/// C5a (2026-08-05) re-point: <c>PlayerMovementController.CommitPreparedPosition</c>
|
||||
/// is deleted (zero production callers — production placement now arms
|
||||
/// the login-entry leash via <c>ArmConstraintLeashAtCommittedPlacement</c>,
|
||||
/// called from <c>RuntimeLocalPlayerPhysicsPublicationState.ArmFirstEntryConstraintLeash</c>
|
||||
/// AFTER <c>RuntimeSetPositionState.TryApplyDormantLocalActivationFinalCommit</c>
|
||||
/// has already published the shared current cell — see that method's
|
||||
/// doc comment). Architecture-review correction (A5, 2026-08-05): the two
|
||||
/// deleted invariants did NOT relocate symmetrically.
|
||||
/// <b>Render-root publish DID move</b> — it happens inside
|
||||
/// <c>RuntimeSetPositionState.TryApplyDormantLocalActivationFinalCommit</c>
|
||||
/// itself, via <c>_physics.Engine.UpdatePlayerCurrCell(result.CellId)</c>
|
||||
/// (<c>RuntimeSetPositionState.cs:2774</c>).
|
||||
/// <b>Sticky-target release did NOT move anywhere</b> — <c>grep -rn
|
||||
/// "UnStick" src/AcDream.Runtime/</c> returns zero call sites on this
|
||||
/// path; the only local-player <c>UnStick</c> left is
|
||||
/// <c>PlayerMovementController.SetPositionCore</c>'s
|
||||
/// <c>if (publishSharedState) PositionManager?.UnStick();</c>, and
|
||||
/// <c>PreparePositionForCommit</c> passes <c>publishSharedState: false</c>.
|
||||
/// The unstick-at-first-entry-commit behaviour <c>CommitPreparedPosition</c>
|
||||
/// used to perform is simply gone — it was dead code (the method had zero
|
||||
/// production callers before this slice deleted it), so nothing regresses
|
||||
/// today, but no layer pins the invariant "first-entry commit releases any
|
||||
/// sticky target" any more. That is disposition 3.6's one real coverage
|
||||
/// loss (see the C5a commit message).
|
||||
/// This App-layer fixture (a bare <see cref="PlayerMovementController"/> +
|
||||
/// <see cref="EntityPhysicsHost"/> pair, no Runtime activation pipeline)
|
||||
/// cannot drive the Runtime final-commit transaction without
|
||||
/// disproportionate fixture growth — recorded here as the explicit C5a
|
||||
/// scope decision rather than silently dropped.
|
||||
/// What THIS test still proves, unchanged: <see cref="PlayerMovementController.PreparePositionForCommit"/>
|
||||
/// defers the render-root publish exactly as before (<c>controller.CellId</c>
|
||||
/// updates immediately; <c>physics.DataCache.CellGraph.CurrCell</c> and
|
||||
/// the sticky target stay untouched), and the surviving production
|
||||
/// commit-arm, <see cref="PlayerMovementController.ArmConstraintLeashAtCommittedPlacement"/>,
|
||||
/// arms the constraint leash without independently touching either —
|
||||
/// neither the render-root publish (a DIFFERENT layer's job now) nor the
|
||||
/// sticky release (nobody's job any more).
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void PreparedPosition_DoesNotPublishRenderRootOrUnstickUntilCommit()
|
||||
public void PreparedPosition_DefersRenderRootPublish_CommitArmsLeashOnly()
|
||||
{
|
||||
PhysicsEngine physics = PhysicsWithCells(PriorCell, DestinationCell);
|
||||
physics.UpdatePlayerCurrCell(PriorCell);
|
||||
|
|
@ -38,11 +77,19 @@ public sealed class PlayerMovementPlacementTransactionTests
|
|||
Assert.Equal(DestinationCell, controller.CellId);
|
||||
Assert.Equal(PriorCell, physics.DataCache!.CellGraph.CurrCell!.Id);
|
||||
Assert.Equal(TargetGuid, player.PositionManager.GetStickyObjectId());
|
||||
Assert.False(player.PositionManager.IsFullyConstrained());
|
||||
Assert.Null(player.PositionManager.Constraint);
|
||||
|
||||
controller.CommitPreparedPosition();
|
||||
controller.ArmConstraintLeashAtCommittedPlacement();
|
||||
|
||||
Assert.Equal(DestinationCell, physics.DataCache.CellGraph.CurrCell!.Id);
|
||||
Assert.Equal(0u, player.PositionManager.GetStickyObjectId());
|
||||
// The leash is armed...
|
||||
Assert.NotNull(player.PositionManager.Constraint);
|
||||
Assert.True(player.PositionManager.Constraint!.IsConstrained);
|
||||
// ...but the surviving App-layer commit does NOT publish the render
|
||||
// root or release the sticky target — those now happen inside the
|
||||
// Runtime dormant-activation final commit, before this method runs.
|
||||
Assert.Equal(PriorCell, physics.DataCache.CellGraph.CurrCell!.Id);
|
||||
Assert.Equal(TargetGuid, player.PositionManager.GetStickyObjectId());
|
||||
}
|
||||
|
||||
private static PhysicsEngine PhysicsWithCells(params uint[] cellIds)
|
||||
|
|
|
|||
|
|
@ -343,7 +343,7 @@ public sealed class RetailLocalPlayerFrameControllerTests
|
|||
|
||||
var clock = new RetailObjectQuantumClock();
|
||||
var controller = new PlayerMovementController(engine, clock);
|
||||
controller.SetPosition(new Vector3(96f, 96f, 50f), 0x0001u);
|
||||
controller.SeedPlacementForTest(new Vector3(96f, 96f, 50f), 0x0001u, new Vector3(96f, 96f, 50f));
|
||||
Assert.True(clock.IsActive);
|
||||
return controller;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ public sealed class PlayerInteractionMovementSinkTests
|
|||
MovementType expectedType)
|
||||
{
|
||||
var controller = new PlayerMovementController(new PhysicsEngine());
|
||||
controller.SetPosition(Vector3.Zero, Cell);
|
||||
controller.SeedPlacementForTest(Vector3.Zero, Cell, Vector3.Zero);
|
||||
bool nonAutonomousAtTargetInstall = false;
|
||||
int cancellations = 0;
|
||||
double targetQuantum = 0d;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ public sealed class PlayerMovementHiddenTests
|
|||
const uint cellId = 0x01010001u;
|
||||
|
||||
var controller = new PlayerMovementController(new PhysicsEngine());
|
||||
controller.SetPosition(Vector3.Zero, cellId, Vector3.Zero);
|
||||
controller.SeedPlacementForTest(Vector3.Zero, cellId, Vector3.Zero);
|
||||
|
||||
var hosts = new Dictionary<uint, IPhysicsObjHost>();
|
||||
EntityPhysicsHost? playerHost = null;
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ public sealed class CameraFrameControllerTests
|
|||
0f,
|
||||
0f);
|
||||
var controller = new PlayerMovementController(engine);
|
||||
controller.SetPosition(new Vector3(96f, 96f, 50f), 0x0001u);
|
||||
controller.SeedPlacementForTest(new Vector3(96f, 96f, 50f), 0x0001u, new Vector3(96f, 96f, 50f));
|
||||
return controller;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ public sealed class LocalPlayerTeleportControllerTests
|
|||
Assert.Null(harness.Presentation.BeginProjection);
|
||||
|
||||
harness.Mode.Controller = new PlayerMovementController(new PhysicsEngine());
|
||||
harness.Mode.Controller.SetPosition(
|
||||
harness.Mode.Controller.SeedPlacementForTest(
|
||||
Vector3.Zero,
|
||||
0x20210001u,
|
||||
Vector3.Zero);
|
||||
|
|
@ -117,7 +117,7 @@ public sealed class LocalPlayerTeleportControllerTests
|
|||
Assert.Empty(harness.Streaming.Reservations);
|
||||
|
||||
harness.Mode.Controller = new PlayerMovementController(new PhysicsEngine());
|
||||
harness.Mode.Controller.SetPosition(Vector3.Zero, 0x20210001u, Vector3.Zero);
|
||||
harness.Mode.Controller.SeedPlacementForTest(Vector3.Zero, 0x20210001u, Vector3.Zero);
|
||||
harness.Controller.Tick(0.016f);
|
||||
|
||||
Assert.Equal(0x20210001u, harness.Controller.ActiveDestinationCell);
|
||||
|
|
@ -156,7 +156,7 @@ public sealed class LocalPlayerTeleportControllerTests
|
|||
harness.Mode.RebuildOnEnter = () =>
|
||||
{
|
||||
var controller = new PlayerMovementController(new PhysicsEngine());
|
||||
controller.SetPosition(Vector3.Zero, 0x20210001u, Vector3.Zero);
|
||||
controller.SeedPlacementForTest(Vector3.Zero, 0x20210001u, Vector3.Zero);
|
||||
return controller;
|
||||
};
|
||||
harness.Controller.Tick(0.016f);
|
||||
|
|
@ -353,7 +353,7 @@ public sealed class LocalPlayerTeleportControllerTests
|
|||
// AddSyntheticIndoorCell doc comment for why CommitLandblockCollision
|
||||
// alone (terrain-only) cannot make it spawn-ready.
|
||||
harness.AddSyntheticIndoorCell(0x30310100u);
|
||||
harness.Mode.Controller!.SetPosition(
|
||||
harness.Mode.Controller!.SeedPlacementForTest(
|
||||
Vector3.Zero,
|
||||
0x20210001u,
|
||||
Vector3.Zero);
|
||||
|
|
@ -649,7 +649,7 @@ public sealed class LocalPlayerTeleportControllerTests
|
|||
// body/cell/orientation BEFORE this suffix runs. Reproduce that
|
||||
// pre-state directly rather than re-resolving it here - Place() no
|
||||
// longer resolves anything (D-T4).
|
||||
controllerSlot.Controller.SetPosition(position, cell, position);
|
||||
controllerSlot.Controller.SeedPlacementForTest(position, cell, position);
|
||||
controllerSlot.Controller.SetBodyOrientation(rotation);
|
||||
var cameras = new ChaseCameraInputState
|
||||
{
|
||||
|
|
@ -727,14 +727,14 @@ public sealed class LocalPlayerTeleportControllerTests
|
|||
{
|
||||
Controller = new PlayerMovementController(new PhysicsEngine()),
|
||||
};
|
||||
controllerSlot.Controller.SetPosition(
|
||||
controllerSlot.Controller.SeedPlacementForTest(
|
||||
Vector3.Zero,
|
||||
sourceCell,
|
||||
Vector3.Zero);
|
||||
// C4 route 3: reproduce the canonical Runtime commit's pre-state
|
||||
// (body/cell already resolved) - Place() no longer resolves it.
|
||||
var destinationPosition = new Vector3(12f, 24f, 6f);
|
||||
controllerSlot.Controller.SetPosition(
|
||||
controllerSlot.Controller.SeedPlacementForTest(
|
||||
destinationPosition,
|
||||
destinationCell,
|
||||
destinationPosition);
|
||||
|
|
@ -1303,7 +1303,7 @@ public sealed class LocalPlayerTeleportControllerTests
|
|||
{
|
||||
_order = order;
|
||||
Controller = new PlayerMovementController(new PhysicsEngine());
|
||||
Controller.SetPosition(Vector3.Zero, 0x20210001u, Vector3.Zero);
|
||||
Controller.SeedPlacementForTest(Vector3.Zero, 0x20210001u, Vector3.Zero);
|
||||
}
|
||||
|
||||
public PlayerMovementController? Controller { get; set; }
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ public sealed class StreamingFrameControllerTests
|
|||
var fixture = new Fixture(initializeOrigin: true);
|
||||
fixture.Mode.IsPlayerMode = true;
|
||||
var player = new PlayerMovementController(new PhysicsEngine());
|
||||
player.SetPosition(
|
||||
player.SeedPlacementForTest(
|
||||
new Vector3(383f, -0.01f, 0f),
|
||||
0x0A140001u,
|
||||
new Vector3(1f, 1f, 0f));
|
||||
|
|
@ -159,7 +159,7 @@ public sealed class StreamingFrameControllerTests
|
|||
{
|
||||
State = PlayerState.PortalSpace,
|
||||
};
|
||||
player.SetPosition(
|
||||
player.SeedPlacementForTest(
|
||||
new Vector3(1000f, -1000f, 0f),
|
||||
0x0A140001u,
|
||||
new Vector3(1f, 1f, 0f));
|
||||
|
|
@ -179,7 +179,7 @@ public sealed class StreamingFrameControllerTests
|
|||
var fixture = new Fixture(initializeOrigin: true);
|
||||
fixture.Mode.IsPlayerMode = true;
|
||||
var player = new PlayerMovementController(new PhysicsEngine());
|
||||
player.SetPosition(
|
||||
player.SeedPlacementForTest(
|
||||
new Vector3(1000f, -1000f, 0f),
|
||||
0x0A140001u,
|
||||
new Vector3(1f, 1f, 0f));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue