/// <summary> /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Update(GameTime gameTime) { Timing.TotalTime = gameTime.TotalGameTime.TotalSeconds; Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds; int updateIterations = (int)Math.Floor(Timing.Accumulator / Timing.Step); if (Timing.Accumulator > Timing.Step * 6.0) { //if the game's running too slowly then we have no choice //but to skip a bunch of steps //otherwise it snowballs and becomes unplayable Timing.Accumulator = Timing.Step; } CrossThread.ProcessTasks(); PlayerInput.UpdateVariable(); bool paused = true; if (SoundManager != null) { if (WindowActive || !Config.MuteOnFocusLost) { SoundManager.ListenerGain = SoundManager.CompressionDynamicRangeGain; } else { SoundManager.ListenerGain = 0.0f; } } while (Timing.Accumulator >= Timing.Step) { Stopwatch sw = new Stopwatch(); sw.Start(); fixedTime.IsRunningSlowly = gameTime.IsRunningSlowly; TimeSpan addTime = new TimeSpan(0, 0, 0, 0, 16); fixedTime.ElapsedGameTime = addTime; fixedTime.TotalGameTime.Add(addTime); base.Update(fixedTime); PlayerInput.Update(Timing.Step); if (loadingScreenOpen) { //reset accumulator if loading // -> less choppy loading screens because the screen is rendered after each update // -> no pause caused by leftover time in the accumulator when starting a new shift GameMain.ResetFrameTime(); if (!TitleScreen.PlayingSplashScreen) { SoundPlayer.Update((float)Timing.Step); } if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen && (!waitForKeyHit || ((PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.LeftButtonClicked()) && WindowActive))) { loadingScreenOpen = false; } if (!hasLoaded && !CoroutineManager.IsCoroutineRunning(loadingCoroutine)) { string errMsg = "Loading was interrupted due to an error"; if (loadingCoroutine.Exception != null) { errMsg += ": " + loadingCoroutine.Exception.Message + "\n" + loadingCoroutine.Exception.StackTrace; } throw new Exception(errMsg); } } else if (hasLoaded) { if (ConnectLobby != 0) { if (Client != null) { Client.Disconnect(); Client = null; GameMain.MainMenuScreen.Select(); } Steam.SteamManager.JoinLobby(ConnectLobby, true); ConnectLobby = 0; ConnectEndpoint = null; ConnectName = null; } else if (!string.IsNullOrWhiteSpace(ConnectEndpoint)) { if (Client != null) { Client.Disconnect(); Client = null; GameMain.MainMenuScreen.Select(); } UInt64 serverSteamId = SteamManager.SteamIDStringToUInt64(ConnectEndpoint); Client = new GameClient(SteamManager.GetUsername(), serverSteamId != 0 ? null : ConnectEndpoint, serverSteamId, string.IsNullOrWhiteSpace(ConnectName) ? ConnectEndpoint : ConnectName); ConnectLobby = 0; ConnectEndpoint = null; ConnectName = null; } SoundPlayer.Update((float)Timing.Step); if (PlayerInput.KeyHit(Keys.Escape) && WindowActive) { // Check if a text input is selected. if (GUI.KeyboardDispatcher.Subscriber != null) { if (GUI.KeyboardDispatcher.Subscriber is GUITextBox textBox) { textBox.Deselect(); } GUI.KeyboardDispatcher.Subscriber = null; } //if a verification prompt (are you sure you want to x) is open, close it else if (GUIMessageBox.VisibleBox as GUIMessageBox != null && GUIMessageBox.VisibleBox.UserData as string == "verificationprompt") { ((GUIMessageBox)GUIMessageBox.VisibleBox).Close(); } else if (Tutorial.Initialized && Tutorial.ContentRunning) { (GameSession.GameMode as TutorialMode).Tutorial.CloseActiveContentGUI(); } else if (GUI.PauseMenuOpen) { GUI.TogglePauseMenu(); } else if ((Character.Controlled?.SelectedConstruction == null || !Character.Controlled.SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null)) && Inventory.SelectedSlot == null && CharacterHealth.OpenHealthWindow == null) { // Otherwise toggle pausing, unless another window/interface is open. GUI.TogglePauseMenu(); } } GUI.ClearUpdateList(); paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen || Tutorial.ContentRunning) && (NetworkMember == null || !NetworkMember.GameStarted); #if !DEBUG if (NetworkMember == null && !WindowActive && !paused && true && Screen.Selected != MainMenuScreen && Config.PauseOnFocusLost) { GUI.TogglePauseMenu(); paused = true; } #endif Screen.Selected.AddToGUIUpdateList(); if (Client != null) { Client.AddToGUIUpdateList(); } DebugConsole.AddToGUIUpdateList(); DebugConsole.Update(this, (float)Timing.Step); paused = paused || (DebugConsole.IsOpen && (NetworkMember == null || !NetworkMember.GameStarted)); if (!paused) { Screen.Selected.Update(Timing.Step); } else if (Tutorial.Initialized && Tutorial.ContentRunning) { (GameSession.GameMode as TutorialMode).Update((float)Timing.Step); } if (NetworkMember != null) { NetworkMember.Update((float)Timing.Step); } GUI.Update((float)Timing.Step); } CoroutineManager.Update((float)Timing.Step, paused ? 0.0f : (float)Timing.Step); SteamManager.Update((float)Timing.Step); SoundManager?.Update(); Timing.Accumulator -= Timing.Step; sw.Stop(); PerformanceCounter.AddElapsedTicks("Update total", sw.ElapsedTicks); PerformanceCounter.UpdateTimeGraph.Update(sw.ElapsedTicks / (float)TimeSpan.TicksPerMillisecond); PerformanceCounter.UpdateIterationsGraph.Update(updateIterations); } if (!paused) { Timing.Alpha = Timing.Accumulator / Timing.Step; } }
/// <summary> /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Update(GameTime gameTime) { Timing.TotalTime = gameTime.TotalGameTime.TotalSeconds; Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds; PlayerInput.UpdateVariable(); bool paused = true; while (Timing.Accumulator >= Timing.Step) { fixedTime.IsRunningSlowly = gameTime.IsRunningSlowly; TimeSpan addTime = new TimeSpan(0, 0, 0, 0, 16); fixedTime.ElapsedGameTime = addTime; fixedTime.TotalGameTime.Add(addTime); base.Update(fixedTime); PlayerInput.Update(Timing.Step); if (loadingScreenOpen) { //reset accumulator if loading // -> less choppy loading screens because the screen is rendered after each update // -> no pause caused by leftover time in the accumulator when starting a new shift Timing.Accumulator = 0.0f; if (TitleScreen.LoadState >= 100.0f && (!waitForKeyHit || PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.LeftButtonClicked())) { loadingScreenOpen = false; } if (!hasLoaded && !CoroutineManager.IsCoroutineRunning(loadingCoroutine)) { throw new Exception("Loading was interrupted due to an error"); } } else if (hasLoaded) { SoundPlayer.Update((float)Timing.Step); if (PlayerInput.KeyHit(Keys.Escape)) { GUI.TogglePauseMenu(); } GUIComponent.ClearUpdateList(); paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen) && (NetworkMember == null || !NetworkMember.GameStarted); if (!paused) { Screen.Selected.AddToGUIUpdateList(); } if (NetworkMember != null) { NetworkMember.AddToGUIUpdateList(); } GUI.AddToGUIUpdateList(); DebugConsole.AddToGUIUpdateList(); GUIComponent.UpdateMouseOn(); DebugConsole.Update(this, (float)Timing.Step); paused = paused || (DebugConsole.IsOpen && (NetworkMember == null || !NetworkMember.GameStarted)); if (!paused) { Screen.Selected.Update(Timing.Step); } if (NetworkMember != null) { NetworkMember.Update((float)Timing.Step); } GUI.Update((float)Timing.Step); } CoroutineManager.Update((float)Timing.Step, paused ? 0.0f : (float)Timing.Step); Timing.Accumulator -= Timing.Step; } if (!paused) { Timing.Alpha = Timing.Accumulator / Timing.Step; } }
/// <summary> /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Update(GameTime gameTime) { Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds; int updateIterations = (int)Math.Floor(Timing.Accumulator / Timing.Step); if (Timing.Accumulator > Timing.Step * 6.0) { //if the game's running too slowly then we have no choice //but to skip a bunch of steps //otherwise it snowballs and becomes unplayable Timing.Accumulator = Timing.Step; } CrossThread.ProcessTasks(); PlayerInput.UpdateVariable(); if (SoundManager != null) { if (WindowActive || !Config.MuteOnFocusLost) { SoundManager.ListenerGain = SoundManager.CompressionDynamicRangeGain; } else { SoundManager.ListenerGain = 0.0f; } } while (Timing.Accumulator >= Timing.Step) { Timing.TotalTime += Timing.Step; Stopwatch sw = new Stopwatch(); sw.Start(); fixedTime.IsRunningSlowly = gameTime.IsRunningSlowly; TimeSpan addTime = new TimeSpan(0, 0, 0, 0, 16); fixedTime.ElapsedGameTime = addTime; fixedTime.TotalGameTime.Add(addTime); base.Update(fixedTime); PlayerInput.Update(Timing.Step); if (loadingScreenOpen) { //reset accumulator if loading // -> less choppy loading screens because the screen is rendered after each update // -> no pause caused by leftover time in the accumulator when starting a new shift GameMain.ResetFrameTime(); if (!TitleScreen.PlayingSplashScreen) { SoundPlayer.Update((float)Timing.Step); } if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen && (!waitForKeyHit || ((PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.PrimaryMouseButtonClicked()) && WindowActive))) { loadingScreenOpen = false; } #if DEBUG if (TitleScreen.LoadState >= 100.0f && !TitleScreen.PlayingSplashScreen && Config.AutomaticQuickStartEnabled && FirstLoad) { loadingScreenOpen = false; FirstLoad = false; MainMenuScreen.QuickStart(); } #endif if (!hasLoaded && !CoroutineManager.IsCoroutineRunning(loadingCoroutine)) { throw new LoadingException(loadingCoroutine.Exception); } } else if (hasLoaded) { if (ConnectLobby != 0) { if (Client != null) { Client.Disconnect(); Client = null; GameMain.MainMenuScreen.Select(); } Steam.SteamManager.JoinLobby(ConnectLobby, true); ConnectLobby = 0; ConnectEndpoint = null; ConnectName = null; } else if (!string.IsNullOrWhiteSpace(ConnectEndpoint)) { if (Client != null) { Client.Disconnect(); Client = null; GameMain.MainMenuScreen.Select(); } UInt64 serverSteamId = SteamManager.SteamIDStringToUInt64(ConnectEndpoint); Client = new GameClient(Config.PlayerName, serverSteamId != 0 ? null : ConnectEndpoint, serverSteamId, string.IsNullOrWhiteSpace(ConnectName) ? ConnectEndpoint : ConnectName); ConnectLobby = 0; ConnectEndpoint = null; ConnectName = null; } SoundPlayer.Update((float)Timing.Step); if (PlayerInput.KeyHit(Keys.Escape) && WindowActive) { // Check if a text input is selected. if (GUI.KeyboardDispatcher.Subscriber != null) { if (GUI.KeyboardDispatcher.Subscriber is GUITextBox textBox) { textBox.Deselect(); } GUI.KeyboardDispatcher.Subscriber = null; } //if a verification prompt (are you sure you want to x) is open, close it else if (GUIMessageBox.VisibleBox as GUIMessageBox != null && GUIMessageBox.VisibleBox.UserData as string == "verificationprompt") { ((GUIMessageBox)GUIMessageBox.VisibleBox).Close(); } else if (Tutorial.Initialized && Tutorial.ContentRunning) { (GameSession.GameMode as TutorialMode).Tutorial.CloseActiveContentGUI(); } else if (GameSession.IsTabMenuOpen) { gameSession.ToggleTabMenu(); } else if (GUI.PauseMenuOpen) { GUI.TogglePauseMenu(); } //open the pause menu if not controlling a character OR if the character has no UIs active that can be closed with ESC else if ((Character.Controlled == null || !itemHudActive()) //TODO: do we need to check Inventory.SelectedSlot? && Inventory.SelectedSlot == null && CharacterHealth.OpenHealthWindow == null && !CrewManager.IsCommandInterfaceOpen && !(Screen.Selected is SubEditorScreen editor && !editor.WiringMode && Character.Controlled?.SelectedConstruction != null)) { // Otherwise toggle pausing, unless another window/interface is open. GUI.TogglePauseMenu(); } bool itemHudActive() { if (Character.Controlled?.SelectedConstruction == null) { return(false); } return (Character.Controlled.SelectedConstruction.ActiveHUDs.Any(ic => ic.GuiFrame != null) || ((Character.Controlled.ViewTarget as Item)?.Prefab?.FocusOnSelected ?? false)); } } #if DEBUG if (GameMain.NetworkMember == null) { if (PlayerInput.KeyHit(Keys.P) && !(GUI.KeyboardDispatcher.Subscriber is GUITextBox)) { DebugConsole.Paused = !DebugConsole.Paused; } } #endif GUI.ClearUpdateList(); Paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen || Tutorial.ContentRunning || DebugConsole.Paused) && (NetworkMember == null || !NetworkMember.GameStarted); #if !DEBUG if (NetworkMember == null && !WindowActive && !Paused && true && Screen.Selected != MainMenuScreen && Config.PauseOnFocusLost) { GUI.TogglePauseMenu(); Paused = true; } #endif Screen.Selected.AddToGUIUpdateList(); if (Client != null) { Client.AddToGUIUpdateList(); } FileSelection.AddToGUIUpdateList(); DebugConsole.AddToGUIUpdateList(); DebugConsole.Update((float)Timing.Step); Paused = Paused || (DebugConsole.IsOpen && (NetworkMember == null || !NetworkMember.GameStarted)); if (!Paused) { Screen.Selected.Update(Timing.Step); } else if (Tutorial.Initialized && Tutorial.ContentRunning) { (GameSession.GameMode as TutorialMode).Update((float)Timing.Step); } else if (DebugConsole.Paused) { if (Screen.Selected.Cam == null) { DebugConsole.Paused = false; } else { Screen.Selected.Cam.MoveCamera((float)Timing.Step); } } if (NetworkMember != null) { NetworkMember.Update((float)Timing.Step); } GUI.Update((float)Timing.Step); } CoroutineManager.Update((float)Timing.Step, Paused ? 0.0f : (float)Timing.Step); SteamManager.Update((float)Timing.Step); TaskPool.Update(); SoundManager?.Update(); Timing.Accumulator -= Timing.Step; sw.Stop(); PerformanceCounter.AddElapsedTicks("Update total", sw.ElapsedTicks); PerformanceCounter.UpdateTimeGraph.Update(sw.ElapsedTicks * 1000.0f / (float)Stopwatch.Frequency); PerformanceCounter.UpdateIterationsGraph.Update(updateIterations); } if (!Paused) { Timing.Alpha = Timing.Accumulator / Timing.Step; } }
/// <summary> /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Update(GameTime gameTime) { Timing.TotalTime = gameTime.TotalGameTime.TotalSeconds; Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds; int updateIterations = (int)Math.Floor(Timing.Accumulator / Timing.Step); if (Timing.Accumulator > Timing.Step * 6.0) { //if the game's running too slowly then we have no choice //but to skip a bunch of steps //otherwise it snowballs and becomes unplayable Timing.Accumulator = Timing.Step; } PlayerInput.UpdateVariable(); bool paused = true; while (Timing.Accumulator >= Timing.Step) { Stopwatch sw = new Stopwatch(); sw.Start(); fixedTime.IsRunningSlowly = gameTime.IsRunningSlowly; TimeSpan addTime = new TimeSpan(0, 0, 0, 0, 16); fixedTime.ElapsedGameTime = addTime; fixedTime.TotalGameTime.Add(addTime); base.Update(fixedTime); PlayerInput.Update(Timing.Step); if (loadingScreenOpen) { //reset accumulator if loading // -> less choppy loading screens because the screen is rendered after each update // -> no pause caused by leftover time in the accumulator when starting a new shift Timing.Accumulator = 0.0f; if (TitleScreen.LoadState >= 100.0f && (!waitForKeyHit || PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.LeftButtonClicked())) { loadingScreenOpen = false; } if (!hasLoaded && !CoroutineManager.IsCoroutineRunning(loadingCoroutine)) { string errMsg = "Loading was interrupted due to an error"; if (loadingCoroutine.Exception != null) { errMsg += ": " + loadingCoroutine.Exception.Message + "\n" + loadingCoroutine.Exception.StackTrace; } throw new Exception(errMsg); } } else if (hasLoaded) { SoundPlayer.Update((float)Timing.Step); if (PlayerInput.KeyHit(Keys.Escape)) { GUI.TogglePauseMenu(); } GUI.ClearUpdateList(); paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen) && (NetworkMember == null || !NetworkMember.GameStarted); Screen.Selected.AddToGUIUpdateList(); if (NetworkMember != null) { NetworkMember.AddToGUIUpdateList(); } DebugConsole.AddToGUIUpdateList(); DebugConsole.Update(this, (float)Timing.Step); paused = paused || (DebugConsole.IsOpen && (NetworkMember == null || !NetworkMember.GameStarted)); if (!paused) { Screen.Selected.Update(Timing.Step); } if (NetworkMember != null) { NetworkMember.Update((float)Timing.Step); } GUI.Update((float)Timing.Step); } CoroutineManager.Update((float)Timing.Step, paused ? 0.0f : (float)Timing.Step); SteamManager.Update((float)Timing.Step); Timing.Accumulator -= Timing.Step; sw.Stop(); PerformanceCounter.AddElapsedTicks("Update total", sw.ElapsedTicks); PerformanceCounter.UpdateTimeGraph.Update(sw.ElapsedTicks / (float)TimeSpan.TicksPerMillisecond); PerformanceCounter.UpdateIterationsGraph.Update(updateIterations); } if (!paused) { Timing.Alpha = Timing.Accumulator / Timing.Step; } }
/// <summary> /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Update(GameTime gameTime) { Timing.TotalTime = gameTime.TotalGameTime.TotalSeconds; Timing.Accumulator += gameTime.ElapsedGameTime.TotalSeconds; PlayerInput.UpdateVariable(); bool paused = true; if (GameMain.NilMod.UseExperimentalFPSLagPrevention && !loadingScreenOpen) { if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 2) { Timing.Step = 1.0 / 8.0; FarseerPhysics.Settings.VelocityIterations = 10; FarseerPhysics.Settings.PositionIterations = 4; FarseerPhysics.Settings.TOIPositionIterations = 25; FarseerPhysics.Settings.TOIVelocityIterations = 10; } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 4) { Timing.Step = 1.0 / 10.0; FarseerPhysics.Settings.VelocityIterations = 10; FarseerPhysics.Settings.PositionIterations = 4; FarseerPhysics.Settings.TOIPositionIterations = 25; FarseerPhysics.Settings.TOIVelocityIterations = 10; } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 6) { Timing.Step = 1.0 / 12.0; FarseerPhysics.Settings.VelocityIterations = 10; FarseerPhysics.Settings.PositionIterations = 4; FarseerPhysics.Settings.TOIPositionIterations = 25; FarseerPhysics.Settings.TOIVelocityIterations = 10; } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 8) { Timing.Step = 1.0 / 15.0; FarseerPhysics.Settings.VelocityIterations = 9; FarseerPhysics.Settings.PositionIterations = 4; FarseerPhysics.Settings.TOIPositionIterations = 22; FarseerPhysics.Settings.TOIVelocityIterations = 9; } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 10) { Timing.Step = 1.0 / 20.0; FarseerPhysics.Settings.VelocityIterations = 9; FarseerPhysics.Settings.PositionIterations = 4; FarseerPhysics.Settings.TOIPositionIterations = 22; FarseerPhysics.Settings.TOIVelocityIterations = 9; } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 12) { Timing.Step = 1.0 / 25.0; FarseerPhysics.Settings.VelocityIterations = 9; FarseerPhysics.Settings.PositionIterations = 4; FarseerPhysics.Settings.TOIPositionIterations = 22; FarseerPhysics.Settings.TOIVelocityIterations = 9; } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 14) { Timing.Step = 1.0 / 30.0; FarseerPhysics.Settings.VelocityIterations = 8; FarseerPhysics.Settings.PositionIterations = 3; FarseerPhysics.Settings.TOIPositionIterations = 20; FarseerPhysics.Settings.TOIVelocityIterations = 8; } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 16) { Timing.Step = 1.0 / 35.0; FarseerPhysics.Settings.VelocityIterations = 8; FarseerPhysics.Settings.PositionIterations = 3; FarseerPhysics.Settings.TOIPositionIterations = 20; FarseerPhysics.Settings.TOIVelocityIterations = 8; } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 18) { Timing.Step = 1.0 / 40.0; FarseerPhysics.Settings.VelocityIterations = 8; FarseerPhysics.Settings.PositionIterations = 3; FarseerPhysics.Settings.TOIPositionIterations = 20; FarseerPhysics.Settings.TOIVelocityIterations = 8; } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 20) { Timing.Step = 1.0 / 45.0; FarseerPhysics.Settings.VelocityIterations = 8; FarseerPhysics.Settings.PositionIterations = 3; FarseerPhysics.Settings.TOIPositionIterations = 20; FarseerPhysics.Settings.TOIVelocityIterations = 8; } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 22) { Timing.Step = 1.0 / 50.0; FarseerPhysics.Settings.VelocityIterations = 8; FarseerPhysics.Settings.PositionIterations = 3; FarseerPhysics.Settings.TOIPositionIterations = 20; FarseerPhysics.Settings.TOIVelocityIterations = 8; } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 25) { Timing.Step = 1.0 / 55.0; FarseerPhysics.Settings.VelocityIterations = 8; FarseerPhysics.Settings.PositionIterations = 3; FarseerPhysics.Settings.TOIPositionIterations = 20; FarseerPhysics.Settings.TOIVelocityIterations = 8; } else { Timing.Step = 1.0 / 60.0; FarseerPhysics.Settings.VelocityIterations = 8; FarseerPhysics.Settings.PositionIterations = 3; FarseerPhysics.Settings.TOIPositionIterations = 20; FarseerPhysics.Settings.TOIVelocityIterations = 8; } } else { Timing.Step = 1.0 / 60.0; FarseerPhysics.Settings.VelocityIterations = 8; FarseerPhysics.Settings.PositionIterations = 3; FarseerPhysics.Settings.TOIPositionIterations = 20; FarseerPhysics.Settings.TOIVelocityIterations = 8; } while (Timing.Accumulator >= Timing.Step) { NilModProfiler.SWMainUpdateLoop.Start(); fixedTime.IsRunningSlowly = gameTime.IsRunningSlowly; TimeSpan addTime = new TimeSpan(0, 0, 0, 0, 16); if (GameMain.NilMod.UseExperimentalFPSLagPrevention) { if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 2) { addTime = new TimeSpan(0, 0, 0, 0, 125); } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 4) { addTime = new TimeSpan(0, 0, 0, 0, 100); } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 6) { addTime = new TimeSpan(0, 0, 0, 0, 83); } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 8) { addTime = new TimeSpan(0, 0, 0, 0, 66); } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 10) { addTime = new TimeSpan(0, 0, 0, 0, 50); } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 12) { addTime = new TimeSpan(0, 0, 0, 0, 40); } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 14) { addTime = new TimeSpan(0, 0, 0, 0, 33); } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 16) { addTime = new TimeSpan(0, 0, 0, 0, 28); } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 18) { addTime = new TimeSpan(0, 0, 0, 0, 25); } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 20) { addTime = new TimeSpan(0, 0, 0, 0, 22); } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 22) { addTime = new TimeSpan(0, 0, 0, 0, 20); } else if ((int)GameMain.FrameCounter.CurrentFramesPerSecond <= 25) { addTime = new TimeSpan(0, 0, 0, 0, 18); } else { addTime = new TimeSpan(0, 0, 0, 0, 16); } } fixedTime.ElapsedGameTime = addTime; fixedTime.TotalGameTime.Add(addTime); base.Update(fixedTime); NilModProfiler.SWPlayerInput.Start(); if (WindowActive) { PlayerInput.Update(Timing.Step); } NilModProfiler.RecordPlayerInput(); if (loadingScreenOpen) { //reset accumulator if loading // -> less choppy loading screens because the screen is rendered after each update // -> no pause caused by leftover time in the accumulator when starting a new shift if (TitleScreen.LoadState >= 100f) { Timing.Accumulator = 0.0f; this.TargetElapsedTime = new TimeSpan(0, 0, 0, 0, 12); } else { Timing.Accumulator = Timing.Step * 1.99; this.TargetElapsedTime = new TimeSpan(0, 0, 0, 0, 1); } if (TitleScreen.LoadState >= 100.0f && (!waitForKeyHit || PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.LeftButtonClicked())) { loadingScreenOpen = false; } if (!hasLoaded && !CoroutineManager.IsCoroutineRunning(loadingCoroutine)) { throw new Exception("Loading was interrupted due to an error"); } } else if (hasLoaded) { NilMod.Update((float)Timing.Step); NilModProfiler.SWSoundPlayer.Start(); SoundPlayer.Update((float)Timing.Step); NilModProfiler.RecordSoundPlayer(); if (PlayerInput.KeyHit(Keys.Escape)) { GUI.TogglePauseMenu(); } GUIComponent.ClearUpdateList(); paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen) && (NetworkMember == null || !NetworkMember.GameStarted); if (!paused) { Screen.Selected.AddToGUIUpdateList(); } if (NetworkMember != null) { NetworkMember.AddToGUIUpdateList(); } GUI.AddToGUIUpdateList(); DebugConsole.AddToGUIUpdateList(); GUIComponent.UpdateMouseOn(); NilModProfiler.SWDebugConsole.Start(); DebugConsole.Update(this, (float)Timing.Step); paused = paused || (DebugConsole.IsOpen && (NetworkMember == null || !NetworkMember.GameStarted)); NilModProfiler.RecordDebugConsole(); if (!paused) { NilModProfiler.SWGameScreen.Start(); Screen.Selected.Update(Timing.Step); NilModProfiler.RecordGameScreen(); } if (NetworkMember != null) { NilModProfiler.SWNetworkMember.Start(); NetworkMember.Update((float)Timing.Step); NilModProfiler.RecordNetworkMember(); } NilModProfiler.SWGUIUpdate.Start(); GUI.Update((float)Timing.Step); NilModProfiler.RecordGUIUpdate(); } NilModProfiler.SWCoroutineManager.Start(); CoroutineManager.Update((float)Timing.Step, paused ? 0.0f : (float)Timing.Step); NilModProfiler.RecordCoroutineManager(); Timing.Accumulator -= Timing.Step; if (NilModProfiler.SWMainUpdateLoop.ElapsedTicks > 0) { NilModProfiler.RecordMainLoopUpdate(); } } GameMain.NilModProfiler.Update((float)Timing.Step); if (!paused) { Timing.Alpha = Timing.Accumulator / Timing.Step; } }