bugfix(logic): Restore retail compatibility after change to frozen time check#2803
bugfix(logic): Restore retail compatibility after change to frozen time check#2803Caball009 wants to merge 1 commit into
Conversation
|
| Filename | Overview |
|---|---|
| Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp | Adds setTimeFrozen sync + early-return after script update; skips terrain/objects/CRC/frame-increment on frozen frames, matching retail behaviour. |
| Generals/Code/GameEngine/Source/Common/GameEngine.cpp | Removes frozen-time guard from canUpdateLogic and drops the canUpdateScript fallback branch; GameLogic::update() now always runs and handles the frozen check internally. |
| GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp | Identical change to the Zero Hour variant of GameEngine::update() — consistent with the Generals copy. |
| GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp | Identical change to the Zero Hour variant of GameLogic::update() — consistent with the Generals copy. |
Sequence Diagram
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant GE as GameEngine::update()
participant GL as GameLogic::update()
participant SE as ScriptEngine
participant FP as FramePacer
participant World as Terrain/Objects/CRC
Note over GE: canUpdateLogic = canUpdate && !isGameHalted()<br/>(frozen check removed)
GE->>GL: UPDATE() [always, unless halted]
GL->>SE: UPDATE()
SE-->>FP: (may set frozen state)
GL->>GE: isTimeFrozen()
GE-->>GL: frozen?
GL->>FP: setTimeFrozen(frozen)
alt time is frozen
GL-->>GE: return early (skip terrain/objects/CRC/m_frame++)
else time not frozen
GL->>World: TerrainLogic, Objects, CRC, m_frame++
end
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant GE as GameEngine::update()
participant GL as GameLogic::update()
participant SE as ScriptEngine
participant FP as FramePacer
participant World as Terrain/Objects/CRC
Note over GE: canUpdateLogic = canUpdate && !isGameHalted()<br/>(frozen check removed)
GE->>GL: UPDATE() [always, unless halted]
GL->>SE: UPDATE()
SE-->>FP: (may set frozen state)
GL->>GE: isTimeFrozen()
GE-->>GL: frozen?
GL->>FP: setTimeFrozen(frozen)
alt time is frozen
GL-->>GE: return early (skip terrain/objects/CRC/m_frame++)
else time not frozen
GL->>World: TerrainLogic, Objects, CRC, m_frame++
end
Reviews (1): Last reviewed commit: "bugfix(logic): Check if time is frozen d..." | Re-trigger Greptile
xezon
left a comment
There was a problem hiding this comment.
This is unfortunate. Can we fix this somehow without moving the early return back into the Game Logic Update function? It makes the logic more complicated to understand again. It would be good to implement it in simple terms.
I don't see how to avoid the early return in a way that doesn't have major downsides. |
|
What downsides do you see? |
Either code duplication, or a potential risk of game logic changes. If you want to keep the exact same logic, you'd need to keep these in place:
Only solution I see at the moment to keep the changes as is, or perhaps put the code up to the script engine update in a separate function, although I'm not entirely sure if that's going to work. |
|
Unless you have a better suggestion, can we just merge this? I can create an issue / task to refactor this so that we can perhaps find a better way to implement this in the future. |
|
As last resort, maybe only do the hack in RETAIL_COMPATIBLE_CRC builds? |
The non-retail compatible code would always be one frame behind with freezing and unfreezing time; e.g. if a script is supposed to freeze the game at frame 1000 and unfreeze at frame 1100, but it actually does that at frames 1001 and 1101. It probably is rarely used so we didn't notice it before, but I don't like the idea of keeping that unexpected behavior. |
#1528 introduced a small change to the game logic as is shown below.
Implementation before approximately:
Implementation after approximately:
Replay vc6_replay_scripted_frozen_time.zip on map "[Mod] Football v3" mismatches because of that change. This PR fixes the mismatch.