跳转到主要内容
Game Saves 的设计支持在线与离线两种情况,即便网络连接不可用,玩家也能继续游玩。系统会根据网络可用性和用户选择在两种不同的模式下工作。

连接模式

已连接云端模式

当网络可用且 PFGameSaveFilesAddUserWithUiAsync() 成功完成时,系统运行于已连接云端模式。在此模式下:
  • 所有 API 均正常工作,支持完整的云端同步
  • 存档数据可按预期上传
  • 存储配额信息可用
  • 活动设备监控可正常工作

离线模式(未连接云端)

当网络不可用或用户选择离线游玩时,系统进入离线模式,功能受限。你可以使用 PFGameSaveFilesIsConnectedToCloud() 检查当前连接状态,以判断系统所处的模式。

处理初次同步时的网络故障

当在无网络连接时调用 PFGameSaveFilesAddUserWithUiAsync(),会触发 PFGameSaveFilesUiSyncFailedCallback。系统在等待用户响应期间不会触发 XAsyncBlock 回调。异步操作会一直暂停,直到用户选择了一个最终动作。
用户响应选项:
  • 再试一次(Retry):重新发起网络调用。如果重试仍失败,此回调会再次触发,用户须再次响应。在每次重试循环中 XAsyncBlock 回调都会保持延迟。
  • 使用离线模式(UseOffline):XAsyncBlock 回调以 S_OK 触发,但系统进入离线模式(可通过 PFGameSaveFilesIsConnectedToCloud() 检测)。
  • 取消:XAsyncBlock 回调以 E_PF_GAMESAVE_USER_CANCELLED 触发。

离线模式下的 API 行为

在离线模式下,各 API 的行为有所不同:

正常工作的 API

  • PFGameSaveFilesGetFolder() —— 返回本地存档文件夹路径

功能受限的 API

  • PFGameSaveFilesUploadWithUiAsync() —— 立即返回 S_OK,但异步完成时返回 E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD
  • PFGameSaveFilesGetRemainingQuota() —— 返回 E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD
  • PFGameSaveFilesSetActiveDeviceChangedCallback() —— 可以设置,但永远不会触发

恢复在线模式

  • 再次调用 PFGameSaveFilesAddUserWithUiAsync() 以尝试重新连接
  • 无需完全重新初始化 Game Saves 系统
  • 如果网络仍不可用,会再次显示失败 UI
  • 重试后使用 PFGameSaveFilesIsConnectedToCloud() 验证连接状态

Game Saves 何时进入离线模式或返回错误

一个常见的集成问题是:初次同步(PFGameSaveFilesAddUserWithUiAsync)何时会让玩家进入离线模式,何时会以错误代码失败? 共有三种最终结果(已连接、离线或已取消),而取消既可能来自玩家,也可能来自游戏: 要点:
  • 离线模式是成功结果,而不是错误。 只有在明确选择 Use Offline 时才会进入离线模式,并且异步操作以 S_OK 完成。使用 PFGameSaveFilesIsConnectedToCloud() 检测它。
  • 暂时性/技术性故障通过同步失败 UI 呈现,而不是直接从 PFGameSaveFilesAddUserWithUiAsync 返回。随后由用户(或你的自动响应)选择 Retry、UseOffline 或 Cancel,最终得到上述三种结果之一。
  • 取消是最终结果,且不会提供存档文件夹。 将“已取消”(或任何未留下文件夹的失败)视为不允许游玩。
  • 玩家取消和游戏取消返回不同的代码。 只有玩家在提示中选择 Cancel 才会产生 E_PF_GAMESAVE_USER_CANCELLED。如果你的游戏自行使用 XAsyncCancel 取消操作,则操作以 E_ABORT 完成。如果希望以相同方式处理两者,请同时检查这两个代码。
取消冲突提示同样是最终结果。它以 E_PF_GAMESAVE_USER_CANCELLED 完成,并且不会自动转入同步失败的“Use Offline”提示。如果你希望提供“拒绝冲突但继续离线游玩”的体验,请明确地进行设计(例如,重新运行 PFGameSaveFilesAddUserWithUiAsync,并在随后的失败中选择 Use Offline)。请参阅 Game Saves 冲突。

Game Saves 错误代码

以下 HRESULT 由 Game Saves SDK 定义。0x8923xxxx 范围内的代码是 Game Saves 专用的;0x800704C7 是 HRESULT_FROM_WIN32(ERROR_CANCELLED)。 有关这些结果如何由内置(进程外)系统 UI 与你自己的回调分别产生,请参阅 Game Saves UI 回调。

其他连接状态场景

PFGameSaveFilesIsConnectedToCloud() API 特别有用,因为断开连接可能以多种方式发生:
  • 同步期间网络不可用:用户明确选择离线游玩
  • 活动设备变更:另一台设备接管成为活动设备,会自动将当前设备置于离线模式
在尝试云端操作前使用此 API,以便向用户提供合适的反馈。

离线支持最佳实践

  1. 始终实现同步失败回调,以妥善处理网络问题
  2. 在尝试云端操作前,定期使用 PFGameSaveFilesIsConnectedToCloud() 检查连接状态
  3. 在离线模式下运行时告知玩家,让他们了解存档不会同步
  4. 在网络恢复时提供重试选项
  5. 本地存档始终可用——不论网络状态如何,玩家都可以继续游玩
  6. 监控断开事件——请记住,当另一台设备成为活动设备时,本设备可能被断开

已连接模式下的上传行为

即使在已连接模式下,上传也可能因网络问题或速率限制而失败。发生此情况时,XAsyncBlock 回调不会立即触发。系统会在通过 UI 回调状态机 等待用户响应期间暂停异步操作:
  1. PFGameSaveFilesUiSyncFailedCallback 会带着错误详情触发。
  2. XAsyncBlock 回调尚未触发。操作会在系统等待响应期间暂停。
  3. 如果用户选择 Retry,将重试上传。如果再次失败,回调会再次触发,用户须再次响应。
  4. 如果用户选择 Cancel,XAsyncBlock 回调会以 E_PF_GAMESAVE_USER_CANCELLED 触发。
  5. 如果重试成功,XAsyncBlock 回调会以 S_OK 触发。
网络恢复后,游戏可以稍后再次调用 PFGameSaveFilesUploadWithUiAsync()。
在进程内模式下,上传正在运行时不要在同步失败提示中提供 Use Offline。 上传会触发与初次同步相同的 PFGameSaveFilesUiSyncFailedCallback,因此 SDK 不会限制可选项。但是,如果你的游戏对上传失败响应 UseOffline,上传将以 E_ABORT 失败(并且调试版本会触发断言)。此时只应提供 Retry 和 Cancel。

上传何时使会话进入离线状态

上传通常不会改变连接模式,但在以下情况下,上传结束时会话可能处于离线状态。在每种情况下,上传都会以 E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD 完成,并且之后 PFGameSaveFilesIsConnectedToCloud() 返回 false。
  • 会话已经处于离线状态。 上传不会运行,并以 E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD 完成,即使网络已经恢复也是如此。
  • 云端有较新的存档。 如果在上传最终完成时服务报告另一台设备已提交了较新的存档,Game Saves 会使会话进入离线状态,触发活动设备变更回调,并以 E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD 完成上传。
  • 玩家在重新锁定提示中选择 Use Offline。 如果之前的上传已提交其数据但随后失败,则下一次上传必须先重新获取存档锁。在此步骤中出现的同步失败提示可以用 UseOffline 响应,这会使会话进入离线状态,并以 E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD 完成上传。
若要重新连接,请再次调用 PFGameSaveFilesAddUserWithUiAsync()。

取消上传

上传的取消方式与初次同步相同:用户可以在上传进行期间对进度 UI 选择 Cancel,或者在上传遇到错误时对同步失败提示选择 Cancel。无论哪种方式,PFGameSaveFilesUploadWithUiAsync() 都会以 E_PF_GAMESAVE_USER_CANCELLED(0x800704C7)完成,并且存档不会被上传。其最终结果为成功、已取消或失败(其中 E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD 表示会话现在处于离线状态;请参阅上传何时使会话进入离线状态)。请将 E_PF_GAMESAVE_USER_CANCELLED 与其他失败区分处理,以便区分“玩家主动退出”和“上传出错”。如果你的游戏自行使用 XAsyncCancel 取消上传,则会以 E_ABORT 而不是 E_PF_GAMESAVE_USER_CANCELLED 完成。
最后修改于 2026年10月20日