Skip to content

bugfix(gameengine): Fix logic in GameEngine::canUpdateRegularGameLogic()#2707

Open
xezon wants to merge 1 commit into
TheSuperHackers:mainfrom
xezon:xezon/fix-logic-update
Open

bugfix(gameengine): Fix logic in GameEngine::canUpdateRegularGameLogic()#2707
xezon wants to merge 1 commit into
TheSuperHackers:mainfrom
xezon:xezon/fix-logic-update

Conversation

@xezon
Copy link
Copy Markdown

@xezon xezon commented May 14, 2026

This change fixes a logic error in GameEngine::canUpdateRegularGameLogic. It was spotted when loading a save game while max fps was uncapped, but after saveload it gets capped with TheGlobalData->m_useFpsLimit = true, which was then ignored in GameEngine::canUpdateRegularGameLogic. The result was an update timing discrepancy in GameEngine update, which caused glitches on game world visuals.

TODO

  • Replicate in Generals

@xezon xezon added this to the Decouple logic and rendering milestone May 14, 2026
@xezon xezon added Bug Something is not working right, typically is user facing Minor Severity: Minor < Major < Critical < Blocker Gen Relates to Generals ZH Relates to Zero Hour ThisProject The issue was introduced by this project, or this task is specific to this project labels May 14, 2026
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 14, 2026

Greptile Summary

This PR fixes a timing discrepancy bug in GameEngine::canUpdateRegularGameLogic() where changes to TheGlobalData->m_useFpsLimit (e.g. after loading a save game) were not being respected, causing visual glitches.

  • Replaces raw getFramesPerSecondLimit() / getLogicTimeScaleFps() calls with getActualFramesPerSecondLimit() / getActualLogicTimeScaleFps(flags), which correctly account for m_useFpsLimit, the enabled state, and game/time-halt flags.
  • Removes the now-redundant !enabled shortcut, since getActualLogicTimeScaleFps() already returns RenderFpsPreset::UncappedFpsValue when the logic time scale is disabled, naturally satisfying logicTimeScaleFps >= maxRenderFps.
  • Propagates FramePacer::IgnoreFrozenTime | FramePacer::IgnoreHaltedGame flags through the call chain so frozen/halted state is handled in the caller (update()), not baked into the scheduling decision.

Confidence Score: 5/5

The change is a tightly-scoped fix that correctly threads the fps-limit enabled state into the logic update decision. No behavioral regressions are introduced for the network or fast-mode paths.

Both getActualFramesPerSecondLimit() and getActualLogicTimeScaleFps(flags) correctly consolidate the state that was previously read piecemeal, removing the original inconsistency. The dropped !enabled guard is fully covered by getActualLogicTimeScaleFps returning UncappedFpsValue when the scale is disabled, preserving identical runtime behaviour in that branch.

No files require special attention; both changed files are straightforward.

Important Files Changed

Filename Overview
GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp Core bugfix: replaces raw FramePacer getters with getActual* variants in canUpdateRegularGameLogic and threads logicTimeQueryFlags through canUpdateGameLogic so fps-limit and enable-state changes are respected at runtime.
GeneralsMD/Code/GameEngine/Include/Common/GameEngine.h Header updated to match the new UnsignedInt logicTimeQueryFlags parameter signatures for canUpdateGameLogic and canUpdateRegularGameLogic.

Reviews (1): Last reviewed commit: "bugfix(gameengine): Fix logic in GameEng..." | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something is not working right, typically is user facing Gen Relates to Generals Minor Severity: Minor < Major < Critical < Blocker ThisProject The issue was introduced by this project, or this task is specific to this project ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant