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.BeginReveal(RuntimePortalKind.Login, 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 = state.BeginReveal(RuntimePortalKind.Portal, 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 = state.BeginReveal(RuntimePortalKind.Portal, OutdoorCell); Assert.True(state.AcknowledgeDestinationReadiness( Ready(generation, OutdoorCell))); Assert.True(state.AcknowledgeMaterialized( generation, 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.AcknowledgeMaterialized( generation, 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 = state.BeginReveal(RuntimePortalKind.Portal, OutdoorCell); Assert.False(state.AcknowledgeMaterialized( generation, 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.BeginReveal(RuntimePortalKind.Login, 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.BeginReveal(RuntimePortalKind.Login, 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.BeginReveal(RuntimePortalKind.Login, 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 = state.BeginReveal(RuntimePortalKind.Portal, 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(1, state.Snapshot.InvariantFailureCount); } [Fact] public void Completion_RejectsReorderedLoginAndPortalEdges() { var state = new RuntimeWorldTransitState(); long login = state.BeginReveal(RuntimePortalKind.Login, OutdoorCell); Assert.False(state.Complete(login)); Assert.False(state.Snapshot.Completed); long portal = state.BeginReveal(RuntimePortalKind.Portal, OtherCell); 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.BeginReveal(RuntimePortalKind.Login, OutdoorCell); long second = state.BeginReveal(RuntimePortalKind.Portal, OtherCell); Assert.True(second > first); Assert.False(state.AcknowledgeDestinationReadiness( Ready(first, OutdoorCell))); Assert.False(state.AcknowledgeMaterialized(first, 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 = state.BeginReveal(RuntimePortalKind.Portal, 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.AcknowledgeMaterialized( generation, 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 = state.BeginReveal(RuntimePortalKind.Portal, OutdoorCell); state.AcknowledgeDestinationReadiness( Ready(generation, OutdoorCell)); state.AcknowledgeMaterialized(generation, 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 = state.BeginReveal(RuntimePortalKind.Portal, 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 = state.BeginReveal(RuntimePortalKind.Portal, 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.AcknowledgeMaterialized( generation, OutdoorCell)); } [Fact] public void ResetSession_ClearsVisibleStateButNeverReusesGeneration() { var state = new RuntimeWorldTransitState(); long first = state.BeginReveal(RuntimePortalKind.Portal, OutdoorCell); state.ResetSession(); Assert.Equal(RuntimePortalSnapshot.Idle, state.Snapshot); Assert.True(state.IsWorldSimulationAvailable); long second = state.BeginReveal(RuntimePortalKind.Login, 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 = first.BeginReveal(RuntimePortalKind.Portal, OutdoorCell); long secondGeneration = second.BeginReveal(RuntimePortalKind.Login, OtherCell); first.AcknowledgeDestinationReadiness( Ready(firstGeneration, OutdoorCell)); first.AcknowledgeMaterialized(firstGeneration, 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 = state.BeginReveal(RuntimePortalKind.Portal, OutdoorCell); Assert.True(state.AcknowledgeDestinationReadiness( Ready(generation, OutdoorCell))); Assert.True(state.AcknowledgeMaterialized( generation, OutdoorCell)); Assert.True(state.Complete(generation)); Assert.True(state.Snapshot.Completed); Assert.True(state.IsWorldSimulationAvailable); Assert.True(state.DiagnosticFailureCount >= 4); Assert.IsType( state.LastDiagnosticFailure); } 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); }