Skip to content

bugfix(savegame): Guard GameLogic xfer version bump with RETAIL_COMPATIBLE_XFER_SAVE#2418

Open
bobtista wants to merge 2 commits intoTheSuperHackers:mainfrom
bobtista:fix/gamelogic-xfer-object-list-no-version-bump
Open

bugfix(savegame): Guard GameLogic xfer version bump with RETAIL_COMPATIBLE_XFER_SAVE#2418
bobtista wants to merge 2 commits intoTheSuperHackers:mainfrom
bobtista:fix/gamelogic-xfer-object-list-no-version-bump

Conversation

@bobtista
Copy link

@bobtista bobtista commented Mar 7, 2026

Summary

  • Guards the xfer version bump in GameLogic::xfer behind RETAIL_COMPATIBLE_XFER_SAVE, replacing the unconditional bump from fix(object): Save and load game object list in correct order #2161
  • When retail compatible: keeps original version (10 for GeneralsMD, 9 for Generals), saves objects in forward order, and always reverses the object list after load to fix the prepend-induced reversal
  • When not retail compatible: bumps the version (11 for GeneralsMD, 10 for Generals), saves objects in reverse order so they load in correct order without post-load fixup

Test plan

  • Save and load a game, verify object list order is correct
  • Load a pre-existing save file, verify it loads without error and object order is correct

@greptile-apps
Copy link

greptile-apps bot commented Mar 7, 2026

Greptile Summary

This PR refines the fix from #2161 by guarding the Xfer version bump and reverse-save iteration behind #if !RETAIL_COMPATIBLE_XFER_SAVE rather than committing to a permanent version bump. Since RETAIL_COMPATIBLE_XFER_SAVE defaults to 1 in Core/GameEngine/Include/Common/GameDefines.h, default builds retain version 9 (Generals) / version 10 (Zero Hour) compatibility with retail saves, while the post-load list reversal is now unconditionally applied to all saves at or below those version thresholds to correct prepend-induced ordering.

  • Version gating: currentVersion is now 9 (Generals) or 10 (Zero Hour) in default builds, restoring the ability to load those saves with unmodified retail code.
  • Save-path branching: Forward-order iteration is used in the retail-compatible path; reverse-order iteration is preserved under #if !RETAIL_COMPATIBLE_XFER_SAVE.
  • Load-path unification: The in-place linked-list reversal now applies to all version ≤ 9/10 saves, covering both old retail saves and new retail-compatible saves; no reversal is done for version 10/11 (non-retail path) saves that were already saved in reverse order.
  • Saves created under PR fix(object): Save and load game object list in correct order #2161 (version 10 / 11 in Generals / Zero Hour respectively) will trigger XFER_INVALID_VERSION when loaded by a default (RETAIL_COMPATIBLE_XFER_SAVE=1) build, as currentVersion is now lower than the stored version. This is an acknowledged and intentional trade-off noted in the PR description.

Confidence Score: 4/5

  • Safe to merge for default builds; the logic covering all three save/load version scenarios is correct and well-documented.
  • The core logic — guarding the version bump and reverse-iteration behind RETAIL_COMPATIBLE_XFER_SAVE, then unconditionally reversing at load time for all sub-threshold versions — is verified correct for every scenario (old retail saves, new retail-compatible saves, new non-retail saves). The only known breakage (saves from the narrow PR fix(object): Save and load game object list in correct order #2161 window) is intentional and documented. No new serialized fields are introduced.
  • No files require special attention; both changed files are symmetric mirrors of the same fix.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[GameLogic::xfer called] --> B{XFER_SAVE or XFER_LOAD?}

    B -->|SAVE| C{RETAIL_COMPATIBLE_XFER_SAVE?}
    C -->|Yes - version 9/10| D[Iterate forward: getFirstObject → getNextObject]
    C -->|No - version 10/11| E[Find lastObj, iterate backward: getPrevObject]
    D --> F[Write objects newest-first]
    E --> G[Write objects oldest-first]

    B -->|LOAD| H[Create & prepend each object during load]
    H --> I{saved version <= 9 or <= 10?}
    I -->|Yes - forward-saved file| J[Reverse linked list in-place]
    I -->|No - reverse-saved file version 10+/11+| K[No reversal needed]
    J --> L[List order: newest at head]
    K --> L
Loading

Last reviewed commit: 805d193

@L3-M L3-M added 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 Fix Is fixing something, but is not user facing labels Mar 7, 2026
@bobtista bobtista force-pushed the fix/gamelogic-xfer-object-list-no-version-bump branch from 24ae0b7 to 805d193 Compare March 7, 2026 15:16
@bobtista bobtista changed the title bugfix(savegame): Fix object list order without Xfer version bump bugfix(savegame): Guard GameLogic xfer version bump with RETAIL_COMPATIBLE_XFER_SAVE Mar 7, 2026
@xezon xezon added Bug Something is not working right, typically is user facing and removed Fix Is fixing something, but is not user facing labels Mar 7, 2026
Copy link

@xezon xezon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks correct to me.

Did you test it? Does it work?

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.

3 participants