Conversation
PR Summary by QodoDecouple drawable and decal fades from render rate
AI Description
Diagram
High-Level Assessment
Files changed (4)
|
|
| Filename | Overview |
|---|---|
| Generals/Code/GameEngine/Include/GameClient/Drawable.h | Changes elapsed fade progress to a fractional frame-equivalent value. |
| Generals/Code/GameEngine/Source/GameClient/Drawable.cpp | Scales visual fade progression by the frame-pacer ratio and preserves the existing serialized integer format. |
| GeneralsMD/Code/GameEngine/Include/GameClient/Drawable.h | Mirrors the fractional fade-state definition for Zero Hour. |
| GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp | Mirrors the timing and save-compatibility changes for Zero Hour. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
R[Render update] --> P[Read logic/render ratio]
P --> F[Advance drawable fade]
P --> D[Advance terrain-decal opacity]
F --> O[Apply visual opacity]
D --> O
F --> S[Convert elapsed fade to integer for saves]
S --> L[Restore integer progress as Real on load]
Reviews (1): Last reviewed commit: "bugfix(drawable): Replicate fade timing ..." | Re-trigger Greptile
Code Review by Qodo
1. Objects remain translucent after fades
|
| ++m_timeElapsedFade; | ||
| // TheSuperHackers @bugfix bobtista 15/09/2026 Decouple Drawable fade timing from render updates. | ||
| const Real fadeTimeScale = TheFramePacer->getActualLogicTimeScaleOverFpsRatio(); | ||
| m_timeElapsedFade += fadeTimeScale; |
There was a problem hiding this comment.
1. Objects remain translucent after fades 🐞 Bug ≡ Correctness
Drawable::updateDrawable() applies opacity from the old m_timeElapsedFade, then adds a fractional step and clears m_fadeMode without applying the terminal opacity. When the step crosses rather than lands on m_timeToFade, fade-ins retain opacity below 1 and fade-outs retain opacity above 0 in both game variants.
Agent Prompt
## Issue description
Fractional fade steps can cross the duration after the current opacity has already been applied, causing the fade mode to stop without ever assigning its exact final opacity.
## Fix Focus Areas
- Generals/Code/GameEngine/Source/GameClient/Drawable.cpp[1147-1155]
- GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp[1149-1157]
## Recommended Fix
When the updated elapsed time exceeds the fade duration, explicitly set opacity to `1.0f` for a fade-in or `0.0f` for a fade-out before clearing the fade mode. Apply the same correction to both game variants.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
|
||
| // time elapsed fade | ||
| xfer->xferUnsignedInt( &m_timeElapsedFade ); | ||
| UnsignedInt timeElapsedFadeFrames = static_cast<UnsignedInt>(m_timeElapsedFade); |
There was a problem hiding this comment.
What is the risk - if any - if the cast rounds the value to an integer value?
| // time elapsed fade | ||
| xfer->xferUnsignedInt( &m_timeElapsedFade ); | ||
| UnsignedInt timeElapsedFadeFrames = static_cast<UnsignedInt>(m_timeElapsedFade); | ||
| xfer->xferUnsignedInt( &timeElapsedFadeFrames ); |
There was a problem hiding this comment.
Wouldn't it be better to only keep the cast in retail compatible?
| ++m_timeElapsedFade; | ||
| // TheSuperHackers @bugfix bobtista 15/09/2026 Decouple Drawable fade timing from render updates. | ||
| const Real fadeTimeScale = TheFramePacer->getActualLogicTimeScaleOverFpsRatio(); | ||
| m_timeElapsedFade += fadeTimeScale; |
There was a problem hiding this comment.
Can be reduced to a single line expression
| m_decalOpacity += m_decalOpacityFadeRate; | ||
| // TheSuperHackers @bugfix bobtista 15/09/2026 Decouple decal opacity fade timing from render updates. | ||
| const Real decalFadeTimeScale = TheFramePacer->getActualLogicTimeScaleOverFpsRatio(); | ||
| m_decalOpacity += m_decalOpacityFadeRate * decalFadeTimeScale; |
There was a problem hiding this comment.
Can be reduced to a single line expression
Drawable fade in/out and terrain decal opacity currently advance once per render frame, so they run faster at higher render rates.
This scales their progress by the logic/render ratio. At 120 render FPS and 30 logic FPS, a Rebel Ambush authored with
FadeTime = 3000currently finishes in 750 ms. With this change it takes 3 seconds as authored.m_timeElapsedFadechanges fromUnsignedInttoRealto accumulate fractional steps during play. Saves keep the existing integer representation, so save compatibility is unchanged; loading may discard less than one 30 Hz frame of fade progress.Rebel Ambush comparison:
pr2055_sidebyside.mp4
To reproduce: load a save,
Ctrl+KP_Plusto raise the render cap to 120,Ctrl+Shift+KP_Minusuntil the logic time scale reads 30, then fire Rebel Ambush.Todo: