using System.Numerics; using AcDream.Core.Physics; using AcDream.Runtime.World; namespace AcDream.Runtime.Tests.World; public sealed class RuntimeWorldTransitStateTests { private const uint OutdoorCell = 0x11340021u; private const uint OtherCell = 0x3032001Cu; [Fact] public void BeginReveal_OwnsGenerationDestinationAndSimulationGate() { var state = new RuntimeWorldTransitState(); long generation = state.BeginLoginReveal(OutdoorCell); Assert.Equal(1, generation); Assert.Equal(generation, state.Snapshot.Generation); Assert.Equal(RuntimePortalKind.Login, state.Snapshot.Kind); Assert.Equal(OutdoorCell, state.Snapshot.DestinationCell); Assert.False(state.IsWorldSimulationAvailable); Assert.False(state.Snapshot.IsReady); } [Fact] public void TypedReadiness_RejectsWrongGenerationAndDestination() { List log = []; var state = new RuntimeWorldTransitState(log.Add); long generation = BeginPortal(state, OutdoorCell); Assert.False(state.AcknowledgeDestinationReadiness( Ready(generation + 1, OutdoorCell))); Assert.False(state.AcknowledgeDestinationReadiness( Ready(generation, OtherCell))); Assert.Equal(OutdoorCell, state.Snapshot.DestinationCell); Assert.False(state.Snapshot.IsReady); Assert.Equal(1, state.Snapshot.InvariantFailureCount); Assert.Equal( 1, log.Count(value => value.Contains( "event=invariant-failure", StringComparison.Ordinal))); Assert.Single( log, value => value.Contains( "event=rejected", StringComparison.Ordinal)); } [Fact] public void Materialization_ReleasesSimulationBeforeViewportAndCompletion() { var state = new RuntimeWorldTransitState(); long generation = BeginPortal(state, OutdoorCell); Assert.True(state.AcknowledgeDestinationReadiness( Ready(generation, OutdoorCell))); Assert.True(state.AcknowledgePortalMaterialized( generation, 1, OutdoorCell)); Assert.True(state.IsWorldSimulationAvailable); Assert.True(state.Snapshot.Materialized); Assert.False(state.Snapshot.WorldViewportObserved); Assert.False(state.Snapshot.Completed); Assert.Equal(1, state.Snapshot.PortalMaterializationCount); Assert.False(state.AcknowledgePortalMaterialized( generation, 1, OutdoorCell)); Assert.True(state.AcknowledgeWorldViewportVisible(generation)); Assert.True(state.Complete(generation)); Assert.True(state.Snapshot.WorldViewportObserved); Assert.True(state.Snapshot.Completed); Assert.Equal(1, state.Snapshot.PortalMaterializationCount); } [Fact] public void MaterializationBeforeReadiness_IsRejectedWithoutOpeningWorld() { var state = new RuntimeWorldTransitState(); long generation = BeginPortal(state, OutdoorCell); Assert.False(state.AcknowledgePortalMaterialized( generation, 1, OutdoorCell)); Assert.False(state.IsWorldSimulationAvailable); Assert.False(state.Snapshot.Materialized); Assert.Equal(1, state.Snapshot.InvariantFailureCount); Assert.Equal(0, state.Snapshot.PortalMaterializationCount); } [Fact] public void LoginCompletion_ReleasesSimulationBeforeFirstVisibleFrame() { var state = new RuntimeWorldTransitState(); long generation = state.BeginLoginReveal(OutdoorCell); state.AcknowledgeDestinationReadiness( Ready(generation, OutdoorCell)); Assert.True(state.Complete(generation)); Assert.True(state.IsWorldSimulationAvailable); Assert.False(state.Snapshot.WorldViewportObserved); Assert.True(state.AcknowledgeWorldViewportVisible(generation)); Assert.True(state.Snapshot.WorldViewportObserved); Assert.Equal(0, state.Snapshot.InvariantFailureCount); } [Fact] public void EarlyViewport_IsRejectedWithoutFabricatingVisibility() { var state = new RuntimeWorldTransitState(); long generation = state.BeginLoginReveal(OutdoorCell); Assert.False(state.AcknowledgeWorldViewportVisible(generation)); Assert.False(state.Snapshot.IsReady); Assert.False(state.Snapshot.WorldViewportObserved); Assert.Equal(1, state.Snapshot.InvariantFailureCount); } [Fact] public void ReadinessShape_MustMatchDestinationCell() { var state = new RuntimeWorldTransitState(); long generation = state.BeginLoginReveal(OutdoorCell); RuntimeDestinationReadiness invalid = Ready(generation, OutdoorCell) with { IsIndoor = true, RequiredRenderRadius = 0, }; Assert.False(state.AcknowledgeDestinationReadiness(invalid)); Assert.False(state.Snapshot.IsReady); Assert.Equal(1, state.Snapshot.InvariantFailureCount); } [Fact] public void AcceptedReadiness_IsGenerationSticky() { var state = new RuntimeWorldTransitState(); long generation = BeginPortal(state, OutdoorCell); RuntimeDestinationReadiness accepted = Ready(generation, OutdoorCell); Assert.True(state.AcknowledgeDestinationReadiness(accepted)); RuntimeDestinationReadiness regressed = accepted with { IsCollisionReady = false, }; Assert.False(state.AcknowledgeDestinationReadiness(regressed)); Assert.Equal(accepted, state.Snapshot.Readiness); Assert.True(state.Snapshot.IsReady); Assert.Equal(0, state.Snapshot.InvariantFailureCount); } [Fact] public void Completion_RejectsReorderedLoginAndPortalEdges() { var state = new RuntimeWorldTransitState(); long login = state.BeginLoginReveal(OutdoorCell); Assert.False(state.Complete(login)); Assert.False(state.Snapshot.Completed); long portal = BeginPortal(state, OtherCell, sequence: 2); Assert.True(state.AcknowledgeDestinationReadiness( Ready(portal, OtherCell))); Assert.False(state.Complete(portal)); Assert.False(state.Snapshot.Completed); Assert.Equal(2, state.Snapshot.InvariantFailureCount); } [Fact] public void Supersession_RejectsOldAcknowledgementsAndKeepsLatestDestination() { var state = new RuntimeWorldTransitState(); long first = state.BeginLoginReveal(OutdoorCell); long second = BeginPortal(state, OtherCell); Assert.True(second > first); Assert.False(state.AcknowledgeDestinationReadiness( Ready(first, OutdoorCell))); Assert.False(state.AcknowledgePortalMaterialized( first, 1, OutdoorCell)); Assert.Equal(second, state.Snapshot.Generation); Assert.Equal(OtherCell, state.Snapshot.DestinationCell); Assert.False(state.Snapshot.IsReady); Assert.False(state.IsWorldSimulationAvailable); Assert.Equal(0, state.Snapshot.InvariantFailureCount); } [Fact] public void Cancel_ReleasesSimulationAndRejectsLateHostWork() { var state = new RuntimeWorldTransitState(); long generation = BeginPortal(state, OutdoorCell); Assert.True(state.Cancel(generation)); Assert.True(state.IsWorldSimulationAvailable); Assert.True(state.Snapshot.Cancelled); Assert.False(state.AcknowledgeDestinationReadiness( Ready(generation, OutdoorCell))); Assert.False(state.AcknowledgePortalMaterialized( generation, 1, OutdoorCell)); Assert.False(state.Complete(generation)); Assert.False(state.Snapshot.Materialized); Assert.False(state.Snapshot.Completed); } [Fact] public void MaterializedThenCancelled_RemainsAvailableAndCannotComplete() { var state = new RuntimeWorldTransitState(); long generation = BeginPortal(state, OutdoorCell); state.AcknowledgeDestinationReadiness( Ready(generation, OutdoorCell)); state.AcknowledgePortalMaterialized( generation, 1, OutdoorCell); Assert.True(state.Cancel(generation)); Assert.True(state.IsWorldSimulationAvailable); Assert.True(state.Snapshot.Materialized); Assert.True(state.Snapshot.Cancelled); Assert.False(state.Complete(generation)); Assert.False(state.Snapshot.Completed); Assert.Equal(1, state.Snapshot.PortalMaterializationCount); } [Fact] public void WaitCue_UsesRetailFiveSecondEdgeWithoutCompletingReveal() { var state = new RuntimeWorldTransitState(); long generation = BeginPortal(state, OutdoorCell); Assert.False(state.ObserveWait( generation, RuntimeWorldTransitState.RetailWaitCueDelay - TimeSpan.FromMilliseconds(1))); Assert.True(state.ObserveWait( generation, RuntimeWorldTransitState.RetailWaitCueDelay)); Assert.True(state.ObserveWait( generation, RuntimeWorldTransitState.RetailWaitCueDelay + TimeSpan.FromSeconds(20))); Assert.True(state.Snapshot.WaitCueShown); Assert.False(state.Snapshot.Completed); Assert.False(state.IsWorldSimulationAvailable); } [Fact] public void UnhydratableDestination_IsAnExplicitReadyAcknowledgement() { var state = new RuntimeWorldTransitState(); long generation = BeginPortal(state, OutdoorCell); var acknowledgement = new RuntimeDestinationReadiness( generation, OutdoorCell, IsIndoor: false, IsUnhydratable: true, RequiredRenderRadius: 1, IsRenderNeighborhoodReady: false, AreCompositeTexturesReady: false, IsCollisionReady: false); Assert.True(state.AcknowledgeDestinationReadiness(acknowledgement)); Assert.True(state.Snapshot.IsReady); Assert.True(state.AcknowledgePortalMaterialized( generation, 1, OutdoorCell)); } [Fact] public void ResetSession_ClearsVisibleStateButNeverReusesGeneration() { var state = new RuntimeWorldTransitState(); long first = BeginPortal(state, OutdoorCell); state.ResetSession(); Assert.Equal(RuntimePortalSnapshot.Idle, state.Snapshot); Assert.True(state.IsWorldSimulationAvailable); long second = state.BeginLoginReveal(OtherCell); Assert.True(second > first); Assert.False(state.AcknowledgeDestinationReadiness( Ready(first, OutdoorCell))); Assert.Equal(second, state.Snapshot.Generation); Assert.Equal(OtherCell, state.Snapshot.DestinationCell); } [Fact] public void Instances_IsolateGenerationReadinessAndMaterializationCounts() { var first = new RuntimeWorldTransitState(); var second = new RuntimeWorldTransitState(); long firstGeneration = BeginPortal(first, OutdoorCell); long secondGeneration = second.BeginLoginReveal(OtherCell); first.AcknowledgeDestinationReadiness( Ready(firstGeneration, OutdoorCell)); first.AcknowledgePortalMaterialized( firstGeneration, 1, OutdoorCell); Assert.Equal(1, first.Snapshot.PortalMaterializationCount); Assert.Equal(0, second.Snapshot.PortalMaterializationCount); Assert.True(first.IsWorldSimulationAvailable); Assert.False(second.IsWorldSimulationAvailable); Assert.Equal(OtherCell, second.Snapshot.DestinationCell); Assert.Equal(1, secondGeneration); } [Fact] public void DiagnosticCallbackFailure_CannotInterruptCanonicalTransition() { var state = new RuntimeWorldTransitState( _ => throw new InvalidOperationException("diagnostic failed")); long generation = BeginPortal(state, OutdoorCell); Assert.True(state.AcknowledgeDestinationReadiness( Ready(generation, OutdoorCell))); Assert.True(state.AcknowledgePortalMaterialized( generation, 1, OutdoorCell)); Assert.True(state.Complete(generation)); Assert.True(state.Snapshot.Completed); Assert.True(state.IsWorldSimulationAvailable); Assert.True(state.DiagnosticFailureCount >= 4); Assert.IsType( state.LastDiagnosticFailure); } [Fact] public void ReplacementRejectsDelayedPriorDestinationAndAcceptsCurrentAdvance() { var state = new RuntimeWorldTransitState(); Assert.True(state.TryQueueTeleportStart(10)); Assert.True(state.ActivateQueuedTeleport()); state.EndTeleport(); Assert.True(state.TryQueueTeleportStart(11)); Assert.True(state.ActivateQueuedTeleport()); Assert.False(state.OfferTeleportDestination( Destination(OutdoorCell, 10, x: 10f), teleportTimestampAdvanced: true)); Assert.True(state.OfferTeleportDestination( Destination(OtherCell, 11, x: 11f), teleportTimestampAdvanced: true)); Assert.True(state.TryGetAcceptedTeleportDestination( out RuntimeTeleportDestination accepted)); Assert.Equal(11f, accepted.Position.Frame.Origin.X); Assert.Equal(OtherCell, accepted.CellId); } [Fact] public void PositionBeforeF751IsBufferedAndEqualFollowupCannotReplaceIt() { var state = new RuntimeWorldTransitState(); Assert.False(state.OfferTeleportDestination( Destination(OutdoorCell, 11, x: 110f), teleportTimestampAdvanced: true)); Assert.Equal(1, state.BufferedTeleportDestinationCount); Assert.True(state.TryQueueTeleportStart(11)); Assert.True(state.ActivateQueuedTeleport()); Assert.True(state.TryGetAcceptedTeleportDestination( out RuntimeTeleportDestination buffered)); Assert.Equal(110f, buffered.Position.Frame.Origin.X); Assert.False(state.OfferTeleportDestination( Destination(OtherCell, 11, x: 111f), teleportTimestampAdvanced: false)); Assert.True(state.TryGetAcceptedTeleportDestination(out buffered)); Assert.Equal(OutdoorCell, buffered.CellId); } [Fact] public void InactiveOrdinaryPositionIsNeverBuffered() { var state = new RuntimeWorldTransitState(); Assert.False(state.OfferTeleportDestination( Destination(OutdoorCell, 11), teleportTimestampAdvanced: false)); Assert.Equal(0, state.BufferedTeleportDestinationCount); Assert.True(state.TryQueueTeleportStart(11)); Assert.True(state.ActivateQueuedTeleport()); Assert.False(state.HasAcceptedTeleportDestination); } [Fact] public void DuplicateStartIsRejectedButSequenceWrapIsFresh() { var state = new RuntimeWorldTransitState(); Assert.True(state.TryQueueTeleportStart(ushort.MaxValue)); Assert.True(state.ActivateQueuedTeleport()); state.EndTeleport(); Assert.False(state.CanQueueTeleportStart(ushort.MaxValue)); Assert.False(state.TryQueueTeleportStart(ushort.MaxValue)); Assert.True(state.CanQueueTeleportStart(0)); Assert.True(state.TryQueueTeleportStart(0)); Assert.True(state.HasPendingTeleportStart); } [Fact] public void ExactHalfRangeUsesRetailLowerStampTieBreak() { var state = new RuntimeWorldTransitState(); Assert.True(state.TryQueueTeleportStart(0x8000)); Assert.True(state.ActivateQueuedTeleport()); state.EndTeleport(); Assert.True(state.CanQueueTeleportStart(0x0000)); Assert.True(state.TryQueueTeleportStart(0x0000)); } [Fact] public void PendingStartAcceptsEqualPositionUntilHostCanActivate() { var state = new RuntimeWorldTransitState(); Assert.True(state.TryQueueTeleportStart(11)); Assert.False(state.OfferTeleportDestination( Destination(OutdoorCell, 11, x: 110f), teleportTimestampAdvanced: false)); Assert.True(state.ActivateQueuedTeleport()); Assert.True(state.TryGetAcceptedTeleportDestination( out RuntimeTeleportDestination buffered)); Assert.Equal(110f, buffered.Position.Frame.Origin.X); Assert.True(state.IsTeleportActive); } [Fact] public void AdvancingPositionPrunesSkippedDestination() { var state = new RuntimeWorldTransitState(); Assert.False(state.OfferTeleportDestination( Destination(OutdoorCell, 11), teleportTimestampAdvanced: true)); Assert.False(state.OfferTeleportDestination( Destination(OtherCell, 12), teleportTimestampAdvanced: true)); Assert.Equal(1, state.BufferedTeleportDestinationCount); Assert.True(state.TryQueueTeleportStart(12)); Assert.True(state.ActivateQueuedTeleport()); Assert.True(state.TryGetAcceptedTeleportDestination( out RuntimeTeleportDestination buffered)); Assert.Equal(OtherCell, buffered.CellId); } [Fact] public void ObsoleteDestinationCannotSurviveSequenceWrap() { var state = new RuntimeWorldTransitState(); Assert.False(state.OfferTeleportDestination( Destination(OutdoorCell, ushort.MaxValue), teleportTimestampAdvanced: true)); Assert.False(state.OfferTeleportDestination( Destination(OtherCell, 0), teleportTimestampAdvanced: true)); Assert.True(state.TryQueueTeleportStart(0)); Assert.True(state.ActivateQueuedTeleport()); Assert.True(state.TryGetAcceptedTeleportDestination( out RuntimeTeleportDestination wrapped)); Assert.Equal(OtherCell, wrapped.CellId); state.EndTeleport(); Assert.True(state.TryQueueTeleportStart(0x7FFF)); Assert.True(state.ActivateQueuedTeleport()); state.EndTeleport(); Assert.True(state.TryQueueTeleportStart(0xFFFE)); Assert.True(state.ActivateQueuedTeleport()); state.EndTeleport(); Assert.True(state.TryQueueTeleportStart(ushort.MaxValue)); Assert.True(state.ActivateQueuedTeleport()); Assert.False(state.HasAcceptedTeleportDestination); } [Fact] public void PortalRevealClaimsOnlyExactAcceptedSequenceAndCell() { var state = new RuntimeWorldTransitState(); Assert.True(state.TryQueueTeleportStart(7)); Assert.True(state.ActivateQueuedTeleport()); Assert.True(state.OfferTeleportDestination( Destination(OutdoorCell, 7), teleportTimestampAdvanced: true)); Assert.False(state.TryBeginPortalReveal( 8, OutdoorCell, out _)); Assert.False(state.TryBeginPortalReveal( 7, OtherCell, out _)); Assert.Equal(RuntimePortalSnapshot.Idle.Generation, state.Snapshot.Generation); Assert.True(state.HasAcceptedTeleportDestination); Assert.True(state.TryBeginPortalReveal( 7, OutdoorCell, out long generation)); Assert.True(generation > 0); Assert.False(state.HasAcceptedTeleportDestination); Assert.True(state.CanPlacePortalDestination( generation, 7, OutdoorCell)); Assert.False(state.CanPlacePortalDestination( generation, 8, OutdoorCell)); Assert.False(state.CanPlacePortalDestination( generation, 7, OtherCell)); } [Fact] public void MaterializationRequiresExactGenerationSequenceAndCell() { var state = new RuntimeWorldTransitState(); long generation = BeginPortal(state, OutdoorCell, sequence: 17); Assert.True(state.AcknowledgeDestinationReadiness( Ready(generation, OutdoorCell))); Assert.False(state.AcknowledgePortalMaterialized( generation + 1, 17, OutdoorCell)); Assert.False(state.AcknowledgePortalMaterialized( generation, 18, OutdoorCell)); Assert.False(state.AcknowledgePortalMaterialized( generation, 17, OtherCell)); Assert.False(state.Snapshot.Materialized); Assert.True(state.AcknowledgePortalMaterialized( generation, 17, OutdoorCell)); Assert.True(state.Snapshot.Materialized); } [Fact] public void ResetSessionClearsCorrelationHistoryAndBufferedDestinations() { var state = new RuntimeWorldTransitState(); Assert.False(state.OfferTeleportDestination( Destination(OutdoorCell, 7), teleportTimestampAdvanced: true)); Assert.True(state.TryQueueTeleportStart(8)); state.ResetSession(); Assert.False(state.IsTeleportActive); Assert.False(state.HasPendingTeleportStart); Assert.False(state.HasAcceptedTeleportDestination); Assert.Equal(0, state.BufferedTeleportDestinationCount); Assert.True(state.TryQueueTeleportStart(8)); } private static long BeginPortal( RuntimeWorldTransitState state, uint cell, ushort sequence = 1) { Assert.True(state.TryQueueTeleportStart(sequence)); Assert.True(state.ActivateQueuedTeleport()); Assert.True(state.OfferTeleportDestination( Destination(cell, sequence), teleportTimestampAdvanced: true)); Assert.True(state.TryBeginPortalReveal( sequence, cell, out long generation)); return generation; } private static RuntimeTeleportDestination Destination( uint cell, ushort sequence, float x = 1f) => new( EntityGuid: 0x50000001u, InstanceSequence: 1, PositionSequence: 1, TeleportSequence: sequence, ForcePositionSequence: 1, Position: new Position( cell, new Vector3(x, 2f, 3f), Quaternion.Identity)); private static RuntimeDestinationReadiness Ready( long generation, uint cell) => new( generation, cell, IsIndoor: (cell & 0xFFFFu) >= 0x0100u, IsUnhydratable: false, RequiredRenderRadius: (cell & 0xFFFFu) >= 0x0100u ? 0 : 1, IsRenderNeighborhoodReady: true, AreCompositeTexturesReady: true, IsCollisionReady: true); }