Skip to content

fix(savegame): rebuild shroud grid on load to clear fog over own base#234

Closed
coolswood wants to merge 1 commit into
fbraz3:mainfrom
coolswood:fix/challenge-continue-defeat-during-cinematic
Closed

fix(savegame): rebuild shroud grid on load to clear fog over own base#234
coolswood wants to merge 1 commit into
fbraz3:mainfrom
coolswood:fix/challenge-continue-defeat-during-cinematic

Conversation

@coolswood

Copy link
Copy Markdown

Description

Fixes fog of war creeping over the player's own base after loading a save in Generals Challenge mode.

Symptom: After saving → loading a challenge save, fog of war covered the player's own buildings within ~5-10 seconds. The player's own structures became gray "previously seen" ghosts that could no longer be selected or controlled.

Root cause

After a save load, PartitionManager restores the per-cell shroud counters (m_currentShroud) and the pending undo-queue from the file, but nothing re-applies object lookers — PartitionManager::loadPostProcess() was an empty stub.

When the restored undo-queue drains (~m_unlookPersistDuration = 30 frames later), removeLooker fires at each queued position. Static structures never re-look, so their cells drop to FOGGED (gray ghost / unselectable). The restored m_partitionLastLook and the cell counters also disagree, so any later handleShroud() would double-count.

A relationship-loss hypothesis was investigated first and disproved: brute-forcing all players to mutual ALLIES on load did not fix it, because relationships only matter inside Object::look(), which is never called after load.

Changes

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/PartitionManager.cpp

Implemented PartitionManager::loadPostProcess() (previously an empty stub) by mirroring the established TerrainLogic::setActiveBoundary rebuild pattern:

  1. Drain the restored undo-queue so lingering undoes don't fire after rebuild
  2. Snapshot explored (FOGGED) and permanently-revealed (CLEAR) cells via storeFoggedCells
  3. Release ghost-object partition data
  4. Invalidate every object's sighting state (friend_prepareForMapBoundaryAdjust) so the later unlook()/unshroud() are no-ops instead of double-undoes
  5. Tear the cell grid down to the all-shrouded default (reset() + init())
  6. Restore permanently-revealed cells
  7. Re-look every object (friend_notifyOfNewMapBoundary → each object owns exactly one live looker)
  8. Restore explored cells + ghost objects + refreshShroudForLocalPlayer()

After this the undo-queue is empty, every live object owns its looker, and static structures stay CLEAR permanently.

GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp

Guarded the challenge-mode relationship-setup block in tryStartNewGame() with loadingSaveGame == FALSE, so it cannot overwrite serialized relationships on load.

Verification

  • macOS build (macos-vulkan), Zero Hour target
  • Loaded the previously-broken challenge save (00000062.sav, ~6.7 MB)
  • Observed for 30+ seconds: fog no longer creeps over the player's own base
  • Buildings remain selectable and controllable
  • Previously-explored-but-not-visible areas stay gray (FOGGED), not black (SHROUDED) — confirms restoreFoggedCells preserves explored state

Notes

  • Zero Hour only — Generals Challenge is an expansion feature, so no backport to the base game.
  • This is a load-path bug, not a relationship/diplomacy bug. The relationship guards are defensive; the actual fix is the shroud rebuild.

After loading a save in Generals Challenge, fog of war crept over the
player's own base within a few seconds: static structures never re-look,
so when the restored undo-queue drained (~30 frames) their cells dropped
to FOGGED and became unselectable gray ghosts.

PartitionManager::loadPostProcess was an empty stub, so nothing re-applied
object lookers after the per-cell counters and undo-queue were deserialized.
Mirror the established TerrainLogic::setActiveBoundary rebuild: drain the
queue, snapshot explored/permanently-revealed cells, reset the grid to the
all-shrouded default, then re-look every object so each owns exactly one
live looker. Also guard the challenge relationship-setup block against
running on load.

Tested: loading a challenge save no longer fogs the player's own base and
buildings stay selectable.
@fbraz3

fbraz3 commented Jul 22, 2026

Copy link
Copy Markdown
Owner

Hey @coolswood thank for the PR.

Could you please fix the build pipeline? thanks!

@coolswood

Copy link
Copy Markdown
Author

Looks like the macOS ZH build failed, but it's not the code — vcpkg couldn't download freetype from gitlab.freedesktop.org (HTTP 504 on all 3 retry attempts). The build never even got to compiling the game.

The same change builds fine on the other jobs, including macOS Generals and Linux ZH, so this looks like a transient network issue with the GitLab mirror.

Would someone with access mind re-running the failed job? Should go green once the mirror is back up.

@Caball009

Copy link
Copy Markdown

@coolswood coolswood closed this Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants