When AsyncSaveGameToSlotForLocalPlayer is called multiple times before a save completes, it can trigger the ensure(CurrentSaveRequest > LastSuccessfulSaveRequest) or ensure(CurrentSaveRequest > LastErrorSaveRequest).
This is due to the fact that ULocalPlayerSaveGame::ProcessSaveComplete always operates on the latest CurrentSaveRequest instead of the of the SaveRequest representing the async request. So if multiple async saves are requested before one completes, the first that completes will mark the latest save request as the latest one processed while that request hasn’t completed yet. ISaveGameSystem uses a Task System FPipe so I believe they should always be processed in FIFO order (unless there are prerequisites).
Suggested fix is for ULocalPlayerSaveGame::ProcessSaveComplete to use the SaveRequest passed in which represents the the async request:
// Now that a save completed, update the success/failure
// Every time CurrentSaveRequest is incremented it will result in setting either success or error, but there could be multiple in flight that are processed in order
if (bSuccess)
{
//ensure(CurrentSaveRequest > LastSuccessfulSaveRequest);
//LastSuccessfulSaveRequest = CurrentSaveRequest;
ensure(SaveRequest > LastSuccessfulSaveRequest);
LastSuccessfulSaveRequest = SaveRequest;
}
else
{
//ensure(CurrentSaveRequest > LastErrorSaveRequest);
//LastErrorSaveRequest = CurrentSaveRequest;
ensure(SaveRequest > LastErrorSaveRequest);
LastErrorSaveRequest = SaveRequest;
}
HandlePostSave(bSuccess);
}