using System.Reflection; using AcDream.App.Rendering; using AcDream.App.Streaming; using AcDream.App.Update; using AcDream.App.World; namespace AcDream.App.Tests.World; public sealed class UpdateFrameOrchestratorTests { [Fact] public void Tick_PreservesTheCompleteAcceptedPhaseGraph() { var calls = new List(); UpdateFrameOrchestrator frame = Create(calls); frame.Tick(new UpdateFrameInput(1.0 / 60.0)); Assert.Equal( [ "teardown", "clock", "streaming", "input", "objects", "network", "commands", "ordinary-reconcile", "liveness", "teleport", "auto-entry", "camera", "commit", ], calls); } [Fact] public void ConditionalReconciles_RemainAtTheirOwningEdges() { // The outer ownership oracle is complemented by the production // teleport and camera tests that pin both conditional reconcile edges. var calls = new List(); UpdateFrameOrchestrator frame = Create( calls, teleportPlace: true, inboundCreatedPlayer: true); frame.Tick(new UpdateFrameInput(1.0 / 60.0)); Assert.Equal( [ "teardown", "clock", "streaming", "input", "objects", "network", "commands", "ordinary-reconcile", "liveness", "teleport-place", "teleport-reconcile", "teleport-reveal", "auto-entry", "inbound-player-projection", "inbound-player-reconcile", "camera", "commit", ], calls); } [Theory] [InlineData(double.NaN)] [InlineData(double.NegativeInfinity)] [InlineData(double.PositiveInfinity)] [InlineData(-1.0)] [InlineData(0.0)] [InlineData(double.MaxValue)] public void InvalidSimulationDelta_BecomesZeroWithoutSuppressingOuterPhases( double hostDelta) { var calls = new List(); var observed = new FrameObservations(); UpdateFrameOrchestrator frame = Create(calls, observed: observed); frame.Tick(new UpdateFrameInput(hostDelta)); Assert.Equal( [ "teardown", "clock", "streaming", "input", "objects", "network", "commands", "ordinary-reconcile", "liveness", "teleport", "auto-entry", "camera", "commit", ], calls); Assert.Equal([0.0], observed.PublishedTimes); Assert.Equal([0.0], observed.Input.Select(value => value.SimulationDeltaSeconds)); Assert.Equal([0f], observed.LiveDeltas); Assert.Equal([0f], observed.TeleportDeltas); Assert.Equal([0.0], observed.Camera.Select(value => value.SimulationDeltaSeconds)); Assert.All( observed.Input.Concat(observed.Camera), timing => Assert.Equal(0.0, timing.ScriptTime)); } [Fact] public void Clock_AdvancesOnceAndPublishesTheSameTimeToEveryConsumer() { var calls = new List(); var observed = new FrameObservations(); UpdateFrameOrchestrator frame = Create(calls, observed: observed); frame.Tick(new UpdateFrameInput(0.25)); frame.Tick(new UpdateFrameInput(double.NaN)); frame.Tick(new UpdateFrameInput(0.5)); Assert.Equal([0.25, 0.25, 0.75], observed.PublishedTimes); Assert.Equal( [0.25, 0.25, 0.75], observed.Input.Select(value => value.ScriptTime)); Assert.Equal( [0.25, 0.25, 0.75], observed.Camera.Select(value => value.ScriptTime)); Assert.Equal([0.25f, 0f, 0.5f], observed.LiveDeltas); Assert.Equal([0.25f, 0f, 0.5f], observed.TeleportDeltas); Assert.Equal( [0.25, 0.0, 0.5], observed.Input.Select(value => value.SimulationDeltaSeconds)); Assert.Equal( [0.25, 0.0, 0.5], observed.Camera.Select(value => value.SimulationDeltaSeconds)); } [Fact] public void QuiescedWorld_FreezesScriptClockAndLivenessWhilePortalPhasesContinue() { var calls = new List(); var observed = new FrameObservations(); var availability = new WorldGenerationAvailabilityState(); availability.Begin(7); UpdateFrameOrchestrator frame = Create( calls, observed: observed, availability: availability); frame.Tick(new UpdateFrameInput(0.25)); frame.Tick(new UpdateFrameInput(0.25)); availability.End(7); frame.Tick(new UpdateFrameInput(0.25)); Assert.Equal([0.0, 0.0, 0.25], observed.PublishedTimes); Assert.Equal(1, calls.Count(call => call == "liveness")); Assert.Equal(3, calls.Count(call => call == "streaming")); Assert.Equal(3, calls.Count(call => call == "network")); Assert.Equal(3, calls.Count(call => call == "teleport")); Assert.Equal(3, calls.Count(call => call == "camera")); Assert.Equal(3, calls.Count(call => call == "commit")); Assert.Equal([0.25f, 0.25f, 0.25f], observed.LiveDeltas); Assert.Equal([0.25f, 0.25f, 0.25f], observed.TeleportDeltas); } [Fact] public void Clock_RejectsFiniteDeltaAboveTheSinglePrecisionConsumerRange() { double tooLarge = (double)float.MaxValue * 2.0; Assert.True(double.IsFinite(tooLarge)); Assert.Equal(0.0, UpdateFrameClock.NormalizeDeltaSeconds(tooLarge)); } [Fact] public void AggregateTeardownFailure_IsReportedAndRetriedNextFrame() { var calls = new List(); var teardown = new RecordingTeardown(calls) { Failure = new AggregateException(new InvalidOperationException("transient")), }; var failures = new RecordingFailureSink(); UpdateFrameOrchestrator frame = Create( calls, teardown: teardown, failureSink: failures); frame.Tick(new UpdateFrameInput(0.1)); teardown.Failure = null; frame.Tick(new UpdateFrameInput(0.1)); Assert.Equal(2, teardown.Attempts); Assert.Single(failures.Errors); string[] oneFrame = [ "teardown", "clock", "streaming", "input", "objects", "network", "commands", "ordinary-reconcile", "liveness", "teleport", "auto-entry", "camera", "commit", ]; Assert.Equal(oneFrame.Concat(oneFrame), calls); } [Fact] public void NonAggregateTeardownFailure_PropagatesBeforeTimeOrLaterPhases() { var calls = new List(); var teardown = new RecordingTeardown(calls) { Failure = new InvalidOperationException("fatal"), }; UpdateFrameOrchestrator frame = Create(calls, teardown: teardown); InvalidOperationException error = Assert.Throws( () => frame.Tick(new UpdateFrameInput(0.1))); Assert.Equal("fatal", error.Message); Assert.Equal(["teardown"], calls); } [Fact] public void OrchestrationTypes_UseOnlyTheExplicitTypedOwnerGraph() { Type[] expectedFieldTypes = [ typeof(IUpdateFrameTeardownPhase), typeof(IUpdateFrameFailureSink), typeof(UpdateFrameClock), typeof(IUpdateFrameScriptClockPublisher), typeof(IStreamingFramePhase), typeof(IGameplayInputFramePhase), typeof(IRetailLiveFramePhase), typeof(ILiveEntityLivenessFramePhase), typeof(ILocalPlayerTeleportFramePhase), typeof(IPlayerModeAutoEntryFramePhase), typeof(ICameraFramePhase), typeof(IUpdateFrameCommitPhase), typeof(IWorldGenerationAvailability), ]; FieldInfo[] fields = typeof(UpdateFrameOrchestrator).GetFields( BindingFlags.Instance | BindingFlags.NonPublic); Assert.Equal( expectedFieldTypes.OrderBy(type => type.FullName), fields.Select(field => field.FieldType).OrderBy(type => type.FullName)); Assert.All(fields, field => { Assert.NotEqual(typeof(GameWindow), field.FieldType); Assert.False(typeof(Delegate).IsAssignableFrom(field.FieldType)); }); Type[] phaseInterfaces = expectedFieldTypes.Where(type => type.IsInterface).ToArray(); Assert.DoesNotContain( phaseInterfaces, phaseInterface => phaseInterface.IsAssignableFrom(typeof(GameWindow))); Type[] productionPhaseOwners = typeof(GameWindow).Assembly.GetTypes() .Where(type => !type.IsAbstract && !type.IsInterface) .Where(type => phaseInterfaces.Any(contract => contract.IsAssignableFrom(type))) .ToArray(); foreach (Type owner in productionPhaseOwners) { FieldInfo[] ownerFields = owner.GetFields( BindingFlags.Instance | BindingFlags.NonPublic); Assert.DoesNotContain(ownerFields, field => field.FieldType == typeof(GameWindow)); Assert.DoesNotContain( ownerFields, field => typeof(Delegate).IsAssignableFrom(field.FieldType)); } Assert.DoesNotContain( typeof(GameWindow).GetFields(BindingFlags.Instance | BindingFlags.NonPublic), field => field.Name == "_physicsScriptGameTime"); } [Fact] public void PhysicsScriptClockConsumers_RetainTheTypedSourceNotGameWindowClosures() { Type[] consumers = [ typeof(DatLiveEntityProjectionMaterializer), typeof(AcDream.App.Physics.LiveEntityNetworkUpdateController), ]; foreach (Type consumer in consumers) { FieldInfo clock = Assert.Single( consumer.GetFields(BindingFlags.Instance | BindingFlags.NonPublic), field => field.Name == "_gameTime"); Assert.Equal(typeof(IPhysicsScriptTimeSource), clock.FieldType); Assert.DoesNotContain( consumer.GetFields(BindingFlags.Instance | BindingFlags.NonPublic), field => field.FieldType == typeof(GameWindow)); } Assert.False(typeof(IPhysicsScriptTimeSource).IsAssignableFrom(typeof(GameWindow))); } [Fact] public void ProductionFrame_PublishesPhysicsScriptTimeExactlyOnce() { string root = FindRepoRoot(); string source = File.ReadAllText(Path.Combine( root, "src", "AcDream.App", "Rendering", "GameWindow.cs")); string adapters = File.ReadAllText(Path.Combine( root, "src", "AcDream.App", "Update", "UpdateFrameRuntimeAdapters.cs")); string frameRoot = File.ReadAllText(Path.Combine( root, "src", "AcDream.App", "Composition", "FrameRootComposition.cs")); Assert.Equal(0, CountOccurrences(source, "PublishTime(")); Assert.Equal(1, CountOccurrences(adapters, "_runner.PublishTime(")); Assert.Contains("new PhysicsScriptClockPublisher(", frameRoot, StringComparison.Ordinal); } [Fact] public void ExtractedLiveObjectSource_PinsRetailAndRegisteredAdaptationOrder() { string source = File.ReadAllText(Path.Combine( FindRepoRoot(), "src", "AcDream.App", "Update", "LiveObjectFrameController.cs")); AssertAppearsInOrder( source, "_localPlayerFrame.AdvanceBeforeNetwork", "_selectionInteractions?.DrainOutbound", "_animations.Tick", "_staticAnimations.Tick", "_animationPresenter.Present", "_equippedChildren.Tick", "_staticAnimations.ProcessHooks", "_effects.Tick"); AssertAppearsInOrder( source, "_translucencyFades.AdvanceAll", "_animationHooks.Drain", "_entityEffects.RefreshLiveOwnerPoses", "_particleSink.RefreshAttachedEmitters", "_lights.Refresh", "_particleVisibility.Apply", "_particles.Tick", "_scripts.Tick"); AssertAppearsInOrder( source, "public void Reconcile()", "_entityEffects.RefreshLiveOwnerPoses", "_equippedChildren.ReconcileSpatialMutations", "_particleSink.RefreshAttachedEmitters", "_lights.Refresh"); Assert.Equal(1, CountOccurrences(source, "_staticAnimations.Tick(")); Assert.Equal(1, CountOccurrences(source, "_staticAnimations.ProcessHooks(")); Assert.Equal(1, CountOccurrences(source, "_effects.Tick(")); Assert.Equal(1, CountOccurrences(source, "_particles.Tick(")); Assert.Equal(1, CountOccurrences(source, "_scripts.Tick(")); } [Fact] public void GameWindow_ComposesTheLiveFrameOwnersWithoutOwningTheirBodies() { string source = File.ReadAllText(Path.Combine( FindRepoRoot(), "src", "AcDream.App", "Rendering", "GameWindow.cs")); string livePresentation = File.ReadAllText(Path.Combine( FindRepoRoot(), "src", "AcDream.App", "Composition", "LivePresentationComposition.cs")); string sessionPlayer = File.ReadAllText(Path.Combine( FindRepoRoot(), "src", "AcDream.App", "Composition", "SessionPlayerComposition.cs")); string frameRoot = File.ReadAllText(Path.Combine( FindRepoRoot(), "src", "AcDream.App", "Composition", "FrameRootComposition.cs")); Assert.Contains("new LiveObjectFrameController(", sessionPlayer); Assert.Contains("new LiveSpatialPresentationReconciler(", sessionPlayer); Assert.Contains("new RetailLiveFrameCoordinator(", frameRoot); Assert.DoesNotContain("AdvanceLiveObjectRuntime", source, StringComparison.Ordinal); Assert.DoesNotContain("ReconcileLiveObjectSpatialPresentation", source, StringComparison.Ordinal); Assert.DoesNotContain("ILiveAnimationPresentationContext", source, StringComparison.Ordinal); } [Fact] public void GameWindow_DelegatesTheCompleteStreamingFrameBody() { string source = File.ReadAllText(Path.Combine( FindRepoRoot(), "src", "AcDream.App", "Rendering", "GameWindow.cs")); string sessionPlayer = File.ReadAllText(Path.Combine( FindRepoRoot(), "src", "AcDream.App", "Composition", "SessionPlayerComposition.cs")); Assert.Contains("new StreamingFrameController(", sessionPlayer); Assert.DoesNotContain("_streamingFrame", source, StringComparison.Ordinal); Assert.Equal(1, CountOccurrences( source, "_frameGraphs.Tick(")); Assert.DoesNotContain("_streamingController.Tick(observerCx", source, StringComparison.Ordinal); Assert.DoesNotContain("DungeonStreamingGate.Compute", source, StringComparison.Ordinal); Assert.DoesNotContain("DrainRescued()", source, StringComparison.Ordinal); } [Fact] public void GameWindow_DelegatesTheCompleteGameplayInputFrameBody() { string source = File.ReadAllText(Path.Combine( FindRepoRoot(), "src", "AcDream.App", "Rendering", "GameWindow.cs")); string sessionPlayer = File.ReadAllText(Path.Combine( FindRepoRoot(), "src", "AcDream.App", "Composition", "SessionPlayerComposition.cs")); Assert.Contains("new GameplayInputFrameController(", sessionPlayer); Assert.DoesNotContain("_gameplayInputFrame!.Tick", source, StringComparison.Ordinal); Assert.DoesNotContain("_inputDispatcher?.Tick()", source, StringComparison.Ordinal); Assert.DoesNotContain("TryTakeRawSample", source, StringComparison.Ordinal); Assert.DoesNotContain("_combatAttackController?.Tick()", source, StringComparison.Ordinal); Assert.DoesNotContain("CaptureMovementInput", source, StringComparison.Ordinal); Assert.DoesNotContain("EndMouseLookAndRestoreCursor", source, StringComparison.Ordinal); Assert.DoesNotContain("HideCursorForMouseLook", source, StringComparison.Ordinal); Assert.DoesNotContain("RestoreCursorAfterMouseLook", source, StringComparison.Ordinal); Assert.DoesNotContain("CanStartLiveCombatAttack", source, StringComparison.Ordinal); Assert.DoesNotContain("SendLiveCombatAttack", source, StringComparison.Ordinal); Assert.DoesNotContain("PreparePlayerForAttackRequest", source, StringComparison.Ordinal); Assert.DoesNotContain("DumpMovementTruthOutbound", source, StringComparison.Ordinal); Assert.DoesNotContain("DumpMovementTruthServerEcho", source, StringComparison.Ordinal); Assert.DoesNotContain("wantCaptureMouse: ()", source, StringComparison.Ordinal); Assert.DoesNotContain( "_gameplayInputFrame?.EndMouseLook", source, StringComparison.Ordinal); string pointerSource = File.ReadAllText(Path.Combine( FindRepoRoot(), "src", "AcDream.App", "Input", "CameraPointerInputController.cs")); Assert.Contains("_gameplayFrame?.EndMouseLook();", pointerSource, StringComparison.Ordinal); string teleportSource = File.ReadAllText(Path.Combine( FindRepoRoot(), "src", "AcDream.App", "Streaming", "LocalPlayerTeleportController.cs")); AssertAppearsInOrder( teleportSource, "_transit.CanBegin(teleportSequence)", "_input.EndMouseLook();", "_transit.QueueStart(teleportSequence)"); string playerModeSource = File.ReadAllText(Path.Combine( FindRepoRoot(), "src", "AcDream.App", "Input", "PlayerModeController.cs")); Assert.Contains("_input.EndMouseLook();", playerModeSource, StringComparison.Ordinal); AssertAppearsInOrder( source, "private void OnFocusChanged(bool focused)", "_cameraPointerInput?.HandleFocusChanged(focused);"); } [Fact] public void GameWindow_DelegatesTheCompleteLocalTeleportLifetime() { string root = FindRepoRoot(); string source = File.ReadAllText(Path.Combine( root, "src", "AcDream.App", "Rendering", "GameWindow.cs")); string networkSource = File.ReadAllText(Path.Combine( root, "src", "AcDream.App", "Physics", "LiveEntityNetworkUpdateController.cs")); string sessionPlayer = File.ReadAllText(Path.Combine( root, "src", "AcDream.App", "Composition", "SessionPlayerComposition.cs")); string frameRoot = File.ReadAllText(Path.Combine( root, "src", "AcDream.App", "Composition", "FrameRootComposition.cs")); Assert.Contains( "new LocalPlayerTeleportController(", sessionPlayer, StringComparison.Ordinal); Assert.DoesNotContain("_localPlayerTeleport!.Tick", source, StringComparison.Ordinal); Assert.DoesNotContain("_teleportTransit", source, StringComparison.Ordinal); Assert.DoesNotContain("_teleportAnim", source, StringComparison.Ordinal); Assert.DoesNotContain("_teleportViewPlane", source, StringComparison.Ordinal); Assert.DoesNotContain("_pendingTeleport", source, StringComparison.Ordinal); Assert.DoesNotContain("AimTeleportDestination", source, StringComparison.Ordinal); Assert.DoesNotContain("ResetTeleportTransitState", source, StringComparison.Ordinal); Assert.DoesNotContain("PlaceTeleportArrival", source, StringComparison.Ordinal); Assert.DoesNotContain("TryActivatePendingTeleportPresentation", source, StringComparison.Ordinal); Assert.DoesNotContain("Action", networkSource, StringComparison.Ordinal); Assert.Contains("ILocalPlayerTeleportNetworkSink", networkSource, StringComparison.Ordinal); AssertAppearsInOrder( frameRoot, "new LiveEntityLivenessFramePhase(", "session.LocalTeleport,", "new PlayerModeAutoEntryFramePhase(", "cameraFrame,", "live.WorldAvailability);"); } [Fact] public void GameplayInputOwnersUseTypedSeamsWithoutGameWindowBackReferences() { Type[] owners = [ typeof(AcDream.App.Input.GameplayInputFrameController), typeof(AcDream.App.Input.DispatcherMovementInputSource), typeof(AcDream.App.Input.MouseLookController), ]; foreach (Type owner in owners) { FieldInfo[] fields = owner.GetFields( BindingFlags.Instance | BindingFlags.NonPublic); Assert.DoesNotContain(fields, field => field.FieldType == typeof(GameWindow)); Assert.DoesNotContain( fields, field => typeof(Delegate).IsAssignableFrom(field.FieldType)); } Assert.DoesNotContain( typeof(AcDream.App.Input.MouseLookController).GetFields( BindingFlags.Instance | BindingFlags.NonPublic), field => field.FieldType == typeof(Silk.NET.Input.IMouse)); FieldInfo combatOperations = Assert.Single( typeof(AcDream.Runtime.Gameplay.RuntimeCombatAttackState).GetFields( BindingFlags.Instance | BindingFlags.NonPublic), field => field.Name == "_operations"); Assert.Equal( typeof(AcDream.Runtime.Gameplay.IRuntimeCombatAttackOperations), combatOperations.FieldType); Assert.DoesNotContain( typeof(AcDream.App.Combat.LiveCombatAttackOperations).GetFields( BindingFlags.Instance | BindingFlags.NonPublic), field => typeof(Delegate).IsAssignableFrom(field.FieldType)); FieldInfo combatTargets = Assert.Single( typeof(AcDream.App.Combat.LiveCombatAttackOperations).GetFields( BindingFlags.Instance | BindingFlags.NonPublic), field => field.Name == "_targets"); Assert.Equal( typeof(AcDream.App.Combat.ICombatAttackTargetSource), combatTargets.FieldType); Assert.DoesNotContain( typeof(AcDream.App.Combat.CombatAttackTargetSource).GetFields( BindingFlags.Instance | BindingFlags.NonPublic), field => typeof(Delegate).IsAssignableFrom(field.FieldType)); Assert.DoesNotContain( typeof(AcDream.App.Combat.CombatAttackTargetSource).GetFields( BindingFlags.Instance | BindingFlags.NonPublic), field => field.FieldType == typeof(AcDream.App.Interaction.SelectionInteractionController)); FieldInfo outboundDiagnostics = Assert.Single( typeof(LocalPlayerOutboundController).GetFields( BindingFlags.Instance | BindingFlags.NonPublic), field => field.Name == "_diagnostic"); Assert.Equal( typeof(IMovementTruthDiagnosticSink), outboundDiagnostics.FieldType); Assert.DoesNotContain( typeof(AcDream.App.Input.MovementTruthDiagnosticController).GetFields( BindingFlags.Instance | BindingFlags.NonPublic), field => typeof(Delegate).IsAssignableFrom(field.FieldType)); FieldInfo approachCompletions = Assert.Single( typeof(AcDream.App.Input.PlayerModeController).GetFields( BindingFlags.Instance | BindingFlags.NonPublic), field => field.Name == "_approachCompletions"); Assert.Equal( typeof(AcDream.App.Interaction.IPlayerApproachCompletionLifetimeOwner), approachCompletions.FieldType); Assert.DoesNotContain( typeof(AcDream.App.Input.PlayerModeController).GetFields( BindingFlags.Instance | BindingFlags.NonPublic), field => field.FieldType == typeof(AcDream.App.Interaction.SelectionInteractionController)); Assert.DoesNotContain( typeof(AcDream.App.Interaction.PlayerApproachCompletionState).GetFields( BindingFlags.Instance | BindingFlags.NonPublic), field => typeof(Delegate).IsAssignableFrom(field.FieldType)); string playerModeSource = File.ReadAllText(Path.Combine( FindRepoRoot(), "src", "AcDream.App", "Input", "PlayerModeController.cs")); AssertAppearsInOrder( playerModeSource, "controller.PreparePositionForCommit(", "_camera.EnterChaseMode(legacyCamera, retailCamera);", "EntityPhysicsHostComposition.SelectStableHostWithoutRebind(", "_shadow.SyncPose(", "EntityPhysicsHostComposition.InstallOrRebind(", "playerEntity.SetPosition(initial.Position);", "controller.CommitPreparedPosition();", "_controllerSlot.Controller = controller;", "_mode.IsPlayerMode = true;"); Assert.Contains("_shadow.Restore(playerEntity, priorShadow);", playerModeSource, StringComparison.Ordinal); Assert.Contains("_camera.RestoreState(priorCamera);", playerModeSource, StringComparison.Ordinal); string mouseLookSource = File.ReadAllText(Path.Combine( FindRepoRoot(), "src", "AcDream.App", "Input", "MouseLookController.cs")); AssertAppearsInOrder( mouseLookSource, "controller?.StopMouseDrift", "retail.FilterMouseDelta", "_state.ApplyDelta"); string localPlayerSource = File.ReadAllText(Path.Combine( FindRepoRoot(), "src", "AcDream.App", "Input", "RetailLocalPlayerFrameController.cs")); Assert.DoesNotContain("Func", localPlayerSource, StringComparison.Ordinal); Assert.Contains("IMovementInputSource", localPlayerSource, StringComparison.Ordinal); } [Fact] public void CameraAndLocalPlayerFrameOwnersUseTypedSeamsWithoutWindowCallbacks() { Type[] owners = [ typeof(AcDream.App.Rendering.CameraFrameController), typeof(AcDream.App.Input.RetailLocalPlayerFrameController), typeof(AcDream.App.Input.LocalPlayerProjectionController), typeof(AcDream.App.Input.LiveLocalPlayerFrameRuntime), typeof(AcDream.App.Input.LiveLocalPlayerProjectionRuntime), typeof(AcDream.App.Combat.CombatCameraTargetSource), ]; foreach (Type owner in owners) { FieldInfo[] fields = owner.GetFields( BindingFlags.Instance | BindingFlags.NonPublic); Assert.DoesNotContain(fields, field => field.FieldType == typeof(GameWindow)); Assert.DoesNotContain( fields, field => typeof(Delegate).IsAssignableFrom(field.FieldType)); } string root = FindRepoRoot(); string source = File.ReadAllText(Path.Combine( root, "src", "AcDream.App", "Rendering", "GameWindow.cs")); Assert.Equal(1, CountOccurrences( source, "_frameGraphs.Tick(")); Assert.DoesNotContain("CanAdvanceLocalPlayer", source, StringComparison.Ordinal); Assert.DoesNotContain("GetCombatCameraTargetPoint()", source, StringComparison.Ordinal); Assert.DoesNotContain("_cameraController.Fly.Update(", source, StringComparison.Ordinal); Assert.DoesNotContain("_localPlayerFrame.TryGetPresentationAfterNetwork", source, StringComparison.Ordinal); Assert.DoesNotContain("_cameraFrame", source, StringComparison.Ordinal); string cameraSource = File.ReadAllText(Path.Combine( root, "src", "AcDream.App", "Rendering", "CameraFrameController.cs")); AssertAppearsInOrder( cameraSource, "_localFrame.TryGetPresentationAfterNetwork", "_spatialReconciler.Reconcile();", "legacy.Update(", "retail?.Update("); } [Fact] public void GameWindow_OnUpdateOwnsOnlyProfilingAndOneOrchestratorTick() { string source = File.ReadAllText(Path.Combine( FindRepoRoot(), "src", "AcDream.App", "Rendering", "GameWindow.cs")); Assert.Equal(1, CountOccurrences( source, "_frameGraphs.Tick(")); Assert.DoesNotContain("_updateFrameClock.Advance(", source, StringComparison.Ordinal); Assert.DoesNotContain("_liveFrameCoordinator", source, StringComparison.Ordinal); Assert.DoesNotContain("_liveEntityLiveness?.Tick", source, StringComparison.Ordinal); Assert.DoesNotContain("_playerModeAutoEntry?.TryEnter", source, StringComparison.Ordinal); AssertAppearsInOrder( source, "private void OnUpdate(double dt)", "_frameProfiler.BeginStage(", "_frameGraphs.Tick(", "private void OnRender(double deltaSeconds)"); } [Fact] public void ProductionFrameAdaptersRetainTypedOwnersWithoutWindowCallbacks() { Type[] adapters = [ typeof(LiveEntityTeardownFramePhase), typeof(ConsoleUpdateFrameFailureSink), typeof(PhysicsScriptClockPublisher), typeof(LiveEntityLivenessFramePhase), typeof(PlayerModeAutoEntryFramePhase), ]; foreach (Type adapter in adapters) { FieldInfo[] fields = adapter.GetFields( BindingFlags.Instance | BindingFlags.NonPublic); Assert.DoesNotContain(fields, field => field.FieldType == typeof(GameWindow)); Assert.DoesNotContain( fields, field => typeof(Delegate).IsAssignableFrom(field.FieldType)); } FieldInfo clock = Assert.Single( typeof(LiveEntityLivenessFramePhase).GetFields( BindingFlags.Instance | BindingFlags.NonPublic), field => field.Name == "_clock"); Assert.Equal(typeof(IClientMonotonicTimeSource), clock.FieldType); FieldInfo teardownRuntime = Assert.Single( typeof(LiveEntityTeardownFramePhase).GetFields( BindingFlags.Instance | BindingFlags.NonPublic)); Assert.Equal(typeof(LiveEntityRuntime), teardownRuntime.FieldType); Type[] typedProductionOwners = [ typeof(LiveEntityLivenessController), typeof(AcDream.App.Input.LivePlayerModeAutoEntryContext), typeof(LiveSessionLocalPhysicsTimestampPublisher), typeof(AcDream.App.Physics.LiveEntityNetworkUpdateController), typeof(AcDream.App.Rendering.LiveEntityPartArrayLifecycle), typeof(AcDream.App.Physics.RemoteShadowPlacementSynchronizer), typeof(AcDream.App.Physics.RemoteTeleportPlacementPresentation), typeof(AcDream.App.Net.LiveEntitySessionController), ]; foreach (Type owner in typedProductionOwners) { FieldInfo[] fields = owner.GetFields( BindingFlags.Instance | BindingFlags.NonPublic); Assert.DoesNotContain(fields, field => field.FieldType == typeof(GameWindow)); Assert.DoesNotContain( fields, field => typeof(Delegate).IsAssignableFrom(field.FieldType)); } FieldInfo originIdentity = Assert.Single( typeof(LiveEntityWorldOriginCoordinator).GetFields( BindingFlags.Instance | BindingFlags.NonPublic), field => field.Name == "_identity"); Assert.Equal( typeof(AcDream.App.Input.ILocalPlayerIdentitySource), originIdentity.FieldType); string source = File.ReadAllText(Path.Combine( FindRepoRoot(), "src", "AcDream.App", "Rendering", "GameWindow.cs")); string livePresentation = File.ReadAllText(Path.Combine( FindRepoRoot(), "src", "AcDream.App", "Composition", "LivePresentationComposition.cs")); string sessionRuntime = File.ReadAllText(Path.Combine( FindRepoRoot(), "src", "AcDream.App", "Net", "LiveSessionRuntimeFactory.cs")); Assert.DoesNotContain("PublishLocalPhysicsTimestamps", source, StringComparison.Ordinal); Assert.DoesNotContain("LoginWorldReady", source, StringComparison.Ordinal); Assert.DoesNotContain("candidate => _liveEntityHydration.OnPrune", source, StringComparison.Ordinal); Assert.DoesNotContain("CreateLiveEntitySessionSink", source, StringComparison.Ordinal); Assert.DoesNotContain("private System.Numerics.Vector3 CellLocalForSeed", source, StringComparison.Ordinal); Assert.DoesNotContain("OnPlayScriptReceived", source, StringComparison.Ordinal); Assert.Contains("d.WorldOrigin.GetCenter", livePresentation, StringComparison.Ordinal); Assert.Contains("d.WorldOrigin.CellLocalForSeed", livePresentation, StringComparison.Ordinal); Assert.DoesNotContain("CreateLiveSessionEventRouter", source, StringComparison.Ordinal); Assert.Contains("_world.EntitySession.CreateSink()", sessionRuntime, StringComparison.Ordinal); Assert.DoesNotContain("GameWindow", sessionRuntime, StringComparison.Ordinal); } private static UpdateFrameOrchestrator Create( List calls, RecordingTeardown? teardown = null, RecordingFailureSink? failureSink = null, FrameObservations? observed = null, bool teleportPlace = false, bool inboundCreatedPlayer = false, IWorldGenerationAvailability? availability = null) { teardown ??= new RecordingTeardown(calls); failureSink ??= new RecordingFailureSink(); return new UpdateFrameOrchestrator( teardown, failureSink, new UpdateFrameClock(), new RecordingClockPublisher(calls, observed), new RecordingStreaming(calls), new RecordingInput(calls, observed), new RecordingLiveFrame(calls, observed), new RecordingLiveness(calls), new RecordingTeleport(calls, observed, teleportPlace), new RecordingAutoEntry(calls), new RecordingCamera(calls, observed, inboundCreatedPlayer), new RecordingCommit(calls), availability); } private sealed class RecordingTeardown(List calls) : IUpdateFrameTeardownPhase { public Exception? Failure { get; set; } public int Attempts { get; private set; } public void RetryPendingTeardowns() { calls.Add("teardown"); Attempts++; if (Failure is not null) throw Failure; } } private sealed class RecordingFailureSink : IUpdateFrameFailureSink { public List Errors { get; } = []; public void ReportTeardownFailure(AggregateException error) => Errors.Add(error); } private sealed class RecordingClockPublisher( List calls, FrameObservations? observed) : IUpdateFrameScriptClockPublisher { public void PublishTime(double scriptTime) { calls.Add("clock"); observed?.PublishedTimes.Add(scriptTime); } } private sealed class RecordingStreaming(List calls) : IStreamingFramePhase { public void Tick() => calls.Add("streaming"); } private sealed class RecordingInput( List calls, FrameObservations? observed) : IGameplayInputFramePhase { public void Tick(UpdateFrameTiming timing) { calls.Add("input"); observed?.Input.Add(timing); } } private sealed class RecordingLiveFrame( List calls, FrameObservations? observed) : IRetailLiveFramePhase { public void Tick(float deltaSeconds) { observed?.LiveDeltas.Add(deltaSeconds); calls.Add("objects"); calls.Add("network"); calls.Add("commands"); calls.Add("ordinary-reconcile"); } } private sealed class RecordingLiveness(List calls) : ILiveEntityLivenessFramePhase { public void Tick() => calls.Add("liveness"); } private sealed class RecordingTeleport( List calls, FrameObservations? observed, bool place) : ILocalPlayerTeleportFramePhase { public void Tick(float deltaSeconds) { observed?.TeleportDeltas.Add(deltaSeconds); if (!place) { calls.Add("teleport"); return; } calls.Add("teleport-place"); calls.Add("teleport-reconcile"); calls.Add("teleport-reveal"); } } private sealed class RecordingAutoEntry(List calls) : IPlayerModeAutoEntryFramePhase { public void TryEnter() => calls.Add("auto-entry"); } private sealed class RecordingCamera( List calls, FrameObservations? observed, bool inboundCreatedPlayer) : ICameraFramePhase { public void Tick(UpdateFrameTiming timing) { if (inboundCreatedPlayer) { calls.Add("inbound-player-projection"); calls.Add("inbound-player-reconcile"); } calls.Add("camera"); observed?.Camera.Add(timing); } } private sealed class RecordingCommit(List calls) : IUpdateFrameCommitPhase { public void Commit() => calls.Add("commit"); } private sealed class FrameObservations { public List PublishedTimes { get; } = []; public List Input { get; } = []; public List LiveDeltas { get; } = []; public List TeleportDeltas { get; } = []; public List Camera { get; } = []; } private static string FindRepoRoot() { DirectoryInfo? directory = new(AppContext.BaseDirectory); while (directory is not null) { if (File.Exists(Path.Combine(directory.FullName, "AcDream.slnx"))) return directory.FullName; directory = directory.Parent; } throw new DirectoryNotFoundException("Could not find AcDream.slnx."); } private static void AssertAppearsInOrder(string source, params string[] markers) { int previous = -1; foreach (string marker in markers) { int current = source.IndexOf(marker, previous + 1, StringComparison.Ordinal); Assert.True(current >= 0, $"Missing source marker: {marker}"); Assert.True(current > previous, $"Out-of-order source marker: {marker}"); previous = current; } } private static int CountOccurrences(string source, string marker) => source.Split(marker, StringSplitOptions.None).Length - 1; }