-
Notifications
You must be signed in to change notification settings - Fork 151
feat(replay): Add checkpoint save and resume functionality for replays #2152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat(replay): Add checkpoint save and resume functionality for replays #2152
Conversation
|
| Filename | Overview |
|---|---|
| Core/GameEngine/Source/Common/ReplaySimulation.cpp | Implemented checkpoint save at specified frame and resume functionality with proper error handling |
| GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp | Implemented serialization methods for replay state, added file reopening logic, and proper CRCInfo cleanup in reset() |
| GeneralsMD/Code/GameEngine/Source/Common/System/SaveGame/GameState.cpp | Added CHUNK_Recorder snapshot block, headless mode checks for UI calls, and logic to skip visual blocks in headless saves |
Sequence Diagram
sequenceDiagram
participant CLI as Command Line
participant GM as GameMain
participant RS as ReplaySimulation
participant GS as GameState
participant RC as RecorderClass
participant GL as GameLogic
participant FS as FileSystem
Note over CLI,FS: Checkpoint Save Flow
CLI->>GM: -replay file.rep -saveAtFrame 49000 -saveTo checkpoint.sav
GM->>RS: simulateReplays([file.rep])
RS->>RC: playbackFile(file.rep)
RC->>FS: Open replay file
FS-->>RC: File handle
loop Until target frame or end
RS->>GL: UPDATE()
GL-->>RS: Current frame
alt Frame == saveAtFrame
RS->>GS: saveGame(checkpoint.sav)
GS->>RC: xfer(XFER_SAVE)
Note over RC: Saves replay filename,<br/>file position, CRC state
GS->>FS: Write checkpoint file
FS-->>GS: Success
RS->>RC: stopPlayback()
RC->>FS: Close replay file
end
end
Note over CLI,FS: Checkpoint Resume Flow
CLI->>GM: -loadCheckpoint checkpoint.sav
GM->>RS: continueReplayFromCheckpoint(checkpoint.sav)
RS->>GS: loadGame(checkpoint.sav)
GS->>FS: Read checkpoint file
FS-->>GS: Checkpoint data
GS->>RC: xfer(XFER_LOAD)
Note over RC: Restores replay filename,<br/>file position, CRC state
GS->>RC: loadPostProcess()
RC->>FS: reopenReplayFileAtPosition(position)
FS-->>RC: File handle at saved position
loop Until replay end or CRC mismatch
RS->>GL: UPDATE()
GL-->>RS: Current frame
RC->>FS: Read next commands from position
alt CRC mismatch detected
RS-->>GM: Exit with error
end
end
RS-->>GM: Exit code
| if (TheRecorder->sawCRCMismatch()) | ||
| { | ||
| numErrors++; | ||
| break; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are some issues with the CRC computation for the replay from save game.
|
Looks nice! Will -loadCheckpoint also work with savegames that the player generated? If so we could check that savegames from retail can still be loaded. |
8fc8cb0 to
5674c54
Compare
…r checkpoint loading
…clearing pending queue and initializing m_lastCell
3c73de8 to
f184759
Compare
…y flags instead of pointer
f184759 to
90213b7
Compare
…point CRC consistency Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…C consistency Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…verification Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
eb03756 to
646e04a
Compare
…o-checkpoint feature Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
646e04a to
67f736d
Compare
… recalculation after checkpoint load
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…pointer after load Replace the flag-comparison hack in updateWeaponSet with a proper fix: - Add syncTemplatePointerAfterLoad() method to WeaponSet - Call it from Object::loadPostProcess() to sync the pointer - This ensures m_curWeaponTemplateSet matches what updateWeaponSet would look up Addresses xezon's review feedback about the original fix being a hack. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The wall pieces loop was using MAX_WALL_PIECES as the array index instead of i, causing out-of-bounds memory access and potentially non-deterministic CRC values. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ition after checkpoint load
…eckpoint check Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…those with paths Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…s instead of reset Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ckpoint load Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
… simulation check Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…l from AI Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…vergence after checkpoint load Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…re object updates Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Summary
New Features:
CRC Consistency Fixes:
Testing
-[x] Save checkpoint during replay, load it, verify replay continues without desync
-[x]Test headless mode checkpoint save/load via command line
-[x] Verify CRC matches between original replay and checkpoint-resumed replay
TODO
Notes