acdream/src/AcDream.Runtime/Physics/RuntimeSetPositionState.cs
Erik 529e0e9d88 feat(runtime): C3c - production placement cutover: both hosts on the residence conductors (routes 1+8)
Campaign P remaining-physics-divergence, placement cutover slice C3c
(docs/plans/2026-08-02-placement-cutover.md). Both production hosts now
register every initial Create through the residence + continuation-
executor + first-entry-conductor machinery (C0-C3b):

- Graphical (route 1): RegisterEntityWithInitialResidence at Create; the
  shared RuntimeFirstEntryDriveController pumps both conductors from the
  placement-receipt flow; MaterializeProjection and RebucketLiveEntity
  are presentation-only while a residence is ACTIVE (ExecutorCompleted is
  the presentation-binding receipt); post-residence entities take the
  full legacy path including the prepare_to_enter_world clock edges.
  PlayerModeController attaches presentation to the Runtime-published
  controller; its legacy resolve/step-heights/host-construction path is
  deleted; presentation-only rollback (retail has no entry-flow rollback).
- Headless (route 8): OnSpawned registers with residence when a drive
  exists; content-less sessions keep the pre-flip direct registration;
  SynchronizeLocalPlayer/CreateController/ApplySetupStepHeights deleted;
  prepared-collision read failure is a typed AwaitingCollisionSource
  retry; far remotes outside the service window complete celless.
- RuntimeLocalPlayerMovementState.Controller setter sealed internal; all
  controller mutation flows through the publication lifecycle.

Fix slices landed within this cutover, each dual-gated:
- F1: live movement-stat/server-physics application routed through the
  Runtime ownership seam (post-logout ingest crash on the retired
  controller eliminated; RuntimeMovementSkillProjection deleted).
- F2: login activation wedge - collision-admission prefix gate factored
  out of the seal (reentrant-commit RejectedAuthority), rearm generation
  identity corrected, PlayerModeAutoEntry requires the Runtime-published
  controller (world reveal can no longer seal unmaterialized).
- F3: landblock-prefix 0-sentinel replaced by explicit absent-id guards;
  map-corner landblocks (grid row/col 0) fully legal through admission,
  park/rearm/retire, quiescence, and outdoor shadow seeds.
- F5: local-player first-entry ground contact seeded by the shared
  SpawnPlacementSettler (moved App->Core) at FinalizeActivation - the
  retail first-gravity-frame touch (enter_world 0x00516170 carries no
  seed); the legacy unconditional force-seed is overwritten by a real
  floor-found contact; airborne spawns stay airborne; outbound contact
  bit verified end-to-end. Fixes the standing-cast 'You can't do that
  while in the air!' rejections.
- R1 (dual-review round): login constraint leash armed at the committed
  placement (HandleReceivedPosition 0x00453FD0 analog); register rows
  AD-61 (settle-timing compression now covering the local player) and
  AD-42 (repointed off the deleted resolve split) in this commit;
  residence-conversion owner API; wire-landblock guards; drive-pending
  ledger in IsConverged; route attach/detach latch; executor-drain drift
  model documented + source-pinned.

Gates: Runtime 1,003, App 4,039/3 skips, Headless 79, complete solution
10,816/0 failed/4 skips (Release, -m:1); connected lifecycle/reconnect
gate PASS (logs/connected-world-gate-20260802-175401; graceful exits,
world-visible, zero airborne rejections). The nine-stop soak remains red
for the pre-existing 6b28ff99 whole-world collision-clone throughput
regression (attributed with evidence; scheduled as its own slice before
C5). Dual Opus reviews (retail-conformance + adversarial): delta PASS.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 18:10:33 +02:00

5563 lines
225 KiB
C#

