Connection modes
Connected to cloud mode
When network is available andPFGameSaveFilesAddUserWithUiAsync() completes successfully, the system operates in connected to cloud mode. In this mode:
- All APIs function normally with full cloud synchronization
- Save data uploads work as expected
- Storage quota information is available
- Active device monitoring works properly
Offline mode (not connected to cloud)
When network is unavailable or the user chooses to play offline, the system enters offline mode with limited functionality. You can check the current connection status usingPFGameSaveFilesIsConnectedToCloud() to determine which mode the system is operating in.
Handling network failures during initial sync
WhenPFGameSaveFilesAddUserWithUiAsync() is called without network connectivity, it triggers a PFGameSaveFilesUiSyncFailedCallback. The XAsyncBlock callback doesn’t fire while the system waits for the user’s response. The async operation is paused until the user selects a terminal action.
- Try Again (
Retry): Retries the network call. If the retry also fails, this callback fires again and the user must respond again. TheXAsyncBlockcallback remains deferred through each retry loop. - Use Offline (
UseOffline): TheXAsyncBlockcallback fires withS_OK, but the system enters offline mode (detectable withPFGameSaveFilesIsConnectedToCloud()). - Cancel: The
XAsyncBlockcallback fires withE_PF_GAMESAVE_USER_CANCELLED.
API behavior in offline mode
When in offline mode, APIs behave differently:APIs that work normally
PFGameSaveFilesGetFolder()- Returns local save folder path
APIs with limited functionality
PFGameSaveFilesUploadWithUiAsync()- ReturnsS_OKimmediately, but async completion returnsE_PF_GAMESAVE_DISCONNECTED_FROM_CLOUDPFGameSaveFilesGetRemainingQuota()- ReturnsE_PF_GAMESAVE_DISCONNECTED_FROM_CLOUDPFGameSaveFilesSetActiveDeviceChangedCallback()- Can be set but will never trigger
Returning to online mode
- Call
PFGameSaveFilesAddUserWithUiAsync()again to attempt reconnection - No need to fully reinitialize the Game Saves system
- Will show failure UI again if network is still unavailable
- Use
PFGameSaveFilesIsConnectedToCloud()to verify connection status after retry attempts
When Game Saves enters offline mode or returns an error
A common integration question is: when does the initial sync (PFGameSaveFilesAddUserWithUiAsync) drop the player into offline mode, and when does it fail with an error code? There are three terminal outcomes (connected, offline, or cancelled), and a cancel can come from either the player or the game:
Key points:
- Offline mode is a success outcome, not an error. It is only entered by an explicit Use Offline choice, and the async operation completes with
S_OK. Detect it withPFGameSaveFilesIsConnectedToCloud(). - Transient/technical failures are surfaced through the sync-failed UI, not returned directly from
PFGameSaveFilesAddUserWithUiAsync. The user (or your auto-response) then choosesRetry,UseOffline, orCancel, which resolves to one of the three outcomes above. - Cancel is terminal and produces no save folder. Treat “cancelled” (or any failure that leaves no folder) as don’t allow play.
- Player cancel and game cancel return different codes. Only the player choosing Cancel on a prompt produces
E_PF_GAMESAVE_USER_CANCELLED. If your game cancels the operation itself withXAsyncCancel, it completes withE_ABORT. Check for both if you want to treat them the same way.
Cancelling a conflict prompt is also terminal. It completes with
E_PF_GAMESAVE_USER_CANCELLED and does not automatically fall through to a sync-failed “Use Offline” prompt. If you want a “reject the conflict but keep playing offline” experience, design it explicitly (for example, re-run PFGameSaveFilesAddUserWithUiAsync and select Use Offline on the resulting failure). See Game Saves conflicts.Game Saves error codes
The following HRESULTs are defined by the Game Saves SDK. Codes in the0x8923xxxx range are Game Saves-specific; 0x800704C7 is HRESULT_FROM_WIN32(ERROR_CANCELLED).
For how these outcomes are produced by the built-in (out-of-process) system UI versus your own callbacks, see Game Saves UI callbacks.
Additional connection status scenarios
ThePFGameSaveFilesIsConnectedToCloud() API is particularly useful because disconnection can happen in multiple ways:
- Network unavailable during sync: User explicitly chooses to play offline
- Active device changed: Another device takes over as the active device, automatically putting this device in offline mode
Best practices for offline support
- Always implement sync failure callbacks to handle network issues gracefully
- Check connection status regularly using
PFGameSaveFilesIsConnectedToCloud()before attempting cloud operations - Inform players when operating in offline mode so they understand saves won’t sync
- Provide retry options when network connectivity is restored
- Local saves always work - players can continue playing regardless of network status
- Monitor for disconnection - remember that devices can be disconnected when another device becomes active
Upload behavior in connected mode
Even in connected mode, uploads can fail due to network issues or rate limits. When this happens, theXAsyncBlock callback doesn’t fire immediately. The async operation pauses while the system waits for the user’s response through the UI callback state machine:
- The
PFGameSaveFilesUiSyncFailedCallbackfires with the error details. - The
XAsyncBlockcallback doesn’t fire yet. The operation is paused while the system waits for a response. - If the user selects
Retry, the upload retries. If it fails again, the callback fires again and the user must respond again. - If the user selects
Cancel, theXAsyncBlockcallback fires withE_PF_GAMESAVE_USER_CANCELLED. - If a retry succeeds, the
XAsyncBlockcallback fires withS_OK.
PFGameSaveFilesUploadWithUiAsync() again later when network is restored.
In-process, don’t offer
Use Offline in the sync-failed prompt while an upload is running. The upload fires the same PFGameSaveFilesUiSyncFailedCallback as the initial sync, so the SDK doesn’t restrict the choices. However, if your game responds with UseOffline to an upload failure, the upload fails with E_ABORT (and debug builds assert). Offer only Retry and Cancel there.When an upload takes the session offline
An upload doesn’t normally change the connection mode, but it can end with the session offline in the following cases. In each one, the upload completes withE_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD, and PFGameSaveFilesIsConnectedToCloud() returns false afterward.
- The session was already offline. The upload doesn’t run and completes with
E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD, even if the network has been restored. - The cloud has a newer save. If the service reports that a newer save was committed from another device when the upload finalizes, Game Saves puts the session offline, fires the active-device-changed callback, and completes the upload with
E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD. - The player chooses
Use Offlineon the re-lock prompt. If an earlier upload committed its data but failed afterward, the next upload first has to re-acquire the save lock. A sync-failed prompt during that step can be answered withUseOffline, which takes the session offline and completes the upload withE_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD.
PFGameSaveFilesAddUserWithUiAsync() again.
Cancelling an upload
An upload can be cancelled the same way the initial sync can: the user canCancel the progress UI while the upload is in flight, or Cancel the sync-failed prompt if the upload hit an error. Either way, PFGameSaveFilesUploadWithUiAsync() completes with E_PF_GAMESAVE_USER_CANCELLED (0x800704C7) and the save isn’t uploaded. Its terminal results are success, cancelled, or failed (where E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD means the session is now offline; see When an upload takes the session offline). Handle E_PF_GAMESAVE_USER_CANCELLED distinctly from other failures so you can tell “the player backed out” apart from “the upload errored.” If your game cancels the upload itself with XAsyncCancel, it completes with E_ABORT rather than E_PF_GAMESAVE_USER_CANCELLED.