acdream/tests/AcDream.Runtime.Tests/Session/RuntimeRemotePlacementDriveControllerTests.cs
Erik 36255af0f6 fix(physics): C4 route 5 — projectile authoritative placement (#276 partial)
Ports retail's missile Position handling into the canonical Runtime
placement owner instead of the deleted ApplyAuthoritativePosition
short-circuit. The Create/residence-window halves of the projectile
pipeline (RuntimeProjectile binding, TryBind's adopted-body branch,
the collision/shadow registration) were already canonical from prior
slices; this closes the remaining gap — how an ACCEPTED Position for
an in-flight missile is classified, placed, and presented.

Byte-decode (Step 1 hard gate, before any code was written):
CPhysicsObj::MoveOrTeleport @0x00516330-0x00516438 disassembled from
the PDB-paired binary (Capstone, x86 32-bit thiscall). `ret 0x10`
establishes four stack args; [esp+0x7c] (arg5, the velocity pointer)
is never referenced in any of the three branches (teleport/near/far).
The retail reviewer independently reproduced this by searching the
whole function body for the `24 7c` mod/rm+disp8 encoding a
`[esp+0x7c]` read would require and found zero occurrences. This
retired a fabricated `?? Vector3.Zero` fallback in the deleted method
— retail's PositionPack::UnPack initializes an absent velocity to
zero and MoveOrTeleport never installs it; the projectile's Vector
channel (RuntimeProjectilePhysicsUpdater.ApplyAuthoritativeVector)
remains the sole velocity authority for a missile. D-P5 in the
contract; the Runtime seam commits no velocity from the Position
packet at all.

The unbound-missile fix: RuntimeEntityObjectLifetime's
ClassifyRemoteAcceptedPosition now derives ProjectileAuthoritative
from a CONJUNCTIVE predicate — the Missile bit AND a bound
RuntimeProjectile whose Body is the canonical PhysicsBody — never the
bit alone. Retail places every non-player CPhysicsObj unconditionally
(there is no missile-specific placement gate in MoveOrTeleport or its
callers), so an unbindable or not-yet-bound missile taking the
ordinary remote tail is retail-faithful, not a fallback: the earlier
bit-only discriminator would have silently frozen it instead.

AP-141 records this as a deliberate, recorded divergence, not
fidelity. Retail mechanically WOULD arm a missile's ConstrainTo leash
on any nonzero MoveOrTeleport return: HandleReceivedPosition
@0x00453FD0's only kind test is player-vs-not, ConstrainTo
@0x00454272 has no kind test of its own, and CPhysicsObj::ConstrainTo
@0x00510520 creates a PositionManager on demand via
MakePositionManager @0x00510523 if one doesn't exist. acdream
deliberately does not construct that EntityPhysicsHost/
PositionManager/InterpolationManager chain for a ballistic body — the
route-5b split the C4 route 5 contract rejected — so a live missile
never shows an armed leash and never catches up via the near/
UnroutedCatchUp policy. This divergence is safe specifically because
ACE never sends UpdatePosition for a missile
(references/ACE/Source/ACE.Server/WorldObjects/WorldObject_Tick.cs:
333-334, SendUpdatePosition() commented out inside the
PhysicsState.Missile branch at :265) — every half of this row is
deterministic-test-gated only, never exercised against a real server.

AP-141 also records the surviving ConstrainTo re-anchor divergence
under clause (b): for the adopted-body case (TryBind's shared-body
branch — an ordinary remote whose Missile bit is set by a later
State packet, so it still carries a live RemoteMotion), acdream now
ports retail's teleport-branch and far-branch StopInterpolating
action (Interp.Clear()), but never re-arms or re-anchors the
inherited ConstrainTo leash the way retail's HandleReceivedPosition
@0x00454254/@0x00454272 does on every nonzero return. The risk
column's earlier wording — that a stale leash "would drag the body
toward a stale anchor" — was wrong and is retracted in this same
commit: ConstraintManager.ConstraintPos is write-only in both retail
and the port (never read by AdjustOffset), and
ConstraintManager::adjust_offset @0x00556180 only tapers or zeroes an
already-composed per-tick offset while InContact — a leash brakes
motion the interp/sticky chain already produced, it cannot pull
anything toward the anchor. The real residual is one tick of un-reset
brake accumulator, contact-gated, and it cannot move an airborne
far-snapped missile at all (the clamp branch does not run while
airborne).

NO CONNECTED GATE EXISTS for this route, by design: ACE never sends a
missile UpdatePosition (see above), so retail's own server never
exercises this code path in play. Every proof obligation here is
test-gated only — Runtime and App-level fixtures constructing the
packet directly — never a live client/server capture.

Three review rounds closed 8 MAJOR findings before this landed:
round 1 (A1 App discarded the seam's status; A2/R1 silent swallow on
an unbound missile; A3/R2 the adopted-body teleport_hook never
wired; A4/A5 zero Runtime/App test coverage); round 2 (a
ParentCellId regression introduced by round 1's own R6 finding,
which the retail reviewer retracted the following round as factually
wrong — the fix here is the REVERT to record.FullCellId, not the
relocation round 1 shipped; B2 the far-branch StopInterpolating skip
never extended to the adopted-body case; residual App/Runtime store-
path coverage; a per-packet closure contradicting the file's own
#315 cached-delegate pattern). Round 3 closed on coverage alone (no
defect): the Advance() retry arm's projectile branch — added at
round 2, semantically reordered at round 2's B5 fix (skip prediction
invalidation on a re-parked Contention, since it writes nothing) —
had never been executed by any test; two new tests drive it directly
and are sabotage-verified against both the reordering and the
retry-arm's own SyncProjectilePresentation call site. The one
recorded defect this campaign produced (the ParentCellId regression)
was caused by complying with a review finding that its own author
later retracted — the standing lesson recorded for future rounds is
that review findings are evidence to re-verify against the code, not
commands to obey unconditionally.

Complete Release suite: 11,063 passed / 4 skipped / 0 failed
(baseline 11,036 at 30d3d114, +27 new tests across this campaign).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 21:03:41 +02:00

3354 lines
156 KiB
C#

