feat(gui): Add configurable menu transition speed#2840
Conversation
|
| Filename | Overview |
|---|---|
| Core/GameEngine/Source/Common/OptionPreferences.cpp | Adds getGameWindowTransitionSpeedMultiplier() but clamps the range to [1.0, 1000.0] instead of the documented [0.1, 10.0], making slow-transition values impossible and the upper bound excessively large. |
| Core/GameEngine/Include/Common/OptionPreferences.h | Adds const declaration for getGameWindowTransitionSpeedMultiplier(); straightforward header change. |
| Core/GameEngine/Source/GameClient/GUI/GameWindowTransitions.cpp | Multiplies the existing FPS-decoupled timeScale by the GlobalData multiplier; logic is correct assuming the multiplier value is valid. |
| Generals/Code/GameEngine/Include/Common/GlobalData.h | Adds m_gameWindowTransitionSpeedMultiplier field with a proper comment; mirrors GeneralsMD correctly. |
| Generals/Code/GameEngine/Source/Common/GlobalData.cpp | Initialises and populates the new multiplier field from OptionPreferences; mirrors GeneralsMD correctly. |
| GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h | Adds m_gameWindowTransitionSpeedMultiplier field; identical change to Generals counterpart. |
| GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp | Initialises and populates the new multiplier field from OptionPreferences; identical change to Generals counterpart. |
Sequence Diagram
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant INI as Options.ini
participant OP as OptionPreferences
participant GD as GlobalData
participant TG as TransitionGroup::update()
participant FP as FramePacer
INI->>OP: GameWindowTransitionSpeedMultiplier value
OP->>OP: clamp(min, value, max) — bounds bug here
OP->>GD: parseGameDataDefinition() sets m_gameWindowTransitionSpeedMultiplier
FP->>TG: getBaseOverUpdateFpsRatio()
GD->>TG: m_gameWindowTransitionSpeedMultiplier
TG->>TG: "timeScale = ratio * multiplier"
TG->>TG: "m_currentFrame += directionMultiplier * timeScale"
%%{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 INI as Options.ini
participant OP as OptionPreferences
participant GD as GlobalData
participant TG as TransitionGroup::update()
participant FP as FramePacer
INI->>OP: GameWindowTransitionSpeedMultiplier value
OP->>OP: clamp(min, value, max) — bounds bug here
OP->>GD: parseGameDataDefinition() sets m_gameWindowTransitionSpeedMultiplier
FP->>TG: getBaseOverUpdateFpsRatio()
GD->>TG: m_gameWindowTransitionSpeedMultiplier
TG->>TG: "timeScale = ratio * multiplier"
TG->>TG: "m_currentFrame += directionMultiplier * timeScale"
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
Core/GameEngine/Source/Common/OptionPreferences.cpp:895
The `clamp` call uses wrong bounds: `clamp(min, value, max)` in this codebase means speed is clamped to `[1.0, 1000.0]`, not `[0.1, 10.0]` as stated in the PR description. Any user who sets `MenuTransitionSpeed=0.5` expecting slower transitions will silently have their value overridden to `1.0`, and the upper cap of 1000× allows a wildly excessive speed that could make transitions instantaneous in a single frame loop iteration.
```suggestion
return clamp(0.1f, speed, 10.0f);
```
Reviews (4): Last reviewed commit: "refactor(gui): Replicate GameWindowTrans..." | Re-trigger Greptile
| // transitions cannot skip a state when the render frame rate dips below the base rate. | ||
| const Real timeScale = TheFramePacer->getBaseOverUpdateFpsRatio(); | ||
| // TheSuperHackers @feature bobtista 28/06/2026 Scale by the user menu transition speed preference. | ||
| const Real timeScale = TheFramePacer->getBaseOverUpdateFpsRatio() * TheGlobalData->m_menuTransitionSpeed; |
There was a problem hiding this comment.
Maybe also apply this to the movement speed of Control Bar, Diplomacy Screen? Or does that need to be a separate setting?
There was a problem hiding this comment.
Those don't go through TransitionGroup they use the sliding/animate-window path. Could make another PR for those - would you want it to be a separate setting or controlled by this one?
There was a problem hiding this comment.
Maybe make it a separate setting GameWindowMovementSpeedMultiplier
It's iteration-bound (frame-pacer frozen in that loop), so lowering Sleep speeds the fade up rather than smoothing it, is that what you want? It would be like 30x faster right? Maybe the proper change is to route the loop through the frame pacer, which would presumably be in its own PR. |
Right, perhaps
I don't think that's necessary. |
|
|
||
| Real OptionPreferences::getGameWindowTransitionSpeed() const | ||
| { | ||
| OptionPreferences::const_iterator it = find("GameWindowTransitionSpeed"); |
There was a problem hiding this comment.
Maybe call it GameWindowTransitionSpeedMultiplier or GameWindowTransitionSpeedScale because it is not clear what "Speed" refers to, but "Multiplier", "Scale" tells that it scales the speed.
Let's handle this in another PR. If we use that formula it will double count the denominator, duration becomes 1/speed². That 33 msec delay just makes the whole fade loop have 30fps pacing. We could do something like |
…nd enforce 1-1000 range
Would you mind doing a follow-up PR for this, then? |
Closes #2839
Adds a per-user
MenuTransitionSpeedoption (inOptions.ini) that scales the speed of menu/window transition animations, as requested following #2056. Defaults to1.0(unchanged behavior); values range from1.0(1× slower) to1000.0(1000× faster).The multiplier is applied to the existing frame-rate-decoupled time step from #2056, so transitions still step through every state and never skip.
Todo