From bee22c389ed5e9afe91a59e3720890925f33d08b Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Sat, 4 Jul 2026 22:01:59 +0200 Subject: [PATCH 1/2] bugfix(logic): Check if time is frozen directly after script engine update. --- .../GameEngine/Source/Common/GameEngine.cpp | 21 +++++++------------ .../Source/GameLogic/System/GameLogic.cpp | 6 ++++++ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp index 74781f946a5..52de355f495 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp @@ -821,7 +821,7 @@ void GameEngine::resetSubsystems() /// ----------------------------------------------------------------------------------------------- Bool GameEngine::canUpdateGameLogic(UnsignedInt logicTimeQueryFlags) { - // Must be first. + // This updates the paused game status of the game logic. TheGameLogic->preUpdate(); TheFramePacer->setTimeFrozen(isTimeFrozen()); @@ -915,20 +915,15 @@ void GameEngine::update() } } - const Bool canUpdate = canUpdateGameLogic(FramePacer::IgnoreFrozenTime | FramePacer::IgnoreHaltedGame); - const Bool canUpdateLogic = canUpdate && !TheFramePacer->isGameHalted() && !TheFramePacer->isTimeFrozen(); - const Bool canUpdateScript = canUpdate && !TheFramePacer->isGameHalted(); - - if (canUpdateLogic) + // TheSuperHackers @info Ignores frozen time because the script engine needs updating in the logic update regardless. + if (canUpdateGameLogic(FramePacer::IgnoreFrozenTime)) { - TheGameClient->step(); TheGameLogic->UPDATE(); - } - else if (canUpdateScript) - { - // TheSuperHackers @info Still update the Script Engine to allow - // for scripted camera movements while the time is frozen. - TheScriptEngine->UPDATE(); + + if (!TheFramePacer->isTimeFrozen()) + { + TheGameClient->step(); + } } } } diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp index 622aeb5da10..db7345c065b 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp @@ -3732,6 +3732,12 @@ void GameLogic::update() TheScriptEngine->UPDATE(); } + // TheSuperHackers @info Updates the frozen time status because it may have changed after the script engine update. + TheFramePacer->setTimeFrozen(TheGameEngine->isTimeFrozen()); + + if (TheFramePacer->isTimeFrozen()) + return; + // Note - TerrainLogic update needs to happen after ScriptEngine update, but before object updates. jba. // This way changes in bridges are noted in the script engine before being cleared in TerrainLogic->update { From cc042548bb3ad929f0cbcc19626669f8e63b0118 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Sat, 4 Jul 2026 22:02:30 +0200 Subject: [PATCH 2/2] Replicated in Generals. --- .../GameEngine/Source/Common/GameEngine.cpp | 21 +++++++------------ .../Source/GameLogic/System/GameLogic.cpp | 6 ++++++ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Generals/Code/GameEngine/Source/Common/GameEngine.cpp b/Generals/Code/GameEngine/Source/Common/GameEngine.cpp index 3750383655c..733beafac12 100644 --- a/Generals/Code/GameEngine/Source/Common/GameEngine.cpp +++ b/Generals/Code/GameEngine/Source/Common/GameEngine.cpp @@ -654,7 +654,7 @@ void GameEngine::resetSubsystems() /// ----------------------------------------------------------------------------------------------- Bool GameEngine::canUpdateGameLogic(UnsignedInt logicTimeQueryFlags) { - // Must be first. + // This updates the paused game status of the game logic. TheGameLogic->preUpdate(); TheFramePacer->setTimeFrozen(isTimeFrozen()); @@ -748,20 +748,15 @@ void GameEngine::update() } } - const Bool canUpdate = canUpdateGameLogic(FramePacer::IgnoreFrozenTime | FramePacer::IgnoreHaltedGame); - const Bool canUpdateLogic = canUpdate && !TheFramePacer->isGameHalted() && !TheFramePacer->isTimeFrozen(); - const Bool canUpdateScript = canUpdate && !TheFramePacer->isGameHalted(); - - if (canUpdateLogic) + // TheSuperHackers @info Ignores frozen time because the script engine needs updating in the logic update regardless. + if (canUpdateGameLogic(FramePacer::IgnoreFrozenTime)) { - TheGameClient->step(); TheGameLogic->UPDATE(); - } - else if (canUpdateScript) - { - // TheSuperHackers @info Still update the Script Engine to allow - // for scripted camera movements while the time is frozen. - TheScriptEngine->UPDATE(); + + if (!TheFramePacer->isTimeFrozen()) + { + TheGameClient->step(); + } } } } diff --git a/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp b/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp index be7d76d2894..367bd2b47b7 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp @@ -3193,6 +3193,12 @@ void GameLogic::update() TheScriptEngine->UPDATE(); } + // TheSuperHackers @info Updates the frozen time status because it may have changed after the script engine update. + TheFramePacer->setTimeFrozen(TheGameEngine->isTimeFrozen()); + + if (TheFramePacer->isTimeFrozen()) + return; + // Note - TerrainLogic update needs to happen after ScriptEngine update, but before object updates. jba. // This way changes in bridges are noted in the script engine before being cleared in TerrainLogic->update {