using System.Numerics; using AcDream.App.Physics; using AcDream.Core.Net.Messages; using AcDream.Core.Physics; using AcDream.Runtime; using AcDream.Runtime.Entities; using AcDream.Runtime.Physics; using AcDream.Runtime.Session; namespace AcDream.App.Tests.Physics; /// /// C4 route 4b-2: behavioural acceptance for the remote far snap. Every test /// calls the PRODUCTION routing entry point /// () /// against a REAL , a real /// canonical / pair, /// and REAL /// output. Nothing /// is re-derived in a test body — that is the #292 gap route 2 left and route /// 4a's first attempt repeated. /// /// /// The load-bearing discriminator is the worldPos argument: it is /// deliberately DIFFERENT from the accepted destination merged onto the /// canonical snapshot. The deleted legacy far block wrote /// Body.Position = worldPos; the canonical placement writes the /// snapshot's destination resolved through Runtime's world frame. Any /// regression back to the legacy write therefore fails /// /// on the exact position value. /// /// public sealed class LiveEntityNetworkRemoteFarSnapIntegrationTests { private static readonly Vector3 Destination = new(12f, 14f, 7f); /// A wire pose the caller passes but the far arm must ignore — /// distinct from in every component. private static readonly Vector3 DecoyWirePose = new(-70f, -80f, -90f); [Fact] public void FarSnap_PlacesTheBodyFromTheCanonicalDestination_NotTheCallersWirePose() { using var fixture = new RemotePlacementDriveFixture(); fixture.PublishDestinationCollision(); fixture.AllowDestination(); (RuntimeEntityRecord record, RemoteMotion remote, PhysicsBody body) = fixture.AddRemote(0x70004001u, Destination); LiveEntityNetworkUpdateController.RemoteContactRouting routing = LiveEntityNetworkUpdateController.ApplyRemoteContactRouting( fixture.Drive, record, remote, Classify(hasContact: true, playerDistance: 200f), DecoyWirePose, Quaternion.Identity, willBeDrTicked: true, runTeleportHook: () => true); Assert.Equal( LiveEntityNetworkUpdateController.RemoteContactArm.FarSnapPlacement, routing.Arm); Assert.Equal( RuntimeRemotePlacementExecutionStatus.Committed, routing.Placement); Assert.Equal( Destination + RemotePlacementDriveFixture.DestinationWorldOffset, body.Position); Assert.NotEqual(DecoyWirePose, body.Position); // The canonical placement — not the App — committed residency. Assert.Equal(RemotePlacementDriveFixture.DestinationCell, record.FullCellId); fixture.DrainPlacementFifo(); Assert.Equal(0, fixture.LiveOperationCount); Assert.Equal(0, fixture.RemotePlacementLedger); } /// /// Retail's far branch stops the interpolation queue BEFORE placing /// (@0x005163CB precedes @0x005163D9). A stale near waypoint surviving the /// snap would drag the freshly placed body back on the next per-tick /// catch-up. /// [Fact] public void FarSnap_ClearsTheInterpolationQueue() { using var fixture = new RemotePlacementDriveFixture(); fixture.PublishDestinationCollision(); fixture.AllowDestination(); (RuntimeEntityRecord record, RemoteMotion remote, PhysicsBody body) = fixture.AddRemote(0x70004002u, Destination); remote.Interp.Enqueue( new Vector3(40f, 40f, 7f), Quaternion.Identity, isMovingTo: false, currentBodyPosition: body.Position, currentBodyOrientation: body.Orientation); Assert.True(remote.Interp.IsActive); _ = LiveEntityNetworkUpdateController.ApplyRemoteContactRouting( fixture.Drive, record, remote, Classify(hasContact: true, playerDistance: 200f), DecoyWirePose, Quaternion.Identity, willBeDrTicked: true, runTeleportHook: () => true); Assert.False(remote.Interp.IsActive); fixture.DrainPlacementFifo(); } /// /// The inverted test (C4 route 4b-2 review). This used to assert /// Assert.Equal(before, body.Position) and so PINNED the defect /// both reviews found: a refused far snap left the body at its stale pose /// with the interpolation queue already cleared, i.e. a frozen remote /// that the next 5-10 Hz packet reproduces identically. /// /// /// Retail never leaves the object behind. When /// CPhysicsObj::SetPositionInternal @0x00515BD0 resolves no cell, /// it takes @0x00515C1D and still commits the destination — /// store_position @0x00515CE2 — before GotoLostCell /// @0x00515CF2. So a refusal advances the body to the accepted /// destination, resolved through Runtime's world frame (NOT the caller's /// wire pose), while retaining no operation and committing no cell. /// /// [Fact] public void FarSnap_RefusedDestination_StillAdvancesTheBodyToTheAcceptedDestination() { using var fixture = new RemotePlacementDriveFixture(); fixture.PublishDestinationCollision(); // Deliberately NOT AllowDestination(). (RuntimeEntityRecord record, RemoteMotion remote, PhysicsBody body) = fixture.AddRemote(0x70004003u, Destination); Vector3 before = body.Position; LiveEntityNetworkUpdateController.RemoteContactRouting routing = LiveEntityNetworkUpdateController.ApplyRemoteContactRouting( fixture.Drive, record, remote, Classify(hasContact: true, playerDistance: 200f), DecoyWirePose, Quaternion.Identity, willBeDrTicked: true, runTeleportHook: () => true); Assert.Equal( LiveEntityNetworkUpdateController.RemoteContactArm.FarSnapPlacement, routing.Arm); Assert.Equal( RuntimeRemotePlacementExecutionStatus.Refused, routing.Placement); // store_position: the body TRACKED, and from the canonical // destination — not the caller's wire pose, and not its stale pose. Assert.Equal( Destination + RemotePlacementDriveFixture.DestinationWorldOffset, body.Position); Assert.NotEqual(before, body.Position); Assert.NotEqual(DecoyWirePose, body.Position); // …and it is a store_position, NOT a placement: no cell was // committed, nothing was retained. Assert.Equal(RemotePlacementDriveFixture.SourceCell, record.FullCellId); Assert.True(body.InWorld); Assert.True(record.ObjectClock.IsActive); Assert.Equal(0, fixture.LiveOperationCount); Assert.Equal(0, fixture.RemotePlacementLedger); } /// /// The same refusal repeated: a remote genuinely beyond the host's /// service window keeps TRACKING every packet rather than freezing until /// the window opens. This is the reachable production shape the review /// named — a remote that is rendered but still streaming, refused while /// genuinely beyond 96 m — and it is why the fallback cannot be a /// one-shot. /// [Fact] public void FarSnap_RepeatedRefusals_KeepTrackingEveryPacket() { using var fixture = new RemotePlacementDriveFixture(); fixture.PublishDestinationCollision(); (RuntimeEntityRecord record, RemoteMotion remote, PhysicsBody body) = fixture.AddRemote(0x7000400Cu, Destination); foreach (Vector3 step in new[] { new Vector3(20f, 14f, 7f), new Vector3(28f, 14f, 7f), new Vector3(36f, 14f, 7f), }) { record.Snapshot = record.Snapshot with { Position = new CreateObject.ServerPosition( RemotePlacementDriveFixture.DestinationCell, step.X, step.Y, step.Z, 1f, 0f, 0f, 0f), }; LiveEntityNetworkUpdateController.RemoteContactRouting routing = LiveEntityNetworkUpdateController.ApplyRemoteContactRouting( fixture.Drive, record, remote, Classify(hasContact: true, playerDistance: 200f), DecoyWirePose, Quaternion.Identity, willBeDrTicked: true, runTeleportHook: () => true); Assert.Equal( RuntimeRemotePlacementExecutionStatus.Refused, routing.Placement); Assert.Equal( step + RemotePlacementDriveFixture.DestinationWorldOffset, body.Position); } Assert.Equal(0, fixture.LiveOperationCount); Assert.Equal(0, fixture.RemotePlacementLedger); } // ── The null / Rejected* / cell-less policy ──────────────────────────── /// /// The login-window trap. ClassifyRemoteAcceptedPosition returns /// null for EVERY remote packet until the local movement controller /// exists, because there is no player_distance to derive. Deleting /// the legacy block without a replacement would freeze every remote for /// that whole window. The stated policy routes it through AP-87's /// catch-up, whose 4 m guard PLACES a body that has drifted. /// [Fact] public void NoClassificationAtAll_StillTracksTheServer() { using var fixture = new RemotePlacementDriveFixture(); (RuntimeEntityRecord record, RemoteMotion remote, PhysicsBody body) = fixture.AddRemote(0x70004004u, Destination); var target = new Vector3(60f, 10f, 7f); // 50 m from the body. LiveEntityNetworkUpdateController.RemoteContactRouting routing = LiveEntityNetworkUpdateController.ApplyRemoteContactRouting( fixture.Drive, record, remote, route: null, target, Quaternion.Identity, willBeDrTicked: true, runTeleportHook: () => true); Assert.Equal( LiveEntityNetworkUpdateController.RemoteContactArm.UnroutedCatchUp, routing.Arm); Assert.Equal(target, body.Position); // No canonical placement was attempted for an unclassified packet. Assert.Equal(0, fixture.LiveOperationCount); } /// /// …and the same policy ENQUEUES when the body is already tracking, which /// is what proves it is AP-87's catch-up rather than an unconditional /// snap bolted on to make the previous test pass. /// /// /// R7 review fix: the earlier version asserted only that the body did not /// move, which "snap when bodyToTarget > 4 m, else do nothing" /// satisfies just as well as an enqueue — it and its sibling both passed /// against that regression. The queue assertion below is what actually /// distinguishes "enqueued" from "did nothing". /// /// [Fact] public void NoClassificationAtAll_NearAndTicked_EnqueuesInsteadOfSnapping() { using var fixture = new RemotePlacementDriveFixture(); (RuntimeEntityRecord record, RemoteMotion remote, PhysicsBody body) = fixture.AddRemote(0x70004005u, Destination); Vector3 before = body.Position; var target = before + new Vector3(0.5f, 0f, 0f); LiveEntityNetworkUpdateController.RemoteContactRouting routing = LiveEntityNetworkUpdateController.ApplyRemoteContactRouting( fixture.Drive, record, remote, route: null, target, Quaternion.Identity, willBeDrTicked: true, runTeleportHook: () => true); Assert.Equal( LiveEntityNetworkUpdateController.RemoteContactArm.UnroutedCatchUp, routing.Arm); Assert.Equal(before, body.Position); Assert.True(remote.Interp.IsActive); } [Fact] public void RejectedData_TakesTheUnroutedCatchUp_NotTheFarSnap() { using var fixture = new RemotePlacementDriveFixture(); fixture.PublishDestinationCollision(); fixture.AllowDestination(); (RuntimeEntityRecord record, RemoteMotion remote, PhysicsBody body) = fixture.AddRemote(0x70004006u, Destination); var target = new Vector3(60f, 10f, 7f); RuntimeAuthoritativePositionRoute rejected = Classify(hasContact: true, playerDistance: float.NaN); Assert.Equal( RuntimeAuthoritativePositionDisposition.RejectedData, rejected.Disposition); LiveEntityNetworkUpdateController.RemoteContactRouting routing = LiveEntityNetworkUpdateController.ApplyRemoteContactRouting( fixture.Drive, record, remote, rejected, target, Quaternion.Identity, willBeDrTicked: true, runTeleportHook: () => true); Assert.Equal( LiveEntityNetworkUpdateController.RemoteContactArm.UnroutedCatchUp, routing.Arm); Assert.Equal(target, body.Position); Assert.Equal(0, fixture.LiveOperationCount); } /// /// C4 route 4b-3 (D1/D5): retail's cell-less body takes /// this_1->cell == 0 @0x00516386 — the SAME teleport branch as a /// fresh TELEPORT_TS — never the far/near/leftover arms. The hook runs /// (before the placement, per D3) and the body ends at the canonical /// RESOLVED destination, not at the caller's separately-supplied /// wire pose (the decoy discriminates the same /// way the far-snap test above does). /// [Fact] public void CellLessRemote_TakesTheTeleportArm_RunsTheHookAndPlacesCanonically() { using var fixture = new RemotePlacementDriveFixture(); fixture.PublishDestinationCollision(); fixture.AllowDestination(); (RuntimeEntityRecord record, RemoteMotion remote, PhysicsBody body) = fixture.AddRemote(0x70004007u, Destination); var target = new Vector3(60f, 10f, 7f); RuntimeAuthoritativePositionRoute cellLess = Classify( hasContact: true, playerDistance: 200f, committedCellId: 0u); Assert.Equal( RuntimeAuthoritativePositionDisposition.SetPosition, cellLess.Disposition); int hookCalls = 0; LiveEntityNetworkUpdateController.RemoteContactRouting routing = LiveEntityNetworkUpdateController.ApplyRemoteContactRouting( fixture.Drive, record, remote, cellLess, target, Quaternion.Identity, willBeDrTicked: true, runTeleportHook: () => { hookCalls++; return true; }); Assert.Equal(1, hookCalls); Assert.Equal( LiveEntityNetworkUpdateController.RemoteContactArm.TeleportPlacement, routing.Arm); Assert.Equal( RuntimeRemotePlacementExecutionStatus.Committed, routing.Placement); Assert.Equal( Destination + RemotePlacementDriveFixture.DestinationWorldOffset, body.Position); Assert.NotEqual(target, body.Position); Assert.Equal(RemotePlacementDriveFixture.DestinationCell, record.FullCellId); fixture.DrainPlacementFifo(); Assert.Equal(0, fixture.LiveOperationCount); Assert.Equal(0, fixture.RemotePlacementLedger); } /// /// The airborne precedence carve-out still outranks the far snap, not /// only the near branch: a remote mid-arc whose packet happens to /// classify far must keep the pre-existing authoritative hard-snap rather /// than open a canonical placement. /// [Fact] public void AirborneBody_OutranksTheFarSnap() { using var fixture = new RemotePlacementDriveFixture(); fixture.PublishDestinationCollision(); fixture.AllowDestination(); (RuntimeEntityRecord record, RemoteMotion remote, PhysicsBody body) = fixture.AddRemote(0x70004008u, Destination); // AP-140 (retired 2026-08-04): "mid-arc" is retail's CONTACT_TS-clear // (`InterpolationManager::adjust_offset` gates on `transient_state & 1` // @0x00555D52), not the client `Airborne` walkability flag. Both are // set here so the test states free flight in the terms the gate now // reads AND the terms it used to. remote.Airborne = true; remote.Body.TransientState = TransientStateFlags.Active; var target = new Vector3(60f, 10f, 7f); LiveEntityNetworkUpdateController.RemoteContactRouting routing = LiveEntityNetworkUpdateController.ApplyRemoteContactRouting( fixture.Drive, record, remote, Classify(hasContact: true, playerDistance: 200f), target, Quaternion.Identity, willBeDrTicked: true, runTeleportHook: () => true); Assert.Equal( LiveEntityNetworkUpdateController.RemoteContactArm.AirborneSnap, routing.Arm); Assert.Equal(target, body.Position); Assert.Equal(0, fixture.LiveOperationCount); } /// /// C4 route 4b-3, test-plan item 6 / contract D5: the teleport/cell-less /// classification is decided BEFORE ApplyRemoteContactRouting ever /// reads remote.Body.InContact — retail's MoveOrTeleport /// tests this_1->cell == 0 || newer_event(TELEPORT_TS) /// @0x00516375-@0x00516386 strictly before the wire-contact branch at /// @0x0051638E. A mid-arc body's teleport packet must therefore still /// place canonically — the OPPOSITE outcome of /// above, which proves the /// far arm defers to airborne precedence while this proves the teleport /// arm does not. Fails against a broken ordering that lets the airborne /// carve-out claim the packet first: would then /// sit at the raw target wire pose the airborne branch writes, /// never resolved through the canonical destination. /// [Fact] public void AirborneBody_TeleportOutranksAirborneSnap() { using var fixture = new RemotePlacementDriveFixture(); fixture.PublishDestinationCollision(); fixture.AllowDestination(); (RuntimeEntityRecord record, RemoteMotion remote, PhysicsBody body) = fixture.AddRemote(0x7000400Cu, Destination); // Same mid-arc state as AirborneBody_OutranksTheFarSnap: no wire // contact, free flight in both the old and new terms of the gate. remote.Airborne = true; remote.Body.TransientState = TransientStateFlags.Active; var target = new Vector3(60f, 10f, 7f); RuntimeAuthoritativePositionRoute cellLess = Classify( hasContact: false, playerDistance: 200f, committedCellId: 0u); Assert.Equal( RuntimeAuthoritativePositionDisposition.SetPosition, cellLess.Disposition); int hookCalls = 0; LiveEntityNetworkUpdateController.RemoteContactRouting routing = LiveEntityNetworkUpdateController.ApplyRemoteContactRouting( fixture.Drive, record, remote, cellLess, target, Quaternion.Identity, willBeDrTicked: true, runTeleportHook: () => { hookCalls++; return true; }); Assert.Equal(1, hookCalls); Assert.Equal( LiveEntityNetworkUpdateController.RemoteContactArm.TeleportPlacement, routing.Arm); Assert.Equal( RuntimeRemotePlacementExecutionStatus.Committed, routing.Placement); Assert.Equal( Destination + RemotePlacementDriveFixture.DestinationWorldOffset, body.Position); Assert.NotEqual(target, body.Position); Assert.Equal(RemotePlacementDriveFixture.DestinationCell, record.FullCellId); fixture.DrainPlacementFifo(); Assert.Equal(0, fixture.LiveOperationCount); Assert.Equal(0, fixture.RemotePlacementLedger); } /// /// Per-entity independence across the two arms in the same tick: one /// remote's committed placement must not touch another's body or leak /// into its ledger. /// [Fact] public void TwoRemotesInTheSameTick_FarAndNear_DoNotContaminateEachOther() { using var fixture = new RemotePlacementDriveFixture(); fixture.PublishDestinationCollision(); fixture.AllowDestination(); (RuntimeEntityRecord farRecord, RemoteMotion farRemote, PhysicsBody farBody) = fixture.AddRemote(0x70004009u, Destination); (RuntimeEntityRecord nearRecord, RemoteMotion nearRemote, PhysicsBody nearBody) = fixture.AddRemote(0x7000400Au, Destination); Vector3 nearBefore = nearBody.Position; Assert.Equal( LiveEntityNetworkUpdateController.RemoteContactArm.FarSnapPlacement, LiveEntityNetworkUpdateController.ApplyRemoteContactRouting( fixture.Drive, farRecord, farRemote, Classify(hasContact: true, playerDistance: 200f), DecoyWirePose, Quaternion.Identity, willBeDrTicked: true, runTeleportHook: () => true).Arm); Assert.Equal( LiveEntityNetworkUpdateController.RemoteContactArm .SteadyStateInterpolate, LiveEntityNetworkUpdateController.ApplyRemoteContactRouting( fixture.Drive, nearRecord, nearRemote, Classify(hasContact: true, playerDistance: 10f), nearBefore + new Vector3(0.5f, 0f, 0f), Quaternion.Identity, willBeDrTicked: true, runTeleportHook: () => true).Arm); Assert.Equal( Destination + RemotePlacementDriveFixture.DestinationWorldOffset, farBody.Position); Assert.Equal(nearBefore, nearBody.Position); fixture.DrainPlacementFifo(); Assert.Equal(0, fixture.LiveOperationCount); Assert.Equal(0, fixture.RemotePlacementLedger); } /// /// R10 review fix: AirborneNoOperation used to fall into /// default:, whose comment ASSERTED unreachability that nothing /// enforced — so a caller that skipped its own airborne-no-op early /// return would have silently enqueued a waypoint on a branch where /// retail writes nothing at all (@0x0051636D). The explicit case is what /// makes the assertion true. /// [Fact] public void AirborneNoOperationClassification_IsRejectedByTheRoutingSeam() { using var fixture = new RemotePlacementDriveFixture(); (RuntimeEntityRecord record, RemoteMotion remote, PhysicsBody body) = fixture.AddRemote(0x7000400Du, Destination); Vector3 before = body.Position; RuntimeAuthoritativePositionRoute airborne = Classify(hasContact: false, playerDistance: 200f); Assert.Equal( RuntimeAuthoritativePositionDisposition.NoPositionOperation, airborne.Disposition); Assert.Throws(() => LiveEntityNetworkUpdateController.ApplyRemoteContactRouting( fixture.Drive, record, remote, airborne, new Vector3(60f, 10f, 7f), Quaternion.Identity, willBeDrTicked: true, runTeleportHook: () => true)); Assert.Equal(before, body.Position); Assert.False(remote.Interp.IsActive); Assert.Equal(0, fixture.LiveOperationCount); } // ── The NPC arm's post-routing wire-cell adoption ────────────────────── /// /// After a far snap the canonical placement owns the cell. The NPC arm's /// wire-cell write sits AFTER its routing (the player arm's sits before), /// and RemoteMotion.CellId writes through to the canonical /// FullCellId — so an unguarded write would discard the resolved /// cell the placement just committed. /// [Fact] public void WireCellAdoption_IsSuppressedAfterAFarSnapAndRunsForEveryOtherArm() { using var fixture = new RemotePlacementDriveFixture(); (RuntimeEntityRecord record, RemoteMotion remote, _) = fixture.AddRemote(0x7000400Bu, Destination); uint resolved = remote.CellId; Assert.Equal(RemotePlacementDriveFixture.SourceCell, resolved); Assert.False( LiveEntityNetworkUpdateController.TryAdoptWireCellAfterRouting( remote, LiveEntityNetworkUpdateController.RemoteContactArm .FarSnapPlacement, RemotePlacementDriveFixture.DestinationCell)); Assert.Equal(resolved, remote.CellId); Assert.Equal(resolved, record.FullCellId); foreach (LiveEntityNetworkUpdateController.RemoteContactArm arm in new[] { LiveEntityNetworkUpdateController.RemoteContactArm.AirborneSnap, LiveEntityNetworkUpdateController.RemoteContactArm .SteadyStateInterpolate, LiveEntityNetworkUpdateController.RemoteContactArm .UnroutedCatchUp, }) { remote.CellId = RemotePlacementDriveFixture.SourceCell; Assert.True( LiveEntityNetworkUpdateController.TryAdoptWireCellAfterRouting( remote, arm, RemotePlacementDriveFixture.DestinationCell)); Assert.Equal( RemotePlacementDriveFixture.DestinationCell, remote.CellId); } } private static RuntimeAuthoritativePositionRoute Classify( bool hasContact, float playerDistance, uint committedCellId = RemotePlacementDriveFixture.SourceCell) => RuntimeAuthoritativePositionRouteClassifier.ClassifyAcceptedPosition( new RuntimeAcceptedPositionRouteRequest( new RuntimeAuthoritativePositionAuthority( new RuntimeGenerationToken(7), new RuntimeEntityKey(0x70000001u, 3), PositionAuthorityVersion: 11UL, AcceptedPositionSequence: 20, PreviousTeleportSequence: 10, AcceptedTeleportSequence: 10, PositionTimestampDisposition.Apply), RuntimePositionEntityKind.Remote, RuntimeAcceptedPositionSource.PositionEvent, new CreateObject.ServerPosition( RemotePlacementDriveFixture.DestinationCell, Destination.X, Destination.Y, Destination.Z, 1f, 0f, 0f, 0f), PlacementFrame: 0u, PositionPackVelocity: Vector3.Zero, committedCellId, hasContact, playerDistance, UsePositionFromServer: false, HasAnimations: false, default)); }