using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using AcDream.Content;
using AcDream.Core.Items;
using AcDream.Core.Net.Messages;
using AcDream.Core.Physics;
using AcDream.Runtime.Entities;
using AcDream.Runtime.Gameplay;
namespace AcDream.Runtime.Physics;
internal enum RuntimeSetPositionOperationKind
{
InitialLogin,
LocalAuthoritative,
RemoteAuthoritative,
ProjectileAuthoritative,
}
internal enum RuntimeSetPositionStatus
{
Rejected,
DeferredCell,
CommittedHostAcknowledgementPending,
Committed,
Cancelled,
}
internal enum RuntimeEntityPlacementStage
{
AwaitingPreparation,
AwaitingWithdrawalAcknowledgement,
AwaitingCell,
QuiescenceHeld,
AwaitingFinalShadowPreparation,
AwaitingCommitAcknowledgement,
CancelledAwaitingAcknowledgement,
}
internal enum RuntimeEntityPlacementPreparationKind : byte
{
LegacyDirect,
AuthoredMover,
}
internal readonly record struct RuntimeEntityPlacementToken(
ulong SessionLifetimeVersion,
RuntimeEntityKey Entity,
ulong PositionAuthorityVersion,
ulong OperationId,
RuntimeEntityPlacementPreparationKind PreparationKind)
{
internal bool IsValid => OperationId != 0UL
&& Entity.LocalEntityId != 0u
&& PositionAuthorityVersion != 0UL;
}
public enum RuntimePlacementProjectionKind
{
Withdraw,
Place,
Discard,
/// <summary>
/// C0-1: the initial-create continuation executor's own FIFO drain has
/// finished for this entity (not itself a SetPosition operation - the
/// residence lease is already released by the time this publishes).
/// Published on the SAME ordered stream every Place/Withdraw/Discard
/// receipt uses so a host learns "this entity's placement committed and
/// its FIFO drained" through the one already-built observer seam,
/// instead of a second stream/queue. Acknowledge-only, like Discard -
/// see AcknowledgeProjection's dedicated branch.
/// </summary>
ExecutorCompleted,
}
public readonly record struct RuntimePortalPlacementAuthority(
bool Present,
long RevealGeneration,
ushort TeleportSequence,
RuntimeWorldHostProjectionToken Projection)
{
internal bool IsEmpty => !Present
&& RevealGeneration == 0
&& TeleportSequence == 0
&& Projection == default;
internal bool IsValid => Present
&& RevealGeneration != 0
&& Projection.IsValid
&& Projection.Generation == RevealGeneration;
}
internal readonly record struct RuntimeSetPositionCommand(
PhysicsSetPositionRequest Physics,
RuntimeSetPositionOperationKind Kind,
double GameTime,
ulong ExpectedVelocityAuthorityVersion,
float ShadowWorldOffsetX = 0f,
float ShadowWorldOffsetY = 0f,
RuntimePortalPlacementAuthority Portal = default);
internal readonly record struct RuntimeCollisionGenerationAuthority(
uint LandblockId,
ulong Generation);
internal readonly record struct RuntimeCollisionPrefixQuiescenceToken(
ulong SessionLifetimeVersion,
uint LandblockPrefix,
ulong CollisionGeneration,
ulong OperationId)
{
// C3c-F3: presence is discriminated by OperationId (allocated from a
// monotonic counter starting at 1, so a default token always carries 0)
// and CollisionGeneration (generations also start at 1) — NOT by
// LandblockPrefix != 0. Prefix 0x00000000 is the legitimate prefix of
// landblock (0,0) (id 0x0000FFFF, Dereth's map corner); the old
// prefix-based term made every real corner-landblock token read as
// invalid, wedging TryGetCurrentQuiescence and every release path.
internal bool IsValid => (LandblockPrefix & 0xFFFFu) == 0u
&& CollisionGeneration != 0UL
&& OperationId != 0UL;
}
internal readonly record struct RuntimeCollisionPrefixMutationPermission(
RuntimeCollisionPrefixQuiescenceToken Quiescence,
ImmutableArray<RuntimePlacementProjectionToken> Withdrawals)
{
internal bool IsValid => Quiescence.IsValid;
}
internal readonly record struct RuntimeCollisionEvaluationAuthority(
ulong CollisionWorldAuthority,
ulong ShadowWorldAuthority,
ClientObjectTable? ObjectTable,
ulong ObjectTableBindingAuthority,
ulong ObjectTableAuthority,
ImmutableArray<RuntimeCollisionGenerationAuthority> Generations)
{
internal bool IsValid => CollisionWorldAuthority != 0UL
&& !Generations.IsDefault;
}
internal readonly record struct RuntimeDormantSetPositionEvaluation(
RuntimeEntityPlacementToken Placement,
RuntimeSetPositionCommand Command,
PhysicsSetPositionResult Result,
RuntimeCollisionEvaluationAuthority CollisionAuthority)
{
internal bool IsValid => Placement.IsValid
&& CollisionAuthority.IsValid;
}
internal enum RuntimeDormantSetPositionCommitStatus : byte
{
None,
AwaitingFinalShadowPreparation,
Committed,
DeferredCell,
RejectedPlacement,
RejectedAuthority,
}
internal sealed class PreparedDormantSetPositionCommit
{
internal required RuntimeDormantSetPositionEvaluation Evaluation
{ get; init; }
internal required RuntimeEntityKey Entity { get; init; }
internal required ulong OperationId { get; init; }
internal required ulong ExpectedProjectionSequence { get; init; }
internal required ShadowObjectRegistry.PreparedSetPositionShadowCommit?
Shadow { get; init; }
internal required RuntimeCollisionReportingState
.PreparedSetPositionCollisionBatch? Collision { get; init; }
internal required RuntimePlacementProjectionSnapshot Projection
{ get; init; }
internal required SortedDictionary<ulong, RuntimePlacementProjectionSnapshot>?
PendingProjection { get; init; }
internal required ulong DeferredCollisionGeneration { get; init; }
internal required List<RuntimeEntityKey>? DeferredBucket { get; init; }
internal required bool DeferredBucketIsNew { get; init; }
}
internal sealed class PreparedDormantActivationFinalCommit
{
internal required RuntimeEntityKey Entity { get; init; }
internal required ulong OperationId { get; init; }
internal required ulong ExpectedProjectionSequence { get; init; }
internal required ShadowObjectRegistry.PreparedSetPositionShadowCommit
Shadow { get; init; }
internal required RuntimePlacementProjectionSnapshot Projection
{ get; init; }
internal required SortedDictionary<ulong, RuntimePlacementProjectionSnapshot>
PendingProjection { get; init; }
}
internal readonly record struct RuntimeDormantSetPositionCommitReceipt(
RuntimeDormantSetPositionCommitStatus Status,
RuntimeEntityKey Entity,
ulong OperationId,
RuntimePlacementProjectionSnapshot Projection,
RuntimeCollisionReportingState.SetPositionCollisionBatchReceipt Collision,
ShadowObjectRegistry.SetPositionShadowCommitReceipt Shadow,
RuntimeCollisionEvaluationAuthority CollisionAuthority,
ulong SourceVectorAuthorityVersion,
bool HitGround,
bool LeaveGround)
{
internal bool IsCommitted => Status
is RuntimeDormantSetPositionCommitStatus.Committed;
}
public readonly record struct RuntimePlacementProjectionToken(
ulong Sequence,
ulong Revision,
RuntimeEntityKey Entity,
ulong PositionAuthorityVersion,
ulong SpatialAuthorityVersion,
ulong PlacementCommitVersion,
ulong SessionLifetimeVersion,
uint ExactCellId,
ulong CollisionGeneration,
RuntimePortalPlacementAuthority Portal)
{
internal bool IsValid => Sequence != 0
&& Entity.LocalEntityId != 0u
&& PositionAuthorityVersion != 0UL;
}
public readonly record struct RuntimePlacementProjectionSnapshot(
RuntimePlacementProjectionToken Token,
RuntimePlacementProjectionKind Kind,
Vector3 WorldPosition,
Quaternion Orientation,
Vector3 CellLocalPosition,
bool InContact,
bool OnWalkable);
internal readonly record struct RuntimeSetPositionOutcome(
RuntimeSetPositionStatus Status,
PhysicsSetPositionError Error,
PhysicsResidenceDisposition Residence,
uint ExactCellId,
RuntimePlacementProjectionToken Projection)
{
internal bool Accepted => Error == PhysicsSetPositionError.Ok;
}
internal readonly record struct RuntimePlacementCancellationReceipt(
RuntimePlacementProjectionSnapshot Projection)
{
internal bool IsValid => Projection.Kind
is RuntimePlacementProjectionKind.Discard
&& Projection.Token.IsValid;
}
internal readonly record struct RuntimeSetPositionOwnershipSnapshot(
int ActiveOperationCount,
int AwaitingPreparationCount,
int DeferredCellCount,
int PendingProjectionAcknowledgementCount,
int LostDeadlineCount,
int LostDeadlineNodeCount,
int LostDeadlineIndexCount,
int ExpiredLostCellCount,
int ExpiredLostCellIndexCount,
int DeferredBucketCount,
int DeferredBucketOrderCount,
int UnboundDeferredCellCount,
int UnboundDeferredCellOrderCount,
int PreparedMoverCount,
int MoverPreparationAuthorityCount,
int PlacementCompletionWatchCount,
int AcknowledgedPlacementCompletionCount,
int CollisionPrefixQuiescenceCount,
int PendingQuiescenceProjectionCount,
int PooledOperationCount)
{
internal bool IndexesConsistent =>
LostDeadlineCount == LostDeadlineNodeCount
&& LostDeadlineCount == LostDeadlineIndexCount
&& ExpiredLostCellCount == ExpiredLostCellIndexCount
&& DeferredBucketCount == DeferredBucketOrderCount
&& UnboundDeferredCellCount == UnboundDeferredCellOrderCount
&& MoverPreparationAuthorityCount <= ActiveOperationCount;
/// <summary>
/// F2: deliberately EXCLUDED from <see cref="IsConverged"/>.
/// <see cref="PooledOperationCount"/> is retained, idle Operation
/// capacity in the C2 object pool - legitimate to hold mid-session (that
/// is the entire point of pooling), so it must not make an otherwise
/// fully-drained, healthy session read as "not converged". Reset/dispose
/// tests assert it separately drops to zero
/// (OperationPoolClearsOnResetSession /
/// OperationPoolClearsOnDispose) instead of folding it into this gate.
/// </summary>
internal bool IsConverged => ActiveOperationCount == 0
&& AwaitingPreparationCount == 0
&& DeferredCellCount == 0
&& PendingProjectionAcknowledgementCount == 0
&& LostDeadlineCount == 0
&& LostDeadlineNodeCount == 0
&& LostDeadlineIndexCount == 0
&& ExpiredLostCellCount == 0
&& ExpiredLostCellIndexCount == 0
&& DeferredBucketCount == 0
&& DeferredBucketOrderCount == 0
&& UnboundDeferredCellCount == 0
&& UnboundDeferredCellOrderCount == 0
&& PreparedMoverCount == 0
&& MoverPreparationAuthorityCount == 0
&& PlacementCompletionWatchCount == 0
&& AcknowledgedPlacementCompletionCount == 0
&& CollisionPrefixQuiescenceCount == 0
&& PendingQuiescenceProjectionCount == 0;
}
/// <summary>
/// Presentation-independent owner of retail SetPosition residence. Runtime
/// commits the complete Core packet before publishing an immutable projection
/// token. A host can retry the exact token until acknowledged; no App delegate
/// is retained and no presentation callback can duplicate simulation state.
/// </summary>
internal sealed class RuntimeSetPositionState : IDisposable
{
// Retail accepts an unsigned num_tries and performs the attempts in one
// synchronous call. Runtime preparation is an authority boundary, so an
// untrusted uint.MaxValue must not turn that verbatim loop into a frame-
// thread denial of service. Authored retail callers use small counts;
// 64 preserves that shape while making the synchronous work finite.
private const uint MaxSynchronousScatterAttempts = 64u;
private readonly record struct CellGenerationKey(
uint CellId,
uint CollisionPrefix,
ulong CollisionGeneration);
private readonly record struct UnboundCellKey(
uint CellId,
uint CollisionPrefix);
private readonly record struct MoverPreparationAuthority(
ulong OperationId,
CreateObject.ServerPosition AcceptedPosition,
uint SetupTableId,
ulong PositionAuthorityVersion,
ulong VelocityAuthorityVersion,
ulong StateAuthorityVersion,
ulong VectorAuthorityVersion,
ulong ObjDescAuthorityVersion,
ulong CreateIntegrationVersion,
ulong PhysicsStateMutationVersion,
bool Prepared,
RuntimeSetPositionCommand PreparedCommand);
/// <summary>
/// C2: settable (not <c>init</c>/<c>required</c>) so <see cref="RentOperation"/>
/// / <see cref="RetireOperationToPool"/> can recycle instances via
/// <see cref="ResetAllFieldsToDefault"/> instead of allocating a fresh
/// object on every accepted placement. This was the single largest
/// contributor to the C2 allocation budget finding (see
/// docs/research/2026-07-31-canonical-set-position.md). Every
/// construction site (<c>BeginAcceptedPlacementCore</c>,
/// <c>CreateWithdrawalOperation</c>, <c>ParkDeferred</c>) still sets
/// every field it always set before; the only behavior change is that a
/// field left unset by a given site now comes from an explicit reset
/// instead of the CLR's implicit new-object default - the two are
/// identical in value.
/// </summary>
private sealed class Operation
{
internal RuntimeEntityRecord Record { get; set; } = null!;
internal PhysicsBody? Body { get; set; }
internal RuntimeEntityPlacementToken Token { get; set; }
internal RuntimeEntityKey Key { get; set; }
internal ulong PositionAuthorityVersion { get; set; }
internal ulong SessionLifetimeVersion { get; set; }
internal ulong SourceSpatialAuthorityVersion { get; set; }
internal ulong SourceVelocityAuthorityVersion { get; set; }
internal bool PreviousContact { get; set; }
internal bool PreviousOnWalkable { get; set; }
internal RuntimeSetPositionCommand Command { get; set; }
internal PhysicsSetPositionResult Result { get; set; }
internal ulong SpatialAuthorityVersion { get; set; }
internal ulong PlacementCommitVersion { get; set; }
internal uint ExactCellId { get; set; }
internal ulong CollisionGeneration { get; set; }
internal uint CollisionPrefix { get; set; }
internal bool WithdrawalAcknowledged { get; set; }
internal bool CollisionGenerationReady { get; set; }
internal bool CollisionQuiescenceHeld { get; set; }
internal ulong ProjectionSequence { get; set; }
internal bool WakeableLostCell { get; set; }
internal RuntimeEntityPlacementStage Stage { get; set; }
internal RuntimeSetPositionOperationKind Kind { get; set; }
internal RuntimePortalPlacementAuthority Portal { get; set; }
internal bool RequiresPreparation { get; set; }
internal bool Expired { get; set; }
internal List<RuntimeEntityKey>? LostFamilyKeys { get; set; }
internal bool InheritedLostDeadline { get; set; }
internal bool EnteringWorldFromCelllessResidence { get; set; }
internal bool DormantLocalActivation { get; set; }
internal RuntimeSetPositionCommand? PreparedCommandAwaitingWithdrawalAck
{
get;
set;
}
/// <summary>
/// F3: pool-membership guard, not operation data. Set true by
/// <see cref="RetireOperationToPool"/> right before pushing; cleared
/// here (called from <see cref="RentOperation"/> right after
/// popping). Lets RetireOperationToPool detect and throw on a
/// double-retire - two retire calls for the same instance without an
/// intervening rent would otherwise silently duplicate it in the
/// pool stack.
/// </summary>
internal bool InPool { get; set; }
/// <summary>
/// C2/F4: the ONLY place every field is set to its inert default -
/// this is the completeness net that `required`/`init` used to
/// provide before pooling needed plain settable properties. Called
/// exactly once when an Operation is retired to the pool
/// (<see cref="RetireOperationToPool"/>), before it can be handed
/// back out by <see cref="RentOperation"/>. <see cref="Record"/> is
/// left null! only for the instant the instance sits in the pool -
/// every rent site immediately overwrites it before any other
/// member is read. A reflection-based test
/// (OperationResetAllFieldsToDefaultTouchesEveryDeclaredField) pins
/// that this method assigns every declared instance field of this
/// class by name - a newly added field fails that test until both
/// the reset and the test's expected-field list are updated.
/// </summary>
internal void ResetAllFieldsToDefault()
{
Record = null!;
Body = null;
Token = default;
Key = default;
PositionAuthorityVersion = 0UL;
SessionLifetimeVersion = 0UL;
SourceSpatialAuthorityVersion = 0UL;
SourceVelocityAuthorityVersion = 0UL;
PreviousContact = false;
PreviousOnWalkable = false;
Command = default;
Result = default;
SpatialAuthorityVersion = 0UL;
PlacementCommitVersion = 0UL;
ExactCellId = 0u;
CollisionGeneration = 0UL;
CollisionPrefix = 0u;
WithdrawalAcknowledged = false;
CollisionGenerationReady = false;
CollisionQuiescenceHeld = false;
ProjectionSequence = 0UL;
WakeableLostCell = false;
Stage = default;
Kind = default;
Portal = default;
RequiresPreparation = false;
Expired = false;
LostFamilyKeys = null;
InheritedLostDeadline = false;
EnteringWorldFromCelllessResidence = false;
DormantLocalActivation = false;
PreparedCommandAwaitingWithdrawalAck = null;
InPool = false;
}
}
private sealed class CollisionPrefixQuiescence
{
internal required RuntimeCollisionPrefixQuiescenceToken Token
{ get; init; }
internal required bool IncludeOutdoorCells { get; init; }
internal required ulong ProjectionBarrierSequence { get; init; }
internal SortedDictionary<ulong, RuntimePlacementProjectionToken>
PendingWithdrawals { get; } = [];
internal SortedDictionary<ulong, RuntimePlacementProjectionToken>
PendingRestorePlacements { get; } = [];
internal List<RuntimePlacementProjectionToken> RetainedWithdrawals
{ get; } = [];
internal bool ResidentsParked { get; set; }
internal bool PermissionIssued { get; set; }
internal bool ReleaseInProgress { get; set; }
internal ulong ReleaseGeneration { get; set; }
internal bool ReleaseGenerationReady { get; set; }
}
/// <summary>
/// F1: captures the operation's PositionAuthorityVersion/
/// SpatialAuthorityVersion as PLAIN VALUES at construction time instead
/// of holding an <see cref="Operation"/> reference and reading its
/// fields lazily inside <see cref="IsCurrent"/>. <c>IsCurrent</c> can run
/// DURING the ground-edge HitGround/LeaveGround callbacks this guard is
/// built for - a synchronous cancel-then-begin (or begin-twice) chain
/// for the SAME entity can retire this exact Operation instance to the
/// pool and rent it right back out (LIFO) for a different logical
/// operation before this guard is asked whether it is still current. A
/// live Operation reference would then silently read the WRONG
/// operation's authority versions; these captured scalars cannot be
/// repurposed out from under it.
/// </summary>
private sealed class ContactCommitGuard(
RuntimeSetPositionState owner,
ulong positionAuthorityVersion,
ulong spatialAuthorityVersion,
RuntimeEntityRecord record,
PhysicsBody body,
ulong placementCommitVersion,
uint fullCellId)
{
internal bool IsCurrent() =>
owner.IsCanonicalPlacementCommitCurrent(
positionAuthorityVersion,
spatialAuthorityVersion,
record,
body,
placementCommitVersion,
fullCellId,
requireSpatialRoot: false);
}
private readonly RuntimePhysicsState _physics;
private readonly RuntimeEntityDirectory _entities;
private readonly Dictionary<RuntimeEntityKey, Operation> _operations = [];
private readonly Dictionary<CellGenerationKey, List<RuntimeEntityKey>>
_deferredByCellGeneration = [];
private SortedDictionary<ulong, RuntimePlacementProjectionSnapshot>
_pendingProjection = [];
private readonly List<CellGenerationKey> _deferredBucketOrder = [];
private readonly Dictionary<UnboundCellKey, List<RuntimeEntityKey>>
_unboundDeferredByCell = [];
private readonly List<UnboundCellKey> _unboundDeferredCellOrder = [];
private readonly Dictionary<RuntimeEntityKey, double> _lostDeadlines = [];
private readonly List<LostDeadlineEntry> _lostDeadlineNodes = [];
private readonly Dictionary<RuntimeEntityKey, int>
_lostDeadlineNodeIndex = [];
private readonly Dictionary<RuntimeEntityKey, PhysicsSetPositionRequest>
_preparedMovers = [];
private readonly Dictionary<RuntimeEntityKey, MoverPreparationAuthority>
_moverPreparationAuthorities = [];
private readonly HashSet<RuntimeEntityPlacementToken>
_placementCompletionWatches = [];
private readonly Dictionary<RuntimeEntityPlacementToken,
RuntimePlacementProjectionToken> _acknowledgedPlacementCompletions = [];
private readonly Dictionary<uint, CollisionPrefixQuiescence>
_collisionPrefixQuiescence = [];
private readonly LinkedList<RuntimeEntityKey> _expiredLostCells = [];
private readonly Dictionary<RuntimeEntityKey, LinkedListNode<RuntimeEntityKey>>
_expiredLostCellNodes = [];
private ulong _nextProjectionSequence;
private ulong _nextOperationId;
private ulong _nextCollisionPrefixQuiescenceOperationId;
private ulong _nextLostDeadlineSequence;
private RuntimeEntityObjectEventStream? _events;
private Action<RuntimeEntityKey, ulong>? _executorCompletionAcknowledged;
private bool _disposed;
private readonly record struct LostDeadlineEntry(
RuntimeEntityKey Key,
double Deadline,
ulong Sequence);
/// <summary>
/// C2: everything <see cref="HandleSetPositionCollisionsCallback"/> reads
/// to invoke <see cref="RuntimePhysicsState.HandleSetPositionCollisions"/>
/// on behalf of the in-flight <c>PhysicsEngine.SetPosition</c> call. A
/// plain per-call lambda closing over the live <see cref="Operation"/>
/// (and, at one call site, a local <c>canonicalCommand</c>) allocated a
/// fresh display class every accepted placement; this struct is pushed by
/// value onto <see cref="_collisionCallbackContexts"/> instead so the ONE
/// cached delegate below never needs a new closure. A stack (not a single
/// field) survives any theoretical nested/re-entrant SetPosition call at
/// the PhysicsEngine layer - <c>TransitionScratchArena.ActiveDepth</c>/
/// <c>Capacity</c> implies nesting is possible there even though
/// <see cref="RuntimePhysicsState.HandleSetPositionCollisions"/> itself
/// never calls back into this class.
/// </summary>
private readonly record struct CollisionCallbackContext(
RuntimeEntityRecord Record,
ulong PositionAuthorityVersion,
ulong SpatialAuthorityVersion,
ulong VelocityAuthorityVersion,
double GameTime,
bool PreviousContact,
bool PreviousOnWalkable);
private readonly Stack<CollisionCallbackContext> _collisionCallbackContexts
= new(4);
private readonly Func<PhysicsSetPositionCollisionReport, bool>
_handleSetPositionCollisionsCallback;
// C2: retired Operation instances wait here for reuse by
// BeginAcceptedPlacementCore instead of a fresh `new Operation` every
// accepted placement. Bounded so a pathological retirement/rent
// imbalance (e.g. many entities despawning with none spawning) cannot
// grow this into an unbounded retained cache - beyond the cap we simply
// let the retired instance become garbage, exactly like before pooling
// existed.
private const int MaxPooledOperations = 64;
private readonly Stack<Operation> _operationPool = new();
internal RuntimeSetPositionState(
RuntimePhysicsState physics,
RuntimeEntityDirectory entities)
{
_physics = physics ?? throw new ArgumentNullException(nameof(physics));
_entities = entities ?? throw new ArgumentNullException(nameof(entities));
_handleSetPositionCollisionsCallback =
HandleSetPositionCollisionsCallback;
}
/// <summary>
/// C2: the single cached delegate every accepted-placement SetPosition
/// call passes to <c>PhysicsEngine.SetPosition</c> in place of a fresh
/// per-call closure. Reads the innermost pushed
/// <see cref="CollisionCallbackContext"/> rather than capturing state
/// directly, so this delegate instance (created once in the
/// constructor) is reused for the lifetime of this owner.
/// </summary>
private bool HandleSetPositionCollisionsCallback(
PhysicsSetPositionCollisionReport report)
{
CollisionCallbackContext context = _collisionCallbackContexts.Peek();
return _physics.HandleSetPositionCollisions(
context.Record,
context.PositionAuthorityVersion,
context.SpatialAuthorityVersion,
context.VelocityAuthorityVersion,
context.GameTime,
context.PreviousContact,
context.PreviousOnWalkable,
report);
}
/// <summary>
/// C2: returns a pooled instance reset to inert defaults right here (NOT
/// at retirement - see <see cref="RetireOperationToPool"/> for why that
/// ordering matters), or allocates a fresh instance exactly as
/// <c>BeginAcceptedPlacementCore</c> did before pooling existed. Callers
/// MUST set every field they previously set via object-initializer
/// syntax - a rented instance's unset fields are the SAME defaults a
/// brand-new instance would have (see
/// <see cref="Operation.ResetAllFieldsToDefault"/>), never leftover
/// state from a prior use.
/// </summary>
private Operation RentOperation()
{
if (_operationPool.Count == 0)
return new Operation();
Operation pooled = _operationPool.Pop();
pooled.ResetAllFieldsToDefault();
return pooled;
}
/// <summary>
/// C2: the only place an Operation is retired to the pool - called the
/// instant one is removed from <see cref="_operations"/> for good.
/// Deliberately does NOT reset the instance here (that happens in
/// <see cref="RentOperation"/> instead, right before reuse): a reentrant
/// callback chain can retire the operation the OUTER frame is still
/// executing inside of and needs to keep reading.
///
/// <para>Round 3 correction: an earlier revision of this comment claimed
/// <c>IsCanonicalPlacementCommitCurrent</c> additionally compared the
/// operation's Token to detect exactly this recycling. That claim was
/// wrong and the check it described was reverted - retail's
/// SetPositionInternal settle is UNCONDITIONAL, so an in-flight
/// ground-edge commit for an entity a reentrant cancel-then-begin has
/// since displaced must still complete its physical settle (contact
/// transition, collision reports, shadow sync) - see
/// ReentrantGroundEdgePlacementCannotBeCancelledByDisplacedOperation. A
/// Token/identity gate on the settle path itself would incorrectly abort
/// that commit the moment the entity is displaced.</para>
///
/// <para>The ACTUAL safety mechanism, class-wide, is captured-token-vs-
/// fresh-lookup at every frame that holds an Operation reference across
/// a reentrancy point (a synchronous publish, a collision-report
/// dispatch that can reach an arbitrary
/// <c>IRuntimeCollisionReportObserver</c>, or a ground-edge HitGround/
/// LeaveGround callback): capture <c>operation.Token</c> (globally
/// unique - <c>checked(++_nextOperationId)</c> is never reissued) into a
/// local BEFORE the reentrancy point, then after it re-resolve via a
/// fresh <c>_operations.TryGetValue</c> and compare
/// <c>current.Token == capturedToken</c> - never
/// <c>ReferenceEquals</c>/<c>IsCurrent(Operation)</c> against the
/// original reference, which becomes a tautology once pooling can hand
/// that SAME physical instance back out for a different logical
/// operation. This identity gate belongs at publication/cancellation/
/// ownership decisions (see the token comparisons in
/// <c>BeginAcceptedPlacementCore</c>, <c>SubmitPreparedPlacementCore</c>,
/// <c>RetryDeferred</c>, and <c>CommitCanonical</c>'s own bookkeeping-
/// write gate), never inside the settle/currency layer itself.</para>
///
/// F3 reorders BeginAcceptedPlacementCore to rent only AFTER this method
/// retires the displaced operation - every field this class still needs
/// from a displaced operation is captured into a local before that
/// retire point (never read from the possibly-the-same, freshly-reset
/// instance after), so it is safe, and more efficient, for a single-
/// entity churn cycle to hand the SAME instance right back out as the
/// next operation (LIFO). <see cref="Operation.InPool"/> guards the one
/// invariant that ordering depends on: this method must never be called
/// twice for the same instance without an intervening
/// <see cref="RentOperation"/> in between - that would silently
/// duplicate the instance in <see cref="_operationPool"/>, so it throws
/// instead.
/// </summary>
private void RetireOperationToPool(Operation operation)
{
if (operation.InPool)
{
throw new InvalidOperationException(
"Operation was already retired to the pool - a double-retire " +
"without an intervening rent would duplicate it in the pool " +
"stack.");
}
if (_operationPool.Count >= MaxPooledOperations)
return;
operation.InPool = true;
_operationPool.Push(operation);
}
internal RuntimeSetPositionOwnershipSnapshot CaptureOwnership()
{
int deferred = 0;
int awaitingPreparation = 0;
foreach (Operation operation in _operations.Values)
{
if (operation.Stage
is RuntimeEntityPlacementStage.AwaitingPreparation)
{
awaitingPreparation++;
}
if (operation.WakeableLostCell)
deferred++;
}
int pendingQuiescenceProjections = 0;
foreach (CollisionPrefixQuiescence quiescence
in _collisionPrefixQuiescence.Values)
{
pendingQuiescenceProjections +=
quiescence.PendingWithdrawals.Count
+ quiescence.PendingRestorePlacements.Count;
}
return new RuntimeSetPositionOwnershipSnapshot(
_operations.Count,
awaitingPreparation,
deferred,
_pendingProjection.Count,
_lostDeadlines.Count,
_lostDeadlineNodes.Count,
_lostDeadlineNodeIndex.Count,
_expiredLostCells.Count,
_expiredLostCellNodes.Count,
_deferredByCellGeneration.Count,
_deferredBucketOrder.Count,
_unboundDeferredByCell.Count,
_unboundDeferredCellOrder.Count,
_preparedMovers.Count,
_moverPreparationAuthorities.Count,
_placementCompletionWatches.Count,
_acknowledgedPlacementCompletions.Count,
_collisionPrefixQuiescence.Count,
pendingQuiescenceProjections,
_operationPool.Count);
}
internal int PendingProjectionCount => _pendingProjection.Count;
internal bool CanBeginAuthoredPlacementSequence =>
_nextOperationId != ulong.MaxValue;
internal bool IsCollisionPrefixQuiescing(uint landblockId) =>
_collisionPrefixQuiescence.ContainsKey(
landblockId & 0xFFFF0000u);
internal RuntimeCollisionPrefixQuiescenceToken
BeginCollisionPrefixQuiescence(
uint landblockId,
ulong collisionGeneration,
bool includeOutdoorCells)
{
EnsureNotDisposed();
if (collisionGeneration == 0UL)
throw new ArgumentOutOfRangeException(nameof(collisionGeneration));
// C3c-F3: reject only the genuinely-absent landblock id (0). Prefix
// 0x00000000 is landblock (0,0) — the map corner — so a prefix == 0
// test can no longer stand in for "no landblock"; that sentinel
// collision crashed every collision publication whose streaming
// window reached the corner (connected-gate 20260802-135444).
if (landblockId == 0u)
throw new ArgumentOutOfRangeException(nameof(landblockId));
uint prefix = landblockId & 0xFFFF0000u;
if (_collisionPrefixQuiescence.TryGetValue(
prefix,
out CollisionPrefixQuiescence? active)
&& active.ReleaseInProgress)
{
throw new InvalidOperationException(
$"Collision quiescence 0x{prefix:X8}/{active.Token.OperationId} is releasing its retained residents.");
}
_collisionPrefixQuiescence.Remove(
prefix,
out CollisionPrefixQuiescence? superseded);
var token = new RuntimeCollisionPrefixQuiescenceToken(
_entities.SessionLifetimeVersion,
prefix,
collisionGeneration,
checked(++_nextCollisionPrefixQuiescenceOperationId));
var replacement = new CollisionPrefixQuiescence
{
Token = token,
IncludeOutdoorCells = includeOutdoorCells,
ProjectionBarrierSequence = superseded is null
? _nextProjectionSequence
: Math.Max(
_nextProjectionSequence,
superseded.ProjectionBarrierSequence),
ResidentsParked = superseded?.ResidentsParked ?? false,
};
if (superseded is not null)
{
foreach ((ulong sequence, RuntimePlacementProjectionToken pending)
in superseded.PendingWithdrawals)
replacement.PendingWithdrawals.Add(sequence, pending);
replacement.RetainedWithdrawals.AddRange(
superseded.RetainedWithdrawals);
}
_collisionPrefixQuiescence.Add(prefix, replacement);
if (superseded is not null)
{
RebindQuiescedDeferredOperations(
superseded.Token,
collisionGeneration,
ready: false);
}
_physics.AdvanceCollisionQuiescenceAuthority();
return token;
}
internal bool TryAcquireCollisionPrefixMutationPermission(
in RuntimeCollisionPrefixQuiescenceToken token,
out RuntimeCollisionPrefixMutationPermission permission)
{
EnsureNotDisposed();
permission = default;
if (!TryGetCurrentQuiescence(token, out CollisionPrefixQuiescence? state))
return false;
CollisionPrefixQuiescence current = state!;
if (HasPendingProjectionThrough(current.ProjectionBarrierSequence))
return false;
if (HasOldPrefixPlacementDebt(current))
return false;
if (!current.ResidentsParked)
{
ParkCollisionResidentsForQuiescence(current);
current.ResidentsParked = true;
return false;
}
else if (HasAffectedCollisionResident(
token.LandblockPrefix,
current.IncludeOutdoorCells))
{
ParkCollisionResidentsForQuiescence(current);
return false;
}
RemoveRetiredQuiescenceWithdrawals(current);
if (current.PendingWithdrawals.Count != 0
|| HasAffectedCollisionResident(
token.LandblockPrefix,
current.IncludeOutdoorCells)
|| HasOldPrefixPlacementDebt(current)
|| HasCollisionDispatchDebt())
{
return false;
}
current.PermissionIssued = true;
permission = new RuntimeCollisionPrefixMutationPermission(
current.Token,
current.RetainedWithdrawals.Count == 0
? default
: current.RetainedWithdrawals.ToImmutableArray());
return true;
}
internal bool IsCollisionPrefixMutationPermissionCurrent(
in RuntimeCollisionPrefixMutationPermission permission)
{
EnsureNotDisposed();
return permission.IsValid
&& TryGetCurrentQuiescence(
permission.Quiescence,
out CollisionPrefixQuiescence? state)
&& state!.PermissionIssued
&& state.PendingWithdrawals.Count == 0
&& !HasAffectedCollisionResident(
state.Token.LandblockPrefix,
state.IncludeOutdoorCells)
&& !HasOldPrefixPlacementDebt(state)
&& !HasCollisionDispatchDebt();
}
internal bool CancelCollisionPrefixQuiescence(
in RuntimeCollisionPrefixQuiescenceToken token,
ulong successorGeneration = 0UL,
bool successorReady = false)
{
EnsureNotDisposed();
if (!TryGetCurrentQuiescence(token, out CollisionPrefixQuiescence? state))
return false;
CollisionPrefixQuiescence current = state!;
if (!current.ResidentsParked
&& current.PendingWithdrawals.Count == 0
&& current.PendingRestorePlacements.Count == 0
&& !HasQuiescedDeferredOperations(token.LandblockPrefix))
{
bool removedBeforePark = _collisionPrefixQuiescence.Remove(
token.LandblockPrefix);
if (removedBeforePark)
_physics.AdvanceCollisionQuiescenceAuthority();
return removedBeforePark;
}
if (successorGeneration == 0UL)
return false;
return AdvanceCollisionPrefixRelease(
token,
successorGeneration,
successorReady,
requireMutationPermission: false);
}
internal bool CancelCollisionPrefixQuiescenceToUnavailable(
in RuntimeCollisionPrefixQuiescenceToken token)
{
EnsureNotDisposed();
return AdvanceCollisionPrefixRelease(
token,
generation: 0UL,
ready: false,
requireMutationPermission: false);
}
internal bool ReleaseCollisionPrefixAfterMutation(
in RuntimeCollisionPrefixQuiescenceToken token,
ulong activeGeneration,
bool ready)
{
EnsureNotDisposed();
return AdvanceCollisionPrefixRelease(
token,
activeGeneration,
ready,
requireMutationPermission: true);
}
private bool AdvanceCollisionPrefixRelease(
in RuntimeCollisionPrefixQuiescenceToken token,
ulong generation,
bool ready,
bool requireMutationPermission)
{
if ((generation == 0UL && ready)
|| !TryGetCurrentQuiescence(
token,
out CollisionPrefixQuiescence? state))
{
return false;
}
CollisionPrefixQuiescence current = state!;
if (current.PendingWithdrawals.Count != 0)
return false;
if (requireMutationPermission
&& !current.PermissionIssued
&& !current.ReleaseInProgress)
{
return false;
}
if (!current.ReleaseInProgress)
{
current.ReleaseInProgress = true;
current.ReleaseGeneration = generation;
current.ReleaseGenerationReady = ready;
current.PermissionIssued = false;
}
else if (current.ReleaseGeneration != generation
|| current.ReleaseGenerationReady != ready)
{
return false;
}
// A re-entrant/network placement may have joined the still-closed
// prefix after release started. Transfer every exact newcomer on each
// poll before deciding the barrier can open.
if (_operations.Count != 0)
{
RebindQuiescedDeferredOperations(
token,
ready ? generation : 0UL,
ready,
releaseUnavailable: !ready);
}
if (current.PendingRestorePlacements.Count != 0
|| HasQuiescedDeferredOperations(token.LandblockPrefix))
{
return false;
}
bool removed = _collisionPrefixQuiescence.Remove(
token.LandblockPrefix);
if (removed)
_physics.AdvanceCollisionQuiescenceAuthority();
return removed;
}
internal void BindEventStream(RuntimeEntityObjectEventStream events)
{
EnsureNotDisposed();
ArgumentNullException.ThrowIfNull(events);
if (_events is not null)
throw new InvalidOperationException(
"The Runtime placement event stream is already bound.");
_events = events;
}
internal void RetryPendingProjections()
{
EnsureNotDisposed();
RuntimePlacementProjectionSnapshot[] snapshot =
_pendingProjection.Values.ToArray();
for (int index = 0; index < snapshot.Length; index++)
{
RuntimePlacementProjectionSnapshot projection = snapshot[index];
if (_pendingProjection.TryGetValue(
projection.Token.Sequence,
out RuntimePlacementProjectionSnapshot current)
&& current == projection)
{
PublishPlacement(projection);
}
}
}
/// <summary>
/// C0-1: publishes the initial-create continuation executor's own
/// completion (its FIFO drain has finished and its residence lease is
/// already released) on the SAME ordered receipt stream every
/// Place/Withdraw/Discard uses - the pinned contract forbids a second
/// stream/queue. This is NOT an Operation-backed receipt (the executor's
/// own placement operation, if any, already committed and was
/// acknowledged earlier in the drain - see
/// RuntimeInitialCreateContinuationExecutor.ExecuteCore's call site) so
/// the token is built the same way PublishProjection assembles one, but
/// from the CANONICAL record's current authority/version/cell facts
/// (self-consistent: nothing else can move them synchronously between
/// the executor's release and this publish) instead of a now-gone
/// Operation. AcknowledgeProjection's dedicated ExecutorCompleted branch
/// treats it exactly like Discard - acknowledge-only, no operation to
/// resume or commit against.
/// </summary>
internal RuntimePlacementProjectionToken PublishExecutorCompletion(
RuntimeEntityRecord record,
Action<RuntimePlacementProjectionToken>? beforePublish = null,
RuntimePortalPlacementAuthority portal = default)
{
EnsureNotDisposed();
ArgumentNullException.ThrowIfNull(record);
if (record.Key is not { } key)
return default;
PhysicsBody? body = record.PhysicsBody;
ulong sequence = checked(++_nextProjectionSequence);
var token = new RuntimePlacementProjectionToken(
sequence,
Revision: 1UL,
key,
record.PositionAuthorityVersion,
record.SpatialAuthorityVersion,
record.PlacementCommitVersion,
_entities.SessionLifetimeVersion,
record.FullCellId,
_physics.ExpectedCollisionGeneration(record.FullCellId),
portal);
var snapshot = new RuntimePlacementProjectionSnapshot(
token,
RuntimePlacementProjectionKind.ExecutorCompleted,
body?.Position ?? Vector3.Zero,
body?.Orientation ?? Quaternion.Identity,
body?.CellPosition.Frame.Origin ?? Vector3.Zero,
body?.InContact ?? false,
body?.OnWalkable ?? false);
_pendingProjection.Add(sequence, snapshot);
// F2: register-before-publish - beforePublish runs while the token is
// already in _pendingProjection but before PublishPlacement's
// synchronous observer dispatch, so a subscriber reading back the
// executor's correlation entry from inside its OWN OnPlacement
// callback always finds it.
beforePublish?.Invoke(token);
PublishPlacement(snapshot);
return token;
}
/// <summary>
/// F2: binds the ONE notification fired when a Kind ExecutorCompleted
/// receipt is acknowledged (mirrors
/// RuntimeInitialCreateResidenceState.BindRetirementNotification's
/// existing one-bound-delegate shape). The executor uses this to reap
/// its own token-to-receipt correlation entry exactly when the receipt
/// it correlates is consumed - never before (a host might still be
/// mid-retry) and never left dangling after (unbounded per-completed-
/// entity retention).
/// </summary>
internal void BindExecutorCompletionAcknowledgement(
Action<RuntimeEntityKey, ulong> acknowledged)
{
ArgumentNullException.ThrowIfNull(acknowledged);
if (_executorCompletionAcknowledged is not null)
{
throw new InvalidOperationException(
"The executor-completion acknowledgement notification is already bound.");
}
_executorCompletionAcknowledged = acknowledged;
}
internal void ResetSession()
{
EnsureNotDisposed();
ClearOwnedState();
}
internal RuntimeSetPositionOutcome Apply(
RuntimeEntityRecord record,
ulong expectedPositionAuthorityVersion,
in RuntimeSetPositionCommand command)
{
EnsureNotDisposed();
ArgumentNullException.ThrowIfNull(record);
RuntimeEntityPlacementToken token = BeginAcceptedPlacementCore(
record,
expectedPositionAuthorityVersion,
command.Kind,
command.Portal,
captureMoverPreparationAuthority: false);
if (!token.IsValid)
{
return Rejected(command.Physics);
}
return SubmitPreparedPlacementCore(
token,
command,
allowDirectUnsealed: true);
}
internal RuntimeEntityPlacementToken BeginAcceptedPlacement(
RuntimeEntityRecord record,
ulong expectedPositionAuthorityVersion,
RuntimeSetPositionOperationKind kind,
RuntimePortalPlacementAuthority portal = default) =>
BeginAcceptedPlacementCore(
record,
expectedPositionAuthorityVersion,
kind,
portal,
captureMoverPreparationAuthority: false);
internal RuntimeEntityPlacementToken BeginAuthoredPlacement(
RuntimeEntityRecord record,
ulong expectedPositionAuthorityVersion,
RuntimeSetPositionOperationKind kind,
RuntimePortalPlacementAuthority portal = default) =>
BeginAcceptedPlacementCore(
record,
expectedPositionAuthorityVersion,
kind,
portal,
captureMoverPreparationAuthority: true);
internal bool IsPlacementCurrent(
in RuntimeEntityPlacementToken token)
{
EnsureNotDisposed();
// Round 3 audit: safe - fresh lookup + Token check on the SAME line
// immediately precede IsCurrent, nothing reentrant in between.
return token.IsValid
&& _operations.TryGetValue(token.Entity, out Operation? operation)
&& operation.Token == token
&& IsCurrent(operation);
}
/// <summary>
/// Reserves the exact acknowledgement edge for a higher-level Runtime
/// transaction. Ordinary SetPosition operations retain no completion
/// history; only explicitly watched tokens survive operation retirement.
/// </summary>
internal bool WatchPlacementCompletion(
in RuntimeEntityPlacementToken token)
{
EnsureNotDisposed();
return IsPlacementCurrent(token)
&& _placementCompletionWatches.Add(token);
}
internal bool IsPlacementCompletionTracked(
in RuntimeEntityPlacementToken token)
{
EnsureNotDisposed();
return token.IsValid
&& (IsPlacementCurrent(token)
&& _placementCompletionWatches.Contains(token)
|| _acknowledgedPlacementCompletions.ContainsKey(token));
}
internal bool TryPeekAcknowledgedPlacement(
in RuntimeEntityPlacementToken token,
out RuntimePlacementProjectionToken projection)
{
EnsureNotDisposed();
if (token.IsValid
&& _acknowledgedPlacementCompletions.TryGetValue(
token,
out projection))
{
return true;
}
projection = default;
return false;
}
internal bool ConsumeAcknowledgedPlacement(
in RuntimeEntityPlacementToken token,
in RuntimePlacementProjectionToken expected)
{
EnsureNotDisposed();
return token.IsValid
&& _acknowledgedPlacementCompletions.TryGetValue(
token,
out RuntimePlacementProjectionToken current)
&& current == expected
&& _acknowledgedPlacementCompletions.Remove(token);
}
internal void ForgetPlacementCompletion(
in RuntimeEntityPlacementToken token)
{
EnsureNotDisposed();
ForgetPlacementCompletionCore(token);
}
internal RuntimePlacementCancellationReceipt ForgetExactPlacement(
in RuntimeEntityPlacementToken token)
{
EnsureNotDisposed();
ForgetPlacementCompletionCore(token);
if (!token.IsValid
|| !_operations.TryGetValue(token.Entity, out Operation? operation)
|| operation.Token != token)
{
return default;
}
// Round 3: `token` is this call's own parameter, verified fresh
// against `_operations` immediately above with nothing reentrant in
// between - passing it straight through is equivalent to (and safer
// than) re-deriving it from `operation`.
return CancelCore(token.Entity, token);
}
internal RuntimeEntityPlacementToken TryBeginExclusiveAuthoredPlacement(
RuntimeEntityRecord record,
ulong expectedPositionAuthorityVersion,
RuntimeSetPositionOperationKind kind,
RuntimePortalPlacementAuthority portal = default)
{
EnsureNotDisposed();
ArgumentNullException.ThrowIfNull(record);
if (record.Key is not { } key
|| _operations.ContainsKey(key)
|| HasRetainedCompletion(key))
{
return default;
}
return BeginAcceptedPlacementCore(
record,
expectedPositionAuthorityVersion,
kind,
portal,
captureMoverPreparationAuthority: true);
}
internal void PrepareDormantLocalActivationOwnership(
RuntimeEntityRecord record,
PhysicsBody body,
in RuntimeEntityPlacementToken token)
{
EnsureNotDisposed();
ArgumentNullException.ThrowIfNull(record);
ArgumentNullException.ThrowIfNull(body);
// Round 3 audit: safe - fresh lookup + Token check earlier in this
// SAME guard clause precede IsCurrent, nothing reentrant in between.
if (!token.IsValid
|| record.Key != token.Entity
|| !_operations.TryGetValue(token.Entity, out Operation? operation)
|| operation.Token != token
|| operation.Stage is not RuntimeEntityPlacementStage
.AwaitingPreparation
|| !ReferenceEquals(operation.Record, record)
|| record.PhysicsBody is not null
|| !IsCurrent(operation)
|| body.InWorld
|| (body.TransientState & TransientStateFlags.Active) != 0)
{
throw new InvalidOperationException(
"Dormant local activation must bind to the exact current placement owner.");
}
operation.Body = body;
operation.DormantLocalActivation = true;
}
private RuntimeEntityPlacementToken BeginAcceptedPlacementCore(
RuntimeEntityRecord record,
ulong expectedPositionAuthorityVersion,
RuntimeSetPositionOperationKind kind,
RuntimePortalPlacementAuthority portal,
bool captureMoverPreparationAuthority)
{
EnsureNotDisposed();
ArgumentNullException.ThrowIfNull(record);
CreateObject.ServerPosition? acceptedPosition =
record.Snapshot.Physics?.Position ?? record.Snapshot.Position;
if (record.Key is not { } key
|| !_entities.IsCurrent(record)
|| HasRetainedCompletion(key)
|| record.PositionAuthorityVersion
!= expectedPositionAuthorityVersion
|| (captureMoverPreparationAuthority
&& acceptedPosition is null)
|| !(portal.IsEmpty
|| (portal.IsValid
&& kind is RuntimeSetPositionOperationKind
.LocalAuthoritative
&& acceptedPosition is { } portalPosition
&& portal.Projection.DestinationCell
== portalPosition.LandblockId)))
{
return default;
}
var token = new RuntimeEntityPlacementToken(
_entities.SessionLifetimeVersion,
key,
expectedPositionAuthorityVersion,
checked(++_nextOperationId),
captureMoverPreparationAuthority
? RuntimeEntityPlacementPreparationKind.AuthoredMover
: RuntimeEntityPlacementPreparationKind.LegacyDirect);
List<RuntimeEntityKey>? inheritedLostFamily = null;
RuntimePlacementProjectionSnapshot? inheritedWithdrawal = null;
bool inheritedWithdrawalAcknowledged = false;
// F3: captured into locals (rather than re-read from `displaced`
// after CancelCoreDeferred below) because `replacement` is
// deliberately rented AFTER that retire - see the no-self-aliasing
// note below and RetireOperationToPool's doc comment. Reading every
// scalar this method still needs before the retire point keeps this
// correct regardless of which physical instance `replacement` ends
// up being.
PhysicsSetPositionResult inheritedResult = default;
uint inheritedExactCellId = 0u;
ulong inheritedCollisionGeneration = 0UL;
if (_operations.TryGetValue(key, out Operation? displaced)
&& (displaced.WakeableLostCell
|| displaced.InheritedLostDeadline))
{
inheritedLostFamily = displaced.LostFamilyKeys;
displaced.LostFamilyKeys = null;
inheritedWithdrawalAcknowledged =
displaced.WithdrawalAcknowledged;
inheritedResult = displaced.Result;
inheritedExactCellId = displaced.ExactCellId;
inheritedCollisionGeneration = displaced.CollisionGeneration;
if (displaced.ProjectionSequence != 0UL
&& _pendingProjection.TryGetValue(
displaced.ProjectionSequence,
out RuntimePlacementProjectionSnapshot pendingWithdrawal)
&& pendingWithdrawal.Kind
is RuntimePlacementProjectionKind.Withdraw)
{
inheritedWithdrawal = pendingWithdrawal;
displaced.ProjectionSequence = 0UL;
}
}
_ = CancelCoreDeferred(
key,
cancelLostFamily: false,
preserveLostFamily: inheritedLostFamily is not null,
out RuntimePlacementProjectionSnapshot? discard);
// F3: rent only AFTER the retire above (not before, as the C2
// landing originally had it). Every field this method needs from a
// displaced operation was already captured into the locals above,
// so it is both SAFE and efficient for a single-entity churn cycle
// to hand that exact instance right back out here (the pool is
// LIFO) instead of allocating or drawing a different pooled
// instance - a fresh RentOperation() call always starts from
// `ResetAllFieldsToDefault`'s inert state regardless of which
// instance it returns.
Operation replacement = RentOperation();
replacement.Record = record;
replacement.Token = token;
replacement.Key = key;
replacement.PositionAuthorityVersion = expectedPositionAuthorityVersion;
replacement.SessionLifetimeVersion = _entities.SessionLifetimeVersion;
replacement.SourceSpatialAuthorityVersion =
record.SpatialAuthorityVersion;
replacement.SourceVelocityAuthorityVersion =
record.VelocityAuthorityVersion;
replacement.PreviousContact = record.PhysicsBody?.InContact ?? false;
replacement.PreviousOnWalkable =
record.PhysicsBody?.OnWalkable ?? false;
replacement.Command = default;
replacement.Result = default;
replacement.SpatialAuthorityVersion = record.SpatialAuthorityVersion;
replacement.PlacementCommitVersion = record.PlacementCommitVersion;
replacement.Stage = RuntimeEntityPlacementStage.AwaitingPreparation;
replacement.Kind = kind;
replacement.Portal = portal;
replacement.LostFamilyKeys = inheritedLostFamily;
replacement.InheritedLostDeadline = inheritedLostFamily is not null;
replacement.WithdrawalAcknowledged = inheritedWithdrawalAcknowledged;
if (inheritedWithdrawal is { } retainedWithdrawal)
{
replacement.ProjectionSequence =
retainedWithdrawal.Token.Sequence;
replacement.Result = inheritedResult;
replacement.ExactCellId = inheritedExactCellId;
replacement.CollisionGeneration = inheritedCollisionGeneration;
}
_operations[key] = replacement;
if (captureMoverPreparationAuthority)
{
_moverPreparationAuthorities[key] = CapturePreparationAuthority(
replacement,
acceptedPosition!.Value,
prepared: false);
}
if (discard is { } cancelled)
PublishPlacement(cancelled);
// F3: deliberately does NOT use `IsCurrent(replacement)` here.
// `PublishPlacement` above can synchronously notify a subscriber
// that reentrantly calls BeginAcceptedPlacement for the SAME entity
// (see ReentrantBeginDuringDiscardCannotBeOverwrittenByOuterBegin) -
// that reentrant call retires `replacement` and, per this method's
// rent-after-retire ordering, can rent it right back out (LIFO) for
// the INNER operation. `replacement` (the physical object) would
// then read as the inner operation's Key/Token, and comparing it
// against itself via `_operations.TryGetValue(replacement.Key, ...)
// && ReferenceEquals(current, replacement)` is a tautology - it
// would report "still current" even though THIS (outer) Begin
// invocation was clearly superseded. `token` was captured fresh at
// the top of this call, before any reentrancy could touch it, so
// comparing it against whatever now actually owns the key correctly
// answers "is my own invocation still canonical" regardless of
// what happened to `replacement` in between.
return _operations.TryGetValue(key, out Operation? currentOperation)
&& currentOperation.Token == token
? token
: default;
}
private bool HasRetainedCompletion(RuntimeEntityKey key)
{
foreach (RuntimeEntityPlacementToken token
in _acknowledgedPlacementCompletions.Keys)
{
if (token.Entity == key)
return true;
}
return false;
}
internal RuntimeSetPositionMoverPreparationStatus PrepareMover(
in RuntimeEntityPlacementToken token,
in RuntimeSetPositionMoverPreparation preparation,
out RuntimeSetPositionCommand command)
{
EnsureNotDisposed();
command = default;
// Round 3 audit: safe - fresh lookup + Token check earlier in this
// SAME guard clause precede IsCurrent, nothing reentrant in between.
if (!token.IsValid
|| !_operations.TryGetValue(token.Entity, out Operation? operation)
|| operation.Token != token
|| operation.Stage is not (
RuntimeEntityPlacementStage.AwaitingPreparation
or RuntimeEntityPlacementStage.AwaitingCell)
|| operation.Stage is RuntimeEntityPlacementStage.AwaitingCell
&& (!operation.DormantLocalActivation
|| !operation.WakeableLostCell)
|| !IsCurrent(operation)
|| !_moverPreparationAuthorities.TryGetValue(
token.Entity,
out MoverPreparationAuthority authority)
|| authority.OperationId != token.OperationId
|| !IsPreparationAuthorityCurrent(operation, authority))
{
return RuntimeSetPositionMoverPreparationStatus.RejectedAuthority;
}
if (!preparation.Setup.IsResolved)
{
return RuntimeSetPositionMoverPreparationStatus
.RetrySetupUnavailable;
}
if (!RuntimeSetPositionMoverPreparer.TryBuild(
operation.Record,
authority.AcceptedPosition,
authority.SetupTableId,
operation.Kind,
operation.Portal,
authority.VelocityAuthorityVersion,
preparation,
out command)
|| !IsStructurallyValid(command.Physics))
{
command = default;
return RuntimeSetPositionMoverPreparationStatus.InvalidData;
}
_moverPreparationAuthorities[token.Entity] = authority with
{
Prepared = true,
PreparedCommand = command,
};
return RuntimeSetPositionMoverPreparationStatus.Prepared;
}
/// <summary>
/// C0-3: chains the exact-Setup mover pipeline end-to-end for an
/// authored placement (initial-Create or any other authored-mover
/// operation) whose route performs SetPosition - PrepareMover /
/// RuntimeSetPositionMoverPreparer.TryBuild /
/// IPreparedCollisionSource.ReadSetupCollision already exist piecewise
/// (inventory gap a); this is the missing wiring, not a behavior change.
/// Reads the CANONICAL Setup table id from the record via
/// <see cref="CanonicalSetupTableId"/> - the SAME field
/// <see cref="CapturePreparationAuthority"/> already trusts - rather than
/// a caller-supplied id, so this can never be pointed at the wrong
/// Setup. A record with no authored Setup at all (id 0) takes retail's
/// genuine "no Setup" dummy-sphere path
/// (<see cref="RuntimeSetPositionMoverSetup.ResolvedAbsent"/>) instead of
/// reading anything; a record WITH an id but an unavailable/corrupt
/// asynchronous read yields <see cref="RuntimeSetPositionMoverPreparationStatus.RetrySetupUnavailable"/>
/// so the caller retries once the prepared-collision package lands,
/// mirroring <see cref="RuntimeSetPositionMoverSetup"/>'s own
/// doc-comment distinction between "not arrived yet" and "resolved
/// absent". Dormant: internal, no production caller - a residence
/// lease's own <c>Placement</c>/<c>Route.OperationKind</c>/
/// <c>Route.SetPositionFlags</c> are exactly the token/kind/flags this
/// takes.
/// </summary>
internal RuntimeSetPositionMoverPreparationStatus
TryPrepareAndSubmitAuthoredPlacement(
RuntimeEntityRecord record,
in RuntimeEntityPlacementToken token,
RuntimeSetPositionOperationKind operationKind,
PhysicsSetPositionFlags flags,
IPreparedCollisionSource collisionSource,
double gameTime,
out RuntimeSetPositionOutcome outcome,
PhysicsPlacementClass placementClass = PhysicsPlacementClass.Ordinary,
RuntimePortalPlacementAuthority portal = default,
Vector3 line = default,
float scatterRadiusX = 0f,
float scatterRadiusY = 0f,
uint scatterAttempts = 0u,
float shadowWorldOffsetX = 0f,
float shadowWorldOffsetY = 0f)
{
outcome = default;
RuntimeSetPositionMoverPreparationStatus status =
TryPrepareAuthoredMover(
record,
token,
operationKind,
flags,
collisionSource,
gameTime,
out RuntimeSetPositionCommand command,
placementClass,
portal,
line,
scatterRadiusX,
scatterRadiusY,
scatterAttempts,
shadowWorldOffsetX,
shadowWorldOffsetY);
if (status != RuntimeSetPositionMoverPreparationStatus.Prepared)
return status;
outcome = SubmitPreparedPlacement(token, command);
return RuntimeSetPositionMoverPreparationStatus.Prepared;
}
/// <summary>
/// C3a: the exact-Setup-read + <see cref="PrepareMover"/> half of
/// <see cref="TryPrepareAndSubmitAuthoredPlacement"/>, extracted (pure
/// refactor, byte-identical behavior for the existing caller above) so
/// the dormant local-player first-entry conductor
/// (<c>AcDream.Runtime.Gameplay.RuntimeLocalPlayerFirstEntryState</c>)
/// can obtain a prepared <see cref="RuntimeSetPositionCommand"/> WITHOUT
/// the trailing <see cref="SubmitPreparedPlacement"/> call. Submission
/// through the ordinary tail is exactly what an operation with
/// <c>DormantLocalActivation</c> set must never receive — see
/// <see cref="RetryDeferred"/>'s "must never bypass that path through the
/// ordinary remote CommitCanonical tail" comment; the dormant chain's own
/// Evaluate/Commit/FinalizeActivation methods are the sole substitute for
/// submission on that path.
/// </summary>
internal RuntimeSetPositionMoverPreparationStatus TryPrepareAuthoredMover(
RuntimeEntityRecord record,
in RuntimeEntityPlacementToken token,
RuntimeSetPositionOperationKind operationKind,
PhysicsSetPositionFlags flags,
IPreparedCollisionSource collisionSource,
double gameTime,
out RuntimeSetPositionCommand command,
PhysicsPlacementClass placementClass = PhysicsPlacementClass.Ordinary,
RuntimePortalPlacementAuthority portal = default,
Vector3 line = default,
float scatterRadiusX = 0f,
float scatterRadiusY = 0f,
uint scatterAttempts = 0u,
float shadowWorldOffsetX = 0f,
float shadowWorldOffsetY = 0f)
{
EnsureNotDisposed();
ArgumentNullException.ThrowIfNull(record);
ArgumentNullException.ThrowIfNull(collisionSource);
command = default;
uint setupTableId = CanonicalSetupTableId(record);
RuntimeSetPositionMoverSetup setup;
if (setupTableId == 0u)
{
setup = RuntimeSetPositionMoverSetup.ResolvedAbsent;
}
else
{
PreparedCollisionReadResult<FlatSetupCollision> read =
collisionSource.ReadSetupCollision(setupTableId);
if (read.Status != PreparedAssetReadStatus.Loaded
|| read.Data is null)
{
return RuntimeSetPositionMoverPreparationStatus
.RetrySetupUnavailable;
}
setup = RuntimeSetPositionMoverSetup.Resolved(
setupTableId, read.Data);
}
var preparation = new RuntimeSetPositionMoverPreparation(
setup,
operationKind,
gameTime,
placementClass,
flags,
line,
scatterRadiusX,
scatterRadiusY,
scatterAttempts,
shadowWorldOffsetX,
shadowWorldOffsetY,
portal);
return PrepareMover(token, preparation, out command);
}
internal bool IsExactPreparedPlacementCurrent(
RuntimeEntityRecord record,
in RuntimeEntityPlacementToken token,
in RuntimeSetPositionCommand command)
{
EnsureNotDisposed();
ArgumentNullException.ThrowIfNull(record);
// Round 3 audit: safe - fresh lookup + Token check earlier in this
// SAME return expression precede IsCurrent, nothing reentrant in
// between.
return token.IsValid
&& token.Entity == record.Key
&& _operations.TryGetValue(token.Entity, out Operation? operation)
&& ReferenceEquals(operation.Record, record)
&& operation.Token == token
&& operation.Stage
is RuntimeEntityPlacementStage.AwaitingPreparation
&& IsCurrent(operation)
&& _moverPreparationAuthorities.TryGetValue(
token.Entity,
out MoverPreparationAuthority authority)
&& authority.OperationId == token.OperationId
&& authority.Prepared
&& authority.PreparedCommand == command
&& IsPreparationAuthorityCurrent(operation, authority);
}
/// <summary>
/// Evaluates the exact authored local-player placement without mutating
/// the canonical dormant body or any Runtime ownership index. Core's
/// SetPosition transaction is pure; collision reporting is deliberately
/// omitted until the later atomic activation commit.
/// </summary>
internal bool TryEvaluateDormantLocalActivation(
RuntimeEntityRecord record,
PhysicsBody body,
in RuntimeEntityPlacementToken token,
in RuntimeSetPositionCommand command,
out RuntimeDormantSetPositionEvaluation evaluation)
{
EnsureNotDisposed();
ArgumentNullException.ThrowIfNull(record);
ArgumentNullException.ThrowIfNull(body);
evaluation = default;
if (!IsExactDormantLocalActivationCurrent(
record,
body,
token,
command,
out _)
&& !TryRearmDeferredDormantLocalActivation(
record,
body,
token,
command))
{
return false;
}
if (!IsExactDormantLocalActivationCurrent(
record,
body,
token,
command,
out Operation? operation))
{
return false;
}
PhysicsSetPositionRequest canonicalRequest = command.Physics with
{
MoverPhysicsState = record.FinalPhysicsState,
MovingEntityId = token.Entity.LocalEntityId,
CurrentCellId = null,
};
if (!IsStructurallyValid(canonicalRequest))
return false;
var canonicalCommand = command with { Physics = canonicalRequest };
ulong collisionWorldAuthority = _physics.CollisionWorldAuthority;
ulong shadowWorldAuthority = _physics.ShadowWorldAuthority;
ClientObjectTable? objectTable = _physics.ObjectTable;
ulong objectTableBindingAuthority =
_physics.ObjectTableBindingAuthority;
ulong objectTableAuthority = objectTable?.MutationRevision ?? 0UL;
// Round 3 audit: safe - `handleCollisions: null` means this call
// never invokes HandleSetPositionCollisions/HandleReports/
// ReportEnvironment (no collision-report observer can be reached),
// and this dormant-activation path never calls CommitCanonical (so
// no ground-edge HitGround/LeaveGround dispatch either) - there is
// no reentrancy point between `operation` being obtained above and
// the ReferenceEquals check below.
PhysicsSetPositionResult result = _physics.Engine.SetPosition(
canonicalRequest,
handleCollisions: null);
if (!IsExactDormantLocalActivationCurrent(
record,
body,
token,
command,
out Operation? current)
|| !ReferenceEquals(current, operation))
{
return false;
}
if (!_physics.TrySealCollisionEvaluationAuthority(
result,
collisionWorldAuthority,
shadowWorldAuthority,
objectTable,
objectTableBindingAuthority,
objectTableAuthority,
out RuntimeCollisionEvaluationAuthority collisionAuthority))
{
return false;
}
evaluation = new RuntimeDormantSetPositionEvaluation(
token,
canonicalCommand,
result,
collisionAuthority);
return true;
}
internal bool IsDormantLocalEvaluationCurrent(
RuntimeEntityRecord record,
PhysicsBody body,
in RuntimeDormantSetPositionEvaluation evaluation) =>
evaluation.IsValid
&& IsExactDormantLocalActivationCurrent(
record,
body,
evaluation.Placement,
evaluation.Command,
out _,
allowCanonicalCommand: true)
&& _physics.IsCollisionEvaluationAuthorityCurrent(
evaluation.CollisionAuthority);
internal bool IsDormantLocalActivationLeaseCurrent(
RuntimeEntityRecord record,
PhysicsBody body,
in RuntimeEntityPlacementToken token,
in RuntimeSetPositionCommand command) =>
IsExactDormantLocalActivationCurrent(
record,
body,
token,
command,
out _,
allowDeferredLease: true);
internal bool IsDormantLocalActivationAwaitingCell(
RuntimeEntityRecord record,
PhysicsBody body,
in RuntimeEntityPlacementToken token,
in RuntimeSetPositionCommand command)
{
return IsExactDormantLocalActivationCurrent(
record,
body,
token,
command,
out Operation? operation,
allowDeferredLease: true)
&& operation is not null
&& operation.Stage is RuntimeEntityPlacementStage.AwaitingCell
&& operation.DormantLocalActivation
&& operation.WakeableLostCell;
}
/// <summary>
/// C3c-F2: the identity check below is against
/// <see cref="RuntimePhysicsState.CollisionGenerationAuthority"/> — the
/// generation the collision world currently HOLDS — not against
/// <c>ExpectedCollisionGeneration</c>, which means two different things
/// at the two ends of this wait. At park time (this class's own
/// <c>TryPrepareDormantLocalActivationCommit</c>) an admission for the
/// destination landblock is in flight, so Expected == that admission's
/// generation G and the lease correctly parks against G. The wake that
/// sets <c>CollisionGenerationReady</c> is
/// <c>CommitCollisionGeneration(lb, G, ready)</c>, and the very next
/// statement in RuntimePhysicsState retires the admission
/// (AdvanceCommittedActivation) while leaving the committed generation at
/// G — from that instant Expected returns G+1, a generation that does not
/// exist and may never be begun. Comparing the parked G against Expected
/// therefore refused every login rearm forever (the connected-gate
/// DeferredCell wedge: controller never published, world never visible).
/// The committed-authority comparison keeps every staleness guarantee: a
/// superseding BeginCollisionAdmission or a CancelCollisionGeneration
/// moves the authority off G and this lease still refuses to rearm.
///
/// <para>
/// The trailing
/// <see cref="RuntimePhysicsState.IsCollisionEvaluationPrefixAdmissible"/>
/// term is the second half of the same C3c-F2 defect and is what the live
/// probe caught: the collision-generation commit reenters the host's
/// first-entry pump BEFORE its own admission is retired
/// (RuntimePhysicsState.cs:2503 commits the generation, :2552-2558 retires
/// the admission). Rearming inside that window moves the lease out of
/// AwaitingCell and the very next evaluation fails
/// <c>TrySealCollisionEvaluationAuthority</c> on the still-registered
/// admission — at which point EvaluateActivation can no longer report
/// DeferredCell (the operation is no longer AwaitingCell) and returns
/// RejectedAuthority, which is TERMINAL for the conductor. Refusing the
/// rearm until the prefix is evaluable keeps the lease parked and
/// retryable, exactly as the remote wake path already does with
/// <c>TryGetBlockingQuiescence</c> (:4069-4095).
/// </para>
/// </summary>
private bool TryRearmDeferredDormantLocalActivation(
RuntimeEntityRecord record,
PhysicsBody body,
in RuntimeEntityPlacementToken token,
in RuntimeSetPositionCommand command)
{
if (!IsExactDormantLocalActivationCurrent(
record,
body,
token,
command,
out Operation? operation,
allowDeferredLease: true)
|| operation is null
|| operation.Stage is not RuntimeEntityPlacementStage.AwaitingCell
|| !operation.DormantLocalActivation
|| !operation.WakeableLostCell
|| !operation.CollisionGenerationReady
|| operation.ProjectionSequence != 0UL
|| operation.CollisionGeneration != _physics
.CollisionGenerationAuthority(operation.ExactCellId)
|| !_physics.Engine.IsSpawnCellReady(operation.ExactCellId)
|| !_physics.IsCollisionEvaluationPrefixAdmissible(
operation.ExactCellId))
{
return false;
}
UnindexDeferred(operation);
operation.WakeableLostCell = false;
operation.CollisionGenerationReady = false;
operation.Stage = RuntimeEntityPlacementStage.AwaitingPreparation;
return true;
}
internal bool TryPrepareDormantLocalActivationCommit(
RuntimeEntityRecord record,
PhysicsBody body,
in RuntimeDormantSetPositionEvaluation evaluation,
bool provenShapeless,
out PreparedDormantSetPositionCommit? prepared)
{
EnsureNotDisposed();
ArgumentNullException.ThrowIfNull(record);
ArgumentNullException.ThrowIfNull(body);
prepared = null;
if (!IsDormantLocalEvaluationCurrent(record, body, evaluation)
|| !IsExactDormantLocalActivationCurrent(
record,
body,
evaluation.Placement,
evaluation.Command,
out Operation? operation,
allowCanonicalCommand: true)
|| operation is null)
{
return false;
}
PhysicsSetPositionResult result = evaluation.Result;
ShadowObjectRegistry.PreparedSetPositionShadowCommit? shadow = null;
RuntimeCollisionReportingState.PreparedSetPositionCollisionBatch?
collision = null;
RuntimePlacementProjectionSnapshot projection = default;
SortedDictionary<ulong, RuntimePlacementProjectionSnapshot>?
pendingProjection = null;
ulong deferredCollisionGeneration = 0UL;
List<RuntimeEntityKey>? deferredBucket = null;
bool deferredBucketIsNew = false;
if (!result.IsDeferred)
{
if (!_physics.CollisionReports.TryPrepareSetPositionBatch(
record,
body,
evaluation.Command.GameTime,
result.IsCommitted && operation.PreviousContact,
result.IsCommitted && operation.PreviousOnWalkable,
result.IsCommitted && result.OnWalkable,
result.CollidedWithEnvironment,
result.CollidedObjectIds,
out collision)
|| collision is null)
{
return false;
}
}
if (result.IsDeferred)
{
deferredCollisionGeneration = _physics
.ExpectedCollisionGeneration(result.CellId);
_preparedMovers.EnsureCapacity(_preparedMovers.Count + 1);
if (result.CellId != 0u && deferredCollisionGeneration != 0UL)
{
var bucketKey = new CellGenerationKey(
result.CellId,
result.CellId & 0xFFFF0000u,
deferredCollisionGeneration);
if (_deferredByCellGeneration.TryGetValue(
bucketKey,
out deferredBucket))
{
deferredBucket.EnsureCapacity(deferredBucket.Count + 1);
}
else
{
deferredBucket = [operation.Key];
deferredBucketIsNew = true;
_deferredByCellGeneration.EnsureCapacity(
_deferredByCellGeneration.Count + 1);
_deferredBucketOrder.EnsureCapacity(
_deferredBucketOrder.Count + 1);
}
}
if (!_physics.Engine.ShadowObjects.TryPrepareSetPosition(
operation.Key.LocalEntityId,
result.Position,
result.Orientation,
result.CellId,
evaluation.Command.ShadowWorldOffsetX,
evaluation.Command.ShadowWorldOffsetY,
PhysicsShadowCommitAction.Preserve,
ImmutableArray<uint>.Empty,
provenShapeless,
suspendOwner: true,
out shadow)
|| shadow is null)
{
return false;
}
}
ulong expectedProjectionSequence = _nextProjectionSequence;
if (result.IsCommitted)
{
_ = checked(record.ObjectClockEpoch + 1UL);
_ = checked(record.PlacementCommitVersion + 1UL);
if (record.FullCellId != result.CellId)
_ = checked(record.SpatialAuthorityVersion + 1UL);
if (!_physics.TryPrepareSpatialRootAdmission(record))
return false;
ulong sequence = checked(expectedProjectionSequence + 1UL);
ulong spatial = record.SpatialAuthorityVersion
+ (record.FullCellId == result.CellId ? 0UL : 1UL);
ulong placement = checked(record.PlacementCommitVersion + 1UL);
var token = new RuntimePlacementProjectionToken(
sequence,
Revision: 1UL,
operation.Key,
operation.PositionAuthorityVersion,
spatial,
placement,
operation.SessionLifetimeVersion,
result.CellId,
operation.CollisionGeneration,
evaluation.Command.Portal);
projection = new RuntimePlacementProjectionSnapshot(
token,
RuntimePlacementProjectionKind.Place,
result.Position,
result.Orientation,
result.CellLocalPosition,
result.InContact,
result.OnWalkable);
pendingProjection = new SortedDictionary<
ulong,
RuntimePlacementProjectionSnapshot>(_pendingProjection)
{
[sequence] = projection,
};
}
prepared = new PreparedDormantSetPositionCommit
{
Evaluation = evaluation,
Entity = operation.Key,
OperationId = operation.Token.OperationId,
ExpectedProjectionSequence = expectedProjectionSequence,
Shadow = shadow,
Collision = collision,
Projection = projection,
PendingProjection = pendingProjection,
DeferredCollisionGeneration = deferredCollisionGeneration,
DeferredBucket = deferredBucket,
DeferredBucketIsNew = deferredBucketIsNew,
};
return IsPreparedDormantCommitCurrent(record, body, prepared);
}
internal bool TryApplyDormantLocalActivationCommit(
RuntimeEntityRecord record,
PhysicsBody body,
PlayerMovementController controller,
EntityPhysicsHost physicsHost,
PreparedDormantSetPositionCommit prepared,
out RuntimeDormantSetPositionCommitReceipt receipt)
{
EnsureNotDisposed();
ArgumentNullException.ThrowIfNull(record);
ArgumentNullException.ThrowIfNull(body);
ArgumentNullException.ThrowIfNull(controller);
ArgumentNullException.ThrowIfNull(physicsHost);
ArgumentNullException.ThrowIfNull(prepared);
receipt = default;
if (!IsPreparedDormantCommitCurrent(record, body, prepared)
|| !_operations.TryGetValue(
prepared.Entity,
out Operation? operation))
{
return false;
}
PhysicsSetPositionResult result = prepared.Evaluation.Result;
operation.Body = body;
operation.DormantLocalActivation = true;
if (result.IsDeferred)
{
if (prepared.Shadow is null
|| !_physics.Engine.ShadowObjects.TryApplySetPosition(
prepared.Shadow,
out ShadowObjectRegistry.SetPositionShadowCommitReceipt
deferredShadowReceipt))
{
return false;
}
body.Orientation = result.Orientation;
body.StageDormantCellFrame(
result.CellId,
result.Position,
result.CellLocalPosition);
body.InWorld = false;
body.TransientState &= ~TransientStateFlags.Active;
operation.Result = result;
operation.ExactCellId = result.CellId;
operation.WakeableLostCell = true;
operation.CollisionGeneration = prepared
.DeferredCollisionGeneration;
operation.CollisionPrefix = result.CellId & 0xFFFF0000u;
operation.CollisionGenerationReady = false;
operation.Stage = RuntimeEntityPlacementStage.AwaitingCell;
_preparedMovers[operation.Key] = prepared.Evaluation.Command.Physics;
if (prepared.DeferredBucket is { } deferredBucket)
{
var bucketKey = new CellGenerationKey(
result.CellId,
operation.CollisionPrefix,
prepared.DeferredCollisionGeneration);
if (prepared.DeferredBucketIsNew)
{
_deferredByCellGeneration.Add(bucketKey, deferredBucket);
_deferredBucketOrder.Add(bucketKey);
}
else if (!deferredBucket.Contains(operation.Key))
{
deferredBucket.Add(operation.Key);
}
}
receipt = new RuntimeDormantSetPositionCommitReceipt(
RuntimeDormantSetPositionCommitStatus.DeferredCell,
operation.Key,
operation.Token.OperationId,
default,
default,
deferredShadowReceipt,
prepared.Evaluation.CollisionAuthority,
operation.Record.VectorAuthorityVersion,
HitGround: false,
LeaveGround: false);
return true;
}
if (prepared.Collision is null
|| !_physics.CollisionReports.TryInstallSetPositionBatch(
prepared.Collision,
out RuntimeCollisionReportingState
.SetPositionCollisionBatchReceipt collisionReceipt))
{
return false;
}
if (!result.IsCommitted)
{
operation.Result = result;
receipt = new RuntimeDormantSetPositionCommitReceipt(
RuntimeDormantSetPositionCommitStatus.RejectedPlacement,
operation.Key,
operation.Token.OperationId,
default,
collisionReceipt,
default,
prepared.Evaluation.CollisionAuthority,
operation.Record.VectorAuthorityVersion,
HitGround: false,
LeaveGround: false);
return true;
}
bool previousOnWalkable = operation.PreviousOnWalkable;
bool hitGround = !previousOnWalkable
&& result.InContact
&& result.OnWalkable;
bool leaveGround = previousOnWalkable
&& !(result.InContact && result.OnWalkable);
UnindexDeferred(operation);
body.Orientation = result.Orientation;
body.StageDormantCellFrame(
result.CellId,
result.Position,
result.CellLocalPosition);
body.LastUpdateTime = prepared.Evaluation.Command.GameTime;
body.ContactPlaneValid = result.InContact;
body.ContactPlane = result.ContactPlane;
body.ContactPlaneCellId = result.ContactPlaneCellId;
body.ContactPlaneIsWater = result.ContactPlaneIsWater;
if (result.InContact)
body.GroundNormal = result.ContactPlane.Normal;
_ = PhysicsObjUpdate.CommitSetPositionContactPrefix(
body,
result.InContact,
result.OnWalkable,
previousOnWalkable);
operation.Result = result;
operation.ExactCellId = result.CellId;
operation.WakeableLostCell = false;
operation.CollisionGenerationReady = false;
operation.EnteringWorldFromCelllessResidence = false;
operation.Stage = RuntimeEntityPlacementStage
.AwaitingFinalShadowPreparation;
receipt = new RuntimeDormantSetPositionCommitReceipt(
RuntimeDormantSetPositionCommitStatus
.AwaitingFinalShadowPreparation,
operation.Key,
operation.Token.OperationId,
prepared.Projection,
collisionReceipt,
default,
prepared.Evaluation.CollisionAuthority,
operation.Record.VectorAuthorityVersion,
hitGround,
leaveGround);
return true;
}
internal SetPositionCollisionBatchDispatchResult
DispatchDormantLocalActivationCollision(
in RuntimeDormantSetPositionCommitReceipt receipt)
{
if (receipt.Status
is RuntimeDormantSetPositionCommitStatus.DeferredCell
or RuntimeDormantSetPositionCommitStatus.RejectedAuthority)
{
return new(
SetPositionCollisionBatchDispatchStatus.RejectedReceipt,
Reported: false);
}
SetPositionCollisionBatchDispatchResult dispatch = _physics
.CollisionReports.DispatchSetPositionBatchResult(receipt.Collision);
bool reported = dispatch.Reported;
// Round 3 audit: safe - fresh lookup + Token.OperationId check
// earlier in this SAME guard clause precede IsCurrent, nothing
// reentrant in between. This dormant-activation family has zero
// production callers and never routes through CommitCanonical's
// ground-edge callback or the live collision-report dispatch that
// can reach an arbitrary observer.
if (receipt.Status
is RuntimeDormantSetPositionCommitStatus.RejectedPlacement
&& _operations.TryGetValue(receipt.Entity, out Operation? operation)
&& operation.Token.OperationId == receipt.OperationId
&& IsCurrent(operation)
&& !operation.Result.IsCommitted
&& !operation.Result.IsDeferred)
{
operation.Result = operation.Result with
{
Error = reported
? PhysicsSetPositionError.Collided
: PhysicsSetPositionError.NoValidPosition,
CollisionHandlerResult = reported,
};
}
return dispatch;
}
internal bool IsDormantLocalActivationPrephaseCurrent(
RuntimeEntityRecord record,
PhysicsBody body,
in RuntimeDormantSetPositionCommitReceipt receipt)
{
// Round 3 audit: safe - fresh lookup + Token.OperationId check
// earlier in this SAME return expression precede IsCurrent, nothing
// reentrant in between; this dormant family has zero production
// callers.
return receipt.Status is RuntimeDormantSetPositionCommitStatus
.AwaitingFinalShadowPreparation
&& _operations.TryGetValue(receipt.Entity, out Operation? operation)
&& operation.Token.OperationId == receipt.OperationId
&& operation.Stage is RuntimeEntityPlacementStage
.AwaitingFinalShadowPreparation
&& operation.DormantLocalActivation
&& IsCurrent(operation)
&& ReferenceEquals(operation.Record, record)
&& ReferenceEquals(record.PhysicsBody, body)
&& !body.InWorld
&& (body.TransientState & TransientStateFlags.Active) == 0
&& record.PhysicsHost is null
&& record.RemoteMotion is null
&& record.Projectile is null
&& !_physics.IsSpatialRoot(record)
&& _moverPreparationAuthorities.TryGetValue(
receipt.Entity,
out MoverPreparationAuthority authority)
&& authority.OperationId == receipt.OperationId
&& authority.Prepared
&& record.PositionAuthorityVersion
== authority.PositionAuthorityVersion
&& record.ObjDescAuthorityVersion
== authority.ObjDescAuthorityVersion
&& record.CreateIntegrationVersion
== authority.CreateIntegrationVersion
&& CanonicalSetupTableId(record) == authority.SetupTableId;
}
internal bool IsDormantLocalActivationResponseCurrent(
RuntimeEntityRecord record,
PhysicsBody body,
in RuntimeDormantSetPositionCommitReceipt receipt)
{
if (receipt.Status is RuntimeDormantSetPositionCommitStatus
.AwaitingFinalShadowPreparation)
return IsDormantLocalActivationPrephaseCurrent(record, body, receipt);
// Round 3 audit: safe - fresh lookup + Token.OperationId check
// earlier in this SAME return expression precede IsCurrent, nothing
// reentrant in between; this dormant family has zero production
// callers.
return receipt.Status is RuntimeDormantSetPositionCommitStatus
.RejectedPlacement
&& _operations.TryGetValue(receipt.Entity, out Operation? operation)
&& operation.Token.OperationId == receipt.OperationId
&& operation.DormantLocalActivation
&& IsCurrent(operation)
&& ReferenceEquals(operation.Record, record)
&& ReferenceEquals(record.PhysicsBody, body)
&& !operation.Result.IsCommitted
&& !operation.Result.IsDeferred
&& !body.InWorld
&& (body.TransientState & TransientStateFlags.Active) == 0
&& record.PhysicsHost is null
&& record.RemoteMotion is null
&& record.Projectile is null
&& !_physics.IsSpatialRoot(record);
}
internal bool CommitDormantLocalActivationPostGround(
RuntimeEntityRecord record,
PhysicsBody body,
in RuntimeDormantSetPositionCommitReceipt receipt)
{
if (!IsDormantLocalActivationPrephaseCurrent(record, body, receipt))
return false;
PhysicsObjUpdate.CommitSetPositionPostGround(body);
PhysicsSetPositionResult result = _operations[receipt.Entity].Result;
body.SlidingNormal = result.SlidingNormal;
if (result.SlidingNormalValid)
body.TransientState |= TransientStateFlags.Sliding;
else
body.TransientState &= ~TransientStateFlags.Sliding;
return IsDormantLocalActivationPrephaseCurrent(record, body, receipt);
}
internal bool CommitDormantLocalActivationPostCollision(
RuntimeEntityRecord record,
PhysicsBody body,
in RuntimeDormantSetPositionCommitReceipt receipt)
{
// Round 3 audit: safe - fresh lookup + Token.OperationId check
// immediately precede IsCurrent, nothing reentrant in between; this
// dormant family has zero production callers. Nothing between here
// and the final `IsCurrent(operation)` below invokes anything
// reentrant either (IsVelocityCurrent/HandleAllCollisions/
// CommitStationaryBits are pure PhysicsObjUpdate calls on `body`,
// and the nested IsDormantLocalActivationPrephaseCurrent call is
// itself a fresh-lookup check), so the SAME verified `operation`
// reference remains valid through the final check.
if (!_operations.TryGetValue(receipt.Entity, out Operation? operation)
|| operation.Token.OperationId != receipt.OperationId
|| !IsCurrent(operation)
|| !ReferenceEquals(operation.Record, record)
|| !ReferenceEquals(record.PhysicsBody, body))
{
return false;
}
if (receipt.Status is RuntimeDormantSetPositionCommitStatus
.AwaitingFinalShadowPreparation
&& !IsDormantLocalActivationPrephaseCurrent(record, body, receipt))
{
return false;
}
PhysicsSetPositionResult result = operation.Result;
body.FramesStationaryFall = result.FramesStationaryFall;
if (IsVelocityCurrent(operation))
{
PhysicsObjUpdate.HandleAllCollisions(
body,
result.CollisionNormalValid,
result.CollisionNormal,
operation.PreviousContact,
operation.PreviousOnWalkable,
body.OnWalkable);
}
CommitStationaryBits(body, result.FramesStationaryFall);
return IsCurrent(operation);
}
internal bool TryPrepareDormantLocalActivationFinalCommit(
RuntimeEntityRecord record,
PhysicsBody body,
in RuntimeDormantSetPositionCommitReceipt receipt,
bool provenShapeless,
out PreparedDormantActivationFinalCommit? prepared)
{
prepared = null;
if (!IsDormantLocalActivationPrephaseCurrent(record, body, receipt)
|| !_operations.TryGetValue(receipt.Entity, out Operation? operation))
{
return false;
}
PhysicsSetPositionResult result = operation.Result;
if (!_physics.Engine.ShadowObjects.TryPrepareSetPosition(
operation.Key.LocalEntityId,
result.Position,
result.Orientation,
result.CellId,
operation.Command.ShadowWorldOffsetX,
operation.Command.ShadowWorldOffsetY,
result.ShadowAction,
result.CrossCellIds,
provenShapeless,
suspendOwner: false,
out ShadowObjectRegistry.PreparedSetPositionShadowCommit? shadow)
|| shadow is null
|| _nextProjectionSequence + 1UL
!= receipt.Projection.Token.Sequence)
{
return false;
}
var pending = new SortedDictionary<
ulong,
RuntimePlacementProjectionSnapshot>(_pendingProjection)
{
[receipt.Projection.Token.Sequence] = receipt.Projection,
};
prepared = new PreparedDormantActivationFinalCommit
{
Entity = receipt.Entity,
OperationId = receipt.OperationId,
ExpectedProjectionSequence = _nextProjectionSequence,
Shadow = shadow,
Projection = receipt.Projection,
PendingProjection = pending,
};
bool current = IsDormantLocalActivationPrephaseCurrent(
record, body, receipt);
bool shadowCurrent = _physics.Engine.ShadowObjects
.IsPreparedSetPositionCurrent(shadow);
return current && shadowCurrent;
}
internal bool TryApplyDormantLocalActivationFinalCommit(
RuntimeEntityRecord record,
PhysicsBody body,
PlayerMovementController controller,
EntityPhysicsHost physicsHost,
in RuntimeDormantSetPositionCommitReceipt prephase,
PreparedDormantActivationFinalCommit prepared,
out RuntimeDormantSetPositionCommitReceipt committed)
{
committed = default;
if (prepared.Entity != prephase.Entity
|| prepared.OperationId != prephase.OperationId
|| prepared.ExpectedProjectionSequence != _nextProjectionSequence
|| prepared.Projection != prephase.Projection
|| !IsDormantLocalActivationPrephaseCurrent(record, body, prephase)
|| !_physics.Engine.ShadowObjects.TryApplySetPosition(
prepared.Shadow,
out ShadowObjectRegistry.SetPositionShadowCommitReceipt shadow))
{
return false;
}
Operation operation = _operations[prephase.Entity];
PhysicsSetPositionResult result = operation.Result;
if (record.FullCellId != result.CellId)
{
_entities.SetFullCell(record, result.CellId,
(result.CellId & 0xFFFF0000u) | 0xFFFFu);
}
operation.SpatialAuthorityVersion = record.SpatialAuthorityVersion;
_entities.AdvancePlacementCommit(record);
operation.PlacementCommitVersion = record.PlacementCommitVersion;
body.InWorld = true;
bool isStatic = (record.FinalPhysicsState & PhysicsStateFlags.Static) != 0;
if (!isStatic)
body.TransientState |= TransientStateFlags.Active;
_entities.SetPhysicsHost(record, physicsHost);
controller.CommitRuntimeActivationFrame();
_physics.Engine.UpdatePlayerCurrCell(result.CellId);
_physics.AcknowledgeSpatialProjection(record, spatial: true);
_entities.ResetObjectClockForEnterWorld(record, isStatic);
operation.Stage = RuntimeEntityPlacementStage.AwaitingCommitAcknowledgement;
operation.ProjectionSequence = prepared.Projection.Token.Sequence;
_pendingProjection = prepared.PendingProjection;
_nextProjectionSequence = prepared.Projection.Token.Sequence;
CancelLostFamilyDeadlines(operation);
controller.ActivateRuntimePublication();
committed = prephase with
{
Status = RuntimeDormantSetPositionCommitStatus.Committed,
Shadow = shadow,
};
return true;
}
internal void DispatchDormantLocalActivationShadow(
in RuntimeDormantSetPositionCommitReceipt receipt)
{
if (receipt.Status is not (
RuntimeDormantSetPositionCommitStatus.Committed
or RuntimeDormantSetPositionCommitStatus.DeferredCell))
return;
_physics.Engine.ShadowObjects.DispatchSetPositionCommit(receipt.Shadow);
}
internal void DispatchDormantLocalActivationPlacement(
in RuntimeDormantSetPositionCommitReceipt receipt)
{
if (!receipt.IsCommitted)
return;
PublishPlacement(receipt.Projection);
}
internal void DiscardDormantLocalActivationDispatches(
in RuntimeDormantSetPositionCommitReceipt receipt,
bool collisionAlreadyDispatched)
{
if (!collisionAlreadyDispatched)
_physics.CollisionReports.DiscardSetPositionBatch(receipt.Collision);
_physics.Engine.ShadowObjects.DiscardSetPositionCommit(receipt.Shadow);
}
internal void RetireDormantLocalActivation(
in RuntimeDormantSetPositionCommitReceipt receipt,
bool collisionAlreadyDispatched)
{
DiscardDormantLocalActivationDispatches(
receipt,
collisionAlreadyDispatched);
_physics.CollisionReports.RetireSetPositionBatchOwner(
receipt.Collision);
if (_operations.TryGetValue(receipt.Entity, out Operation? operation)
&& operation.Token.OperationId == receipt.OperationId)
{
// Round 3: `operation.Token` is read from the fresh lookup
// immediately above, with nothing reentrant in between - safe
// to pass straight through as the captured token.
_ = CancelCore(receipt.Entity, operation.Token);
}
}
internal void RetireDormantLocalActivationToken(
RuntimeEntityRecord record,
in RuntimeEntityPlacementToken token)
{
if (!token.IsValid
|| record.Key != token.Entity
|| !_operations.TryGetValue(token.Entity, out Operation? operation)
|| operation.Token != token
|| !ReferenceEquals(operation.Record, record))
{
return;
}
// Round 3: `token` is this call's own parameter, verified fresh
// against `_operations` immediately above with nothing reentrant in
// between.
_ = CancelCore(token.Entity, token);
}
internal bool IsDormantLocalActivationCommitCurrent(
RuntimeEntityRecord record,
PhysicsBody body,
in RuntimeDormantSetPositionCommitReceipt receipt)
{
// Round 3 audit: safe - fresh lookup + Stage/ProjectionSequence
// check earlier in this SAME guard clause precede IsCurrent,
// nothing reentrant in between.
if (!receipt.IsCommitted
|| !receipt.Projection.Token.IsValid
|| record.Key != receipt.Projection.Token.Entity
|| !ReferenceEquals(record.PhysicsBody, body)
|| !_pendingProjection.TryGetValue(
receipt.Projection.Token.Sequence,
out RuntimePlacementProjectionSnapshot pending)
|| pending != receipt.Projection
|| !_operations.TryGetValue(
receipt.Projection.Token.Entity,
out Operation? operation)
|| operation.Stage is not RuntimeEntityPlacementStage
.AwaitingCommitAcknowledgement
|| operation.ProjectionSequence
!= receipt.Projection.Token.Sequence
|| !IsCurrent(operation)
|| !body.InWorld
|| !_physics.IsSpatialRoot(record))
{
return false;
}
return true;
}
internal bool TryCaptureDormantLocalActivationResult(
in RuntimeEntityPlacementToken token,
out PhysicsSetPositionResult result)
{
if (!_disposed
&& token.IsValid
&& _operations.TryGetValue(token.Entity, out Operation? operation)
&& operation.Token == token)
{
result = operation.Result;
return true;
}
result = default;
return false;
}
private bool IsPreparedDormantCommitCurrent(
RuntimeEntityRecord record,
PhysicsBody body,
PreparedDormantSetPositionCommit prepared)
{
if (_nextProjectionSequence != prepared.ExpectedProjectionSequence
|| !IsDormantLocalEvaluationCurrent(
record,
body,
prepared.Evaluation)
|| !_operations.TryGetValue(
prepared.Entity,
out Operation? operation)
|| operation.Token.OperationId != prepared.OperationId)
{
return false;
}
if (prepared.Collision is not null
&& !_physics.CollisionReports.IsPreparedSetPositionBatchCurrent(
prepared.Collision))
return false;
return prepared.Shadow is null
|| _physics.Engine.ShadowObjects.IsPreparedSetPositionCurrent(
prepared.Shadow);
}
private static void CommitStationaryBits(
PhysicsBody body,
int framesStationaryFall)
{
body.TransientState &= ~(TransientStateFlags.StationaryFall
| TransientStateFlags.StationaryStop
| TransientStateFlags.StationaryStuck);
body.TransientState |= framesStationaryFall switch
{
1 => TransientStateFlags.StationaryFall,
2 => TransientStateFlags.StationaryStop,
3 => TransientStateFlags.StationaryStuck,
_ => TransientStateFlags.None,
};
}
internal RuntimeSetPositionOutcome SubmitPreparedPlacement(
in RuntimeEntityPlacementToken token,
in RuntimeSetPositionCommand command) =>
SubmitPreparedPlacementCore(
token,
command,
allowDirectUnsealed: token.PreparationKind
is RuntimeEntityPlacementPreparationKind.LegacyDirect);
private RuntimeSetPositionOutcome SubmitPreparedPlacementCore(
in RuntimeEntityPlacementToken token,
in RuntimeSetPositionCommand command,
bool allowDirectUnsealed)
{
EnsureNotDisposed();
Operation? operation = null;
bool ownsToken = token.IsValid
&& _operations.TryGetValue(token.Entity, out operation)
&& operation.Token == token;
MoverPreparationAuthority exactAuthority = default;
bool hasPreparationAuthority = token.IsValid
&& _moverPreparationAuthorities.TryGetValue(
token.Entity,
out exactAuthority)
&& exactAuthority.OperationId == token.OperationId;
// Round 3 audit: safe - `ownsToken` (fresh lookup + Token check)
// was just computed above with nothing reentrant in between; this
// is the function's own entry validation, before any of its
// internal reentrancy points (the SetPosition/CommitCanonical calls
// further down, which ARE converted to IsCurrentByToken).
if (!ownsToken
|| operation is null
|| operation.Stage
is not RuntimeEntityPlacementStage.AwaitingPreparation
|| !IsCurrent(operation)
|| operation.Record.PhysicsBody is not { } body
|| !double.IsFinite(command.GameTime)
|| command.Kind != operation.Kind
|| command.Portal != operation.Portal
|| (hasPreparationAuthority
? !exactAuthority.Prepared
|| exactAuthority.PreparedCommand != command
|| !IsPreparationAuthorityCurrent(
operation,
exactAuthority)
: !allowDirectUnsealed)
|| (command.ExpectedVelocityAuthorityVersion != 0UL
&& operation.Record.VelocityAuthorityVersion
!= command.ExpectedVelocityAuthorityVersion))
{
// Preparation is an accepted-operation input, not the operation
// itself. A malformed or temporarily incomplete preparation must
// remain retryable under the exact token and cannot discard a
// withdrawn resident or its last validated mover shape.
return Rejected(command.Physics);
}
operation.Body = body;
operation.EnteringWorldFromCelllessResidence |=
!body.InWorld || operation.Record.FullCellId == 0u;
if (command.ExpectedVelocityAuthorityVersion != 0UL)
{
operation.SourceVelocityAuthorityVersion =
command.ExpectedVelocityAuthorityVersion;
}
operation.PreviousContact = body.InContact;
operation.PreviousOnWalkable = body.OnWalkable;
var canonicalRequest = command.Physics with
{
Position = operation.WakeableLostCell
? operation.Result.Position
: command.Physics.Position,
Orientation = operation.WakeableLostCell
? operation.Result.Orientation
: command.Physics.Orientation,
CellId = operation.WakeableLostCell
? operation.ExactCellId
: command.Physics.CellId,
CellLocalPosition = operation.WakeableLostCell
? operation.Result.CellLocalPosition
: command.Physics.CellLocalPosition,
MoverPhysicsState = operation.Record.FinalPhysicsState,
MovingEntityId = operation.Key.LocalEntityId,
CurrentCellId = operation.WakeableLostCell
? null
: body.InWorld
&& operation.Record.FullCellId != 0u
? operation.Record.FullCellId
: null,
};
var canonicalCommand = command with { Physics = canonicalRequest };
operation.Command = canonicalCommand;
if (hasPreparationAuthority)
{
_moverPreparationAuthorities[token.Entity] = exactAuthority with
{
PreparedCommand = canonicalCommand,
};
}
if (operation.InheritedLostDeadline
&& !operation.WithdrawalAcknowledged
&& operation.ProjectionSequence != 0UL)
{
operation.PreparedCommandAwaitingWithdrawalAck =
canonicalCommand;
operation.Stage = RuntimeEntityPlacementStage
.AwaitingWithdrawalAcknowledgement;
return Outcome(
RuntimeSetPositionStatus.DeferredCell,
operation.Result,
_pendingProjection.TryGetValue(
operation.ProjectionSequence,
out RuntimePlacementProjectionSnapshot pending)
? pending.Token
: default);
}
if (operation.WakeableLostCell)
{
operation.RequiresPreparation = false;
operation.Stage = RuntimeEntityPlacementStage.AwaitingCell;
if (operation.WithdrawalAcknowledged
&& operation.CollisionGenerationReady
&& operation.ProjectionSequence == 0UL)
{
RetryDeferred(operation);
}
return Outcome(
RuntimeSetPositionStatus.DeferredCell,
operation.Result,
operation.ProjectionSequence != 0UL
&& _pendingProjection.TryGetValue(
operation.ProjectionSequence,
out RuntimePlacementProjectionSnapshot pending)
? pending.Token
: default);
}
if (!IsStructurallyValid(canonicalRequest))
{
PhysicsSetPositionResult invalid = InvalidResult(canonicalRequest);
operation.Result = invalid;
operation.RequiresPreparation = true;
operation.Stage = RuntimeEntityPlacementStage.AwaitingPreparation;
return Outcome(RuntimeSetPositionStatus.Rejected, invalid, default);
}
if (TryGetBlockingQuiescence(
canonicalRequest,
out CollisionPrefixQuiescence? quiescence))
{
var deferred = new PhysicsSetPositionResult(
PhysicsSetPositionError.Ok,
PhysicsResidenceDisposition.DeferredCell,
canonicalRequest.Position,
canonicalRequest.Orientation,
canonicalRequest.CellId,
canonicalRequest.CellLocalPosition,
InContact: operation.PreviousContact,
OnWalkable: operation.PreviousOnWalkable,
ContactPlane: body.ContactPlane,
ContactPlaneCellId: body.ContactPlaneCellId,
ContactPlaneIsWater: body.ContactPlaneIsWater,
SlidingNormalValid: body.SlidingNormal != Vector3.Zero,
SlidingNormal: body.SlidingNormal,
FramesStationaryFall: body.FramesStationaryFall,
CrossCellIds: ImmutableArray<uint>.Empty,
CollidedObjectIds: ImmutableArray<uint>.Empty,
QueriedCellIds: ImmutableArray<uint>.Empty);
operation.Result = deferred;
operation.RequiresPreparation = false;
operation.ExactCellId = deferred.CellId;
_preparedMovers[operation.Key] = canonicalRequest;
return ParkDeferred(
operation,
deferred,
collisionGenerationOverride:
quiescence!.Token.CollisionGeneration,
collisionPrefixOverride:
quiescence.Token.LandblockPrefix);
}
PhysicsSetPositionResult result;
_collisionCallbackContexts.Push(new CollisionCallbackContext(
operation.Record,
operation.PositionAuthorityVersion,
operation.SourceSpatialAuthorityVersion,
operation.SourceVelocityAuthorityVersion,
canonicalCommand.GameTime,
operation.PreviousContact,
operation.PreviousOnWalkable));
try
{
result = _physics.Engine.SetPosition(
canonicalRequest,
_handleSetPositionCollisionsCallback);
}
finally
{
_collisionCallbackContexts.Pop();
}
// Round 3: `_physics.Engine.SetPosition` above can reenter this class
// - its collision-report callback can reach an arbitrary
// IRuntimeCollisionReportObserver subscriber that calls back into
// Begin/Cancel for this (or any) entity, which can retire-then-rent
// (LIFO) this exact `operation` instance for a different logical
// operation. `token` (the function parameter, captured before any
// of this ran) proves identity by value instead of trusting
// `operation`'s live fields.
if (!IsCurrentByToken(token.Entity, token, out operation))
return Outcome(RuntimeSetPositionStatus.Cancelled, result, default);
if (result.IsSuccessful
&& TryGetBlockingQuiescence(
result,
out CollisionPrefixQuiescence? queriedQuiescence))
{
PhysicsSetPositionResult held = result with
{
Residence = PhysicsResidenceDisposition.DeferredCell,
};
operation.Result = held;
operation.RequiresPreparation = false;
operation.ExactCellId = held.CellId;
_preparedMovers[operation.Key] = canonicalRequest;
return ParkDeferred(
operation,
held,
collisionGenerationOverride:
queriedQuiescence!.Token.CollisionGeneration,
collisionPrefixOverride:
queriedQuiescence.Token.LandblockPrefix);
}
operation.Result = result;
if (!result.IsSuccessful)
{
operation.RequiresPreparation = true;
operation.Stage = RuntimeEntityPlacementStage.AwaitingPreparation;
return Outcome(RuntimeSetPositionStatus.Rejected, result, default);
}
// Round 3: same reentrancy hazard as the check right after the
// SetPosition call above - re-verify by token rather than trusting
// `operation` across the collision-report dispatch.
if (!IsCurrentByToken(token.Entity, token, out operation))
return Outcome(RuntimeSetPositionStatus.Cancelled, result, default);
operation.RequiresPreparation = false;
operation.ExactCellId = result.CellId;
_preparedMovers[operation.Key] = canonicalRequest;
if (result.IsDeferred)
return ParkDeferred(operation, result);
if (!CommitCanonical(operation, result))
{
// Round 3: CommitCanonical's own ground-edge callback and
// collision-report dispatch can reenter this class, so
// `operation` may already be stale here even though it was
// just re-verified before the call. `token` (this function's
// own parameter, untouched since entry) is the safe capture.
PublishCancellation(CancelCore(token.Entity, token));
return Outcome(RuntimeSetPositionStatus.Cancelled, result, default);
}
// F1: CommitCanonical can succeed (fully applying the physical
// settle - contact transition, collision reports, shadow sync) for
// an operation a reentrant ground-edge callback has since displaced
// - retail lets that physical commit land regardless (see
// ReentrantGroundEdgePlacementCannotBeCancelledByDisplacedOperation).
// But THIS caller's own operation is no longer canonical, so it must
// still report Cancelled rather than publish a Place projection
// nothing will ever acknowledge again. `token` (the parameter,
// captured before any of this ran) is compared against a fresh
// lookup instead of trusting `operation`'s live fields, which may
// already reflect whatever displaced it.
if (!_operations.TryGetValue(token.Entity, out Operation? stillOwns)
|| stillOwns.Token != token)
{
return Outcome(RuntimeSetPositionStatus.Cancelled, result, default);
}
operation.Stage = RuntimeEntityPlacementStage
.AwaitingCommitAcknowledgement;
RuntimePlacementProjectionToken projection = PublishProjection(
operation,
RuntimePlacementProjectionKind.Place,
result);
return Outcome(
RuntimeSetPositionStatus.CommittedHostAcknowledgementPending,
result,
projection);
}
/// <summary>
/// C2: zero-allocation replacement for the LINQ
/// <c>_pendingProjection.First()</c> pattern used at every call site
/// below. <c>Enumerable.First&lt;TSource&gt;</c> takes an
/// <c>IEnumerable&lt;TSource&gt;</c> parameter, so calling it on a
/// <see cref="SortedDictionary{TKey, TValue}"/> dispatches through the
/// interface-typed <c>IEnumerable&lt;KeyValuePair&lt;TKey,
/// TValue&gt;&gt;.GetEnumerator()</c>, which BOXES the dictionary's
/// normally-struct <c>Enumerator</c> - this was the entire measured C2
/// acknowledgement-path residual (120 B/op). A plain <c>foreach</c> on
/// the concrete <see cref="SortedDictionary{TKey, TValue}"/> field type
/// resolves to its public non-interface, struct-returning
/// <c>GetEnumerator()</c> instead and never boxes. Every call site below
/// already checks <c>_pendingProjection.Count != 0</c> immediately
/// before calling this (short-circuiting `||`/`&amp;&amp;`), exactly
/// mirroring the precondition LINQ's <c>First()</c> relied on - the
/// throw path is unreachable in current usage, kept only so a future
/// caller that skips the guard fails loudly instead of silently, same as
/// LINQ's own contract would have.
/// </summary>
private KeyValuePair<ulong, RuntimePlacementProjectionSnapshot>
FirstPendingProjection()
{
foreach (KeyValuePair<ulong, RuntimePlacementProjectionSnapshot> entry
in _pendingProjection)
{
return entry;
}
throw new InvalidOperationException(
"FirstPendingProjection requires at least one pending entry.");
}
internal bool TryPeekProjection(
out RuntimePlacementProjectionSnapshot projection)
{
EnsureNotDisposed();
if (_pendingProjection.Count == 0)
{
projection = default;
return false;
}
projection = FirstPendingProjection().Value;
return true;
}
internal bool AcknowledgeProjection(
in RuntimePlacementProjectionToken token)
{
EnsureNotDisposed();
if (!token.IsValid
|| _pendingProjection.Count == 0
|| FirstPendingProjection().Key != token.Sequence
|| !_pendingProjection.TryGetValue(
token.Sequence,
out RuntimePlacementProjectionSnapshot pending)
|| pending.Token != token)
{
return false;
}
if (pending.Kind is RuntimePlacementProjectionKind.Discard
or RuntimePlacementProjectionKind.ExecutorCompleted)
{
// C0-1: an ExecutorCompleted receipt is never Operation-backed
// (see PublishExecutorCompletion) - there is nothing to resume or
// commit against, exactly like Discard.
_pendingProjection.Remove(token.Sequence);
RetireQuiescenceProjectionSequence(token.Sequence);
if (pending.Kind is RuntimePlacementProjectionKind.ExecutorCompleted)
{
// F2: notify the executor so it can reap its own
// token-to-receipt correlation entry now - not before (a
// host might still be mid-retry against this exact
// unacknowledged receipt) and not left dangling after.
_executorCompletionAcknowledged?.Invoke(
token.Entity,
token.Sequence);
}
return true;
}
// Round 3 audit: safe - fresh lookup + ProjectionSequence check
// immediately precede IsCurrent, nothing reentrant in between (this
// is AcknowledgeProjection's own entry validation).
if (!_operations.TryGetValue(
token.Entity,
out Operation? operation)
|| operation.ProjectionSequence != token.Sequence
|| !IsCurrent(operation)
|| operation.SpatialAuthorityVersion
!= token.SpatialAuthorityVersion)
{
return false;
}
_pendingProjection.Remove(token.Sequence);
RetireQuiescenceProjectionSequence(token.Sequence);
operation.ProjectionSequence = 0UL;
if (pending.Kind is RuntimePlacementProjectionKind.Place)
{
if (_placementCompletionWatches.Remove(operation.Token))
{
_acknowledgedPlacementCompletions.Add(
operation.Token,
pending.Token);
}
operation.Stage = RuntimeEntityPlacementStage.AwaitingCommitAcknowledgement;
_moverPreparationAuthorities.Remove(operation.Key);
bool removed = _operations.Remove(operation.Key);
if (removed)
RetireOperationToPool(operation);
return removed;
}
if (!operation.WakeableLostCell
&& !operation.InheritedLostDeadline)
{
_moverPreparationAuthorities.Remove(operation.Key);
bool removed = _operations.Remove(operation.Key);
if (removed)
RetireOperationToPool(operation);
return removed;
}
operation.WithdrawalAcknowledged = true;
operation.Stage = operation.RequiresPreparation
|| operation.InheritedLostDeadline
? RuntimeEntityPlacementStage.AwaitingPreparation
: operation.CollisionQuiescenceHeld
? RuntimeEntityPlacementStage.QuiescenceHeld
: RuntimeEntityPlacementStage.AwaitingCell;
if (operation.PreparedCommandAwaitingWithdrawalAck is { } prepared)
{
operation.PreparedCommandAwaitingWithdrawalAck = null;
operation.Stage = RuntimeEntityPlacementStage.AwaitingPreparation;
_ = SubmitPreparedPlacement(operation.Token, prepared);
return true;
}
if (operation.CollisionGenerationReady)
RetryDeferred(operation);
return true;
}
/// <summary>
/// Runs retail's 25-second lost-cell destruction timer. Expired exact
/// incarnation keys are consumed by the entity-lifetime owner; no host
/// callback or GUID-only deletion can cross a replacement generation.
/// </summary>
internal void TickLostCellDeadlines()
{
EnsureNotDisposed();
if (_lostDeadlineNodes.Count == 0)
return;
double now = _physics.MonotonicNowSeconds;
while (_lostDeadlineNodes.Count != 0)
{
LostDeadlineEntry entry = _lostDeadlineNodes[0];
if (entry.Deadline > now)
break;
RemoveLostDeadlineNodeAt(0);
if (!_lostDeadlines.Remove(entry.Key))
throw new InvalidOperationException(
"The lost-cell deadline index diverged from its exact key owner.");
if (_operations.TryGetValue(
entry.Key,
out Operation? operation))
operation.Expired = true;
if (_entities.TryGetByLocalId(
entry.Key.LocalEntityId,
out RuntimeEntityRecord record)
&& record.Key == entry.Key)
{
if (!_expiredLostCellNodes.ContainsKey(entry.Key))
{
LinkedListNode<RuntimeEntityKey> node =
_expiredLostCells.AddLast(entry.Key);
_expiredLostCellNodes.Add(entry.Key, node);
}
}
}
}
internal bool TryDequeueExpiredLostCell(out RuntimeEntityKey key)
{
EnsureNotDisposed();
if (_expiredLostCells.First is not { } first)
{
key = default;
return false;
}
key = first.Value;
_expiredLostCells.RemoveFirst();
_expiredLostCellNodes.Remove(key);
return true;
}
internal bool Cancel(RuntimeEntityRecord record, bool publishWithdrawal)
{
EnsureNotDisposed();
ArgumentNullException.ThrowIfNull(record);
if (record.Key is not { } key)
return false;
bool removed = CancelCoreDeferred(
key,
cancelLostFamily: false,
preserveLostFamily: false,
out RuntimePlacementProjectionSnapshot? discard);
if (!publishWithdrawal || !_entities.IsCurrent(record))
{
if (discard is { } cancelled)
PublishPlacement(cancelled);
return removed;
}
LeaveWorldCanonical(record);
if (record.PhysicsBody is null)
{
if (discard is { } cancelledBodyless)
PublishPlacement(cancelledBodyless);
return removed;
}
var operation = CreateWithdrawalOperation(record, key);
_operations[key] = operation;
// Round 3: `operation.Token` is captured HERE, before
// PublishPlacement below can synchronously reenter this class - a
// subscriber reacting to the withdrawal-of-the-old-operation
// notification can call Begin/Cancel for this SAME entity, which
// (per RetireOperationToPool's doc comment) can retire-then-rent
// (LIFO) this exact `operation` instance for a brand-new logical
// operation before the checks below run. Comparing
// `ReferenceEquals`/`IsCurrent(operation)` against the stale
// reference afterward would be a tautology - it would report "still
// current" and then publish a Withdraw projection carrying the
// NEWER operation's state under the OLD operation's identity.
RuntimeEntityPlacementToken capturedToken = operation.Token;
if (discard is { } cancelledOld)
PublishPlacement(cancelledOld);
if (!IsCurrentByToken(key, capturedToken, out operation))
return true;
_ = PublishProjection(
operation,
RuntimePlacementProjectionKind.Withdraw,
operation.Result);
return true;
}
internal RuntimePlacementCancellationReceipt Forget(
RuntimeEntityRecord record,
bool releasePreparedMover = false)
{
EnsureNotDisposed();
ArgumentNullException.ThrowIfNull(record);
RuntimePlacementCancellationReceipt receipt = default;
if (record.Key is { } key)
{
receipt = CancelCore(key);
if (releasePreparedMover)
_preparedMovers.Remove(key);
}
return receipt;
}
internal void LeaveWorld(RuntimeEntityRecord record)
{
EnsureNotDisposed();
ArgumentNullException.ThrowIfNull(record);
RuntimePlacementCancellationReceipt receipt = record.Key is { } key
? CancelCore(key)
: default;
if (_entities.IsCurrent(record))
LeaveWorldCanonical(record);
PublishCancellation(receipt);
}
internal bool IsDeferred(RuntimeEntityRecord record) =>
record.Key is { } key
&& _operations.TryGetValue(key, out Operation? operation)
&& ReferenceEquals(operation.Record, record)
&& operation.WakeableLostCell;
internal bool TryGetPreparedMoverSphereCount(
RuntimeEntityRecord record,
out int sphereCount)
{
EnsureNotDisposed();
if (record.Key is { } key
&& _preparedMovers.TryGetValue(
key,
out PhysicsSetPositionRequest request))
{
sphereCount = request.Spheres.Length;
return true;
}
sphereCount = 0;
return false;
}
internal bool TryGetAwaitingPreparationToken(
RuntimeEntityRecord record,
out RuntimeEntityPlacementToken token)
{
EnsureNotDisposed();
if (record.Key is { } key
&& _operations.TryGetValue(key, out Operation? operation)
&& ReferenceEquals(operation.Record, record)
&& operation.RequiresPreparation)
{
token = operation.Token;
return true;
}
token = default;
return false;
}
internal void ParkCollisionResidents(
uint landblockId,
bool includeOutdoorCells)
{
EnsureNotDisposed();
uint prefix = landblockId & 0xFFFF0000u;
var roots = new List<RuntimeEntityRecord>();
_physics.CopySpatialRootsTo(roots);
RuntimeEntityRecord[] affected = roots
.Where(record => IsAffectedCollisionResident(
record,
prefix,
includeOutdoorCells))
.ToArray();
for (int index = 0; index < affected.Length; index++)
{
if (affected[index].Key is { } key
&& _operations.ContainsKey(key))
{
throw new InvalidOperationException(
$"Collision retirement for 0x{prefix:X8} cannot overlap active placement for 0x{affected[index].ServerGuid:X8}/{affected[index].Incarnation}.");
}
}
// Close every exact collision-report owner before the first force-end
// callback can re-enter. The prefix admission barrier is already in
// place for transactional callers, so a callback cannot evaluate a
// new placement against the retiring rows.
_physics.CollisionReports.LeaveWorldBatch(affected);
var stagedWithdrawals = new List<RuntimePlacementProjectionSnapshot>(
roots.Count);
for (int index = 0; index < roots.Count; index++)
{
RuntimeEntityRecord record = roots[index];
uint cellId = record.FullCellId;
if (!IsAffectedCollisionResident(
record,
prefix,
includeOutdoorCells)
|| record.Key is not { } key
|| record.PhysicsBody is not { } body
|| _operations.ContainsKey(key)
|| !affected.Any(candidate =>
ReferenceEquals(candidate, record)
&& candidate.Key == key))
{
continue;
}
bool hasPrepared = _preparedMovers.TryGetValue(
key,
out PhysicsSetPositionRequest prepared);
var request = (hasPrepared
? prepared
: new PhysicsSetPositionRequest(
body.Position,
body.Orientation,
cellId,
body.CellPosition.Frame.Origin,
ImmutableArray<FlatCollisionSphere>.Empty,
1f,
0f,
0f)) with
{
Position = body.Position,
Orientation = body.Orientation,
CellId = cellId,
CellLocalPosition = body.CellPosition.Frame.Origin,
MoverPhysicsState = record.FinalPhysicsState,
MovingEntityId = key.LocalEntityId,
CurrentCellId = null,
};
var result = new PhysicsSetPositionResult(
PhysicsSetPositionError.Ok,
PhysicsResidenceDisposition.DeferredCell,
body.Position,
body.Orientation,
cellId,
body.CellPosition.Frame.Origin,
InContact: body.InContact,
OnWalkable: body.OnWalkable,
ContactPlane: body.ContactPlane,
ContactPlaneCellId: body.ContactPlaneCellId,
ContactPlaneIsWater: body.ContactPlaneIsWater,
SlidingNormalValid: body.SlidingNormal != Vector3.Zero,
SlidingNormal: body.SlidingNormal,
FramesStationaryFall: body.FramesStationaryFall,
CrossCellIds: ImmutableArray<uint>.Empty,
CollidedObjectIds: ImmutableArray<uint>.Empty);
var command = new RuntimeSetPositionCommand(
request,
RuntimeSetPositionOperationKind.RemoteAuthoritative,
body.LastUpdateTime,
record.VelocityAuthorityVersion);
// F4: routed through RentOperation() (rather than a fresh
// `new Operation { ... }`) so every construction flows one path
// - see ResetAllFieldsToDefault's completeness-net doc comment.
// No key/displaced-operation collision is possible here: the
// loop above already skips this record when
// `_operations.ContainsKey(key)`.
Operation operation = RentOperation();
operation.Record = record;
operation.Body = body;
operation.Token = new RuntimeEntityPlacementToken(
_entities.SessionLifetimeVersion,
key,
record.PositionAuthorityVersion,
checked(++_nextOperationId),
RuntimeEntityPlacementPreparationKind.AuthoredMover);
operation.Key = key;
operation.PositionAuthorityVersion = record.PositionAuthorityVersion;
operation.SessionLifetimeVersion = _entities.SessionLifetimeVersion;
operation.SourceSpatialAuthorityVersion =
record.SpatialAuthorityVersion;
operation.SourceVelocityAuthorityVersion =
record.VelocityAuthorityVersion;
operation.PreviousContact = body.InContact;
operation.PreviousOnWalkable = body.OnWalkable;
operation.Command = command;
operation.Result = result;
operation.SpatialAuthorityVersion = record.SpatialAuthorityVersion;
operation.PlacementCommitVersion = record.PlacementCommitVersion;
operation.ExactCellId = cellId;
operation.Stage = RuntimeEntityPlacementStage.AwaitingPreparation;
operation.Kind = RuntimeSetPositionOperationKind.RemoteAuthoritative;
operation.Portal = default;
operation.RequiresPreparation = !hasPrepared;
_operations.Add(key, operation);
_moverPreparationAuthorities[key] = CapturePreparationAuthority(
operation,
ServerPositionFrom(
cellId,
body.CellPosition.Frame.Origin,
body.Orientation),
prepared: hasPrepared,
command);
CollisionPrefixQuiescence? quiescence =
_collisionPrefixQuiescence.GetValueOrDefault(prefix);
// C3c-F3: pass the overrides through as genuinely optional —
// `quiescence?.` yields null (absent) with no quiescence and the
// token's exact values (present, prefix 0x00000000 included)
// with one. The old `?? 0u` collapse made a corner-landblock
// quiescence indistinguishable from "no quiescence".
RuntimeSetPositionOutcome parked = ParkDeferred(
operation,
result,
publishImmediately: false,
collisionGenerationOverride:
quiescence?.Token.CollisionGeneration,
collisionPrefixOverride:
quiescence?.Token.LandblockPrefix);
if (_pendingProjection.TryGetValue(
parked.Projection.Sequence,
out RuntimePlacementProjectionSnapshot staged))
{
stagedWithdrawals.Add(staged);
}
if (operation.RequiresPreparation)
{
operation.Stage = RuntimeEntityPlacementStage
.AwaitingPreparation;
}
}
// Canonical residence and operation ownership for every affected root
// must be installed before a synchronous host observer can re-enter.
// A callback may legitimately replace or cancel a later root; publish
// only the exact snapshot that is still pending when its turn arrives.
for (int index = 0; index < stagedWithdrawals.Count; index++)
{
RuntimePlacementProjectionSnapshot staged =
stagedWithdrawals[index];
if (_pendingProjection.TryGetValue(
staged.Token.Sequence,
out RuntimePlacementProjectionSnapshot current)
&& current == staged)
{
PublishPlacement(staged);
}
}
}
private bool IsAffectedCollisionResident(
RuntimeEntityRecord record,
uint prefix,
bool includeOutdoorCells)
{
uint cellId = record.FullCellId;
bool exactResidence = (cellId & 0xFFFF0000u) == prefix
&& (includeOutdoorCells || (cellId & 0xFFFFu) >= 0x0100u);
return exactResidence
&& record.Key is not null
&& _entities.IsCurrent(record)
&& record.PhysicsBody is not null
&& _physics.IsSpatialRoot(record)
&& (record.FinalPhysicsState & PhysicsStateFlags.Static) == 0
&& !_entities.ParentAttachments.HasCommittedParent(
record.ServerGuid);
}
private void ParkCollisionResidentsForQuiescence(
CollisionPrefixQuiescence state)
{
if (!TryGetCurrentQuiescence(state.Token, out CollisionPrefixQuiescence? current)
|| !ReferenceEquals(current, state))
{
return;
}
ParkCollisionResidents(
state.Token.LandblockPrefix,
state.IncludeOutdoorCells);
}
private bool HasAffectedCollisionResident(
uint prefix,
bool includeOutdoorCells)
{
if (_physics.SpatialRootCount == 0)
return false;
var roots = new List<RuntimeEntityRecord>();
_physics.CopySpatialRootsTo(roots);
for (int index = 0; index < roots.Count; index++)
{
if (IsAffectedCollisionResident(
roots[index],
prefix,
includeOutdoorCells))
{
return true;
}
}
return false;
}
private bool TryGetCurrentQuiescence(
in RuntimeCollisionPrefixQuiescenceToken token,
out CollisionPrefixQuiescence? state)
{
if (token.IsValid
&& token.SessionLifetimeVersion == _entities.SessionLifetimeVersion
&& _collisionPrefixQuiescence.TryGetValue(
token.LandblockPrefix,
out state)
&& state.Token == token)
{
return true;
}
state = null;
return false;
}
private bool HasPendingProjectionThrough(ulong barrierSequence) =>
barrierSequence != 0UL
&& _pendingProjection.Count != 0
&& FirstPendingProjection().Key <= barrierSequence;
private bool HasCollisionDispatchDebt()
{
RuntimeCollisionReportingOwnershipSnapshot reports =
_physics.CollisionReports.CaptureOwnership();
return reports.PendingReportCount != 0
|| reports.LeavingOwnerCount != 0
|| reports.AdmissionBlockedOwnerCount != 0
|| reports.PendingSetPositionDispatchCount != 0
|| reports.IsDispatching
|| _physics.Engine.ShadowObjects
.PendingSetPositionDispatchCount != 0;
}
private bool HasOldPrefixPlacementDebt(CollisionPrefixQuiescence state)
{
uint prefix = state.Token.LandblockPrefix;
foreach (Operation operation in _operations.Values)
{
if (operation.WakeableLostCell || operation.DormantLocalActivation)
continue;
if (PlacementTouchesPrefix(operation.Command.Physics, prefix)
|| ResultTouchesPrefix(operation.Result, prefix)
|| _moverPreparationAuthorities.TryGetValue(
operation.Key,
out MoverPreparationAuthority preparation)
&& preparation.OperationId
== operation.Token.OperationId
&& (preparation.AcceptedPosition.LandblockId
& 0xFFFF0000u) == prefix
|| IsAffectedCollisionResident(
operation.Record,
prefix,
state.IncludeOutdoorCells))
{
return true;
}
}
return false;
}
private static bool PlacementTouchesPrefix(
in PhysicsSetPositionRequest request,
uint prefix) =>
(request.CellId & 0xFFFF0000u) == prefix
|| request.CurrentCellId is uint current
&& (current & 0xFFFF0000u) == prefix;
private static bool ResultTouchesPrefix(
in PhysicsSetPositionResult result,
uint prefix)
{
if ((result.CellId & 0xFFFF0000u) == prefix)
return true;
if (!result.QueriedCellIds.IsDefaultOrEmpty)
{
foreach (uint cellId in result.QueriedCellIds)
{
if ((cellId & 0xFFFF0000u) == prefix)
return true;
}
}
return false;
}
private bool TryGetBlockingQuiescence(
in PhysicsSetPositionRequest request,
out CollisionPrefixQuiescence? state)
{
state = null;
foreach (CollisionPrefixQuiescence candidate
in _collisionPrefixQuiescence.Values)
{
if (PlacementTouchesPrefix(
request,
candidate.Token.LandblockPrefix)
&& (state is null
|| candidate.Token.OperationId
< state.Token.OperationId))
{
state = candidate;
}
}
return state is not null;
}
private bool TryGetBlockingQuiescence(
in PhysicsSetPositionResult result,
out CollisionPrefixQuiescence? state,
in RuntimeCollisionPrefixQuiescenceToken excluded = default)
{
state = null;
foreach (CollisionPrefixQuiescence candidate
in _collisionPrefixQuiescence.Values)
{
if (excluded.IsValid && candidate.Token == excluded)
continue;
if (ResultTouchesPrefix(
result,
candidate.Token.LandblockPrefix)
&& (state is null
|| candidate.Token.OperationId
< state.Token.OperationId))
{
state = candidate;
}
}
return state is not null;
}
private void TrackQuiescenceWithdrawal(
Operation operation,
in RuntimePlacementProjectionSnapshot snapshot)
{
if (snapshot.Kind is not RuntimePlacementProjectionKind.Withdraw
|| !_collisionPrefixQuiescence.TryGetValue(
operation.CollisionPrefix,
out CollisionPrefixQuiescence? state)
|| snapshot.Token.CollisionGeneration
!= state.Token.CollisionGeneration)
{
return;
}
state.PendingWithdrawals[snapshot.Token.Sequence] = snapshot.Token;
state.RetainedWithdrawals.Add(snapshot.Token);
state.PermissionIssued = false;
}
private void TrackQuiescenceRestorePlacement(
Operation operation,
in RuntimePlacementProjectionSnapshot snapshot)
{
if (snapshot.Kind is not RuntimePlacementProjectionKind.Place
|| !_collisionPrefixQuiescence.TryGetValue(
operation.CollisionPrefix,
out CollisionPrefixQuiescence? state)
|| !state.ReleaseInProgress
|| !state.ReleaseGenerationReady)
{
return;
}
state.PendingRestorePlacements[snapshot.Token.Sequence] =
snapshot.Token;
}
private void RetireQuiescenceProjectionSequence(ulong sequence)
{
foreach (CollisionPrefixQuiescence state
in _collisionPrefixQuiescence.Values)
{
if (state.PendingWithdrawals.TryGetValue(
sequence,
out _))
{
state.PendingWithdrawals.Remove(sequence);
state.PermissionIssued = false;
return;
}
if (state.PendingRestorePlacements.Remove(sequence))
return;
}
}
private void RemoveRetiredQuiescenceWithdrawals(
CollisionPrefixQuiescence state)
{
if (state.PendingWithdrawals.Count == 0)
return;
ulong[] stale = state.PendingWithdrawals
.Where(pair => !_pendingProjection.ContainsKey(pair.Key))
.Select(pair => pair.Key)
.ToArray();
for (int index = 0; index < stale.Length; index++)
state.PendingWithdrawals.Remove(stale[index]);
}
private void RebindQuiescedDeferredOperations(
in RuntimeCollisionPrefixQuiescenceToken token,
ulong successorGeneration,
bool ready,
bool releaseUnavailable = false)
{
// Round 3: snapshot (Key, Token) PAIRS, not Operation references.
// This loop's own RetryDeferred call below can reenter this class
// (CommitCanonical's ground-edge callbacks, or an arbitrary
// collision-report observer reentrantly calling Begin/Cancel) and
// retire-then-rent (LIFO) a LATER array entry's physical instance
// for a brand-new operation before this loop ever reaches it - a
// stale `Operation` reference captured once at the top (the
// pre-round-3 `.ToArray()` shape) would then silently read/mutate
// the wrong logical operation. Re-resolving by captured Token at
// the top of every iteration (before touching any field) detects
// that instead.
var snapshot =
new List<(RuntimeEntityKey Key, RuntimeEntityPlacementToken Token)>(
_operations.Count);
foreach (Operation existing in _operations.Values)
snapshot.Add((existing.Key, existing.Token));
foreach ((RuntimeEntityKey key, RuntimeEntityPlacementToken capturedToken)
in snapshot)
{
if (!IsCurrentByToken(key, capturedToken, out Operation? operation))
continue;
bool unavailableAfterReadyCommit = ready
&& operation.CollisionQuiescenceHeld
&& operation.CollisionGeneration == 0UL
&& operation.CollisionPrefix == token.LandblockPrefix;
if (!operation.WakeableLostCell
|| !operation.CollisionQuiescenceHeld
|| operation.CollisionPrefix != token.LandblockPrefix
|| (operation.CollisionGeneration
!= token.CollisionGeneration
&& !unavailableAfterReadyCommit))
{
continue;
}
UnindexDeferred(operation);
ulong reboundGeneration = releaseUnavailable
|| unavailableAfterReadyCommit
? 0UL
: successorGeneration;
operation.CollisionGeneration = reboundGeneration;
operation.CollisionGenerationReady = ready
&& reboundGeneration != 0UL;
if (releaseUnavailable || unavailableAfterReadyCommit)
{
operation.CollisionQuiescenceHeld = false;
operation.Stage = operation.RequiresPreparation
? RuntimeEntityPlacementStage.AwaitingPreparation
: RuntimeEntityPlacementStage.AwaitingCell;
}
if (reboundGeneration != 0UL)
IndexDeferred(operation);
else
IndexUnboundDeferred(operation);
if (operation.CollisionGenerationReady
&& operation.WithdrawalAcknowledged)
{
RetryDeferred(operation);
}
}
}
private bool HasQuiescedDeferredOperations(uint prefix)
{
foreach (Operation operation in _operations.Values)
{
if (operation.WakeableLostCell
&& operation.CollisionQuiescenceHeld
&& operation.CollisionPrefix == prefix)
{
return true;
}
}
return false;
}
internal void BeginCollisionGeneration(uint landblockId, ulong generation)
{
EnsureNotDisposed();
if (generation == 0UL)
throw new ArgumentOutOfRangeException(nameof(generation));
uint prefix = landblockId & 0xFFFF0000u;
for (int index = 0; index < _unboundDeferredCellOrder.Count;)
{
UnboundCellKey unboundKey = _unboundDeferredCellOrder[index];
if (unboundKey.CollisionPrefix != prefix
|| !_unboundDeferredByCell.Remove(
unboundKey,
out List<RuntimeEntityKey>? retained))
{
index++;
continue;
}
_unboundDeferredCellOrder.RemoveAt(index);
var bucket = new CellGenerationKey(
unboundKey.CellId,
unboundKey.CollisionPrefix,
generation);
var rebound = new List<RuntimeEntityKey>(retained.Count);
for (int entityIndex = 0;
entityIndex < retained.Count;
entityIndex++)
{
RuntimeEntityKey entity = retained[entityIndex];
if (_operations.TryGetValue(entity, out Operation? operation)
&& operation.WakeableLostCell
&& operation.ExactCellId == unboundKey.CellId
&& operation.CollisionPrefix == prefix
&& operation.CollisionGeneration == 0UL)
{
operation.CollisionGeneration = generation;
rebound.Add(entity);
}
}
if (rebound.Count != 0)
{
if (_deferredByCellGeneration.TryGetValue(
bucket,
out List<RuntimeEntityKey>? futureBound))
{
// The unbound survivors entered lost residence before
// entities indexed directly into this future generation.
// Preserve both append orders while restoring that age.
var merged = new List<RuntimeEntityKey>(
rebound.Count + futureBound.Count);
merged.AddRange(rebound);
merged.AddRange(futureBound);
_deferredByCellGeneration[bucket] = merged;
}
else
{
_deferredByCellGeneration.Add(bucket, rebound);
_deferredBucketOrder.Add(bucket);
}
}
}
foreach (Operation operation in _operations.Values)
{
if (!operation.WakeableLostCell
|| operation.CollisionGeneration != 0UL
|| operation.CollisionPrefix != prefix)
{
continue;
}
operation.CollisionGeneration = generation;
IndexDeferred(operation);
}
}
internal void CancelCollisionGeneration(uint landblockId, ulong generation)
{
EnsureNotDisposed();
if (_deferredBucketOrder.Count == 0)
return;
uint prefix = landblockId & 0xFFFF0000u;
CellGenerationKey[] matching = _deferredBucketOrder
.Where(key => key.CollisionGeneration == generation
&& key.CollisionPrefix == prefix)
.ToArray();
for (int index = 0; index < matching.Length; index++)
{
UnbindDeferredBucket(matching[index]);
}
}
internal void CommitCollisionGeneration(
uint landblockId,
ulong generation,
bool ready)
{
EnsureNotDisposed();
if (!ready || _deferredBucketOrder.Count == 0)
return;
uint prefix = landblockId & 0xFFFF0000u;
var cells = new List<CellGenerationKey>();
for (int index = 0; index < _deferredBucketOrder.Count; index++)
{
CellGenerationKey key = _deferredBucketOrder[index];
if (key.CollisionGeneration == generation
&& key.CollisionPrefix == prefix)
{
cells.Add(key);
}
}
foreach (CellGenerationKey cell in cells)
{
if (!_deferredByCellGeneration.TryGetValue(
cell,
out List<RuntimeEntityKey>? indexed))
{
continue;
}
RuntimeEntityKey[] exact = indexed.ToArray();
if (!_physics.Engine.IsSpawnCellReady(cell.CellId))
{
UnbindDeferredBucket(cell);
continue;
}
RemoveDeferredBucket(cell);
// Round 3 audit: safe - `exact` snapshots KEYS (RuntimeEntityKey
// values), never Operation references, so nothing here can go
// stale the way a snapshotted-reference loop
// (RebindQuiescedDeferredOperations, before its round-3 fix)
// could. Every iteration re-resolves `operation` via a fresh
// `_operations.TryGetValue` and re-validates the exact
// WakeableLostCell/ExactCellId/CollisionPrefix/
// CollisionGeneration shape before acting - a reentrant
// cancel-then-begin from an earlier iteration's RetryDeferred
// call (itself converted to IsCurrentByToken) is either not
// found at all or correctly rejected by this shape check for
// any later iteration touching the same or a different entity.
foreach (RuntimeEntityKey entity in exact)
{
if (!_operations.TryGetValue(
entity,
out Operation? operation)
|| !operation.WakeableLostCell
|| operation.ExactCellId != cell.CellId
|| operation.CollisionPrefix != prefix
|| operation.CollisionGeneration != generation)
{
continue;
}
operation.CollisionGenerationReady = true;
if (operation.WithdrawalAcknowledged)
RetryDeferred(operation);
}
}
}
public void Dispose()
{
if (_disposed)
return;
ClearOwnedState();
_events = null;
_disposed = true;
}
private void ClearOwnedState()
{
_operations.Clear();
_deferredByCellGeneration.Clear();
_deferredBucketOrder.Clear();
_unboundDeferredByCell.Clear();
_unboundDeferredCellOrder.Clear();
_lostDeadlines.Clear();
_lostDeadlineNodes.Clear();
_lostDeadlineNodeIndex.Clear();
_preparedMovers.Clear();
_moverPreparationAuthorities.Clear();
_placementCompletionWatches.Clear();
_acknowledgedPlacementCompletions.Clear();
_collisionPrefixQuiescence.Clear();
_pendingProjection.Clear();
_expiredLostCells.Clear();
_expiredLostCellNodes.Clear();
// F2: the C2 object pool retains full previous-generation entity
// graphs (Record -> Snapshot/PhysicsBody/clock/host references)
// through every pooled instance until it is rented and reset. Both
// callers of this method (ResetSession and Dispose) end the session
// those graphs belonged to, so nothing can still be mid-rent across
// this clear - unlike RetireOperationToPool/RentOperation, which
// must worry about a reentrant frame still executing inside a
// ground-edge callback, a session clear cannot be reentered from
// inside itself.
_operationPool.Clear();
}
/// <summary>
/// C3c-F3: the quiescence-override pair is nullable — null means "no
/// quiescence holds this park", a present value means "parked under that
/// quiescence's exact prefix/generation". Nullable uint is the chosen
/// has-prefix representation for the whole chain because the previous
/// 0-sentinel collided with landblock (0,0)'s legitimate prefix
/// 0x00000000: a corner-landblock quiescence override read as "absent",
/// so <see cref="Operation.CollisionQuiescenceHeld"/> derived false and
/// the parked operation skipped the QuiescenceHeld stage entirely.
/// </summary>
private RuntimeSetPositionOutcome ParkDeferred(
Operation operation,
in PhysicsSetPositionResult result,
bool publishImmediately = true,
ulong? collisionGenerationOverride = null,
uint? collisionPrefixOverride = null)
{
PhysicsBody body = operation.Body!;
body.Orientation = result.Orientation;
body.SnapToCell(
result.CellId,
result.Position,
result.CellLocalPosition);
body.InWorld = false;
body.TransientState &= ~TransientStateFlags.Active;
if (operation.Record.RemoteMotion is IRuntimeRemotePlacement remote)
{
remote.LastServerPosition = result.Position;
// Remote-motion stale-age bookkeeping is in Unix-time seconds
// (RuntimeRemotePhysicsUpdater and the retained App network
// updater both consume this field in that clock domain). The
// placement command's GameTime is the instance simulation clock
// used only by PhysicsBody.LastUpdateTime. Mixing the two after
// a deferred wake makes a fresh server velocity look decades old.
remote.LastServerPositionTime = _physics.UtcNowSeconds;
remote.LastShadowSyncPosition = Vector3.Zero;
remote.LastShadowSyncOrientation = Quaternion.Zero;
}
WithdrawCanonical(operation.Record);
_entities.SuspendObjectClock(operation.Record);
operation.SpatialAuthorityVersion =
operation.Record.SpatialAuthorityVersion;
_entities.AdvancePlacementCommit(operation.Record);
operation.PlacementCommitVersion =
operation.Record.PlacementCommitVersion;
operation.ExactCellId = result.CellId;
operation.WakeableLostCell = true;
operation.EnteringWorldFromCelllessResidence = true;
ArmLostFamilyDeadlines(operation);
operation.CollisionGeneration = collisionGenerationOverride
?? _physics.ExpectedCollisionGeneration(result.CellId);
operation.CollisionPrefix = collisionPrefixOverride
?? result.CellId & 0xFFFF0000u;
operation.CollisionQuiescenceHeld = collisionPrefixOverride.HasValue;
operation.Command = operation.Command with
{
Physics = operation.Command.Physics with
{
Position = result.Position,
Orientation = result.Orientation,
CellId = result.CellId,
CellLocalPosition = result.CellLocalPosition,
CurrentCellId = null,
},
};
if (_moverPreparationAuthorities.ContainsKey(operation.Key))
{
RebindPreparedCommand(operation);
}
else
{
_moverPreparationAuthorities[operation.Key] =
CapturePreparationAuthority(
operation,
ServerPositionFrom(
result.CellId,
result.CellLocalPosition,
result.Orientation),
prepared: true,
operation.Command);
}
IndexDeferred(operation);
operation.Stage = operation.RequiresPreparation
? RuntimeEntityPlacementStage.AwaitingPreparation
: operation.CollisionQuiescenceHeld
? RuntimeEntityPlacementStage.QuiescenceHeld
: RuntimeEntityPlacementStage.AwaitingWithdrawalAcknowledgement;
RuntimePlacementProjectionToken projection = PublishProjection(
operation,
RuntimePlacementProjectionKind.Withdraw,
result,
publishImmediately);
return Outcome(
RuntimeSetPositionStatus.DeferredCell,
result,
projection);
}
/// <summary>
/// Round 3 audit: the entry <see cref="IsCurrent(Operation)"/> check
/// below is safe (not converted to <see cref="IsCurrentByToken"/>)
/// because every one of this method's 4 call sites passes an
/// <paramref name="operation"/> reference obtained via a fresh
/// <c>_operations</c> lookup (or an <see cref="IsCurrentByToken"/> call)
/// with NOTHING reentrant executed between that lookup and this call -
/// <c>AcknowledgeProjection</c> and <c>SubmitPreparedPlacementCore</c>
/// call it immediately after their own entry validation, the
/// exact-cell-ready loop re-resolves by key every iteration and rejects
/// a repurposed operation via its WakeableLostCell/ExactCellId/
/// CollisionPrefix/CollisionGeneration shape, and
/// <c>RebindQuiescedDeferredOperations</c> was converted in round 3 to
/// call <see cref="IsCurrentByToken"/> immediately before this method.
/// </summary>
private void RetryDeferred(Operation operation)
{
// The local-player activation lease owns its dormant body/controller
// and must re-enter through the same sealed evaluation/commit path.
// A collision-generation wake only marks readiness; it must never
// bypass that path through the ordinary remote CommitCanonical tail.
if (operation.DormantLocalActivation)
return;
if (!IsCurrent(operation)
|| !operation.WakeableLostCell
|| operation.RequiresPreparation
|| operation.Expired
|| !operation.WithdrawalAcknowledged
|| !operation.CollisionGenerationReady
|| operation.ProjectionSequence != 0UL)
{
return;
}
if (!IsDeferredWakePreparationCurrent(operation))
return;
// F1: hoisted before the ground-edge-callback-bearing
// CommitCanonical call below (same reasoning as
// SubmitPreparedPlacementCore's `token` parameter) - lets the
// post-CommitCanonical check confirm THIS operation is still
// canonical without trusting `operation`'s live fields, which a
// reentrant cancel-then-begin during the callback may have already
// repurposed.
RuntimeEntityPlacementToken operationToken = operation.Token;
RuntimeCollisionPrefixQuiescenceToken restoringQuiescence = default;
if (TryGetBlockingQuiescence(
operation.Command.Physics,
out CollisionPrefixQuiescence? blocking))
{
if (blocking!.ReleaseInProgress
&& blocking.ReleaseGenerationReady
&& operation.CollisionQuiescenceHeld
&& operation.CollisionPrefix
== blocking.Token.LandblockPrefix)
{
// The selected collision generation is active. Keep the
// admission barrier closed while this exact parked operation
// restores and its Place receipt drains.
restoringQuiescence = blocking.Token;
}
else
{
UnindexDeferred(operation);
operation.CollisionPrefix = blocking.Token.LandblockPrefix;
operation.CollisionGeneration = blocking.Token.CollisionGeneration;
operation.CollisionGenerationReady = false;
operation.CollisionQuiescenceHeld = true;
operation.Stage = RuntimeEntityPlacementStage.QuiescenceHeld;
IndexDeferred(operation);
return;
}
}
UnindexDeferred(operation);
operation.CollisionQuiescenceHeld = false;
operation.Command = operation.Command with
{
GameTime = _physics.PlacementSimulationTime(
operation.Command.GameTime),
};
RebindPreparedCommand(operation);
PhysicsSetPositionResult result;
if (IsStructurallyValid(operation.Command.Physics))
{
_collisionCallbackContexts.Push(new CollisionCallbackContext(
operation.Record,
operation.PositionAuthorityVersion,
operation.SpatialAuthorityVersion,
operation.SourceVelocityAuthorityVersion,
operation.Command.GameTime,
operation.PreviousContact,
operation.PreviousOnWalkable));
try
{
result = _physics.Engine.SetPosition(
operation.Command.Physics,
_handleSetPositionCollisionsCallback);
}
finally
{
_collisionCallbackContexts.Pop();
}
}
else
{
result = InvalidResult(operation.Command.Physics);
}
operation.CollisionGenerationReady = false;
// Round 3: same reentrancy hazard as SubmitPreparedPlacementCore's
// post-SetPosition checks - the collision-report callback above can
// reach an arbitrary observer that calls back into Begin/Cancel and
// retires-then-rents (LIFO) this exact instance. `operationToken`
// was hoisted before the SetPosition call. (`operation` is a plain
// non-nullable parameter here, not a nullable local like
// SubmitPreparedPlacementCore's - route through a temporary so the
// NotNullWhen-proven reference can be assigned back to it.)
if (!IsCurrentByToken(
operationToken.Entity,
operationToken,
out Operation? refreshed))
{
return;
}
operation = refreshed;
if (result.IsSuccessful
&& TryGetBlockingQuiescence(
result,
out CollisionPrefixQuiescence? queriedQuiescence,
restoringQuiescence))
{
PhysicsSetPositionResult held = result with
{
Residence = PhysicsResidenceDisposition.DeferredCell,
};
operation.Result = held;
operation.ExactCellId = held.CellId;
operation.CollisionPrefix =
queriedQuiescence!.Token.LandblockPrefix;
operation.CollisionGeneration =
queriedQuiescence.Token.CollisionGeneration;
operation.CollisionQuiescenceHeld = true;
operation.Stage = RuntimeEntityPlacementStage.QuiescenceHeld;
_preparedMovers[operation.Key] = operation.Command.Physics;
IndexDeferred(operation);
return;
}
if (result.IsDeferred)
{
operation.Result = result;
operation.ExactCellId = result.CellId;
_preparedMovers[operation.Key] = operation.Command.Physics;
operation.CollisionPrefix = result.CellId & 0xFFFF0000u;
operation.CollisionGeneration = _physics
.ExpectedCollisionGeneration(result.CellId);
IndexDeferred(operation);
return;
}
if (!result.IsSuccessful)
{
if (result.Error is PhysicsSetPositionError.InvalidArguments)
{
operation.RequiresPreparation = true;
operation.Stage = RuntimeEntityPlacementStage
.AwaitingPreparation;
operation.CollisionPrefix = operation.ExactCellId
& 0xFFFF0000u;
operation.CollisionGeneration = _physics
.ExpectedCollisionGeneration(operation.ExactCellId);
IndexDeferred(operation);
}
else
{
operation.Stage = RuntimeEntityPlacementStage.AwaitingCell;
operation.CollisionPrefix = operation.ExactCellId
& 0xFFFF0000u;
operation.CollisionGeneration = _physics
.ExpectedCollisionGeneration(operation.ExactCellId);
IndexDeferred(operation);
}
return;
}
// Round 3: nothing reentrant runs between here and the previous
// token check (only quiescence/deferred bookkeeping branches, all
// of which return before reaching this point) - re-verifying by
// token again anyway keeps this in lockstep with the same pattern
// used everywhere else in this method, and `operation` is already
// the freshly-verified reference from that check.
if (!IsCurrentByToken(
operationToken.Entity,
operationToken,
out Operation? stillCurrent))
{
return;
}
operation = stillCurrent;
_preparedMovers[operation.Key] = operation.Command.Physics;
if (!CommitCanonical(operation, result))
{
// Round 3: CommitCanonical's own ground-edge callback and
// collision-report dispatch can reenter this class, so
// `operation` may already be stale here even though it was
// just re-verified before the call.
PublishCancellation(CancelCore(operationToken.Entity, operationToken));
return;
}
// F1: CommitCanonical can succeed (fully applying the physical
// settle) for an operation a reentrant ground-edge callback has
// since displaced - retail lets that physical commit land
// regardless (see
// ReentrantGroundEdgePlacementCannotBeCancelledByDisplacedOperation).
// But if THIS operation is no longer canonical, publishing a Place
// projection for it is wrong - nothing will ever acknowledge it
// again, and `operation`'s own fields may already reflect whatever
// displaced it. `operationToken` (hoisted before the callback) is
// compared against a fresh lookup rather than trusting `operation`
// itself.
if (!_operations.TryGetValue(
operationToken.Entity,
out Operation? stillOwns)
|| stillOwns.Token != operationToken)
{
return;
}
operation.Stage = RuntimeEntityPlacementStage
.AwaitingCommitAcknowledgement;
_ = PublishProjection(
operation,
RuntimePlacementProjectionKind.Place,
result);
}
private bool CommitCanonical(
Operation operation,
in PhysicsSetPositionResult result)
{
// Round 3 audit: safe - this is the function's own entry
// validation; every caller (SubmitPreparedPlacementCore,
// RetryDeferred) passes an `operation` obtained via
// IsCurrentByToken/IsCurrent immediately before calling
// CommitCanonical, with nothing reentrant in between.
if (!result.IsCommitted || !IsCurrent(operation))
return false;
RuntimeEntityRecord record = operation.Record;
PhysicsBody body = operation.Body!;
// F1: every operation-derived scalar this method still needs AFTER
// invoking the ground-edge HitGround/LeaveGround callbacks below is
// captured into a local HERE, before those callbacks run - retail's
// own savedTransientState pattern (pseudo-C 283952 stacks the exact
// same bits before handle_all_collisions). A synchronous ground-edge
// chain that cancels then begins (or begins twice) for the SAME
// entity can retire this exact `operation` instance to the pool and
// rent it right back out (LIFO) for a DIFFERENT logical operation -
// reading `operation`'s live fields after that point would silently
// observe the wrong operation's state. The SETTLE below (contact
// transition, collision reports, shadow sync, and the currency
// checks gating them) deliberately does NOT hoist/compare the
// operation's Token: retail intentionally lets an in-flight
// ground-edge commit for a DISPLACED operation still complete (see
// IsCanonicalPlacementCommitCurrent's doc comment and
// ReentrantGroundEdgePlacementCannotBeCancelledByDisplacedOperation).
// `operationToken` is hoisted anyway - not for the settle, but for
// the Runtime-owned BOOKKEEPING writes at the very end of this
// method (Round 3 addendum A1), which must land on the operation
// THIS frame actually started with, never a nested cancel-then-
// begin's freshly-begun operation that happens to share the key and
// pass the record-state checks (a bare Begin never advances
// PlacementCommitVersion, so the settle-layer checks cannot detect
// that repurposing - only Token identity can).
RuntimeEntityPlacementToken operationToken = operation.Token;
RuntimeEntityKey operationKey = operation.Key;
ulong positionAuthorityVersion = operation.PositionAuthorityVersion;
ulong sourceVelocityAuthorityVersion =
operation.SourceVelocityAuthorityVersion;
double commandGameTime = operation.Command.GameTime;
bool previousContact = operation.PreviousContact;
bool previousOnWalkable = operation.PreviousOnWalkable;
float shadowWorldOffsetX = operation.Command.ShadowWorldOffsetX;
float shadowWorldOffsetY = operation.Command.ShadowWorldOffsetY;
body.Orientation = result.Orientation;
body.SnapToCell(
result.CellId,
result.Position,
result.CellLocalPosition);
bool isStatic = (record.FinalPhysicsState & PhysicsStateFlags.Static) != 0;
if (operation.EnteringWorldFromCelllessResidence)
{
body.LastUpdateTime = commandGameTime;
_entities.ResetObjectClockForEnterWorld(record, isStatic);
}
if (operation.EnteringWorldFromCelllessResidence && !isStatic)
body.TransientState |= TransientStateFlags.Active;
body.ContactPlaneValid = result.InContact;
body.ContactPlane = result.ContactPlane;
body.ContactPlaneCellId = result.ContactPlaneCellId;
body.ContactPlaneIsWater = result.ContactPlaneIsWater;
if (result.InContact)
body.GroundNormal = result.ContactPlane.Normal;
body.SlidingNormal = result.SlidingNormal;
if (result.SlidingNormalValid)
body.TransientState |= TransientStateFlags.Sliding;
else
body.TransientState &= ~TransientStateFlags.Sliding;
IRuntimeRemotePlacement? remote =
record.RemoteMotion as IRuntimeRemotePlacement;
if (record.FullCellId != result.CellId)
{
_entities.SetFullCell(
record,
result.CellId,
(result.CellId & 0xFFFF0000u) | 0xFFFFu);
}
operation.SpatialAuthorityVersion = record.SpatialAuthorityVersion;
ulong spatialAuthorityVersion = record.SpatialAuthorityVersion;
_entities.AdvancePlacementCommit(record);
operation.PlacementCommitVersion = record.PlacementCommitVersion;
ulong canonicalCommitVersion = record.PlacementCommitVersion;
if (remote is not null)
{
remote.CellId = result.CellId;
remote.LastServerPosition = result.Position;
remote.LastServerPositionTime = _physics.UtcNowSeconds;
remote.LastShadowSyncPosition = result.Position;
remote.LastShadowSyncOrientation = result.Orientation;
}
uint committedCellId = result.CellId;
bool collidedWithEnvironment = result.CollidedWithEnvironment;
System.Collections.Immutable.ImmutableArray<uint> collidedObjectIds =
result.CollidedObjectIds;
if (!IsCanonicalPlacementCommitCurrent(
positionAuthorityVersion,
spatialAuthorityVersion,
record,
body,
canonicalCommitVersion,
committedCellId,
requireSpatialRoot: false))
return false;
bool contactCommitted;
if (remote is null)
{
contactCommitted = PhysicsObjUpdate.CommitSetPositionContactTransition(
body,
result.InContact,
result.OnWalkable,
previousOnWalkable);
}
else
{
var guard = new ContactCommitGuard(
this,
positionAuthorityVersion,
spatialAuthorityVersion,
record,
body,
canonicalCommitVersion,
committedCellId);
contactCommitted = PhysicsObjUpdate.CommitSetPositionContactTransition(
body,
result.InContact,
result.OnWalkable,
previousOnWalkable,
remote.HitGround,
remote.LeaveGround,
guard.IsCurrent);
}
if (!contactCommitted
|| !IsCanonicalPlacementCommitCurrent(
positionAuthorityVersion,
spatialAuthorityVersion,
record,
body,
canonicalCommitVersion,
committedCellId,
requireSpatialRoot: false))
{
return false;
}
bool reportingCurrent = !IsCollisionReportingEligible(record, body)
|| _physics.HandleSetPositionCollisionReports(
record,
positionAuthorityVersion,
spatialAuthorityVersion,
commandGameTime,
previousContact,
previousOnWalkable,
collidedWithEnvironment,
collidedObjectIds,
out _);
if (!reportingCurrent
|| !IsCanonicalPlacementCommitCurrent(
positionAuthorityVersion,
spatialAuthorityVersion,
record,
body,
canonicalCommitVersion,
committedCellId,
requireSpatialRoot: false))
return false;
body.FramesStationaryFall = result.FramesStationaryFall;
if (IsVelocityCurrent(sourceVelocityAuthorityVersion, record))
{
PhysicsObjUpdate.HandleAllCollisions(
body,
result.CollisionNormalValid,
result.CollisionNormal,
previousContact,
previousOnWalkable,
body.OnWalkable);
}
body.TransientState &= ~(TransientStateFlags.StationaryFall
| TransientStateFlags.StationaryStop
| TransientStateFlags.StationaryStuck);
body.TransientState |= result.FramesStationaryFall switch
{
1 => TransientStateFlags.StationaryFall,
2 => TransientStateFlags.StationaryStop,
3 => TransientStateFlags.StationaryStuck,
_ => TransientStateFlags.None,
};
if (remote is not null)
remote.Airborne = !body.OnWalkable;
if (!IsCanonicalPlacementCommitCurrent(
positionAuthorityVersion,
spatialAuthorityVersion,
record,
body,
canonicalCommitVersion,
committedCellId,
requireSpatialRoot: false))
return false;
_physics.Engine.ShadowObjects.CommitSetPosition(
operationKey.LocalEntityId,
result.Position,
result.Orientation,
result.CellId,
shadowWorldOffsetX,
shadowWorldOffsetY,
result.ShadowAction,
result.CrossCellIds);
_physics.AcknowledgeSpatialProjection(record, spatial: true);
// A1 (round 3 addendum): unlike the settle above, these are
// Runtime's OWN bookkeeping for which logical operation this settle
// belongs to - a nested cancel-then-begin (reachable via either the
// ground-edge callbacks above OR an arbitrary collision-report
// observer reentrantly calling Begin/Cancel from inside
// HandleSetPositionCollisionReports) can recycle `operation` for a
// brand-new operation that stages at AwaitingPreparation without
// ever advancing PlacementCommitVersion - invisible to the
// record-state checks above. Re-resolve by the token captured
// before any callback ran and only write if it is still the exact
// instance; skipping the writes (rather than failing the whole
// commit) matches retail's already-unconditional physical settle -
// only the ownership bookkeeping is conditional.
if (_operations.TryGetValue(operationKey, out Operation? currentOperation)
&& currentOperation.Token == operationToken)
{
currentOperation.ExactCellId = result.CellId;
currentOperation.Result = result;
currentOperation.WakeableLostCell = false;
currentOperation.EnteringWorldFromCelllessResidence = false;
CancelLostFamilyDeadlines(currentOperation);
}
return IsCanonicalPlacementCommitCurrent(
positionAuthorityVersion,
spatialAuthorityVersion,
record,
body,
canonicalCommitVersion,
committedCellId,
requireSpatialRoot: true);
}
/// <summary>
/// F1: takes the operation's authority versions as explicit VALUES
/// (captured by the caller before invoking the ground-edge HitGround/
/// LeaveGround callbacks) rather than reading them live off an
/// <see cref="Operation"/> reference that a reentrant cancel-then-begin
/// (or begin-twice) chain may have already retired and repurposed for a
/// DIFFERENT logical operation. Deliberately does NOT also compare the
/// operation's Token/identity: retail intentionally lets an in-flight
/// ground-edge commit for a DISPLACED operation still complete (its
/// physical contact-transition/shadow-sync settle even though a newer
/// operation now owns future placement authority for this entity - see
/// ReentrantGroundEdgePlacementCannotBeCancelledByDisplacedOperation).
/// Adding an identity check here would incorrectly abort that commit the
/// moment the entity is displaced, which is exactly the behavior that
/// test pins as wrong. The self-aliasing hazard a Token comparison would
/// otherwise guard against is real, but belongs at the call sites that
/// need "is this SPECIFIC Begin invocation still canonical" (see the
/// local-token comparison at the end of
/// <c>BeginAcceptedPlacementCore</c>), not here.
/// </summary>
private bool IsCanonicalPlacementCommitCurrent(
ulong positionAuthorityVersion,
ulong spatialAuthorityVersion,
RuntimeEntityRecord record,
PhysicsBody body,
ulong placementCommitVersion,
uint fullCellId,
bool requireSpatialRoot) =>
_entities.IsCurrent(record)
&& ReferenceEquals(record.PhysicsBody, body)
&& record.PositionAuthorityVersion == positionAuthorityVersion
&& record.SpatialAuthorityVersion == spatialAuthorityVersion
&& record.PlacementCommitVersion == placementCommitVersion
&& record.FullCellId == fullCellId
&& (!requireSpatialRoot || _physics.IsSpatialRoot(record));
private bool IsCollisionReportingEligible(
RuntimeEntityRecord record,
PhysicsBody body) =>
_entities.IsCurrent(record)
&& ReferenceEquals(record.PhysicsBody, body)
&& body.InWorld
&& (body.State & PhysicsStateFlags.Hidden) == 0;
private void WithdrawCanonical(RuntimeEntityRecord record)
{
_physics.CollisionReports.LeaveWorld(record);
_physics.RemoveSpatialProjection(record);
if (record.Key is { } key)
_physics.Engine.ShadowObjects.Suspend(key.LocalEntityId);
if (record.FullCellId != 0u)
_entities.SetFullCell(record, 0u, 0u);
}
private void LeaveWorldCanonical(RuntimeEntityRecord record)
{
WithdrawCanonical(record);
if (record.PhysicsBody is not { } body)
{
_entities.SuspendObjectClock(record);
_entities.AdvancePlacementCommit(record);
return;
}
body.SnapToCell(
0u,
body.Position,
body.CellPosition.Frame.Origin);
body.InWorld = false;
body.TransientState = TransientStateFlags.None;
body.ContactPlaneValid = false;
body.ContactPlaneCellId = 0u;
body.ContactPlaneIsWater = false;
body.SlidingNormal = Vector3.Zero;
body.FramesStationaryFall = 0;
body.calc_acceleration();
if (record.RemoteMotion is IRuntimeRemotePlacement remote)
remote.CellId = 0u;
_entities.SuspendObjectClock(record);
_entities.AdvancePlacementCommit(record);
}
private RuntimePlacementProjectionToken PublishProjection(
Operation operation,
RuntimePlacementProjectionKind kind,
in PhysicsSetPositionResult result,
bool publishImmediately = true)
{
if (operation.ProjectionSequence != 0UL)
_pendingProjection.Remove(operation.ProjectionSequence);
ulong sequence = checked(++_nextProjectionSequence);
var token = new RuntimePlacementProjectionToken(
sequence,
Revision: 1UL,
operation.Key,
operation.PositionAuthorityVersion,
operation.SpatialAuthorityVersion,
operation.PlacementCommitVersion,
operation.SessionLifetimeVersion,
operation.ExactCellId,
operation.CollisionGeneration,
operation.Command.Portal);
var snapshot = new RuntimePlacementProjectionSnapshot(
token,
kind,
result.Position,
result.Orientation,
result.CellLocalPosition,
result.InContact,
result.OnWalkable);
operation.ProjectionSequence = sequence;
_pendingProjection.Add(sequence, snapshot);
TrackQuiescenceWithdrawal(operation, snapshot);
TrackQuiescenceRestorePlacement(operation, snapshot);
if (publishImmediately)
PublishPlacement(snapshot);
return token;
}
private Operation CreateWithdrawalOperation(
RuntimeEntityRecord record,
RuntimeEntityKey key)
{
PhysicsBody body = record.PhysicsBody
?? throw new InvalidOperationException(
"A withdrawal projection requires the canonical PhysicsBody.");
var physics = new PhysicsSetPositionRequest(
body.Position,
body.Orientation,
body.CellPosition.ObjCellId,
body.CellPosition.Frame.Origin,
ImmutableArray<FlatCollisionSphere>.Empty,
1f,
0f,
0f);
var result = new PhysicsSetPositionResult(
PhysicsSetPositionError.Ok,
PhysicsResidenceDisposition.DeferredCell,
body.Position,
body.Orientation,
body.CellPosition.ObjCellId,
body.CellPosition.Frame.Origin,
CrossCellIds: ImmutableArray<uint>.Empty,
CollidedObjectIds: ImmutableArray<uint>.Empty);
// F4: routed through RentOperation() (rather than a fresh
// `new Operation { ... }`) so every construction flows one path -
// see ResetAllFieldsToDefault's completeness-net doc comment. The
// sole caller (Cancel) always runs CancelCoreDeferred against this
// same key first, so there is no displaced-operation state left to
// read here.
Operation operation = RentOperation();
operation.Record = record;
operation.Body = body;
operation.Token = new RuntimeEntityPlacementToken(
_entities.SessionLifetimeVersion,
key,
record.PositionAuthorityVersion,
checked(++_nextOperationId),
RuntimeEntityPlacementPreparationKind.LegacyDirect);
operation.Key = key;
operation.PositionAuthorityVersion = record.PositionAuthorityVersion;
operation.SessionLifetimeVersion = _entities.SessionLifetimeVersion;
operation.SourceSpatialAuthorityVersion = record.SpatialAuthorityVersion;
operation.SourceVelocityAuthorityVersion = record.VelocityAuthorityVersion;
operation.PreviousContact = body.InContact;
operation.PreviousOnWalkable = body.OnWalkable;
operation.Command = new RuntimeSetPositionCommand(
physics,
RuntimeSetPositionOperationKind.RemoteAuthoritative,
body.LastUpdateTime,
record.VelocityAuthorityVersion,
ShadowWorldOffsetX: 0f,
ShadowWorldOffsetY: 0f);
operation.Result = result;
operation.SpatialAuthorityVersion = record.SpatialAuthorityVersion;
operation.PlacementCommitVersion = record.PlacementCommitVersion;
operation.ExactCellId = result.CellId;
operation.WakeableLostCell = false;
operation.Stage = RuntimeEntityPlacementStage
.AwaitingWithdrawalAcknowledgement;
operation.Kind = RuntimeSetPositionOperationKind.RemoteAuthoritative;
operation.Portal = default;
return operation;
}
/// <summary>
/// Reference-identity currency check. SAFE ONLY when no reentrancy
/// point (a synchronous publish, a collision-report dispatch reaching
/// an arbitrary <c>IRuntimeCollisionReportObserver</c>, or a
/// ground-edge HitGround/LeaveGround callback) has intervened between
/// `operation` being obtained/last verified and this call - every
/// call site is audited and either (a) has no such reentrancy point in
/// between (commented at the call site), or (b) has been converted to
/// <see cref="IsCurrentByToken"/> instead. See
/// <see cref="RetireOperationToPool"/>'s doc comment for why
/// <c>ReferenceEquals</c> becomes a tautology once pooling can hand
/// the SAME physical instance back out for a different logical
/// operation at the same key.
/// </summary>
private bool IsCurrent(Operation operation) =>
_operations.TryGetValue(operation.Key, out Operation? current)
&& ReferenceEquals(current, operation)
&& IsOperationStateConsistent(operation);
/// <summary>
/// Round 3: the consistency half of <see cref="IsCurrent(Operation)"/>,
/// factored out so <see cref="IsCurrentByToken"/> can reuse the exact
/// same checks after establishing identity via Token (safe under
/// pooling) instead of <c>ReferenceEquals</c> (unsafe under pooling -
/// see <see cref="RetireOperationToPool"/>'s doc comment).
/// </summary>
private bool IsOperationStateConsistent(Operation operation) =>
_entities.SessionLifetimeVersion == operation.SessionLifetimeVersion
&& _entities.IsCurrent(operation.Record)
&& operation.Record.Key == operation.Key
&& (operation.Body is null
|| ReferenceEquals(operation.Record.PhysicsBody, operation.Body))
&& operation.Record.PositionAuthorityVersion
== operation.PositionAuthorityVersion
&& operation.Record.SpatialAuthorityVersion
== operation.SpatialAuthorityVersion
&& operation.Record.PlacementCommitVersion
== operation.PlacementCommitVersion;
/// <summary>
/// Round 3: the class-wide replacement for
/// <c>ReferenceEquals</c>/<see cref="IsCurrent(Operation)"/> at any frame
/// that holds an Operation reference across a reentrancy point (a
/// synchronous publish, a collision-report dispatch that can reach an
/// arbitrary <c>IRuntimeCollisionReportObserver</c>, or a ground-edge
/// HitGround/LeaveGround callback). <paramref name="capturedToken"/>
/// MUST be read from the operation (or already be the caller's own
/// token parameter) BEFORE that reentrancy point - reading it fresh off
/// a possibly-already-repurposed reference here would be exactly as
/// tautological as the <c>ReferenceEquals</c> check this replaces (see
/// <see cref="RetireOperationToPool"/>'s doc comment for the full
/// hazard: a reentrant cancel-then-begin can retire-then-rent the SAME
/// physical instance for a DIFFERENT logical operation, LIFO). On
/// success, returns the FRESHLY resolved Operation so the caller
/// continues with a reference proven current at THIS instant, never
/// the possibly-stale one it held before the reentrancy point.
/// </summary>
private bool IsCurrentByToken(
RuntimeEntityKey key,
in RuntimeEntityPlacementToken capturedToken,
[NotNullWhen(true)] out Operation? operation)
{
if (_operations.TryGetValue(key, out Operation? current)
&& current.Token == capturedToken
&& IsOperationStateConsistent(current))
{
operation = current;
return true;
}
operation = null;
return false;
}
private bool IsExactDormantLocalActivationCurrent(
RuntimeEntityRecord record,
PhysicsBody body,
in RuntimeEntityPlacementToken token,
in RuntimeSetPositionCommand command,
out Operation? operation,
bool allowCanonicalCommand = false,
bool allowDeferredLease = false)
{
operation = null;
// Round 3 audit: safe - fresh lookup + Token check earlier in this
// SAME guard clause (below) precede IsCurrent, nothing reentrant in
// between; this dormant family has zero production callers.
if (!token.IsValid
|| token.Entity != record.Key
|| token.PreparationKind
is not RuntimeEntityPlacementPreparationKind.AuthoredMover
|| command.Kind is not (RuntimeSetPositionOperationKind.InitialLogin
or RuntimeSetPositionOperationKind.LocalAuthoritative)
|| command.Portal != default
&& !command.Portal.IsValid
|| !_operations.TryGetValue(token.Entity, out operation)
|| operation.Token != token
|| operation.Stage
is not RuntimeEntityPlacementStage.AwaitingPreparation
&& !(allowDeferredLease
&& operation.DormantLocalActivation
&& (operation.Stage
is RuntimeEntityPlacementStage.AwaitingCell
&& operation.WakeableLostCell
|| operation.Stage is RuntimeEntityPlacementStage
.AwaitingFinalShadowPreparation)
&& operation.ProjectionSequence == 0UL)
|| !ReferenceEquals(operation.Record, record)
|| !IsCurrent(operation)
|| !ReferenceEquals(record.PhysicsBody, body)
|| body.InWorld
|| (body.TransientState & TransientStateFlags.Active) != 0
|| record.PhysicsHost is not null
|| record.RemoteMotion is not null
|| record.Projectile is not null
|| record.PhysicsBodyAcquisitionInProgress
|| record.RemoteMotionBindingInProgress
|| record.ProjectileBindingInProgress
|| record.RequiresRemotePlacementRuntime
|| record.DeleteAcceptedForTeardown
|| _physics.IsSpatialRoot(record)
|| !_moverPreparationAuthorities.TryGetValue(
token.Entity,
out MoverPreparationAuthority authority)
|| authority.OperationId != token.OperationId
|| !authority.Prepared
|| !IsPreparationAuthorityCurrent(operation, authority))
{
operation = null;
return false;
}
if (authority.PreparedCommand == command)
return true;
if (!allowCanonicalCommand)
return false;
RuntimeSetPositionCommand authored = authority.PreparedCommand;
return authored with
{
Physics = authored.Physics with
{
MoverPhysicsState = record.FinalPhysicsState,
MovingEntityId = token.Entity.LocalEntityId,
CurrentCellId = null,
},
} == command;
}
private bool IsVelocityCurrent(Operation operation) =>
IsVelocityCurrent(
operation.SourceVelocityAuthorityVersion,
operation.Record);
/// <summary>
/// F1: overload taking the hoisted scalar directly, for callers (like
/// <c>CommitCanonical</c>) that must not re-read a live
/// <see cref="Operation"/> after a ground-edge callback may have retired
/// and repurposed it.
/// </summary>
private static bool IsVelocityCurrent(
ulong sourceVelocityAuthorityVersion,
RuntimeEntityRecord record) =>
sourceVelocityAuthorityVersion == 0UL
|| record.VelocityAuthorityVersion == sourceVelocityAuthorityVersion;
private static MoverPreparationAuthority CapturePreparationAuthority(
Operation operation,
in CreateObject.ServerPosition acceptedPosition,
bool prepared,
in RuntimeSetPositionCommand preparedCommand = default) => new(
operation.Token.OperationId,
acceptedPosition,
CanonicalSetupTableId(operation.Record),
operation.Record.PositionAuthorityVersion,
operation.Record.VelocityAuthorityVersion,
operation.Record.StateAuthorityVersion,
operation.Record.VectorAuthorityVersion,
operation.Record.ObjDescAuthorityVersion,
operation.Record.CreateIntegrationVersion,
operation.Record.PhysicsStateMutationVersion,
prepared,
preparedCommand);
private static uint CanonicalSetupTableId(RuntimeEntityRecord record) =>
record.Snapshot.Physics?.SetupTableId
?? record.Snapshot.SetupTableId
?? 0u;
private static CreateObject.ServerPosition ServerPositionFrom(
uint cellId,
Vector3 cellLocal,
Quaternion orientation) => new(
cellId,
cellLocal.X,
cellLocal.Y,
cellLocal.Z,
orientation.W,
orientation.X,
orientation.Y,
orientation.Z);
private static bool IsPreparationAuthorityCurrent(
Operation operation,
in MoverPreparationAuthority authority) =>
operation.Record.PositionAuthorityVersion
== authority.PositionAuthorityVersion
&& operation.Record.VelocityAuthorityVersion
== authority.VelocityAuthorityVersion
&& operation.Record.StateAuthorityVersion
== authority.StateAuthorityVersion
&& operation.Record.VectorAuthorityVersion
== authority.VectorAuthorityVersion
&& operation.Record.ObjDescAuthorityVersion
== authority.ObjDescAuthorityVersion
&& operation.Record.CreateIntegrationVersion
== authority.CreateIntegrationVersion
&& operation.Record.PhysicsStateMutationVersion
== authority.PhysicsStateMutationVersion;
private void RebindPreparedCommand(Operation operation)
{
if (_moverPreparationAuthorities.TryGetValue(
operation.Key,
out MoverPreparationAuthority authority)
&& authority.OperationId == operation.Token.OperationId
&& authority.Prepared)
{
_moverPreparationAuthorities[operation.Key] = authority with
{
PreparedCommand = operation.Command,
};
}
}
private bool IsDeferredWakePreparationCurrent(Operation operation)
{
if (_moverPreparationAuthorities.TryGetValue(
operation.Key,
out MoverPreparationAuthority authority)
&& authority.OperationId == operation.Token.OperationId
&& authority.Prepared
&& authority.PreparedCommand == operation.Command
&& IsPreparationAuthorityCurrent(operation, authority))
{
return true;
}
operation.SourceVelocityAuthorityVersion =
operation.Record.VelocityAuthorityVersion;
operation.RequiresPreparation = true;
operation.Stage = RuntimeEntityPlacementStage.AwaitingPreparation;
operation.PreparedCommandAwaitingWithdrawalAck = null;
_moverPreparationAuthorities[operation.Key] =
CapturePreparationAuthority(
operation,
ServerPositionFrom(
operation.ExactCellId,
operation.Result.CellLocalPosition,
operation.Result.Orientation),
prepared: false);
return false;
}
internal void PublishCancellation(
in RuntimePlacementCancellationReceipt receipt)
{
if (!receipt.IsValid)
return;
RuntimePlacementProjectionSnapshot projection = receipt.Projection;
if (_pendingProjection.TryGetValue(
projection.Token.Sequence,
out RuntimePlacementProjectionSnapshot current)
&& current == projection)
{
PublishPlacement(projection);
}
}
private RuntimePlacementCancellationReceipt CancelCore(
RuntimeEntityKey key)
{
_ = CancelCoreDeferred(
key,
cancelLostFamily: false,
preserveLostFamily: false,
out RuntimePlacementProjectionSnapshot? discard);
return discard is { } projection
? new RuntimePlacementCancellationReceipt(projection)
: default;
}
private bool CancelCoreDeferred(
RuntimeEntityKey key,
bool cancelLostFamily,
bool preserveLostFamily,
out RuntimePlacementProjectionSnapshot? discard)
{
discard = null;
if (!preserveLostFamily)
CancelExactLostKey(key);
if (!_operations.Remove(key, out Operation? operation))
return false;
ForgetPlacementCompletionCore(operation.Token);
_moverPreparationAuthorities.Remove(key);
UnindexDeferred(operation);
if (!preserveLostFamily && cancelLostFamily)
CancelLostFamilyDeadlines(operation);
if (operation.ProjectionSequence != 0UL
&& _pendingProjection.TryGetValue(
operation.ProjectionSequence,
out RuntimePlacementProjectionSnapshot pending))
{
RuntimePlacementProjectionSnapshot cancelled = pending with
{
Token = pending.Token with
{
Revision = checked(pending.Token.Revision + 1UL),
},
Kind = RuntimePlacementProjectionKind.Discard,
};
_pendingProjection[operation.ProjectionSequence] = cancelled;
if (pending.Kind is RuntimePlacementProjectionKind.Withdraw)
{
foreach (CollisionPrefixQuiescence state
in _collisionPrefixQuiescence.Values)
{
if (state.PendingWithdrawals.ContainsKey(
operation.ProjectionSequence))
{
state.PendingWithdrawals[
operation.ProjectionSequence] = cancelled.Token;
for (int retainedIndex = 0;
retainedIndex < state.RetainedWithdrawals.Count;
retainedIndex++)
{
if (state.RetainedWithdrawals[retainedIndex].Sequence
== operation.ProjectionSequence)
{
state.RetainedWithdrawals[retainedIndex] =
cancelled.Token;
break;
}
}
break;
}
}
}
operation.Stage = RuntimeEntityPlacementStage
.CancelledAwaitingAcknowledgement;
discard = cancelled;
}
// C2: `operation` was just removed from `_operations` above - see
// RetireOperationToPool's doc comment for why every caller (this one
// included) is safe to hand it back here, even the discard-pending
// case (AcknowledgeProjection's Discard branch never looks the
// operation back up by key).
RetireOperationToPool(operation);
return true;
}
/// <summary>
/// Round 3: takes the entity key plus a Token CAPTURED BY THE CALLER
/// (before any reentrancy point the caller passed through) instead of
/// an <see cref="Operation"/> reference. The <c>ReferenceEquals</c>
/// check this replaced was exactly the shape the round 3 architecture
/// review flagged: safe before pooling (an Operation instance was never
/// reused), silently tautological after (a reentrant cancel-then-begin
/// can retire-then-rent the SAME instance for a DIFFERENT logical
/// operation, so `expected` and the freshly-looked-up `current` could be
/// the same reference while representing different operations) - with
/// the worse outcome that this method would then cancel the NEWER
/// operation instead of correctly no-op'ing. See
/// <see cref="RetireOperationToPool"/>'s doc comment for the full
/// hazard and <see cref="IsCurrentByToken"/> for the equivalent
/// conversion applied to plain currency checks.
/// </summary>
private RuntimePlacementCancellationReceipt CancelCore(
RuntimeEntityKey key,
in RuntimeEntityPlacementToken expectedToken,
bool preserveLostFamily = false)
{
if (!_operations.TryGetValue(key, out Operation? current)
|| current.Token != expectedToken)
{
return default;
}
_ = CancelCoreDeferred(
key,
cancelLostFamily: false,
preserveLostFamily,
out RuntimePlacementProjectionSnapshot? discard);
return discard is { } projection
? new RuntimePlacementCancellationReceipt(projection)
: default;
}
private void ForgetPlacementCompletionCore(
in RuntimeEntityPlacementToken token)
{
if (!token.IsValid)
return;
_placementCompletionWatches.Remove(token);
_acknowledgedPlacementCompletions.Remove(token);
}
private void IndexDeferred(Operation operation)
{
if (operation.ExactCellId == 0u
|| operation.CollisionGeneration == 0UL)
{
return;
}
var bucket = new CellGenerationKey(
operation.ExactCellId,
operation.CollisionPrefix,
operation.CollisionGeneration);
if (!_deferredByCellGeneration.TryGetValue(
bucket,
out List<RuntimeEntityKey>? entities))
{
entities = [];
_deferredByCellGeneration.Add(bucket, entities);
_deferredBucketOrder.Add(bucket);
}
if (!entities.Contains(operation.Key))
entities.Add(operation.Key);
}
private void IndexUnboundDeferred(Operation operation)
{
if (operation.ExactCellId == 0u)
return;
var key = new UnboundCellKey(
operation.ExactCellId,
operation.CollisionPrefix);
if (!_unboundDeferredByCell.TryGetValue(
key,
out List<RuntimeEntityKey>? entities))
{
entities = [];
_unboundDeferredByCell.Add(key, entities);
_unboundDeferredCellOrder.Add(key);
}
if (!entities.Contains(operation.Key))
entities.Add(operation.Key);
}
private void UnindexDeferred(Operation operation)
{
if (operation.ExactCellId == 0u)
{
return;
}
if (operation.CollisionGeneration == 0UL)
{
var key = new UnboundCellKey(
operation.ExactCellId,
operation.CollisionPrefix);
if (_unboundDeferredByCell.TryGetValue(
key,
out List<RuntimeEntityKey>? unbound))
{
int unboundIndex = unbound.IndexOf(operation.Key);
if (unboundIndex >= 0)
{
int last = unbound.Count - 1;
unbound[unboundIndex] = unbound[last];
unbound.RemoveAt(last);
}
if (unbound.Count == 0)
{
_unboundDeferredByCell.Remove(key);
_unboundDeferredCellOrder.Remove(key);
}
}
return;
}
var bucket = new CellGenerationKey(
operation.ExactCellId,
operation.CollisionPrefix,
operation.CollisionGeneration);
if (_deferredByCellGeneration.TryGetValue(
bucket,
out List<RuntimeEntityKey>? entities))
{
int index = entities.IndexOf(operation.Key);
if (index >= 0)
{
int last = entities.Count - 1;
entities[index] = entities[last];
entities.RemoveAt(last);
}
if (entities.Count == 0)
RemoveDeferredBucket(bucket);
}
}
private void UnbindDeferredBucket(CellGenerationKey bucket)
{
if (!_deferredByCellGeneration.TryGetValue(
bucket,
out List<RuntimeEntityKey>? entities))
{
return;
}
RemoveDeferredBucket(bucket);
var unboundKey = new UnboundCellKey(
bucket.CellId,
bucket.CollisionPrefix);
if (!_unboundDeferredByCell.TryGetValue(
unboundKey,
out List<RuntimeEntityKey>? unbound))
{
unbound = [];
_unboundDeferredByCell.Add(unboundKey, unbound);
_unboundDeferredCellOrder.Add(unboundKey);
}
for (int index = 0; index < entities.Count; index++)
{
RuntimeEntityKey key = entities[index];
if (!_operations.TryGetValue(key, out Operation? operation)
|| !operation.WakeableLostCell
|| operation.ExactCellId != bucket.CellId
|| operation.CollisionPrefix != bucket.CollisionPrefix
|| operation.CollisionGeneration != bucket.CollisionGeneration)
{
continue;
}
operation.CollisionGeneration = 0UL;
operation.CollisionGenerationReady = false;
if (!unbound.Contains(key))
unbound.Add(key);
}
if (unbound.Count == 0)
{
_unboundDeferredByCell.Remove(unboundKey);
_unboundDeferredCellOrder.Remove(unboundKey);
}
}
private void RemoveDeferredBucket(CellGenerationKey bucket)
{
_deferredByCellGeneration.Remove(bucket);
int index = _deferredBucketOrder.IndexOf(bucket);
if (index < 0)
return;
int last = _deferredBucketOrder.Count - 1;
_deferredBucketOrder[index] = _deferredBucketOrder[last];
_deferredBucketOrder.RemoveAt(last);
}
private static RuntimeSetPositionOutcome Outcome(
RuntimeSetPositionStatus status,
in PhysicsSetPositionResult result,
in RuntimePlacementProjectionToken projection) => new(
status,
result.Error,
result.Residence,
result.CellId,
projection);
private static RuntimeSetPositionOutcome Rejected(
in PhysicsSetPositionRequest request) => new(
RuntimeSetPositionStatus.Rejected,
PhysicsSetPositionError.InvalidArguments,
PhysicsResidenceDisposition.Unchanged,
request.CellId,
default);
private static PhysicsSetPositionResult InvalidResult(
in PhysicsSetPositionRequest request) => new(
PhysicsSetPositionError.InvalidArguments,
PhysicsResidenceDisposition.Unchanged,
request.Position,
request.Orientation,
request.CellId,
request.CellLocalPosition,
CrossCellIds: ImmutableArray<uint>.Empty,
CollidedObjectIds: ImmutableArray<uint>.Empty);
private static bool IsStructurallyValid(
in PhysicsSetPositionRequest request)
{
static bool Finite(Vector3 value) => float.IsFinite(value.X)
&& float.IsFinite(value.Y)
&& float.IsFinite(value.Z);
// The wire/runtime frame is retail Position::IsValid composed with
// Frame::IsValid: valid inbound cell plus the exact unit-quaternion
// tolerance. This must run before Core or prepared-mover caching.
if (!PositionFrameValidation.IsValid(
request.CellId,
request.CellLocalPosition,
request.Orientation)
|| !Finite(request.Position)
|| !Finite(request.CellLocalPosition)
|| !float.IsFinite(request.StepUpHeight)
|| !float.IsFinite(request.StepDownHeight))
{
return false;
}
if (!request.Spheres.IsDefaultOrEmpty)
{
if (!float.IsFinite(request.Scale))
return false;
int count = Math.Min(request.Spheres.Length, 2);
for (int index = 0; index < count; index++)
{
FlatCollisionSphere sphere = request.Spheres[index];
if (!Finite(sphere.Origin) || !float.IsFinite(sphere.Radius))
return false;
}
}
if (request.Flags.HasFlag(PhysicsSetPositionFlags.Line)
&& !Finite(request.Line))
{
return false;
}
bool scatter = request.Flags.HasFlag(PhysicsSetPositionFlags.Scatter)
|| request.Flags.HasFlag(PhysicsSetPositionFlags.RandomScatter);
if (scatter
&& (!float.IsFinite(request.ScatterRadiusX)
|| !float.IsFinite(request.ScatterRadiusY)
|| request.ScatterAttempts > MaxSynchronousScatterAttempts))
{
return false;
}
return true;
}
private void PublishPlacement(
in RuntimePlacementProjectionSnapshot projection) =>
_events?.PublishPlacement(projection);
private void ArmLostFamilyDeadlines(Operation operation)
{
RuntimeEntityRecord root = operation.Record;
CancelLostFamilyDeadlines(operation);
double deadline = _physics.MonotonicNowSeconds + 25d;
operation.LostFamilyKeys ??= [];
if (root.Key is { } rootKey)
{
operation.LostFamilyKeys.Add(rootKey);
ArmLostDeadline(rootKey, deadline);
}
IReadOnlyList<uint> children = _entities.ParentAttachments
.ChildrenAttachedToParent(root.ServerGuid, root.Incarnation);
for (int index = 0; index < children.Count; index++)
{
if (_entities.TryGetActive(
children[index],
out RuntimeEntityRecord child)
&& child.Key is { } childKey)
{
operation.LostFamilyKeys.Add(childKey);
ArmLostDeadline(childKey, deadline);
}
}
}
private void CancelLostFamilyDeadlines(Operation operation)
{
if (operation.Record.Key is { } rootKey)
{
RemoveLostDeadline(rootKey);
RemoveExpiredLostCell(rootKey);
}
IReadOnlyList<uint> currentChildren = _entities.ParentAttachments
.ChildrenAttachedToParent(
operation.Record.ServerGuid,
operation.Record.Incarnation);
for (int index = 0; index < currentChildren.Count; index++)
{
if (_entities.TryGetActive(
currentChildren[index],
out RuntimeEntityRecord child)
&& child.Key is { } key)
{
RemoveLostDeadline(key);
RemoveExpiredLostCell(key);
}
}
operation.LostFamilyKeys?.Clear();
}
private void CancelExactLostKey(RuntimeEntityKey key)
{
RemoveLostDeadline(key);
RemoveExpiredLostCell(key);
foreach (Operation operation in _operations.Values)
operation.LostFamilyKeys?.Remove(key);
}
private void RemoveExpiredLostCell(RuntimeEntityKey key)
{
if (!_expiredLostCellNodes.Remove(
key,
out LinkedListNode<RuntimeEntityKey>? node))
{
return;
}
_expiredLostCells.Remove(node);
}
private void ArmLostDeadline(RuntimeEntityKey key, double deadline)
{
RemoveLostDeadlineNode(key);
_lostDeadlines[key] = deadline;
int index = _lostDeadlineNodes.Count;
_lostDeadlineNodes.Add(new LostDeadlineEntry(
key,
deadline,
checked(++_nextLostDeadlineSequence)));
_lostDeadlineNodeIndex.Add(key, index);
BubbleLostDeadlineUp(index);
}
private void RemoveLostDeadline(RuntimeEntityKey key)
{
_lostDeadlines.Remove(key);
RemoveLostDeadlineNode(key);
}
private static bool IsEarlier(
in LostDeadlineEntry candidate,
in LostDeadlineEntry current) =>
candidate.Deadline < current.Deadline
|| (candidate.Deadline == current.Deadline
&& candidate.Sequence < current.Sequence);
private void BubbleLostDeadlineUp(int index)
{
while (index > 0)
{
int parent = (index - 1) / 2;
if (!IsEarlier(
_lostDeadlineNodes[index],
_lostDeadlineNodes[parent]))
break;
SwapLostDeadlineNodes(index, parent);
index = parent;
}
}
private void BubbleLostDeadlineDown(int index)
{
while (true)
{
int left = checked(index * 2 + 1);
if (left >= _lostDeadlineNodes.Count)
return;
int right = left + 1;
int earlier = right < _lostDeadlineNodes.Count
&& IsEarlier(
_lostDeadlineNodes[right],
_lostDeadlineNodes[left])
? right
: left;
if (!IsEarlier(
_lostDeadlineNodes[earlier],
_lostDeadlineNodes[index]))
return;
SwapLostDeadlineNodes(index, earlier);
index = earlier;
}
}
private void SwapLostDeadlineNodes(int first, int second)
{
LostDeadlineEntry temporary = _lostDeadlineNodes[first];
_lostDeadlineNodes[first] = _lostDeadlineNodes[second];
_lostDeadlineNodes[second] = temporary;
_lostDeadlineNodeIndex[_lostDeadlineNodes[first].Key] = first;
_lostDeadlineNodeIndex[_lostDeadlineNodes[second].Key] = second;
}
private void RemoveLostDeadlineNode(RuntimeEntityKey key)
{
if (_lostDeadlineNodeIndex.TryGetValue(key, out int index))
RemoveLostDeadlineNodeAt(index);
}
private void RemoveLostDeadlineNodeAt(int index)
{
LostDeadlineEntry removed = _lostDeadlineNodes[index];
_lostDeadlineNodeIndex.Remove(removed.Key);
int last = _lostDeadlineNodes.Count - 1;
if (index != last)
{
LostDeadlineEntry moved = _lostDeadlineNodes[last];
_lostDeadlineNodes[index] = moved;
_lostDeadlineNodeIndex[moved.Key] = index;
}
_lostDeadlineNodes.RemoveAt(last);
if (index >= _lostDeadlineNodes.Count)
return;
int parent = index == 0 ? -1 : (index - 1) / 2;
if (parent >= 0
&& IsEarlier(
_lostDeadlineNodes[index],
_lostDeadlineNodes[parent]))
{
BubbleLostDeadlineUp(index);
}
else
{
BubbleLostDeadlineDown(index);
}
}
private void EnsureNotDisposed() =>
ObjectDisposedException.ThrowIf(_disposed, this);
}