From 6a819f0cb92a647e4939cff08a61ea5fc35ead2a Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Thu, 9 Jul 2026 04:36:08 +0400 Subject: [PATCH 1/4] bugfix(gameengine): Prevent logic time accumulation while the game is halted --- GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp index 52de355f495..5a218c49f1f 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp @@ -872,6 +872,13 @@ Bool GameEngine::canUpdateRegularGameLogic(UnsignedInt logicTimeQueryFlags) } else { + // TheSuperHackers @bugfix bobtista 08/07/2026 Return early when the logic time scale fps is zero, + // otherwise the accumulator banks the paused duration and replays it at render rate after unpausing. + if (logicTimeScaleFps <= 0) + { + return false; + } + // TheSuperHackers @tweak xezon 06/08/2025 // The logic time step is now decoupled from the render update. const Real targetFrameTime = 1.0f / logicTimeScaleFps; From 43e990da4de85df820277f2a83164d7d7effa857 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Thu, 9 Jul 2026 05:12:37 +0400 Subject: [PATCH 2/4] bugfix(gameengine): Prevent logic time accumulation while the game is halted (Generals) --- Generals/Code/GameEngine/Source/Common/GameEngine.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Generals/Code/GameEngine/Source/Common/GameEngine.cpp b/Generals/Code/GameEngine/Source/Common/GameEngine.cpp index 733beafac12..963459a3b9d 100644 --- a/Generals/Code/GameEngine/Source/Common/GameEngine.cpp +++ b/Generals/Code/GameEngine/Source/Common/GameEngine.cpp @@ -705,6 +705,13 @@ Bool GameEngine::canUpdateRegularGameLogic(UnsignedInt logicTimeQueryFlags) } else { + // TheSuperHackers @bugfix bobtista 08/07/2026 Return early when the logic time scale fps is zero, + // otherwise the accumulator banks the paused duration and replays it at render rate after unpausing. + if (logicTimeScaleFps <= 0) + { + return false; + } + // TheSuperHackers @tweak xezon 06/08/2025 // The logic time step is now decoupled from the render update. const Real targetFrameTime = 1.0f / logicTimeScaleFps; From f0f9101901d462dd96fcff7dd91245398da73259 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Fri, 10 Jul 2026 17:43:40 +0400 Subject: [PATCH 3/4] bugfix(gameengine): Check for halted game before fast forward so pause is not overridden --- .../Code/GameEngine/Source/Common/GameEngine.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp index 5a218c49f1f..0d982b2e8ce 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp @@ -857,6 +857,12 @@ Bool GameEngine::canUpdateNetworkGameLogic() Bool GameEngine::canUpdateRegularGameLogic(UnsignedInt logicTimeQueryFlags) { const Int logicTimeScaleFps = TheFramePacer->getActualLogicTimeScaleFps(logicTimeQueryFlags); + + if (logicTimeScaleFps <= 0) + { + return false; + } + const Int maxRenderFps = TheFramePacer->getActualFramesPerSecondLimit(); #if defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) @@ -872,13 +878,6 @@ Bool GameEngine::canUpdateRegularGameLogic(UnsignedInt logicTimeQueryFlags) } else { - // TheSuperHackers @bugfix bobtista 08/07/2026 Return early when the logic time scale fps is zero, - // otherwise the accumulator banks the paused duration and replays it at render rate after unpausing. - if (logicTimeScaleFps <= 0) - { - return false; - } - // TheSuperHackers @tweak xezon 06/08/2025 // The logic time step is now decoupled from the render update. const Real targetFrameTime = 1.0f / logicTimeScaleFps; From 1d81378dda62da4cd582859d70880ece74ca29a4 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Fri, 10 Jul 2026 17:44:08 +0400 Subject: [PATCH 4/4] bugfix(gameengine): Check for halted game before fast forward so pause is not overridden (Generals) --- .../Code/GameEngine/Source/Common/GameEngine.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Generals/Code/GameEngine/Source/Common/GameEngine.cpp b/Generals/Code/GameEngine/Source/Common/GameEngine.cpp index 963459a3b9d..675055715e0 100644 --- a/Generals/Code/GameEngine/Source/Common/GameEngine.cpp +++ b/Generals/Code/GameEngine/Source/Common/GameEngine.cpp @@ -690,6 +690,12 @@ Bool GameEngine::canUpdateNetworkGameLogic() Bool GameEngine::canUpdateRegularGameLogic(UnsignedInt logicTimeQueryFlags) { const Int logicTimeScaleFps = TheFramePacer->getActualLogicTimeScaleFps(logicTimeQueryFlags); + + if (logicTimeScaleFps <= 0) + { + return false; + } + const Int maxRenderFps = TheFramePacer->getActualFramesPerSecondLimit(); #if defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) @@ -705,13 +711,6 @@ Bool GameEngine::canUpdateRegularGameLogic(UnsignedInt logicTimeQueryFlags) } else { - // TheSuperHackers @bugfix bobtista 08/07/2026 Return early when the logic time scale fps is zero, - // otherwise the accumulator banks the paused duration and replays it at render rate after unpausing. - if (logicTimeScaleFps <= 0) - { - return false; - } - // TheSuperHackers @tweak xezon 06/08/2025 // The logic time step is now decoupled from the render update. const Real targetFrameTime = 1.0f / logicTimeScaleFps;