Skip to main content
Game Saves is designed to work both online and offline, allowing players to continue playing even when network connectivity is unavailable. The system operates in two distinct modes based on network availability and user choices.

Connection modes

Connected to cloud mode

When network is available and PFGameSaveFilesAddUserWithUiAsync() 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 using PFGameSaveFilesIsConnectedToCloud() to determine which mode the system is operating in.

Handling network failures during initial sync

When PFGameSaveFilesAddUserWithUiAsync() 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.
User response options:
  • Try Again (Retry): Retries the network call. If the retry also fails, this callback fires again and the user must respond again. The XAsyncBlock callback remains deferred through each retry loop.
  • Use Offline (UseOffline): The XAsyncBlock callback fires with S_OK, but the system enters offline mode (detectable with PFGameSaveFilesIsConnectedToCloud()).
  • Cancel: The XAsyncBlock callback fires with E_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() - Returns S_OK immediately, but async completion returns E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD
  • PFGameSaveFilesGetRemainingQuota() - Returns E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD
  • PFGameSaveFilesSetActiveDeviceChangedCallback() - 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 with PFGameSaveFilesIsConnectedToCloud().
  • Transient/technical failures are surfaced through the sync-failed UI, not returned directly from PFGameSaveFilesAddUserWithUiAsync. The user (or your auto-response) then chooses Retry, UseOffline, or Cancel, 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 with XAsyncCancel, it completes with E_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 the 0x8923xxxx 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

The PFGameSaveFilesIsConnectedToCloud() 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
Use this API before attempting cloud operations to provide appropriate user feedback.

Best practices for offline support

  1. Always implement sync failure callbacks to handle network issues gracefully
  2. Check connection status regularly using PFGameSaveFilesIsConnectedToCloud() before attempting cloud operations
  3. Inform players when operating in offline mode so they understand saves won’t sync
  4. Provide retry options when network connectivity is restored
  5. Local saves always work - players can continue playing regardless of network status
  6. 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, the XAsyncBlock callback doesn’t fire immediately. The async operation pauses while the system waits for the user’s response through the UI callback state machine:
  1. The PFGameSaveFilesUiSyncFailedCallback fires with the error details.
  2. The XAsyncBlock callback doesn’t fire yet. The operation is paused while the system waits for a response.
  3. If the user selects Retry, the upload retries. If it fails again, the callback fires again and the user must respond again.
  4. If the user selects Cancel, the XAsyncBlock callback fires with E_PF_GAMESAVE_USER_CANCELLED.
  5. If a retry succeeds, the XAsyncBlock callback fires with S_OK.
The game can call 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 with E_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 Offline on 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 with UseOffline, which takes the session offline and completes the upload with E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD.
To reconnect, call PFGameSaveFilesAddUserWithUiAsync() again.

Cancelling an upload

An upload can be cancelled the same way the initial sync can: the user can Cancel 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.
Last modified on October 20, 2026