using System.Numerics;
using AcDream.Content;
using AcDream.Content.Pak;
using AcDream.Core.Net;
using AcDream.Core.Net.Messages;
using AcDream.Core.Physics;
using AcDream.Runtime.Entities;
using AcDream.Runtime.Physics;
using AcDream.Runtime.Session;
namespace AcDream.Runtime.Tests.Session;
/// <summary>
/// C4 route 4b-1/4b-2: focused tests for the Runtime-owned, per-entity remote
/// placement infrastructure. 4b-1 wired no production caller at all; 4b-2 gave
/// the far arm one (<c>LiveEntityNetworkUpdateController.ApplyRemoteContactRouting</c>,
/// exercised end to end by <c>LiveEntityNetworkRemoteFarSnapIntegrationTests</c>
/// — correcting this comment's earlier "This route wires NO production
/// caller"). Every test in THIS file still drives the seam directly, because
/// each one constructs an already-classified
/// <see cref="RuntimeAuthoritativePositionRoute"/>
/// directly (the same shape
/// <see cref="RuntimeEntityObjectLifetime.ClassifyRemoteAcceptedPosition"/>
/// would hand a real caller) so each scenario is exercised precisely, mirroring
/// <c>RuntimeSetPositionStateTests</c>' bare-<see cref="RuntimeEntityObjectLifetime"/>
/// fixture rather than the full <c>GameRuntime</c>/<c>LiveSessionHost</c>
/// harness route 2's tests use — this controller has no local-player
/// controller, outbound session, or generation dependency to bootstrap.
///
/// Round 3 (correction n3) — the earlier version of this paragraph asserted
/// that "each test was verified to actually discriminate its own fix", which
/// is a claim about a procedure run outside the tree with no per-test mapping
/// anywhere in it. Reduced to what this file can actually show: every test
/// here names, in its own doc, the specific guard or omission it fails
/// without. Whether that revert was run, and what the run measured, belongs
/// in the slice's review record, not in a comment that cannot be checked
/// against the code beside it.
/// </summary>
public sealed class RuntimeRemotePlacementDriveControllerTests
{
private const uint SourceLandblock = 0xB1000000u;
private const uint SourceCell = SourceLandblock | 0x0001u;
private const uint DestinationLandblock = 0xB2000000u;
private const uint DestinationCell = DestinationLandblock | 0x0001u;
/// <summary>
/// The destination landblock's +X neighbour. Landblock ids pack the block
/// X index in bits 24-31, so 0xB2 → 0xB3 is one block east, and
/// <c>LandDefs.LcoordToGid</c> re-derives exactly this prefix for a global
/// lcoord one cell past the 192 m seam.
/// </summary>
private const uint NeighbourLandblock = 0xB3000000u;
/// <summary>
/// Cell (7, 0) of the destination landblock — block-local X in [168, 192),
/// Y in [0, 24). <c>LandDefs.GidToLcoord</c>'s inverse:
/// <c>low = (ly &amp; 7) + ((lx &amp; 7) &lt;&lt; 3) + 1 = 0 + 56 + 1 = 57</c>.
/// </summary>
private const uint DestinationSeamCell = DestinationLandblock | 57u;
private const float SpawnHeight = 7f;
[Fact]
public void NotApplicable_WhenDispositionIsNotOwnedByThisRoute()
{
foreach (RuntimeAuthoritativePositionDisposition disposition in
new[]
{
RuntimeAuthoritativePositionDisposition.Interpolate,
RuntimeAuthoritativePositionDisposition.NoPositionOperation,
RuntimeAuthoritativePositionDisposition.RejectedAuthority,
RuntimeAuthoritativePositionDisposition.RejectedData,
RuntimeAuthoritativePositionDisposition.AwaitFreshPosition,
})
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003001u);
AttachBody(lifetime, record, SourceCell);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record, disposition, DestinationCell);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.NotApplicable,
drive.TryExecuteAcceptedRemotePosition(record, route));
Assert.Equal(0, drive.PendingCount);
AssertConverged(lifetime);
}
}
[Fact]
public void NotApplicable_WhenTheEntityHasNoCanonicalBody()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003002u);
// Deliberately never attach a body.
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.NotApplicable,
drive.TryExecuteAcceptedRemotePosition(record, route));
}
/// <summary>
/// B6 review fix: <c>OwnsPlacement</c> keyed on <c>Disposition</c> alone
/// would claim this route too — the classifier emits
/// <c>SetPositionSimple</c> for the LOCAL PLAYER's FORCE_POSITION/
/// teleport branches (<c>RuntimeSetPositionOperationKind.LocalAuthoritative</c>),
/// not only for remotes. The static predicate itself is exercised
/// directly (no entity/body needed) since it takes only the route.
///
/// <para>
/// C4 route 5 (D-P3): <c>ProjectileAuthoritative</c> is REMOVED from this
/// negative list — the widening makes it a positively-owned kind now
/// (see <see cref="OwnsPlacement_TrueForProjectileAuthoritative_SetPositionAndSetPositionSimple"/>).
/// Only the two kinds that stay excluded remain here.
/// </para>
/// </summary>
[Fact]
public void OwnsPlacement_FalseWhenOperationKindIsNotRemoteOrProjectileAuthoritative()
{
// RuntimeSetPositionOperationKind is internal, so a public [Theory]
// cannot take it as a parameter (CS0051) — iterate directly instead,
// mirroring NotApplicable_WhenDispositionIsNotOwnedByThisRoute's own
// foreach-over-internal-enum shape.
foreach (RuntimeSetPositionOperationKind operationKind in
new[]
{
RuntimeSetPositionOperationKind.InitialLogin,
RuntimeSetPositionOperationKind.LocalAuthoritative,
})
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x7000300Fu);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
operationKind: operationKind);
Assert.False(
RuntimeRemotePlacementDriveController.OwnsPlacement(route));
// End to end: this controller must decline the SAME route as
// NotApplicable, not merely the static predicate in isolation.
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive =
CreateDrive(lifetime, window);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.NotApplicable,
drive.TryExecuteAcceptedRemotePosition(record, route));
Assert.Equal(0, drive.PendingCount);
}
}
/// <summary>
/// C2-4 review fix (delta round): the <c>OperationKind is RemoteAuthoritative</c>
/// guard alone is STILL not exact — <c>RuntimeAuthoritativePositionRouteClassifier
/// .ClassifyCreate</c> emits <c>Disposition = SetPosition</c> AND
/// <c>OperationKind = RemoteAuthoritative</c> for a REMOTE top-level
/// initial Create too (only the LOCAL PLAYER's Create maps to
/// <c>InitialLogin</c>), so both the disposition and operation-kind
/// guards pass for a Create-shaped route. Retail's own flag choice is
/// what actually distinguishes them: a Create carries
/// <c>InitialCreateFlags</c> (<c>Placement|Slide</c>, no
/// <c>Teleport</c>); every remote accepted-Position SetPosition/
/// SetPositionSimple route carries <c>AuthoritativeTeleportFlags</c>
/// (<c>Teleport|Slide|SendPositionEvent</c>). Route 4b-1 is a
/// POSITION-only route — the first-entry conductor owns every Create —
/// so a Create-shaped route reaching this controller must be declined.
/// </summary>
[Fact]
public void OwnsPlacement_FalseForARemoteTopLevelCreateShapedRoute()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003014u);
RuntimeAuthoritativePositionRoute createRoute = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
operationKind: RuntimeSetPositionOperationKind.RemoteAuthoritative,
setPositionFlags: PhysicsSetPositionFlags.Placement
| PhysicsSetPositionFlags.Slide);
Assert.False(
RuntimeRemotePlacementDriveController.OwnsPlacement(createRoute));
// End to end: this controller must decline the SAME route as
// NotApplicable, not merely the static predicate in isolation.
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive =
CreateDrive(lifetime, window);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.NotApplicable,
drive.TryExecuteAcceptedRemotePosition(record, createRoute));
Assert.Equal(0, drive.PendingCount);
// The genuine remote accepted-Position shape (SAME disposition, SAME
// operation kind, Teleport-flagged) must still be owned — the fix
// must not have over-corrected into refusing everything.
RuntimeAuthoritativePositionRoute positionRoute = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell);
Assert.True(
RuntimeRemotePlacementDriveController.OwnsPlacement(positionRoute));
}
/// <summary>
/// The central decision's core pin: a destination this host's service
/// window does not currently cover must be refused, not parked — no
/// operation may open at all, so the body's own <c>InWorld</c>/object
/// clock are never touched.
/// </summary>
[Fact]
public void Refused_WhenDestinationIsNotWithinServiceWindow_NoOperationOpensAndBodyStaysInWorld()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003003u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
// The service window allows nothing — mirrors a destination
// landblock this host has never collision-published.
var window = new FakeServiceWindow();
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell);
RuntimeRemotePlacementExecutionStatus status =
drive.TryExecuteAcceptedRemotePosition(record, route);
Assert.Equal(RuntimeRemotePlacementExecutionStatus.Refused, status);
Assert.True(body.InWorld);
Assert.True(record.ObjectClock.IsActive);
Assert.Equal(
0,
lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
AssertConverged(lifetime);
}
/// <summary>
/// The exact §"central decision" sequence the contract's acceptance
/// section pins: attempt a placement whose destination is refused, then
/// deliver the entity's NEXT accepted Position — which, whatever it
/// classifies to, ALWAYS runs <c>RuntimeSetPositionState.Forget</c> for
/// this entity first
/// (<see cref="RuntimeEntityObjectLifetime.TryApplyPosition"/>, called
/// unconditionally regardless of disposition). Because nothing was ever
/// parked in the first step, that unconditional Forget has nothing to
/// discard, and the entity is STILL in the world afterward — the
/// invisible-and-intangible failure this route exists to prevent.
/// </summary>
[Fact]
public void CentralDecision_RefusedPlacementThenNextAcceptedPositionForgetsNothing_EntityStaysInWorld()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003004u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
var window = new FakeServiceWindow();
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell);
// Packet N: destination not placeable now.
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Refused,
drive.TryExecuteAcceptedRemotePosition(record, route));
Assert.True(body.InWorld);
Assert.True(record.ObjectClock.IsActive);
// Packet N+1 ~150 ms later: whatever it classifies to (here,
// Interpolate — the caller never reaches this controller at all for
// that disposition), production's merge unconditionally Forgets any
// in-flight operation for this entity FIRST. Simulated directly
// (mirrors RuntimeAcceptedPositionDriveControllerTests'
// Equal_ClearsPendingWithoutReissuing... fixture, which drives the
// same production Forget call without a full second network
// round-trip).
RuntimePlacementCancellationReceipt cancellation =
lifetime.Physics.SetPosition.Forget(record);
if (cancellation.IsValid)
lifetime.Physics.SetPosition.PublishCancellation(cancellation);
Assert.True(body.InWorld);
Assert.True(record.ObjectClock.IsActive);
Assert.Equal(SourceCell, record.FullCellId);
AssertConverged(lifetime);
}
[Fact]
public void Committed_WhenDestinationIsWithinServiceWindowAndCollisionGenerationCommitted()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003005u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
destination);
RuntimeRemotePlacementExecutionStatus status =
drive.TryExecuteAcceptedRemotePosition(record, route);
Assert.Equal(RuntimeRemotePlacementExecutionStatus.Committed, status);
// Runtime's world-frame resolution shifts an authored landblock-local
// position into Runtime's continuous world frame
// (resolveWorldOffsetFromRuntimeFrame: true) — DestinationLandblock
// sits +192m on X from SourceLandblock per CommitLandblockCollision.
Assert.Equal(destination + new Vector3(192f, 0f, 0f), body.Position);
Assert.Equal(0, drive.PendingCount);
// No host subscription is wired in this bare fixture — drain the
// Place receipt exactly like production's placement-projection
// subscription would, so the operation itself (not this drive's own
// ledger) also converges to zero.
DrainPlacementFifo(lifetime);
Assert.Equal(
0, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
AssertConverged(lifetime);
}
/// <summary>
/// B4 review fix: <c>SubmitAndResolve</c>'s Committed branch returns and
/// retains nothing in <c>_pending</c>, but when nothing synchronously
/// consumes-and-acknowledges the Place receipt (this bare fixture has no
/// host subscription wired — production's declined-sink retry scenario
/// is the identical shape), the operation stays live in Core's
/// <c>_operations</c> map until something later calls
/// <c>AcknowledgeProjection</c>. Before this fix
/// <c>RemotePlacementDrivePendingCount</c> was blind to that live
/// operation the instant <c>Committed</c> was returned. This proves it is
/// now visible, and that it still converges to zero once the receipt is
/// actually acknowledged.
/// </summary>
[Fact]
public void Committed_UnacknowledgedOperationStaysVisibleInTheLedgerUntilAcknowledged()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003010u);
AttachBody(lifetime, record, SourceCell);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
destination);
RuntimeRemotePlacementExecutionStatus status =
drive.TryExecuteAcceptedRemotePosition(record, route);
Assert.Equal(RuntimeRemotePlacementExecutionStatus.Committed, status);
// No host subscription is wired in this bare fixture, so the Place
// receipt is still genuinely unacknowledged — the ledger must SEE it.
Assert.Equal(
1, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
Assert.Equal(
1,
lifetime.CaptureOwnership().RemotePlacementDrivePendingCount);
DrainPlacementFifo(lifetime);
Assert.Equal(
0, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
AssertConverged(lifetime);
}
[Fact]
public void Contention_WhenTheEntityAlreadyOwnsAnActiveOperation()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003006u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
Vector3 positionBefore = body.Position;
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
// An external placement authority (portal/teleport/another route)
// already owns this entity's SetPosition operation.
RuntimeEntityPlacementToken displaced = lifetime.Physics.SetPosition
.TryBeginExclusiveAuthoredPlacement(
record,
record.PositionAuthorityVersion,
RuntimeSetPositionOperationKind.RemoteAuthoritative);
Assert.True(displaced.IsValid);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Contention,
drive.TryExecuteAcceptedRemotePosition(record, route));
Assert.Equal(positionBefore, body.Position);
Assert.Equal(0, drive.PendingCount);
RuntimePlacementCancellationReceipt cancellation = lifetime.Physics
.SetPosition.ForgetExactPlacement(displaced);
if (cancellation.IsValid)
lifetime.Physics.SetPosition.PublishCancellation(cancellation);
}
/// <summary>
/// Per-entity independence: two remotes interleaved must not share any
/// state — one entity's Contention must never block the other's Begin,
/// and each converges to zero independently.
/// </summary>
[Fact]
public void PerEntityIndependence_TwoRemotesInterleavedDoNotBlockEachOther()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord first = CreateRemoteRecord(lifetime, 0x70003007u);
RuntimeEntityRecord second = CreateRemoteRecord(lifetime, 0x70003008u);
PhysicsBody firstBody = AttachBody(lifetime, first, SourceCell);
PhysicsBody secondBody = AttachBody(lifetime, second, SourceCell);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
// First entity's own operation is still outstanding (an external
// authority holds it) when the second entity's Position arrives.
RuntimeEntityPlacementToken firstDisplaced = lifetime.Physics.SetPosition
.TryBeginExclusiveAuthoredPlacement(
first,
first.PositionAuthorityVersion,
RuntimeSetPositionOperationKind.RemoteAuthoritative);
Assert.True(firstDisplaced.IsValid);
RuntimeAuthoritativePositionRoute firstRoute = MakeRoute(
first, RuntimeAuthoritativePositionDisposition.SetPosition, DestinationCell);
RuntimeAuthoritativePositionRoute secondRoute = MakeRoute(
second, RuntimeAuthoritativePositionDisposition.SetPosition, DestinationCell,
new Vector3(20f, 22f, SpawnHeight));
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Contention,
drive.TryExecuteAcceptedRemotePosition(first, firstRoute));
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Committed,
drive.TryExecuteAcceptedRemotePosition(second, secondRoute));
Assert.Equal(
new Vector3(20f, 22f, SpawnHeight) + new Vector3(192f, 0f, 0f),
secondBody.Position);
Assert.Equal(0, drive.PendingCount);
RuntimePlacementCancellationReceipt cancellation = lifetime.Physics
.SetPosition.ForgetExactPlacement(firstDisplaced);
if (cancellation.IsValid)
lifetime.Physics.SetPosition.PublishCancellation(cancellation);
DrainPlacementFifo(lifetime);
_ = firstBody;
}
/// <summary>
/// Per-entity independence, the shape route 2's single <c>_pending</c>
/// slot cannot express: TWO entities each hold their OWN outstanding
/// preparation retry at the same time. Route 2's
/// <c>RetainPending</c> throws if a second live entry would displace the
/// first; this per-key map must track both simultaneously and let each
/// resolve (or die) independently.
/// </summary>
[Fact]
public void PerEntityIndependence_TwoConcurrentPreparationRetriesDoNotCollide()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord first = CreateRemoteRecord(
lifetime, 0x7000300Du, setupTableId: 0x02000001u);
RuntimeEntityRecord second = CreateRemoteRecord(
lifetime, 0x7000300Eu, setupTableId: 0x02000001u);
AttachBody(lifetime, first, SourceCell);
AttachBody(lifetime, second, SourceCell);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
RuntimeAuthoritativePositionRoute firstRoute = MakeRoute(
first, RuntimeAuthoritativePositionDisposition.SetPosition, DestinationCell);
RuntimeAuthoritativePositionRoute secondRoute = MakeRoute(
second, RuntimeAuthoritativePositionDisposition.SetPosition, DestinationCell);
// Both entities' Setup assets are unresolved (Missing) — both retry.
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Contention,
drive.TryExecuteAcceptedRemotePosition(first, firstRoute));
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Contention,
drive.TryExecuteAcceptedRemotePosition(second, secondRoute));
Assert.Equal(2, drive.PendingCount);
// The FIRST entity's retry dies (an unrelated accepted Position for
// IT ALONE forgets it); the second must remain completely
// unaffected — a shared/overwriting single slot could not represent
// this.
RuntimePlacementCancellationReceipt cancellation =
lifetime.Physics.SetPosition.Forget(first);
if (cancellation.IsValid)
lifetime.Physics.SetPosition.PublishCancellation(cancellation);
drive.Advance();
Assert.Equal(1, drive.PendingCount);
// The second entity's own operation is still tracked — the first's
// cancellation removed exactly one operation, not both.
Assert.Equal(
1, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
// Cleanup: retire the second entity's still-live retry too.
RuntimePlacementCancellationReceipt secondCancellation =
lifetime.Physics.SetPosition.Forget(second);
if (secondCancellation.IsValid)
{
lifetime.Physics.SetPosition
.PublishCancellation(secondCancellation);
}
drive.Advance();
Assert.Equal(0, drive.PendingCount);
}
/// <summary>
/// B3 review fix: a retained preparation retry must re-check the SAME
/// service-window guard the entry point uses before <c>Advance()</c>
/// resubmits it — a destination that retired its collision publication in
/// the frames since the retry was retained must be dropped, not
/// resubmitted. Discriminates from the OLD unconditional resubmit:
/// resubmitting against the SAME always-<c>Missing</c> collision source
/// returns the SAME retryable status, so without the re-check the entry
/// would simply be re-retained (<c>PendingCount</c> stays 1) even though
/// the window already forbids the destination — never converging.
/// </summary>
[Fact]
public void Advance_DropsRetainedRetryWhenTheServiceWindowNoLongerCoversItsDestination()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
RuntimeEntityRecord record = CreateRemoteRecord(
lifetime, 0x70003011u, setupTableId: 0x02000001u);
AttachBody(lifetime, record, SourceCell);
CommitLandblockCollision(lifetime, DestinationLandblock);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record, RuntimeAuthoritativePositionDisposition.SetPosition, DestinationCell);
// The Setup asset is unresolved (Missing) — the first attempt
// retries rather than commits, retaining the entry.
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Contention,
drive.TryExecuteAcceptedRemotePosition(record, route));
Assert.Equal(1, drive.PendingCount);
Assert.Equal(
1, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
// The remote wandered back out of range between this retry being
// retained and the next host cadence pump.
window.Forbid(DestinationLandblock);
drive.Advance();
Assert.Equal(0, drive.PendingCount);
Assert.Equal(
0, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
AssertConverged(lifetime);
}
/// <summary>
/// Currency: a preparation-retry entry left tracking a token some OTHER
/// caller already Forgot must not leak once this entity's NEXT packet
/// takes a path that itself never touches <c>_pending</c> (here, a
/// service-window refusal) — proving the self-heal is doing real work,
/// not merely being masked by the retry branch's own dictionary
/// overwrite (which would hide the leak if this test only ever re-hit
/// the SAME retryable status).
/// </summary>
[Fact]
public void StalePreparationRetry_SelfHealsRatherThanLeakingWhenTheNextPacketNeverTouchesPending()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
RuntimeEntityRecord record = CreateRemoteRecord(
lifetime, 0x70003009u, setupTableId: 0x02000001u);
AttachBody(lifetime, record, SourceCell);
CommitLandblockCollision(lifetime, DestinationLandblock);
// A Setup asset that never resolves (Missing) — the first attempt
// through this collision source retries rather than commits.
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record, RuntimeAuthoritativePositionDisposition.SetPosition, DestinationCell);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Contention,
drive.TryExecuteAcceptedRemotePosition(record, route));
Assert.Equal(1, drive.PendingCount);
// An unrelated accepted Position for this SAME entity Forgets the
// retained retry before it ever resolves — the mundane 5-10 Hz case.
RuntimePlacementCancellationReceipt cancellation =
lifetime.Physics.SetPosition.Forget(record);
if (cancellation.IsValid)
lifetime.Physics.SetPosition.PublishCancellation(cancellation);
// The destination is no longer serviceable by the NEXT packet (the
// remote wandered back out of range) — the Refused branch never
// assigns or clears _pending itself, so only the entry-point
// self-heal can retire the dead entry left behind above.
window.Forbid(DestinationLandblock);
RuntimeAuthoritativePositionRoute refusedRoute = MakeRoute(
record, RuntimeAuthoritativePositionDisposition.SetPosition, DestinationCell);
RuntimeRemotePlacementExecutionStatus status =
drive.TryExecuteAcceptedRemotePosition(record, refusedRoute);
Assert.Equal(RuntimeRemotePlacementExecutionStatus.Refused, status);
Assert.Equal(0, drive.PendingCount);
AssertConverged(lifetime);
}
/// <summary>
/// C2-1 review fix (delta round): the retained <c>_pending</c> entry
/// holds a LIVE Core operation (already begun via
/// <c>TryBeginExclusiveAuthoredPlacement</c>, sitting at
/// <c>AwaitingPreparation</c>) — clearing this controller's own map on
/// detach is not enough; the operation itself must be cancelled or it
/// pins its landblock prefix forever (docs/ISSUES.md #310). Asserting
/// <c>SetPositionOperationCount == 0</c> in addition to the ledger going
/// to zero is what actually proves the Core operation died, not just
/// that this controller stopped watching it — sibling tests in this file
/// (<c>Committed_...</c>, <c>ParkCollisionResidents_...</c>) already
/// check this dimension; this one previously did not, and would have
/// passed even with the old clear-only <c>DetachRoute</c>.
/// </summary>
[Fact]
public void LedgerConverges_AfterDetachRouteClearsTrackedEntries()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
RuntimeEntityRecord record = CreateRemoteRecord(
lifetime, 0x7000300Au, setupTableId: 0x02000001u);
AttachBody(lifetime, record, SourceCell);
CommitLandblockCollision(lifetime, DestinationLandblock);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var route = new object();
drive.AttachRoute(route);
RuntimeAuthoritativePositionRoute positionRoute = MakeRoute(
record, RuntimeAuthoritativePositionDisposition.SetPosition, DestinationCell);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Contention,
drive.TryExecuteAcceptedRemotePosition(record, positionRoute));
Assert.Equal(1, drive.PendingCount);
Assert.Equal(
1, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
drive.DetachRoute(route);
Assert.Equal(0, drive.PendingCount);
Assert.Equal(0, lifetime.CaptureOwnership().RemotePlacementDrivePendingCount);
Assert.Equal(
0, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
}
/// <summary>
/// C2-1 review fix (delta round): the OTHER map — <c>_awaitingAcknowledgement</c>
/// — holds an equally live Core operation (a published, unacknowledged
/// <c>Place</c> sitting at <c>AwaitingCommitAcknowledgement</c>), and the
/// prior <c>DetachRoute</c> left it live the same way. Mirrors the
/// <c>_pending</c> case above for the SECOND map DetachRoute must cancel.
/// </summary>
[Fact]
public void LedgerConverges_AfterDetachRouteCancelsAnUnacknowledgedCommit()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003012u);
AttachBody(lifetime, record, SourceCell);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var route = new object();
drive.AttachRoute(route);
RuntimeAuthoritativePositionRoute positionRoute = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
new Vector3(12f, 14f, SpawnHeight));
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Committed,
drive.TryExecuteAcceptedRemotePosition(record, positionRoute));
// No host subscription is wired in this bare fixture, so the Place
// receipt is still genuinely unacknowledged — the SAME shape the
// production declined-sink FIFO retry class leaves behind.
Assert.Equal(
1, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
Assert.Equal(
1, lifetime.CaptureOwnership().RemotePlacementDrivePendingCount);
drive.DetachRoute(route);
Assert.Equal(
0, lifetime.CaptureOwnership().RemotePlacementDrivePendingCount);
Assert.Equal(
0, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
}
/// <summary>
/// C2-1 review fix (delta round), disposal safety:
/// <c>CountLiveAwaitingAcknowledgement</c> calls
/// <c>RuntimeSetPositionState.IsPlacementCurrent</c>, whose first
/// statement is <c>EnsureNotDisposed</c> — it THROWS once disposed. A
/// post-<c>Dispose()</c> <c>CaptureOwnership()</c> read is the designed
/// contract (<c>GameWindowLifetime.DisposeGameRuntime</c>:
/// <c>runtime.Dispose(); runtime.CaptureOwnership();</c>), so this
/// dimension must survive it too. Deliberately leaves the entry
/// UNDRAINED at dispose time — a genuine leak, exactly what this ledger
/// exists to report — to prove the disposed branch reports it rather
/// than hiding it behind a thrown exception.
/// </summary>
[Fact]
public void CountLiveAwaitingAcknowledgement_SurvivesReadAfterDisposeWithoutThrowing()
{
var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003013u);
AttachBody(lifetime, record, SourceCell);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
RuntimeAuthoritativePositionRoute positionRoute = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
new Vector3(12f, 14f, SpawnHeight));
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Committed,
drive.TryExecuteAcceptedRemotePosition(record, positionRoute));
lifetime.Dispose();
int pendingAfterDispose = -1;
Exception? thrown = Record.Exception(() =>
pendingAfterDispose =
lifetime.CaptureOwnership().RemotePlacementDrivePendingCount);
Assert.Null(thrown);
Assert.Equal(1, pendingAfterDispose);
}
[Fact]
public void AttachRoute_ThrowsForADifferentRouteWhileTheFirstIsStillLive()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
var window = new FakeServiceWindow();
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var firstRoute = new object();
var secondRoute = new object();
drive.AttachRoute(firstRoute);
Assert.Throws<InvalidOperationException>(
() => drive.AttachRoute(secondRoute));
drive.DetachRoute(firstRoute);
drive.AttachRoute(secondRoute);
}
/// <summary>
/// Gate item: <c>ParkCollisionResidents</c> throws on overlap for every
/// spatial root in a retiring prefix that holds an active operation
/// (<c>RuntimeSetPositionState.ParkCollisionResidents</c> — cited by
/// symbol, not by line: the delta review found line citations in this
/// slice going stale within a single review round). This is the concrete
/// proof it stays unreachable under this route's design — both after a
/// refusal (no operation ever opened) and after a normal commit
/// (operation retired to zero), the SAME prefix can be "retired" without
/// throwing.
/// </summary>
[Fact]
public void ParkCollisionResidents_StaysUnreachable_AfterRefusalAndAfterCommit()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord refusedEntity = CreateRemoteRecord(lifetime, 0x7000300Bu);
AttachBody(lifetime, refusedEntity, DestinationCell);
RuntimeEntityRecord committedEntity = CreateRemoteRecord(lifetime, 0x7000300Cu);
AttachBody(lifetime, committedEntity, SourceCell);
var refusingWindow = new FakeServiceWindow();
RuntimeRemotePlacementDriveController refusingDrive =
CreateDrive(lifetime, refusingWindow);
RuntimeAuthoritativePositionRoute refusedRoute = MakeRoute(
refusedEntity,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Refused,
refusingDrive.TryExecuteAcceptedRemotePosition(refusedEntity, refusedRoute));
var allowingWindow = new FakeServiceWindow();
allowingWindow.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController committingDrive =
CreateDrive(lifetime, allowingWindow);
RuntimeAuthoritativePositionRoute committedRoute = MakeRoute(
committedEntity,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
new Vector3(30f, 30f, SpawnHeight));
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Committed,
committingDrive.TryExecuteAcceptedRemotePosition(
committedEntity, committedRoute));
// No host subscription is wired in this bare fixture — drain the
// Place receipt exactly like production's placement-projection
// subscription would, converging the operation to zero the same way
// a live host's synchronous consumption does.
DrainPlacementFifo(lifetime);
// Both entities now sit resident in the destination prefix with NO
// active operation. Retiring that prefix must not throw.
Exception? thrown = Record.Exception(() =>
lifetime.Physics.SetPosition.ParkCollisionResidents(
DestinationLandblock, includeOutdoorCells: true));
Assert.Null(thrown);
}
// ── C4 route 4b-2: the far-snap arm ──────────────────────────────────
/// <summary>
/// The queue clear does not depend on the placement having run: refuse
/// the placement and the queue is still empty afterwards.
///
/// <para>
/// R7 review fix — <b>what this does and does not prove.</b> Its earlier
/// name and doc claimed proof of retail's ORDER (<c>StopInterpolating</c>
/// @0x005163CB strictly before <c>SetPositionSimple</c> @0x005163D9).
/// It does not have that, and neither can any acdream test: the
/// interpolation queue is not an input to the canonical placement (the
/// destination comes from the merged snapshot), and the placement does
/// not read or write the queue, so swapping the two statements leaves
/// every observable identical. The order is preserved in
/// <c>ApplyAcceptedRemoteFarSnap</c> because retail has it, and is
/// asserted only by reading. What IS pinned here is the strictly weaker
/// and still load-bearing property that ruled out the natural
/// mis-implementation "clear the queue once the placement succeeds":
/// under that shape a refusal would leave a stale near waypoint behind to
/// drag the body back on the next catch-up.
/// </para>
/// </summary>
[Fact]
public void FarSnap_ClearsTheInterpolationQueue_IndependentlyOfThePlacementOutcome()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
// Publishes the world frame as well, so the refusal's store_position
// fallback below has a coordinate system to write into — a live
// session always has one before any remote can classify far.
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003020u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
Vector3 positionBefore = body.Position;
remote.Interp.Enqueue(
new Vector3(40f, 40f, SpawnHeight),
Quaternion.Identity,
isMovingTo: false,
currentBodyPosition: body.Position,
currentBodyOrientation: body.Orientation);
Assert.True(remote.Interp.IsActive);
// The service window allows nothing, so the placement refuses.
RuntimeRemotePlacementDriveController drive =
CreateDrive(lifetime, new FakeServiceWindow());
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
destination,
stopInterpolating: true);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Refused,
drive.ApplyAcceptedRemoteFarSnap(record, remote, route));
Assert.False(remote.Interp.IsActive);
// Refusal is retail's no-resolvable-cell state, and that branch still
// commits the destination — store_position @0x00515CE2. Leaving the
// body at positionBefore with an emptied queue is the freeze both
// reviews found.
Assert.Equal(destination + new Vector3(192f, 0f, 0f), body.Position);
Assert.NotEqual(positionBefore, body.Position);
Assert.True(body.InWorld);
AssertConverged(lifetime);
}
/// <summary>
/// The second non-commit outcome: an entity whose SetPosition operation is
/// already owned by another placement authority contends, so no operation
/// of this route's opens at all — and the body still advances.
/// </summary>
[Fact]
public void FarSnap_ContendedByAnotherAuthority_StillStoresTheDestinationPose()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003024u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
Vector3 positionBefore = body.Position;
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
RuntimeEntityPlacementToken displaced = lifetime.Physics.SetPosition
.TryBeginExclusiveAuthoredPlacement(
record,
record.PositionAuthorityVersion,
RuntimeSetPositionOperationKind.RemoteAuthoritative);
Assert.True(displaced.IsValid);
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
destination,
stopInterpolating: true);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Contention,
drive.ApplyAcceptedRemoteFarSnap(record, remote, route));
Assert.Equal(destination + new Vector3(192f, 0f, 0f), body.Position);
Assert.NotEqual(positionBefore, body.Position);
Assert.Equal(0, drive.PendingCount);
RuntimePlacementCancellationReceipt cancellation = lifetime.Physics
.SetPosition.ForgetExactPlacement(displaced);
if (cancellation.IsValid)
lifetime.Physics.SetPosition.PublishCancellation(cancellation);
AssertConverged(lifetime);
}
/// <summary>
/// The retryable-preparation outcome (an unresolved Setup collision) is
/// also reported as <c>Contention</c>, and it RETAINS an operation for the
/// cadence pump — but the body must not wait for that pump. Retail's
/// analogue never waits: its Setup is always resident, and the object is
/// committed to the destination the moment the packet is handled.
/// </summary>
[Fact]
public void FarSnap_RetryablePreparation_StoresThePoseAndStillRetainsTheRetry()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(
lifetime, 0x70003025u, setupTableId: 0x02000001u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
Vector3 positionBefore = body.Position;
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
destination,
stopInterpolating: true);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Contention,
drive.ApplyAcceptedRemoteFarSnap(record, remote, route));
Assert.Equal(1, drive.PendingCount);
Assert.Equal(destination + new Vector3(192f, 0f, 0f), body.Position);
Assert.NotEqual(positionBefore, body.Position);
// The retained retry converges on its own terms; the pose write above
// is independent of it.
drive.Advance();
Assert.Equal(1, drive.PendingCount);
RuntimePlacementCancellationReceipt cancellation =
lifetime.Physics.SetPosition.Forget(record);
if (cancellation.IsValid)
lifetime.Physics.SetPosition.PublishCancellation(cancellation);
drive.Advance();
Assert.Equal(0, drive.PendingCount);
AssertConverged(lifetime);
}
/// <summary>
/// R8 review fix, part 1 — the RESTORABLE <c>DeferredCell</c> park
/// (<c>SubmitAndResolve</c>'s <c>RuntimeSetPositionStatus.DeferredCell</c>
/// case), which had ZERO coverage in 4b-1 or 4b-2 while the far snap is
/// the first production path that can provoke one. Provoked by letting
/// the service window say "yes" for a destination whose collision
/// generation was never committed, so the engine itself defers.
///
/// <para>
/// The park must be cancelled AND rolled back — <c>CancelToken</c> passes
/// <c>restoreCancelledPark: true</c> and this park opts in with
/// <c>restorableOnCancel: true</c>, so <c>RestoreParkWithdrawal</c>
/// returns <c>InWorld</c>, the object clock, and canonical residency
/// (AP-136). Without the rollback the entity would be left invisible and
/// intangible.
/// </para>
///
/// <para>
/// Delta review: the pose assertion below is the PARK's own
/// <c>store_position</c> (<c>ParkDeferred</c> snaps the body to the
/// deferred result before withdrawing, and the restore deliberately leaves
/// that pose alone), NOT the far arm's fallback — a <c>Deferred</c> status
/// does not store, precisely so the post-sweep park's collision-settled
/// pose cannot be overwritten with the raw destination.
/// </para>
/// </summary>
[Fact]
public void FarSnap_DeferredCellPark_IsCancelledAndRolledBackAtTheDestination()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
// The world frame only — the DESTINATION's collision generation is
// deliberately never committed, which is what makes the engine defer.
lifetime.Physics.ObserveLocalWorldFrame(
SourceCell, teleportAdvanced: false);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003026u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
destination,
stopInterpolating: true);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Deferred,
drive.ApplyAcceptedRemoteFarSnap(record, remote, route));
// The park was rolled back, not left standing.
Assert.True(body.InWorld);
Assert.True(record.ObjectClock.IsActive);
Assert.NotEqual(0u, record.FullCellId);
// …and the body still tracked the server.
Assert.Equal(destination + new Vector3(192f, 0f, 0f), body.Position);
Assert.Equal(
0, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
AssertConverged(lifetime);
}
/// <summary>
/// R8 review fix, part 2 — the NON-restorable park, and why the pre-flight
/// now refuses ahead of it.
///
/// <para>
/// A live in-place collision-prefix quiescence is the residual the class
/// doc names: the tier/residency service window still reads "published",
/// but <c>RuntimeSetPositionState.TryGetBlockingQuiescence</c> defers.
/// When it is the DESTINATION'S OWN prefix that is quiescing — this test —
/// the park stays non-restorable, because AP-136's stated reason applies
/// exactly: <c>RestoreParkWithdrawal</c> would re-admit a spatial root
/// into the prefix that is trying to quiesce, and <c>ParkDeferred</c>
/// declines the rollback whenever the post-snap restore cell is itself
/// quiescing. <c>CanAttemptDestination</c> therefore reads
/// Core's own <c>IsCollisionPrefixQuiescing</c> as part of the SAME
/// pre-flight and refuses instead — and the store_position fallback keeps
/// the remote tracking the server while the prefix mutates.
/// </para>
///
/// <para>
/// Delta review MAJOR B: this is the ONE quiescence shape the pre-flight
/// can see. The source-landblock and swept-neighbour shapes reach Core
/// anyway and are covered by the two tests below, which is why the
/// pre-flight is now an optimisation rather than the correctness
/// mechanism.
/// </para>
/// </summary>
[Fact]
public void FarSnap_QuiescingDestinationPrefix_RefusesWithoutOpeningANonRestorablePark()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003028u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
lifetime.Physics.SetPosition.BeginCollisionPrefixQuiescence(
DestinationLandblock,
collisionGeneration: 1UL,
includeOutdoorCells: true);
// The window is unchanged and still says yes — this is precisely the
// case it cannot see.
Assert.True(window.IsWithinServiceWindow(DestinationCell));
Assert.True(
lifetime.Physics.SetPosition.IsCollisionPrefixQuiescing(
DestinationLandblock));
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
destination,
stopInterpolating: true);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Refused,
drive.ApplyAcceptedRemoteFarSnap(record, remote, route));
// No park was ever opened, so there is nothing to fail to restore.
Assert.True(body.InWorld);
Assert.True(record.ObjectClock.IsActive);
Assert.Equal(destination + new Vector3(192f, 0f, 0f), body.Position);
Assert.Equal(
0, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
AssertConverged(lifetime);
}
/// <summary>
/// Delta review MAJOR B, route 1 of 2 — the SOURCE landblock quiesces.
///
/// <para>
/// <c>CanAttemptDestination</c> tests the DESTINATION prefix and passes,
/// but Core's <c>PlacementTouchesPrefix</c> also matches the request's
/// <c>CurrentCellId</c>, populated from <c>record.FullCellId</c> whenever
/// the body is in world — so a far snap OUT of a quiescing landblock
/// parks at the pre-sweep site no pre-flight can see.
/// </para>
///
/// <para>
/// <b>Round 3 — reachability caveat, measured.</b> The earlier text called
/// this "the likelier of the two shapes". It is not reached by the
/// graphical remote caller at all: that path commits the accepted WIRE
/// cell to <c>record.FullCellId</c> in its shared prologue
/// (<c>LiveEntityRuntime.RebucketLiveEntity</c> →
/// <c>RuntimeEntityObjectLifetime.CommitRebucket</c>) before it routes, so
/// <c>CurrentCellId</c> names the DESTINATION by submit time and the
/// source prefix never matches. This fixture reaches the shape because it
/// drives the seam directly and never rebuckets. The test still earns its
/// place — it is the only coverage of the pre-sweep quiescence park's
/// restore, which a future caller that submits without rebucketing (or a
/// prologue reordering) would reach — but it must not be cited as the
/// production-likely case. The reachable production shapes are the
/// quiescing DESTINATION (refused by the pre-flight here, parked
/// non-restorably on route 2) and the quiescing SWEPT NEIGHBOUR (the test
/// below).
/// </para>
///
/// <para>
/// With the park non-restorable (the shipped state before this fix) the
/// remote is left <c>InWorld = false</c>, clock suspended,
/// <c>FullCellId = 0</c>, with the only operation able to wake it
/// destroyed by <c>CancelToken</c>. <c>ParkDeferred</c> now makes it
/// restorable because the cell it snapped to — the DESTINATION, which is
/// the cell <c>RestoreParkWithdrawal</c> restores residency into — is not
/// quiescing, so nothing is re-admitted into the retiring source.
/// </para>
/// </summary>
[Fact]
public void FarSnap_QuiescingSourceLandblock_RestoresTheRemoteIntoTheWorld()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003030u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
lifetime.Physics.SetPosition.BeginCollisionPrefixQuiescence(
SourceLandblock,
collisionGeneration: 1UL,
includeOutdoorCells: true);
// Both halves of the pre-flight pass — it reads only the destination,
// and cannot see the source at all.
Assert.True(window.IsWithinServiceWindow(DestinationCell));
Assert.False(
lifetime.Physics.SetPosition.IsCollisionPrefixQuiescing(
DestinationLandblock));
Assert.True(
lifetime.Physics.SetPosition.IsCollisionPrefixQuiescing(
SourceLandblock));
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
destination,
stopInterpolating: true);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Deferred,
drive.ApplyAcceptedRemoteFarSnap(record, remote, route));
Assert.True(body.InWorld);
Assert.True(record.ObjectClock.IsActive);
Assert.NotEqual(0u, record.FullCellId);
Assert.Equal(destination + new Vector3(192f, 0f, 0f), body.Position);
Assert.Equal(
0, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
AssertConverged(lifetime);
}
/// <summary>
/// Delta review MAJOR B route 2 of 2, and MAJOR C — a merely-SWEPT
/// NEIGHBOUR landblock quiesces, on a placement that would otherwise have
/// COMMITTED.
///
/// <para>
/// The destination sits one sphere radius inside the seam between
/// <c>DestinationLandblock</c> and its +X neighbour, so
/// <c>CellTransit.AddAllOutsideCells</c> adds the neighbour's cells to the
/// sweep footprint — <c>AddOutsideCell</c> re-derives the block id from
/// the global lcoord and states outright that there is no same-block
/// filter. Core's <c>ResultTouchesPrefix</c> scans every
/// <c>QueriedCellIds</c> entry, so the POST-sweep quiescence check fires
/// on a footprint that did not exist until the sweep ran. No pre-flight
/// can reproduce that, which is the structural half of MAJOR B.
/// </para>
///
/// <para>
/// MAJOR C: that check is <c>result.IsSuccessful &amp;&amp;
/// TryGetBlockingQuiescence(result, …)</c> and sits AHEAD of the
/// restorable <c>result.IsDeferred</c> park, so a healthy, resident,
/// about-to-commit far snap near a seam was rewritten to
/// <c>DeferredCell</c> and parked non-restorably. The
/// <c>Assert.NotEqual(0u, record.FullCellId)</c> below is what fails
/// without the fix.
/// </para>
/// </summary>
[Fact]
public void FarSnap_QuiescingSweptNeighbour_RestoresTheRemoteIntoTheWorld()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
CommitLandblockCollision(
lifetime, NeighbourLandblock, worldOffsetX: 384f);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003031u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
lifetime.Physics.SetPosition.BeginCollisionPrefixQuiescence(
NeighbourLandblock,
collisionGeneration: 1UL,
includeOutdoorCells: true);
// Neither half of the pre-flight can see the neighbour.
Assert.True(window.IsWithinServiceWindow(DestinationSeamCell));
Assert.False(
lifetime.Physics.SetPosition.IsCollisionPrefixQuiescing(
DestinationLandblock));
// Block-local X = 191.95 m: inside cell (7, 0) of the destination
// landblock, 0.05 m from the 192 m seam — closer than the 0.1 m dummy
// sphere radius, which is the `pointX > CellLength - radius` test
// AddAllOutsideCells applies before adding lx + 1.
// Z is deliberately 1 m BELOW the flat terrain so the placement sweep
// lifts the sphere back to the surface: the parked result then carries
// a settled Z that differs from the raw accepted one, which is what
// makes the "Deferred does not store" arm (delta review N2)
// discriminating rather than latent.
var destination = new Vector3(191.95f, 10f, SpawnHeight - 1f);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationSeamCell,
destination,
stopInterpolating: true);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Deferred,
drive.ApplyAcceptedRemoteFarSnap(record, remote, route));
Assert.True(body.InWorld);
Assert.True(record.ObjectClock.IsActive);
Assert.NotEqual(0u, record.FullCellId);
// ParkDeferred already performed retail's store_position, at the
// SETTLED pose; the far arm must not write the raw destination over it.
Assert.Equal(SpawnHeight, body.Position.Z);
Assert.Equal(
0, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
AssertConverged(lifetime);
}
/// <summary>
/// Round-3 correction A5 — why <c>CanAttemptDestination</c> is
/// load-bearing and must not be deleted as "just an optimisation".
///
/// <para>
/// Two live quiescences at once, SOURCE opened first so its
/// <c>OperationId</c> is the lower one. Core files the park under the
/// source, but the cell the rollback would restore into is the
/// DESTINATION, which is retiring — so <c>ParkDeferred</c> would
/// (correctly) refuse the rollback and the remote would be left withdrawn
/// until some later packet commits.
/// </para>
///
/// <para>
/// The pre-flight is what keeps that shape off the remote path entirely:
/// it reads the destination prefix, refuses BEFORE any park is opened,
/// and the <c>store_position</c> fallback keeps the remote tracking the
/// server while both prefixes mutate.
/// </para>
///
/// <para>
/// <b>Round 4 — cross-reference corrected.</b> The earlier text cited a
/// route-2 sibling named
/// <c>ConcurrentQuiescences_ParkIsNotRestoredIntoTheQuiescingDestination</c>.
/// No such test exists, and it cannot: this two-quiescence shape needs
/// the park to be filed under a prefix that is NOT the restore cell's,
/// which needs <c>PlacementTouchesPrefix</c>'s <c>CurrentCellId</c> arm to
/// name a different landblock than the request — and route 2's merge
/// commits the accepted wire cell to <c>record.FullCellId</c> before the
/// drive runs, so on that route the two are the same prefix by
/// construction. (This fixture reaches the shape only because it drives
/// the seam directly and never rebuckets — the same caveat
/// <c>FarSnap_QuiescingSourceLandblock_RestoresTheRemoteIntoTheWorld</c>
/// carries.) The route-2 test that pins the restore decision itself is
/// <c>RuntimeAcceptedPositionDriveControllerTests
/// .QuiescingOwnPrefix_SeamCrossingParkIsRestoredAtTheReDerivedNeighbourCell</c>,
/// which discriminates on the OTHER half of the same predicate: the
/// post-snap restore cell versus the caller's pre-snap
/// <c>result.CellId</c>.
/// </para>
///
/// <para>
/// <b>Scope of this test's own evidence (round 4, N2).</b> It is
/// behaviourally redundant with
/// <c>FarSnap_QuiescingDestinationPrefix_RefusesWithoutOpeningANonRestorablePark</c>
/// — both fail identically if the pre-flight's
/// <c>IsCollisionPrefixQuiescing</c> half is removed — and the
/// <c>OperationId</c> ordering asserted below never influences an
/// observed outcome here, because the pre-flight refuses before any
/// blocking token is selected. It documents the concurrent-quiescence
/// shape and pins the refusal; it does not prove which token Core would
/// have chosen.
/// </para>
/// </summary>
[Fact]
public void FarSnap_ConcurrentQuiescences_RefusesBeforeOpeningAPark()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003037u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
RuntimeCollisionPrefixQuiescenceToken sourceQuiescence =
lifetime.Physics.SetPosition.BeginCollisionPrefixQuiescence(
SourceLandblock,
collisionGeneration: 2UL,
includeOutdoorCells: true);
RuntimeCollisionPrefixQuiescenceToken destinationQuiescence =
lifetime.Physics.SetPosition.BeginCollisionPrefixQuiescence(
DestinationLandblock,
collisionGeneration: 2UL,
includeOutdoorCells: true);
Assert.True(
sourceQuiescence.OperationId < destinationQuiescence.OperationId);
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
destination,
stopInterpolating: true);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Refused,
drive.ApplyAcceptedRemoteFarSnap(record, remote, route));
// No park was opened, so nothing was ever withdrawn — and nothing was
// re-admitted into either retiring prefix.
Assert.True(body.InWorld);
Assert.True(record.ObjectClock.IsActive);
Assert.Equal(destination + new Vector3(192f, 0f, 0f), body.Position);
Assert.Equal(
0, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
AssertConverged(lifetime);
}
/// <summary>
/// Delta review MAJOR A, the do-NOT-store side. The engine's own sweep
/// refuses the destination — retail
/// <c>CPhysicsObj::SetPositionInternal</c> @0x00515BD0 reaches
/// <c>CheckPositionInternal == 0</c> @0x00515C85,
/// <c>handle_all_collisions</c> @0x00515CC2 and
/// <c>return ((eax_14 - eax_14) &amp; 2) + 2</c> @0x00515CD5 WITHOUT ever
/// calling <c>store_position</c>. The shipped fix round routed this
/// through the fallback, which teleported the canonical body into a
/// destination the engine had just refused.
/// </summary>
[Fact]
public void FarSnap_EngineRefusedTheDestination_LeavesTheBodyWhereItWas()
{
PhysicsEngine engine = FlatEngine();
using var lifetime = new RuntimeEntityObjectLifetime(engine);
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003032u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
Vector3 positionBefore = body.Position;
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
engine.TransitionCellCollisionTestHook =
static (_, _, _, _) => TransitionState.Collided;
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
destination,
stopInterpolating: true);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.RejectedByPlacement,
drive.ApplyAcceptedRemoteFarSnap(record, remote, route));
// Retail leaves the object where it was on 2/3/4.
Assert.Equal(positionBefore, body.Position);
Assert.NotEqual(destination + new Vector3(192f, 0f, 0f), body.Position);
Assert.Equal(
0, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
AssertConverged(lifetime);
}
/// <summary>
/// Delta review MAJOR A, the worse sub-case:
/// <c>SubmitPreparedPlacementCore</c> returns <c>Cancelled</c> AFTER
/// <c>CommitCanonical</c> succeeded (F1 — "retail lets that physical
/// commit land regardless"), so the body carries a freshly SETTLED pose
/// while this caller's own operation is no longer canonical. The shipped
/// fix round mapped that to the fallback and overwrote the settle with the
/// raw accepted destination.
///
/// <para>
/// The displacement is provoked the same way
/// <c>ReentrantGroundEdgePlacementCannotBeCancelledByDisplacedOperation</c>
/// provokes it — through the ground-edge <c>HitGround</c> callback
/// <c>CommitSetPositionContactTransition</c> invokes mid-commit — and the
/// callback also merges a NEWER accepted Position into the snapshot,
/// which is the production shape (packet N+1 arriving while packet N is
/// still committing). That merge is what makes the assertion discriminate:
/// if the fallback fires it reads the snapshot at store time and lands the
/// body on the newer destination instead of the settled pose.
/// </para>
/// </summary>
[Fact]
public void FarSnap_CancelledAfterTheCommitSettled_KeepsTheSettledPose()
{
PhysicsEngine engine = FlatEngine();
engine.TransitionCellCollisionTestHook =
(transition, phase, _, observed) =>
{
if (phase == TransitionCellCollisionPhase.Environment)
{
transition.CollisionInfo.SetContactPlane(
new Plane(Vector3.UnitZ, 0f),
DestinationCell);
}
return observed;
};
using var lifetime = new RuntimeEntityObjectLifetime(engine);
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003033u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var destination = new Vector3(12f, 14f, SpawnHeight);
var supersedingDestination = new Vector3(77f, 88f, SpawnHeight);
Vector3 settled = Vector3.Zero;
RuntimeEntityPlacementToken displaced = default;
remote.Movement.Minterp.RemoveLinkAnimations = () =>
{
settled = body.Position;
record.Snapshot = record.Snapshot with
{
Position = new CreateObject.ServerPosition(
DestinationCell,
supersedingDestination.X,
supersedingDestination.Y,
supersedingDestination.Z,
1f,
0f,
0f,
0f),
};
displaced = lifetime.Physics.SetPosition.BeginAcceptedPlacement(
record,
record.PositionAuthorityVersion,
RuntimeSetPositionOperationKind.RemoteAuthoritative);
};
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
destination,
stopInterpolating: true);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.RejectedByPlacement,
drive.ApplyAcceptedRemoteFarSnap(record, remote, route));
// The ground-edge callback really did run mid-commit, and the commit
// really did settle the body before it.
Assert.True(displaced.IsValid);
Assert.NotEqual(Vector3.Zero, settled);
Assert.Equal(settled, body.Position);
Assert.NotEqual(
supersedingDestination + new Vector3(192f, 0f, 0f),
body.Position);
RuntimePlacementCancellationReceipt cancellation = lifetime.Physics
.SetPosition.ForgetExactPlacement(displaced);
if (cancellation.IsValid)
lifetime.Physics.SetPosition.PublishCancellation(cancellation);
AssertConverged(lifetime);
}
/// <summary>
/// Delta review MAJOR A, the store side one stage later than the
/// pre-flight: preparation refuses TERMINALLY
/// (<c>RuntimeSetPositionMoverPreparationStatus.InvalidData</c>, here from
/// a destination cell id <c>PositionFrameValidation</c> rejects), so the
/// engine was never called and retail's no-transition branch — the one
/// that DOES <c>store_position</c> @0x00515CE2 — is what this state
/// corresponds to.
/// </summary>
[Fact]
public void FarSnap_PreparationRejected_StillStoresTheDestinationPose()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003034u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
Vector3 positionBefore = body.Position;
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
// Cell low 0 is outside LandDefs.CellLowInRange, so
// IsStructurallyValid refuses the prepared frame — while the landblock
// prefix is still the one the pre-flight and the world frame resolve.
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationLandblock,
destination,
stopInterpolating: true);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.RejectedPreparation,
drive.ApplyAcceptedRemoteFarSnap(record, remote, route));
Assert.Equal(destination + new Vector3(192f, 0f, 0f), body.Position);
Assert.NotEqual(positionBefore, body.Position);
Assert.Equal(0, drive.PendingCount);
Assert.Equal(
0, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
AssertConverged(lifetime);
}
/// <summary>
/// Delta review MAJOR D: the <c>store_position</c> fallback must
/// re-validate position ownership before it writes, exactly as
/// <c>RuntimeSetPositionState.RestoreParkWithdrawal</c> does and exactly
/// as this route's own remarks demand of every caller "on EVERY placement
/// status, before writing anything else for the packet".
///
/// <para>
/// The production producer is <c>CancelToken</c>'s SYNCHRONOUS
/// cancellation receipt: the placement-projection sink can delete or
/// replace the incarnation from inside the publish, so the record can stop
/// being canonical between the placement returning and the fallback
/// running, and the App-side re-validation only happens after the seam
/// returns. This test reaches that state deterministically by dropping the
/// record from the active directory while every other field it holds — the
/// key, the canonical body, the accepted snapshot — stays exactly as the
/// packet left it. That isolation matters: a full incarnation replacement
/// also clears the key and the body, so it would be caught by the null
/// checks and would prove nothing about the currency test itself.
/// </para>
///
/// <para>
/// <b>What this does and does NOT pin (round 3, correction m3).</b> It
/// pins that the guard exists, that its predicate is
/// <c>Entities.IsCurrent</c> and not a null check, and that it runs on
/// the storing side. It does NOT pin the ORDERING that made the defect
/// reachable in production — the guard sitting AFTER
/// <c>CancelToken</c>'s synchronous cancellation receipt — because the
/// status it drives to is <see cref="RuntimeRemotePlacementExecutionStatus.Refused"/>,
/// which never calls <c>CancelToken</c> at all. Pinning the ordering
/// needs a placement-projection sink that supersedes the incarnation from
/// inside the publish; that sink is production infrastructure this bare
/// <see cref="RuntimeEntityObjectLifetime"/> fixture does not install,
/// and building a stand-in here would test the stand-in.
/// </para>
/// </summary>
[Fact]
public void FarSnap_SupersededIncarnation_DoesNotStoreThroughTheStaleRecord()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003036u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
Vector3 positionBefore = body.Position;
// The service window refuses, so the status is Refused — squarely on
// the STORING side of the partition. The currency guard inside
// StoreAcceptedDestinationPose is therefore the only thing standing
// between this packet and a pose written through a record that is no
// longer the canonical owner.
RuntimeRemotePlacementDriveController drive =
CreateDrive(lifetime, new FakeServiceWindow());
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
destination,
stopInterpolating: true);
Assert.True(lifetime.Entities.RemoveActive(record));
Assert.False(lifetime.Entities.IsCurrent(record));
Assert.NotNull(record.PhysicsBody);
Assert.NotNull(record.Key);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Refused,
drive.ApplyAcceptedRemoteFarSnap(record, remote, route));
Assert.Equal(positionBefore, body.Position);
Assert.NotEqual(destination + new Vector3(192f, 0f, 0f), body.Position);
AssertConverged(lifetime);
}
/// <summary>
/// Delta review N1: <see cref="RuntimeRemotePlacementDriveController.Advance"/>'s
/// window-drop path is the entry point's <c>Refused</c> semantics one
/// cadence pump later, so it owes the same <c>store_position</c>. Without
/// it a retained retry whose destination leaves the window reproduces a
/// smaller version of the freeze this round exists to fix — the remote
/// stops at whatever pose the FIRST packet stored and never advances
/// again.
/// </summary>
[Fact]
public void Advance_DestinationLeavesTheWindow_StoresTheNewestDestinationPose()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(
lifetime, 0x70003035u, setupTableId: 0x02000001u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
// The Setup collision never resolves, so the entry point retains a
// preparation retry for the cadence pump.
var firstDestination = new Vector3(12f, 14f, SpawnHeight);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Contention,
drive.ApplyAcceptedRemoteFarSnap(
record,
remote,
MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
firstDestination,
stopInterpolating: true)));
Assert.Equal(1, drive.PendingCount);
Assert.Equal(
firstDestination + new Vector3(192f, 0f, 0f), body.Position);
// The server keeps broadcasting while the retry sits retained: the
// accepted snapshot moves on, and the destination's collision
// publication retires out from under the retry.
var newestDestination = new Vector3(40f, 50f, SpawnHeight);
record.Snapshot = record.Snapshot with
{
Position = new CreateObject.ServerPosition(
DestinationCell,
newestDestination.X,
newestDestination.Y,
newestDestination.Z,
1f,
0f,
0f,
0f),
};
window.Forbid(DestinationLandblock);
drive.Advance();
Assert.Equal(0, drive.PendingCount);
Assert.Equal(
newestDestination + new Vector3(192f, 0f, 0f), body.Position);
Assert.Equal(
0, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
AssertConverged(lifetime);
}
/// <summary>
/// R9 review fix: contract item 7 names currency across GUID reuse and
/// incarnation, and 4b-2 shipped only the interleaving and teardown
/// dimensions. <see cref="RuntimeRemotePlacementDriveController"/>'s two
/// maps are keyed by <c>RuntimeEntityKey</c> (guid + incarnation), so a
/// reused GUID produces a NEW key and cannot displace the old entry by
/// itself — a dead-incarnation entry would accumulate until
/// <c>DetachRoute</c>.
///
/// <para>
/// The convergence must therefore be IN-SESSION and must not need a
/// teardown: this test retires incarnation 1, re-creates the same GUID at
/// incarnation 2, and asserts the ledger reads zero with the route still
/// attached.
/// </para>
/// </summary>
[Fact]
public void RemotePlacementLedger_ConvergesAcrossGuidReuse_WithoutTeardown()
{
const uint reusedGuid = 0x70003027u;
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var route = new object();
drive.AttachRoute(route);
// Incarnation 1: a far snap whose Setup never resolves, so the
// controller retains a preparation retry keyed by (guid, 1).
RuntimeEntityRecord first = CreateRemoteRecord(
lifetime, reusedGuid, setupTableId: 0x02000001u);
AttachBody(lifetime, first, SourceCell);
RemoteMotion firstRemote = lifetime.Physics.GetOrCreateRemoteMotion(first);
uint firstIncarnation = first.Incarnation;
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Contention,
drive.ApplyAcceptedRemoteFarSnap(
first,
firstRemote,
MakeRoute(
first,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
new Vector3(12f, 14f, SpawnHeight),
stopInterpolating: true)));
Assert.Equal(1, drive.PendingCount);
// The incarnation is replaced and the SAME guid comes back — the exact
// shape ACE produces when an entity leaves and re-enters radar range.
RuntimeEntityRecord second = CreateRemoteRecord(
lifetime, reusedGuid, instanceSequence: 1);
Assert.NotEqual(firstIncarnation, second.Incarnation);
AttachBody(lifetime, second, SourceCell);
// Delta review N7 — the assertions below are ORDER-DEPENDENT and the
// order is now deliberate and documented, because the previous version
// presented them as two independent facts when they are not.
// `PendingCount` is the RAW map size (its own doc says so) and
// `_pending` still holds the dead incarnation-1 entry at this point;
// `CountLivePending`, the ledger's provider, is what prunes it. So:
//
// 1. The LEDGER read is the R9 claim, and it must converge with the
// route still attached, no teardown, no Advance() pump.
// 2. The raw count is then asserted as the POST-heal state — proof
// that the read pruned rather than merely reporting a filtered
// view while the map grew unbounded (the leak R9 describes).
Assert.Equal(
0,
lifetime.CaptureOwnership().RemotePlacementDrivePendingCount);
Assert.Equal(0, drive.PendingCount);
Assert.Equal(
0, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
AssertConverged(lifetime);
drive.DetachRoute(route);
}
/// <summary>
/// The classifier's <c>StopInterpolating</c> flag
/// (<c>:467</c>, <c>!nearby</c>) is what gates the queue clear — the
/// retail condition is READ from the route, never restated. A route
/// carrying <see langword="false"/> must leave the queue alone.
/// </summary>
[Fact]
public void FarSnap_HonoursTheRoutesOwnStopInterpolatingFlag()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003021u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
remote.Interp.Enqueue(
new Vector3(40f, 40f, SpawnHeight),
Quaternion.Identity,
isMovingTo: false,
currentBodyPosition: body.Position,
currentBodyOrientation: body.Orientation);
RuntimeRemotePlacementDriveController drive =
CreateDrive(lifetime, new FakeServiceWindow());
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
stopInterpolating: false);
_ = drive.ApplyAcceptedRemoteFarSnap(record, remote, route);
Assert.True(remote.Interp.IsActive);
}
[Fact]
public void FarSnap_CommitsThroughTheCanonicalPlacementOwner()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003022u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
destination,
stopInterpolating: true);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Committed,
drive.ApplyAcceptedRemoteFarSnap(record, remote, route));
// RemoteMotion shares the canonical body, so the placement's own
// committed pose IS the remote's body pose — no second write.
Assert.Same(body, remote.Body);
Assert.Equal(destination + new Vector3(192f, 0f, 0f), body.Position);
Assert.Equal(DestinationCell, record.FullCellId);
DrainPlacementFifo(lifetime);
Assert.Equal(
0, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
AssertConverged(lifetime);
}
/// <summary>
/// The far arm must never be handed a route it does not own — the caller
/// selects with <c>RuntimeRemoteFarSnapPosition.ResolveArm</c>. Failing
/// loudly is the alternative to silently clearing an interpolation queue
/// for a classification (cell-less, rejected, near) that has no business
/// stopping it.
/// </summary>
[Fact]
public void FarSnap_ThrowsForARouteThisArmDoesNotOwn()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003023u);
AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
RuntimeRemotePlacementDriveController drive =
CreateDrive(lifetime, new FakeServiceWindow());
foreach (RuntimeAuthoritativePositionDisposition disposition in
new[]
{
RuntimeAuthoritativePositionDisposition.SetPosition,
RuntimeAuthoritativePositionDisposition.Interpolate,
RuntimeAuthoritativePositionDisposition.NoPositionOperation,
RuntimeAuthoritativePositionDisposition.RejectedData,
})
{
RuntimeAuthoritativePositionRoute route = MakeRoute(
record, disposition, DestinationCell, stopInterpolating: true);
Assert.Throws<ArgumentException>(
() => drive.ApplyAcceptedRemoteFarSnap(record, remote, route));
}
}
// ── C4 route 4b-3: the teleport/cell-less arm ───────────────────────────
// TryExecuteAcceptedRemotePosition/SubmitAndResolve's own mechanics
// (commit/park/reject dispatch, currency, ledger convergence) are already
// exhaustively proven above for SetPosition-disposition routes — several
// far-snap tests already construct SetPosition routes because
// TryExecuteAcceptedRemotePosition is disposition-agnostic. What is new
// here is ApplyAcceptedRemoteTeleport's OWN behaviour: the route guard,
// the store_position fallback wired for the teleport disposition
// specifically, and (D3) that it does NOT clear the interpolation queue
// itself — unlike the far arm, retail's clear for this branch lives
// inside teleport_hook, not in MoveOrTeleport.
/// <summary>
/// Mirrors <see cref="Committed_WhenDestinationIsWithinServiceWindowAndCollisionGenerationCommitted"/>
/// through the teleport arm specifically.
/// </summary>
[Fact]
public void Teleport_Committed_PlacesFromCanonicalDestination()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003040u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
destination);
RuntimeRemotePlacementExecutionStatus status =
drive.ApplyAcceptedRemoteTeleport(record, remote, route);
Assert.Equal(RuntimeRemotePlacementExecutionStatus.Committed, status);
Assert.Equal(destination + new Vector3(192f, 0f, 0f), body.Position);
DrainPlacementFifo(lifetime);
Assert.Equal(
0, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
AssertConverged(lifetime);
}
/// <summary>
/// Invariant 1: a teleport whose destination the service window declines
/// still advances the body to the accepted destination — retail's
/// no-transition <c>store_position</c> branch, identical to the far arm's
/// own fallback.
/// </summary>
[Fact]
public void Teleport_RefusedByServiceWindow_StillStoresTheDestinationPose()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
// The world frame must still be published (store_position resolves
// through it); the service window is what refuses — mirrors
// FarSnap_ClearsTheInterpolationQueue_IndependentlyOfThePlacementOutcome's
// setup, which is the far arm's own Refused-fallback test.
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003041u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
Vector3 positionBefore = body.Position;
// Deliberately does not Allow(DestinationLandblock) — the service
// window refuses.
var window = new FakeServiceWindow();
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
destination);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Refused,
drive.ApplyAcceptedRemoteTeleport(record, remote, route));
Assert.NotEqual(positionBefore, body.Position);
Assert.True(body.InWorld);
AssertConverged(lifetime);
}
/// <summary>
/// The non-storing half of retail's partition, through the teleport arm:
/// the engine's own sweep refused the destination
/// (<c>RejectedByPlacement</c>), so the body must be left exactly where
/// it was — mirrors
/// <see cref="FarSnap_EngineRefusedTheDestination_LeavesTheBodyWhereItWas"/>.
/// </summary>
[Fact]
public void Teleport_EngineRefusedTheDestination_LeavesTheBodyWhereItWas()
{
PhysicsEngine engine = FlatEngine();
using var lifetime = new RuntimeEntityObjectLifetime(engine);
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003042u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
Vector3 positionBefore = body.Position;
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
engine.TransitionCellCollisionTestHook =
static (_, _, _, _) => TransitionState.Collided;
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
destination);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.RejectedByPlacement,
drive.ApplyAcceptedRemoteTeleport(record, remote, route));
Assert.Equal(positionBefore, body.Position);
Assert.NotEqual(destination + new Vector3(192f, 0f, 0f), body.Position);
AssertConverged(lifetime);
}
/// <summary>
/// D3: unlike the far arm, <c>ApplyAcceptedRemoteTeleport</c> must NOT
/// clear the interpolation queue itself — the classifier's teleport
/// branch carries <c>StopInterpolating: false</c> on purpose, because
/// retail's clear for this branch lives inside <c>teleport_hook</c>'s
/// <c>PositionManager::StopInterpolating</c> @0x00514EFD, which the
/// CALLER (<c>ApplyRemoteContactRouting</c>) runs before this method. If
/// this method also cleared the queue, the two would race on which side
/// "owns" the retail action.
/// </summary>
[Fact]
public void Teleport_DoesNotClearTheInterpolationQueueItself()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003043u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
remote.Interp.Enqueue(
new Vector3(40f, 40f, SpawnHeight),
Quaternion.Identity,
isMovingTo: false,
currentBodyPosition: body.Position,
currentBodyOrientation: body.Orientation);
Assert.True(remote.Interp.IsActive);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
new Vector3(12f, 14f, SpawnHeight));
Assert.False(route.StopInterpolating);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Committed,
drive.ApplyAcceptedRemoteTeleport(record, remote, route));
Assert.True(remote.Interp.IsActive);
DrainPlacementFifo(lifetime);
}
/// <summary>
/// The teleport arm must never be handed a route it does not own — the
/// caller selects with
/// <c>RuntimeRemoteTeleportPosition.OwnsTeleportPlacement</c>. Mirrors
/// <see cref="FarSnap_ThrowsForARouteThisArmDoesNotOwn"/>.
/// </summary>
[Fact]
public void Teleport_ThrowsForARouteThisArmDoesNotOwn()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003044u);
AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
RuntimeRemotePlacementDriveController drive =
CreateDrive(lifetime, new FakeServiceWindow());
foreach (RuntimeAuthoritativePositionDisposition disposition in
new[]
{
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
RuntimeAuthoritativePositionDisposition.Interpolate,
RuntimeAuthoritativePositionDisposition.NoPositionOperation,
RuntimeAuthoritativePositionDisposition.RejectedData,
})
{
RuntimeAuthoritativePositionRoute route = MakeRoute(
record, disposition, DestinationCell);
Assert.Throws<ArgumentException>(
() => drive.ApplyAcceptedRemoteTeleport(record, remote, route));
}
}
/// <summary>
/// Test-plan item 7 / contract D3's currency rule, "now for the teleport
/// arm" — the R5 shape
/// <see cref="FarSnap_SupersededIncarnation_DoesNotStoreThroughTheStaleRecord"/>
/// already pins for <c>ApplyAcceptedRemoteFarSnap</c>. Retail's
/// <c>store_position</c> fallback is the SAME method
/// (<c>StoreAcceptedDestinationPose</c>) both arms call through, but that
/// sharing is exactly why it needs its own pin: a future edit could special-
/// case one arm's call site without the other, and only a same-shaped test
/// for each caller catches that. Reaches the stale-record state the same
/// deterministic way — dropping the record from the active directory while
/// its body/key/snapshot stay exactly as the packet left them, so the
/// currency guard (not a null check) is what's under test.
/// </summary>
[Fact]
public void Teleport_SupersededIncarnation_DoesNotStoreThroughTheStaleRecord()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70003045u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
Vector3 positionBefore = body.Position;
// Deliberately does not Allow(DestinationLandblock) — the service
// window refuses, landing on the SAME store_position fallback the far
// arm's currency test exercises.
RuntimeRemotePlacementDriveController drive =
CreateDrive(lifetime, new FakeServiceWindow());
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
destination);
Assert.True(lifetime.Entities.RemoveActive(record));
Assert.False(lifetime.Entities.IsCurrent(record));
Assert.NotNull(record.PhysicsBody);
Assert.NotNull(record.Key);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Refused,
drive.ApplyAcceptedRemoteTeleport(record, remote, route));
Assert.Equal(positionBefore, body.Position);
Assert.NotEqual(destination + new Vector3(192f, 0f, 0f), body.Position);
AssertConverged(lifetime);
}
/// <summary>
/// Test-plan item 8 / proof obligation 2: teardown, session reset, and
/// generation change all converge <c>RemotePlacementDrivePendingCount</c>
/// to zero — driven through <see cref="ApplyAcceptedRemoteTeleport"/>
/// itself, not assumed transitively from
/// <see cref="LedgerConverges_AfterDetachRouteClearsTrackedEntries"/>
/// (which seeds its retained entry through the lower shared
/// <c>TryExecuteAcceptedRemotePosition</c> entry point, bypassing the
/// teleport arm's own route-ownership check entirely). <c>DetachRoute</c>
/// is the one production convergence hook this controller exposes —
/// <c>GameRuntime</c>'s teardown, session reset, and generation-change
/// paths all funnel through it, exactly as they do for the far arm's own
/// already-covered case; there is no separate per-cause API to test
/// independently at this layer.
///
/// <para>
/// Retains via the SAME "retryable preparation" shape
/// <see cref="FarSnap_RetryablePreparation_StoresThePoseAndStillRetainsTheRetry"/>
/// uses (an unresolved Setup collision reports <c>Contention</c> and
/// parks an entry in <c>_pending</c> for the cadence pump) — so the
/// convergence this test proves is genuinely draining a LIVE retained
/// teleport retry, not an already-empty ledger.
/// </para>
/// </summary>
[Fact]
public void Teleport_LedgerConverges_AfterDetachRouteClearsARetainedRetry()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
RuntimeEntityRecord record = CreateRemoteRecord(
lifetime, 0x70003046u, setupTableId: 0x02000001u);
PhysicsBody body = AttachBody(lifetime, record, SourceCell);
RemoteMotion remote = lifetime.Physics.GetOrCreateRemoteMotion(record);
Vector3 positionBefore = body.Position;
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var route = new object();
drive.AttachRoute(route);
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute teleportRoute = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
destination,
stopInterpolating: true);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Contention,
drive.ApplyAcceptedRemoteTeleport(record, remote, teleportRoute));
// The retained retry is live (not assumed) — a second call through
// the arm proves it, mirroring the far arm's own
// FarSnap_RetryablePreparation test's shape.
Assert.Equal(1, drive.PendingCount);
Assert.Equal(
1, lifetime.CaptureOwnership().RemotePlacementDrivePendingCount);
Assert.Equal(
destination + new Vector3(192f, 0f, 0f), body.Position);
Assert.NotEqual(positionBefore, body.Position);
drive.DetachRoute(route);
Assert.Equal(0, drive.PendingCount);
Assert.Equal(
0, lifetime.CaptureOwnership().RemotePlacementDrivePendingCount);
AssertConverged(lifetime);
}
// ── C4 route 5: projectile arm (D-P2/D-P3/D-P4/D-P5) ───────────────────
/// <summary>
/// D-P3: the widening itself, isolated from any entity/body — mirrors
/// <see cref="OwnsPlacement_FalseWhenOperationKindIsNotRemoteAuthoritative"/>'s
/// shape but for the positive case.
/// </summary>
[Fact]
public void OwnsPlacement_TrueForProjectileAuthoritative_SetPositionAndSetPositionSimple()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70004001u);
foreach (RuntimeAuthoritativePositionDisposition disposition in
new[]
{
RuntimeAuthoritativePositionDisposition.SetPosition,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
})
{
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
disposition,
DestinationCell,
operationKind: RuntimeSetPositionOperationKind.ProjectileAuthoritative);
Assert.True(RuntimeRemotePlacementDriveController.OwnsPlacement(route));
}
// A projectile Create (InitialCreateFlags, no Teleport bit) is still
// excluded — the same Teleport-flag discriminator that excludes a
// remote top-level Create.
RuntimeAuthoritativePositionRoute createRoute = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
operationKind: RuntimeSetPositionOperationKind.ProjectileAuthoritative,
setPositionFlags: PhysicsSetPositionFlags.Placement
| PhysicsSetPositionFlags.Slide);
Assert.False(RuntimeRemotePlacementDriveController.OwnsPlacement(createRoute));
}
[Fact]
public void ApplyAcceptedProjectilePosition_Null_WhenOperationKindIsNotProjectileAuthoritative()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
(RuntimeEntityRecord record, _) = CreateProjectileRecord(
lifetime, 0x70004002u, SourceCell);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
operationKind: RuntimeSetPositionOperationKind.RemoteAuthoritative);
Assert.Null(drive.ApplyAcceptedProjectilePosition(record, route));
Assert.Equal(0, drive.PendingCount);
AssertConverged(lifetime);
}
[Fact]
public void ApplyAcceptedProjectilePosition_Null_WhenNoProjectileComponentIsBound()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
RuntimeEntityRecord record = CreateRemoteRecord(lifetime, 0x70004003u);
AttachBody(lifetime, record, SourceCell);
// Deliberately never BindProjectile — record.Projectile stays null.
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
operationKind: RuntimeSetPositionOperationKind.ProjectileAuthoritative);
Assert.Null(drive.ApplyAcceptedProjectilePosition(record, route));
}
/// <summary>
/// D-P2's teleport/cell-less row + D-P4's force-end + D-P5's no-velocity,
/// asserted together on the ONE committed outcome (process rule 4 —
/// assert the full observable surface, not a subset). The body moves to
/// the resolved (world-frame-shifted) destination, the prediction version
/// advances (trap T3's guard), an in-flight nonzero velocity survives
/// bit-identical (D-P5), no <c>RemoteMotion</c>/constraint host exists
/// anywhere for the entity (D-P4's never-armed pin), and the collision
/// table the teleport hook reduction force-ends is empty afterward
/// (proof obligation P5).
/// </summary>
[Fact]
public void ApplyAcceptedProjectilePosition_TeleportCommit_MovesBodyForceEndsCollisionNoVelocityNoConstraint()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
(RuntimeEntityRecord record, RuntimeProjectile projectile) =
CreateProjectileRecord(lifetime, 0x70004004u, SourceCell);
PhysicsBody body = record.PhysicsBody!;
var inFlightVelocity = new Vector3(5f, 0f, -2f);
body.set_velocity(inFlightVelocity);
ulong predictionBefore = projectile.PredictionAuthorityVersion;
SeedCollisionOwner(lifetime, record, 0x70004104u, SourceCell);
Assert.Equal(
1, lifetime.Physics.CollisionReports.CaptureOwnership().OwnerCount);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
// Airborne (well above CommitLandblockCollision's flat terrain at
// SpawnHeight): landing in ground contact would legitimately let the
// shared placement pipeline's ordinary contact response touch
// velocity (retail landing behaviour, not this route's concern) —
// an airborne destination isolates the no-velocity-FROM-THE-PACKET
// assertion from that confound.
var destination = new Vector3(12f, 14f, SpawnHeight + 10f);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
destination,
operationKind: RuntimeSetPositionOperationKind.ProjectileAuthoritative);
RuntimeRemotePlacementExecutionStatus? status =
drive.ApplyAcceptedProjectilePosition(record, route);
Assert.Equal(RuntimeRemotePlacementExecutionStatus.Committed, status);
Assert.Equal(destination + new Vector3(192f, 0f, 0f), body.Position);
Assert.NotEqual(predictionBefore, projectile.PredictionAuthorityVersion);
Assert.Equal(inFlightVelocity, body.Velocity);
Assert.Null(record.RemoteMotion);
Assert.Equal(
0, lifetime.Physics.CollisionReports.CaptureOwnership().OwnerCount);
// A4 fix (review round): the shadow-sync half of
// SyncProjectilePresentation, asserted directly rather than left
// vacuous — the shadow row moves to the RESOLVED body position.
Assert.True(body.InWorld);
ShadowEntry shadowEntry = Assert.Single(
lifetime.Physics.Engine.ShadowObjects.AllEntriesForDebug(),
entry => entry.EntityId == record.Key!.Value.LocalEntityId);
Assert.Equal(body.Position, shadowEntry.Position);
DrainPlacementFifo(lifetime);
AssertConverged(lifetime);
}
/// <summary>D-P2's far row, mirroring the teleport commit's assertions.</summary>
[Fact]
public void ApplyAcceptedProjectilePosition_FarCommit_MovesBodyNoVelocityNoConstraint()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
(RuntimeEntityRecord record, RuntimeProjectile projectile) =
CreateProjectileRecord(lifetime, 0x70004005u, SourceCell);
PhysicsBody body = record.PhysicsBody!;
var inFlightVelocity = new Vector3(0f, 7f, 1f);
body.set_velocity(inFlightVelocity);
ulong predictionBefore = projectile.PredictionAuthorityVersion;
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var destination = new Vector3(12f, 14f, SpawnHeight + 10f);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
destination,
operationKind: RuntimeSetPositionOperationKind.ProjectileAuthoritative);
RuntimeRemotePlacementExecutionStatus? status =
drive.ApplyAcceptedProjectilePosition(record, route);
Assert.Equal(RuntimeRemotePlacementExecutionStatus.Committed, status);
Assert.Equal(destination + new Vector3(192f, 0f, 0f), body.Position);
Assert.NotEqual(predictionBefore, projectile.PredictionAuthorityVersion);
Assert.Equal(inFlightVelocity, body.Velocity);
Assert.Null(record.RemoteMotion);
Assert.True(body.InWorld);
ShadowEntry shadowEntry = Assert.Single(
lifetime.Physics.Engine.ShadowObjects.AllEntriesForDebug(),
entry => entry.EntityId == record.Key!.Value.LocalEntityId);
Assert.Equal(body.Position, shadowEntry.Position);
DrainPlacementFifo(lifetime);
AssertConverged(lifetime);
}
/// <summary>
/// A4 fix (review round): the spatial+hidden branch — the entity stays
/// <c>InWorld</c> (retail keeps a Hidden object as a retained live
/// <c>CPhysicsObj</c>, not a leave-world) but its shadow row is
/// suspended, not published at the resolved pose.
/// </summary>
[Fact]
public void ApplyAcceptedProjectilePosition_TeleportCommit_HiddenSuspendsShadowStaysInWorld()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
(RuntimeEntityRecord record, _) =
CreateProjectileRecord(lifetime, 0x7000400Bu, SourceCell);
Assert.Equal(1, lifetime.Physics.Engine.ShadowObjects.TotalRegistered);
lifetime.Entities.SetFinalPhysicsState(
record, record.FinalPhysicsState | PhysicsStateFlags.Hidden);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var destination = new Vector3(12f, 14f, SpawnHeight + 10f);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
destination,
operationKind: RuntimeSetPositionOperationKind.ProjectileAuthoritative);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Committed,
drive.ApplyAcceptedProjectilePosition(record, route));
Assert.True(record.PhysicsBody!.InWorld);
Assert.Equal(0, lifetime.Physics.Engine.ShadowObjects.TotalRegistered);
DrainPlacementFifo(lifetime);
AssertConverged(lifetime);
}
/// <summary>
/// A4 fix (review round): the non-spatial branch — a record that never
/// became a spatial root (e.g. still pending a landblock) is left
/// <c>InWorld = false</c>, its <c>Active</c> transient flag cleared, and
/// its shadow suspended.
///
/// <para>
/// Uses the STORE (<c>Refused</c>) path rather than a commit: a
/// successful canonical commit re-establishes spatial-root status as
/// part of entering the world, so the non-spatial branch is reachable
/// only through the outcomes that never touch spatial registration —
/// exactly the store fallback's shape.
/// </para>
/// </summary>
[Fact]
public void ApplyAcceptedProjectilePosition_Refused_NonSpatialDeactivatesAndSuspends()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
lifetime.Physics.ObserveLocalWorldFrame(SourceCell, teleportAdvanced: false);
(RuntimeEntityRecord record, _) =
CreateProjectileRecord(lifetime, 0x7000400Cu, SourceCell);
Assert.Equal(1, lifetime.Physics.Engine.ShadowObjects.TotalRegistered);
// Withdraw spatial-root status — AcknowledgeSpatialProjection
// (spatial: false) is a no-op (only its `true` branch touches
// _spatialRoots); RemoveSpatialProjection is the actual withdrawal.
lifetime.Physics.RemoveSpatialProjection(record);
var window = new FakeServiceWindow();
// Deliberately NOT allowed — the pre-flight refuses, so the store
// fallback runs without ever touching spatial registration.
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var destination = new Vector3(12f, 14f, SpawnHeight + 10f);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
destination,
operationKind: RuntimeSetPositionOperationKind.ProjectileAuthoritative);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Refused,
drive.ApplyAcceptedProjectilePosition(record, route));
Assert.False(record.PhysicsBody!.InWorld);
Assert.Equal(
TransientStateFlags.None,
record.PhysicsBody.TransientState & TransientStateFlags.Active);
Assert.Equal(0, lifetime.Physics.Engine.ShadowObjects.TotalRegistered);
DrainPlacementFifo(lifetime);
AssertConverged(lifetime);
}
/// <summary>
/// A6 fix (review round): the re-entry activation edge. A projectile
/// that had left the world (suspended, <c>InWorld = false</c>) and comes
/// back through a committed accepted Position must be re-flagged
/// <c>Active</c> and have its legacy <c>LastUpdateTime</c> rebased — the
/// exact branch that reading <c>body.InWorld</c> AFTER the placement
/// (instead of capturing it before) made permanently dead.
/// </summary>
[Fact]
public void ApplyAcceptedProjectilePosition_TeleportCommit_ReenteringWorldReactivatesBody()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
(RuntimeEntityRecord record, _) =
CreateProjectileRecord(lifetime, 0x7000400Du, SourceCell);
PhysicsBody body = record.PhysicsBody!;
body.InWorld = false;
body.TransientState &= ~TransientStateFlags.Active;
body.LastUpdateTime = -1d;
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var destination = new Vector3(12f, 14f, SpawnHeight + 10f);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
destination,
operationKind: RuntimeSetPositionOperationKind.ProjectileAuthoritative);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Committed,
drive.ApplyAcceptedProjectilePosition(record, route));
Assert.True(body.InWorld);
Assert.Equal(
TransientStateFlags.Active,
body.TransientState & TransientStateFlags.Active);
Assert.NotEqual(-1d, body.LastUpdateTime);
DrainPlacementFifo(lifetime);
AssertConverged(lifetime);
}
/// <summary>
/// D3's <c>Refused</c> row: the destination is outside the service
/// window, so the pre-flight declines before the engine ever runs — but
/// the accepted destination STILL advances through
/// <c>StoreAcceptedDestinationPose</c> (4b-3 invariant 1, extended by
/// D-P3 to the projectile column). Positive assertions throughout
/// (round-2 finding B1): the pose moved, the entity stayed in-world, and
/// prediction still invalidated once (the store fallback is a body write
/// too).
/// </summary>
[Fact]
public void ApplyAcceptedProjectilePosition_Refused_StillAdvancesPoseNoParkPredictionInvalidated()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
// StoreAcceptedDestinationPose resolves the destination through
// Runtime's OWN world frame (never a caller-supplied position) —
// establish it exactly like CommitLandblockCollision's first step,
// without needing the destination's collision generation to commit
// (this test never reaches the engine).
lifetime.Physics.ObserveLocalWorldFrame(SourceCell, teleportAdvanced: false);
(RuntimeEntityRecord record, RuntimeProjectile projectile) =
CreateProjectileRecord(lifetime, 0x70004006u, SourceCell);
PhysicsBody body = record.PhysicsBody!;
ulong predictionBefore = projectile.PredictionAuthorityVersion;
var window = new FakeServiceWindow();
// Deliberately NOT allowed — the pre-flight refuses.
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
destination,
operationKind: RuntimeSetPositionOperationKind.ProjectileAuthoritative);
RuntimeRemotePlacementExecutionStatus? status =
drive.ApplyAcceptedProjectilePosition(record, route);
Assert.Equal(RuntimeRemotePlacementExecutionStatus.Refused, status);
// The store fallback resolves through Runtime's world frame, the
// same +192m shift on X the committed-outcome tests observe.
Assert.Equal(destination + new Vector3(192f, 0f, 0f), body.Position);
Assert.NotEqual(predictionBefore, projectile.PredictionAuthorityVersion);
Assert.True(body.InWorld);
Assert.True(record.ObjectClock.IsActive);
Assert.Equal(0, drive.PendingCount);
// Residual 2 close (round-2 review): the store path publishes the
// shadow row too, not only the commit path the teleport/far commit
// tests already assert — SyncProjectilePresentation runs on every
// storing outcome, Refused included.
ShadowEntry shadowEntry = Assert.Single(
lifetime.Physics.Engine.ShadowObjects.AllEntriesForDebug(),
entry => entry.EntityId == record.Key!.Value.LocalEntityId);
Assert.Equal(body.Position, shadowEntry.Position);
AssertConverged(lifetime);
}
/// <summary>
/// D-P4's pinned no-op pair: <c>Interpolate</c> (near) and
/// <c>NoPositionOperation</c> (airborne) write nothing and do not
/// invalidate prediction — the positive fact that a straddling quantum
/// may complete over either.
/// </summary>
[Fact]
public void ApplyAcceptedProjectilePosition_PinnedNoOps_BodyAndPredictionUnchanged()
{
// RuntimeAuthoritativePositionDisposition is internal, so a public
// [Theory] cannot take it as a parameter (CS0051) — iterate directly,
// mirroring OwnsPlacement_FalseWhenOperationKindIsNotRemoteAuthoritative's
// own foreach-over-internal-enum shape.
foreach (RuntimeAuthoritativePositionDisposition disposition in
new[]
{
RuntimeAuthoritativePositionDisposition.Interpolate,
RuntimeAuthoritativePositionDisposition.NoPositionOperation,
})
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
(RuntimeEntityRecord record, RuntimeProjectile projectile) =
CreateProjectileRecord(lifetime, 0x70004007u, SourceCell);
PhysicsBody body = record.PhysicsBody!;
Vector3 positionBefore = body.Position;
Quaternion orientationBefore = body.Orientation;
ulong predictionBefore = projectile.PredictionAuthorityVersion;
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
disposition,
DestinationCell,
operationKind: RuntimeSetPositionOperationKind.ProjectileAuthoritative);
Assert.Null(drive.ApplyAcceptedProjectilePosition(record, route));
Assert.Equal(positionBefore, body.Position);
Assert.Equal(orientationBefore, body.Orientation);
Assert.Equal(predictionBefore, projectile.PredictionAuthorityVersion);
Assert.Null(record.RemoteMotion);
Assert.Equal(0, drive.PendingCount);
AssertConverged(lifetime);
}
}
/// <summary>
/// D-P4's swallow rule (trap T5): a <c>RejectedAuthority</c>/
/// <c>RejectedData</c> classification for a missile packet writes
/// nothing — no body write, no store, no fall-through to any remote arm
/// (there is none reachable from this method regardless).
/// </summary>
[Fact]
public void ApplyAcceptedProjectilePosition_RejectedClassification_Swallowed()
{
foreach (RuntimeAuthoritativePositionDisposition disposition in
new[]
{
RuntimeAuthoritativePositionDisposition.RejectedAuthority,
RuntimeAuthoritativePositionDisposition.RejectedData,
})
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
(RuntimeEntityRecord record, RuntimeProjectile projectile) =
CreateProjectileRecord(lifetime, 0x70004008u, SourceCell);
PhysicsBody body = record.PhysicsBody!;
Vector3 positionBefore = body.Position;
ulong predictionBefore = projectile.PredictionAuthorityVersion;
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
disposition,
DestinationCell,
operationKind: RuntimeSetPositionOperationKind.ProjectileAuthoritative);
Assert.Null(drive.ApplyAcceptedProjectilePosition(record, route));
Assert.Equal(positionBefore, body.Position);
Assert.Equal(predictionBefore, projectile.PredictionAuthorityVersion);
Assert.Equal(0, drive.PendingCount);
AssertConverged(lifetime);
}
}
/// <summary>
/// Test-plan item 6 / proof obligation-11: the SAME "retryable
/// preparation" shape <see cref="Teleport_LedgerConverges_AfterDetachRouteClearsARetainedRetry"/>
/// uses, driven through the projectile arm — proves the shared
/// <c>_pending</c>/<c>_awaitingAcknowledgement</c> ledgers converge for a
/// projectile operation with no new code (trap T9: no second map).
/// </summary>
[Fact]
public void ApplyAcceptedProjectilePosition_LedgerConverges_AfterDetachRouteClearsARetainedRetry()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
(RuntimeEntityRecord record, _) = CreateProjectileRecord(
lifetime, 0x70004009u, SourceCell);
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var routeOwner = new object();
drive.AttachRoute(routeOwner);
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
destination,
operationKind: RuntimeSetPositionOperationKind.ProjectileAuthoritative);
RuntimeRemotePlacementExecutionStatus? status =
drive.ApplyAcceptedProjectilePosition(record, route);
Assert.Equal(RuntimeRemotePlacementExecutionStatus.Committed, status);
// A committed placement's Place receipt is never acknowledged in
// this bare fixture (no host subscription wired) — exactly the
// awaiting-acknowledgement dimension the ledger must also converge.
Assert.Equal(
1, lifetime.CaptureOwnership().RemotePlacementDrivePendingCount);
drive.DetachRoute(routeOwner);
Assert.Equal(0, drive.PendingCount);
Assert.Equal(
0, lifetime.CaptureOwnership().RemotePlacementDrivePendingCount);
AssertConverged(lifetime);
}
/// <summary>
/// Round-3 architecture review C1: <c>Advance()</c>'s projectile branch
/// (parked at round 2 / R3, reordered at round 2 / B5) had never been
/// executed by any test — all six pre-existing <c>drive.Advance()</c>
/// call sites in this file are remote-kind. This is the re-parked-
/// <c>Contention</c> half, mirroring
/// <see cref="FarSnap_RetryablePreparation_StoresThePoseAndStillRetainsTheRetry"/>
/// against a projectile instead of a remote: <c>UnusedCollisionSource</c>
/// never resolves a nonzero Setup id, so BOTH the entry-point call and
/// the retry keep returning <c>RetrySetupUnavailable</c> —
/// <c>Contention</c> — and the pending entry never drains on its own.
///
/// <para>
/// The B5 semantic change under test: the entry-point call invalidates
/// prediction unconditionally BEFORE the write (the existing, already-
/// asserted behaviour); the RETRY call must NOT invalidate a second time
/// when it re-parks, because a re-parked <c>Contention</c> writes
/// nothing (no store, no commit) — invalidating for it would violate
/// "the no-op dispositions invalidate nothing" on an arm that wrote
/// nothing. <see cref="RuntimeProjectile.PredictionAuthorityVersion"/>
/// captured immediately before and after <c>Advance()</c> must be equal.
/// </para>
/// </summary>
[Fact]
public void Advance_ProjectileRetryReParksAsContention_PredictionNotInvalidatedASecondTime()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
// Deliberately NOT committing DestinationLandblock's collision
// generation — CanAttemptDestination only tests the service window
// and the collision PREFIX quiescence, neither of which this
// scenario needs to fail; the retryable failure comes from the
// Setup read below, exactly like FarSnap_RetryablePreparation_….
lifetime.Physics.ObserveLocalWorldFrame(SourceCell, teleportAdvanced: false);
(RuntimeEntityRecord record, RuntimeProjectile projectile) =
CreateProjectileRecord(
lifetime,
0x7000400Bu,
SourceCell,
setupTableId: 0x02000001u);
PhysicsBody body = record.PhysicsBody!;
Vector3 positionBefore = body.Position;
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
destination,
operationKind: RuntimeSetPositionOperationKind.ProjectileAuthoritative,
stopInterpolating: true);
// Entry point: Contention, retained, and prediction invalidated
// exactly once (the pre-existing, already-tested entry-point
// behaviour — asserted again here only as the retry's baseline).
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Contention,
drive.ApplyAcceptedProjectilePosition(record, route));
Assert.Equal(1, drive.PendingCount);
Assert.Equal(destination + new Vector3(192f, 0f, 0f), body.Position);
Assert.NotEqual(positionBefore, body.Position);
ulong predictionAfterEntry = projectile.PredictionAuthorityVersion;
// The retry: Setup is still unresolved, so SubmitAndResolve returns
// Contention again and re-parks — the B5 no-invalidate branch.
drive.Advance();
Assert.Equal(1, drive.PendingCount);
Assert.Equal(
predictionAfterEntry, projectile.PredictionAuthorityVersion);
// The re-park wrote nothing — the stored pose from the entry point
// is untouched.
Assert.Equal(destination + new Vector3(192f, 0f, 0f), body.Position);
RuntimePlacementCancellationReceipt cancellation =
lifetime.Physics.SetPosition.Forget(record);
if (cancellation.IsValid)
lifetime.Physics.SetPosition.PublishCancellation(cancellation);
drive.Advance();
Assert.Equal(0, drive.PendingCount);
AssertConverged(lifetime);
}
/// <summary>
/// Round-3 architecture review C1, the second half: a retained
/// projectile retry whose destination leaves the service window before
/// the next cadence pump — mirroring
/// <see cref="Advance_DestinationLeavesTheWindow_StoresTheNewestDestinationPose"/>
/// against a projectile. This exercises the STORING side C1 named as
/// unexercised: the retry's window-drop branch invalidates prediction
/// unconditionally (unlike the re-parked-<c>Contention</c> branch above)
/// because it runs <c>StoreAcceptedDestinationPose</c> — a real body
/// write — and it is the second call site (besides the entry point) that
/// must run <see cref="RuntimeRemotePlacementDriveController"/>'s
/// <c>SyncProjectilePresentation</c>, so the shadow row must follow the
/// body here too, closing B3's remaining retry-arm gap.
/// </summary>
[Fact]
public void Advance_ProjectileRetryDestinationLeavesTheWindow_StoresNewestPoseInvalidatesPredictionSyncsShadow()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
lifetime.Physics.ObserveLocalWorldFrame(SourceCell, teleportAdvanced: false);
(RuntimeEntityRecord record, RuntimeProjectile projectile) =
CreateProjectileRecord(
lifetime,
0x7000400Cu,
SourceCell,
setupTableId: 0x02000001u);
PhysicsBody body = record.PhysicsBody!;
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var firstDestination = new Vector3(12f, 14f, SpawnHeight);
Assert.Equal(
RuntimeRemotePlacementExecutionStatus.Contention,
drive.ApplyAcceptedProjectilePosition(
record,
MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPositionSimple,
DestinationCell,
firstDestination,
operationKind: RuntimeSetPositionOperationKind.ProjectileAuthoritative,
stopInterpolating: true)));
Assert.Equal(1, drive.PendingCount);
ulong predictionAfterEntry = projectile.PredictionAuthorityVersion;
// The server keeps broadcasting while the retry sits retained: the
// accepted snapshot moves on, and the destination falls out of the
// service window before the next cadence pump.
var newestDestination = new Vector3(40f, 50f, SpawnHeight);
record.Snapshot = record.Snapshot with
{
Position = new CreateObject.ServerPosition(
DestinationCell,
newestDestination.X,
newestDestination.Y,
newestDestination.Z,
1f,
0f,
0f,
0f),
};
window.Forbid(DestinationLandblock);
drive.Advance();
Assert.Equal(0, drive.PendingCount);
Assert.Equal(
newestDestination + new Vector3(192f, 0f, 0f), body.Position);
Assert.NotEqual(
predictionAfterEntry, projectile.PredictionAuthorityVersion);
// SyncProjectilePresentation ran on the retry arm too — the shadow
// row followed the body to the newest stored pose.
ShadowEntry shadowEntry = Assert.Single(
lifetime.Physics.Engine.ShadowObjects.AllEntriesForDebug(),
entry => entry.EntityId == record.Key!.Value.LocalEntityId);
Assert.Equal(body.Position, shadowEntry.Position);
Assert.Equal(
0, lifetime.Physics.CaptureOwnership().SetPositionOperationCount);
AssertConverged(lifetime);
}
/// <summary>
/// Test-plan item 4 (trap T3): a split quantum straddling an accepted
/// far/teleport Position must abort at <c>Complete</c> rather than
/// clobber the committed placement — the scenario invisible from reading
/// the classifier alone, and the one this route's App-level predecessor
/// test (<c>AuthoritativeMutationBetweenQuantumHalvesDiscardsPrediction</c>)
/// used to cover before its Position case retired.
/// </summary>
[Fact]
public void ApplyAcceptedProjectilePosition_DuringOpenQuantum_CompleteAbortsAfterPredictionInvalidated()
{
using var lifetime = new RuntimeEntityObjectLifetime(FlatEngine());
CommitLandblockCollision(lifetime, DestinationLandblock);
(RuntimeEntityRecord record, RuntimeProjectile projectile) =
CreateProjectileRecord(lifetime, 0x7000400Au, SourceCell);
var updater = new RuntimeProjectilePhysicsUpdater(lifetime.Physics);
Assert.True(updater.TryBegin(
record,
quantum: 0.05f,
record.ObjectClockEpoch,
externalOwnerValid: null,
out RuntimeProjectilePhysicsCommit commit));
var window = new FakeServiceWindow();
window.Allow(DestinationLandblock);
RuntimeRemotePlacementDriveController drive = CreateDrive(lifetime, window);
var destination = new Vector3(12f, 14f, SpawnHeight);
RuntimeAuthoritativePositionRoute route = MakeRoute(
record,
RuntimeAuthoritativePositionDisposition.SetPosition,
DestinationCell,
destination,
operationKind: RuntimeSetPositionOperationKind.ProjectileAuthoritative);
RuntimeRemotePlacementExecutionStatus? status =
drive.ApplyAcceptedProjectilePosition(record, route);
Assert.Equal(RuntimeRemotePlacementExecutionStatus.Committed, status);
Vector3 committedPosition = record.PhysicsBody!.Position;
bool completed = updater.Complete(
commit,
liveCenterX: 0,
liveCenterY: 0,
acknowledgeProjection: static _ => true);
Assert.False(completed);
Assert.Equal(committedPosition, record.PhysicsBody.Position);
DrainPlacementFifo(lifetime);
AssertConverged(lifetime);
}
private static (RuntimeEntityRecord Record, RuntimeProjectile Projectile) CreateProjectileRecord(
RuntimeEntityObjectLifetime lifetime,
uint guid,
uint cellId,
bool registerShadow = true,
// C1 fix (round-3 architecture review): a nonzero setupTableId is
// what makes CanonicalSetupTableId != 0, which is what makes
// TryPrepareAuthoredMover actually consult UnusedCollisionSource
// (RuntimeSetPositionState.cs:1900-1918) instead of taking the
// ResolvedAbsent no-Setup path every other projectile fixture in
// this file relies on. Default null preserves every existing
// caller's behaviour exactly (id 0, ResolvedAbsent, always
// Prepared) — only the two new retry-arm tests pass a real id to
// deliberately provoke RetrySetupUnavailable.
uint? setupTableId = null)
{
RuntimeEntityRecord record = CreateRemoteRecord(
lifetime, guid, setupTableId);
lifetime.Entities.SetFinalPhysicsState(
record,
PhysicsStateFlags.Gravity
| PhysicsStateFlags.Missile
| PhysicsStateFlags.ReportCollisions);
PhysicsBody body = AttachBody(lifetime, record, cellId);
var sphere = new ProjectileCollisionSphere(Vector3.Zero, 0.1f, 1f);
var projectile = (RuntimeProjectile)lifetime.Physics.BindProjectile(
record, body, sphere);
// A4 fix (review round): a shadow registration is the prerequisite
// for ShadowObjectRegistry.UpdatePosition to do anything at all
// (it early-returns "not registered" otherwise) — without this, a
// test could assert the shadow-sync branch ran while
// SyncProjectilePresentation's shadow write was silently a no-op.
if (registerShadow)
{
lifetime.Physics.Engine.ShadowObjects.Register(
record.Key!.Value.LocalEntityId,
gfxObjId: 0u,
body.Position,
body.Orientation,
radius: 0.1f,
worldOffsetX: 0f,
worldOffsetY: 0f,
cellId & 0xFFFF0000u,
ShadowCollisionType.Sphere,
state: (uint)record.FinalPhysicsState,
seedCellId: cellId,
isStatic: false);
}
return (record, projectile);
}
/// <summary>
/// Seeds one collision-table owner row on <paramref name="owner"/> via
/// a peer entity's dynamic shadow + one reported collision — the same
/// mechanism <c>RuntimeCollisionReportingStateTests</c> uses, reduced to
/// the minimum this file's proof obligation P5 needs.
/// </summary>
private static void SeedCollisionOwner(
RuntimeEntityObjectLifetime lifetime,
RuntimeEntityRecord owner,
uint peerGuid,
uint cellId)
{
RuntimeEntityRecord peer = CreateRemoteRecord(lifetime, peerGuid);
AttachBody(lifetime, peer, cellId);
uint peerLocalId = peer.Key!.Value.LocalEntityId;
lifetime.Physics.Engine.ShadowObjects.Register(
peerLocalId,
gfxObjId: 0u,
peer.PhysicsBody!.Position,
Quaternion.Identity,
radius: 0.4f,
worldOffsetX: 0f,
worldOffsetY: 0f,
cellId & 0xFFFF0000u,
ShadowCollisionType.Sphere,
state: (uint)peer.FinalPhysicsState,
seedCellId: cellId,
isStatic: false);
var report = new PhysicsSetPositionCollisionReport(
ContactPlaneValid: false,
ContactPlane: default,
ContactPlaneCellId: 0u,
ContactPlaneIsWater: false,
LastKnownContactPlaneValid: false,
LastKnownContactPlane: default,
LastKnownContactPlaneCellId: 0u,
LastKnownContactPlaneIsWater: false,
SlidingNormalValid: false,
SlidingNormal: default,
CollisionNormalValid: false,
CollisionNormal: default,
CollidedWithEnvironment: false,
FramesStationaryFall: 0,
AdjustOffset: default,
LastCollidedObjectId: peerLocalId,
CollidedObjectIds: System.Collections.Immutable.ImmutableArray
.Create(peerLocalId));
Assert.True(lifetime.Physics.HandleSetPositionCollisions(
owner,
owner.PositionAuthorityVersion,
owner.SpatialAuthorityVersion,
owner.VelocityAuthorityVersion,
physicsTime: 1d,
previousContact: false,
previousOnWalkable: false,
report));
}
// ── Fixture ──────────────────────────────────────────────────────────
/// <summary>
/// Stands in for the production placement-projection subscription this
/// bare fixture never wires — a committed placement's <c>Place</c>
/// receipt would otherwise sit unacknowledged forever, exactly like
/// <c>RuntimeAcceptedPositionDriveControllerTests.DrainPlacementFifo</c>.
/// </summary>
private static void DrainPlacementFifo(RuntimeEntityObjectLifetime lifetime)
{
while (lifetime.Physics.SetPosition.TryPeekProjection(
out RuntimePlacementProjectionSnapshot head))
{
if (!lifetime.Physics.SetPosition.AcknowledgeProjection(head.Token))
break;
}
}
private static void AssertConverged(RuntimeEntityObjectLifetime lifetime)
{
Assert.Equal(
0,
lifetime.CaptureOwnership().RemotePlacementDrivePendingCount);
}
private static RuntimeRemotePlacementDriveController CreateDrive(
RuntimeEntityObjectLifetime lifetime,
IRuntimeRemotePlacementServiceWindow window) =>
new(
lifetime,
new GameRuntimeClock(),
new UnusedCollisionSource(),
window);
private static RuntimeAuthoritativePositionRoute MakeRoute(
RuntimeEntityRecord record,
RuntimeAuthoritativePositionDisposition disposition,
uint destinationCellId,
Vector3? destinationPosition = null,
RuntimeSetPositionOperationKind operationKind =
RuntimeSetPositionOperationKind.RemoteAuthoritative,
PhysicsSetPositionFlags? setPositionFlags = null,
bool stopInterpolating = false)
{
// Publishes the destination into the record's accepted Snapshot —
// exactly what the upstream merge
// (RuntimeEntityObjectLifetime.TryApplyPosition) already did before a
// real caller would ever reach this controller — so the controller's
// own service-window read (record.Snapshot.Position.LandblockId)
// observes the SAME destination the route was classified against.
Vector3 position = destinationPosition ?? new Vector3(10f, 10f, SpawnHeight);
record.Snapshot = record.Snapshot with
{
Position = new CreateObject.ServerPosition(
destinationCellId,
position.X,
position.Y,
position.Z,
1f,
0f,
0f,
0f),
};
var authority = new RuntimeAuthoritativePositionAuthority(
new RuntimeGenerationToken(1),
record.Key!.Value,
record.PositionAuthorityVersion,
AcceptedPositionSequence: 2,
PreviousTeleportSequence: 0,
AcceptedTeleportSequence: 0,
PositionTimestampDisposition.Apply);
bool performsSetPosition = disposition is
RuntimeAuthoritativePositionDisposition.SetPosition
or RuntimeAuthoritativePositionDisposition.SetPositionSimple;
return new RuntimeAuthoritativePositionRoute(
authority,
disposition,
operationKind,
setPositionFlags ?? (performsSetPosition
? PhysicsSetPositionFlags.Teleport
| PhysicsSetPositionFlags.Slide
: PhysicsSetPositionFlags.None),
PlacementFrame: 0u,
UnparentBeforeRouting: true,
ApplyPlacementFrameBeforeRouting: false,
LeaveWorld: false,
TeleportHookPhase: RuntimeTeleportHookPhase.None,
stopInterpolating,
ConstrainPhase: RuntimePositionConstrainPhase.AfterPositionOperation,
PreserveHeading: false,
ZeroVelocity: false,
SendPositionImmediately: false,
CollisionBatchEligible: true);
}
private static RuntimeEntityRecord CreateRemoteRecord(
RuntimeEntityObjectLifetime lifetime,
uint guid,
uint? setupTableId = null,
ushort instanceSequence = 0)
{
RuntimeEntityRecord record = lifetime.RegisterEntity(
Spawn(guid, setupTableId, instanceSequence)).Canonical!;
lifetime.Entities.SetFinalPhysicsState(record, PhysicsStateFlags.Gravity);
return record;
}
private static PhysicsBody AttachBody(
RuntimeEntityObjectLifetime lifetime,
RuntimeEntityRecord record,
uint cellId)
{
lifetime.Entities.SetFullCell(
record, cellId, (cellId & 0xFFFF0000u) | 0xFFFFu);
var body = new PhysicsBody
{
Position = new Vector3(10f, 10f, SpawnHeight),
Orientation = Quaternion.Identity,
LastUpdateTime = 1d,
State = PhysicsStateFlags.Gravity,
TransientState = TransientStateFlags.Active,
};
body.SnapToCell(cellId, body.Position, body.Position);
lifetime.Entities.SetPhysicsBody(record, body);
record.ObjectClock.Activate();
lifetime.Physics.AcknowledgeSpatialProjection(record, spatial: true);
return body;
}
private static WorldSession.EntitySpawn Spawn(
uint guid,
uint? setupTableId,
ushort instanceSequence = 0) =>
new(
guid,
new CreateObject.ServerPosition(
SourceCell, 10f, 10f, SpawnHeight, 1f, 0f, 0f, 0f),
setupTableId,
AnimPartChanges: Array.Empty<CreateObject.AnimPartChange>(),
TextureChanges: Array.Empty<CreateObject.TextureChange>(),
SubPalettes: Array.Empty<CreateObject.SubPaletteSwap>(),
BasePaletteId: null,
ObjScale: null,
Name: "remote",
ItemType: null,
MotionState: null,
MotionTableId: 0x09000001u,
InstanceSequence: instanceSequence);
private static PhysicsEngine FlatEngine()
{
var engine = new PhysicsEngine
{
DataCache = new PhysicsDataCache(),
};
engine.AddLandblock(
SourceLandblock,
new TerrainSurface(new byte[81], new float[256]),
Array.Empty<CellSurface>(),
Array.Empty<PortalPlane>(),
worldOffsetX: 0f,
worldOffsetY: 0f);
return engine;
}
/// <summary>
/// Mirrors <c>RuntimeAcceptedPositionDriveControllerTests.CommitLandblockCollision</c>
/// exactly, against a bare <see cref="RuntimeEntityObjectLifetime"/>
/// instead of a full <c>GameRuntime</c>. Also observes the SOURCE
/// landblock's world frame once — Runtime's world-frame resolution is
/// arithmetic thereafter, so a destination landblock never needs its own
/// call (route 2's own fixture comment).
/// </summary>
private static void CommitLandblockCollision(
RuntimeEntityObjectLifetime lifetime,
uint landblockId,
float worldOffsetX = 192f)
{
var heights = new byte[81];
Array.Fill(heights, (byte)SpawnHeight);
var heightTable = new float[256];
for (int index = 0; index < heightTable.Length; index++)
heightTable[index] = index;
lifetime.Physics.ObserveLocalWorldFrame(
SourceCell, teleportAdvanced: false);
lifetime.Physics.SetPosition.BeginCollisionGeneration(landblockId, 1UL);
lifetime.Physics.Engine.AddLandblock(
landblockId,
new TerrainSurface(heights, heightTable),
Array.Empty<CellSurface>(),
Array.Empty<PortalPlane>(),
worldOffsetX,
worldOffsetY: 0f);
lifetime.Physics.SetPosition.CommitCollisionGeneration(
landblockId, 1UL, ready: true);
}
private sealed class FakeServiceWindow : IRuntimeRemotePlacementServiceWindow
{
private readonly HashSet<uint> _within = [];
internal void Allow(uint landblockId) =>
_within.Add(Canonical(landblockId));
internal void Forbid(uint landblockId) =>
_within.Remove(Canonical(landblockId));
public bool IsWithinServiceWindow(uint landblockId) =>
_within.Contains(Canonical(landblockId));
private static uint Canonical(uint landblockId) =>
(landblockId & 0xFFFF0000u) | 0xFFFFu;
}
private sealed class UnusedCollisionSource : IPreparedCollisionSource
{
public PreparedAssetPresence ProbeCollision(
PakAssetType type,
uint sourceFileId) =>
PreparedAssetPresence.Available;
public PreparedCollisionReadResult<FlatSetupCollision> ReadSetupCollision(
uint sourceFileId,
CancellationToken cancellationToken = default) =>
PreparedCollisionReadResult<FlatSetupCollision>.Missing;
public PreparedCollisionReadResult<FlatGfxObjCollisionAsset> ReadGfxObjCollision(
uint sourceFileId,
CancellationToken cancellationToken = default) =>
throw new NotSupportedException();
public PreparedCollisionReadResult<FlatCellStructureCollisionAsset> ReadCellStructureCollision(
uint sourceFileId,
CancellationToken cancellationToken = default) =>
throw new NotSupportedException();
public PreparedCollisionReadResult<FlatEnvCellTopology> ReadEnvCellTopology(
uint sourceFileId,
CancellationToken cancellationToken = default) =>
throw new NotSupportedException();
public PreparedCollisionSourceStats CollisionStats => default;
public void Dispose()
{
}
}
}