> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 理解游戏存档同步流程

> 了解六步 XBOX 游戏存档同步流程：标题启动、连接检查、数据所有权、云同步、游戏循环和会话结束。

本文介绍了游戏存档的六部分同步流程。虽然行为可能会因你使用的具体游戏存档 API 略有不同，但用户发起保存的一般流程是相同的。步骤如下。

1. [标题启动](/build/core-features/common/game-save/game-saves-syncing#title-start)
2. [连接检查](/build/core-features/common/game-save/game-saves-syncing#connection-check)
3. [数据所有权检查](/build/core-features/common/game-save/game-saves-syncing#data-ownership-check)
4. [与云同步数据](/build/core-features/common/game-save/game-saves-syncing#syncing-data-with-the-cloud)
5. [游戏循环](/build/core-features/common/game-save/game-saves-syncing#gameplay-loop)
6. [会话结束](/build/core-features/common/game-save/game-saves-syncing#session-end)

## 标题启动

当标题启动时，第一步是确定为其管理游戏存档的用户。如果该用户在另一台设备上有活动的游戏会话，系统对话框会要求用户切换设备。如果用户切换，另一台设备会将其最新的本地游戏存档数据同步到新设备。如果你希望数据是本地的并绑定到设备，可以使用仅机器的提供程序。此选项将 `null` 用户句柄传递到游戏存档 API 中。

标题选择用户后，它会使用该用户的句柄初始化游戏存档。在初始化期间，游戏存档会连接到 XBOX 网络以准备用户的存储空间。

| API              | 游戏存档提供程序初始化函数                          |
| ---------------- | -------------------------------------- |
| `XGameSave`      | `XGameSaveInitializeProvider()`        |
| `XGameSaveFiles` | `XGameSaveFilesGetFolderWithUIAsync()` |

相关系统对话框：

<img src="https://mintcdn.com/microsoft-4404708b/UZTRJSf0emX1fheE/images/gdk/features/common/signed-into-another-device.png?fit=max&auto=format&n=UZTRJSf0emX1fheE&q=85&s=b333cb6234262d4b20d1b00cfa7119f7" alt="你似乎已在另一台设备上登录。" width="792" height="1026" data-path="images/gdk/features/common/signed-into-another-device.png" />

有关用户模型和用户管理的信息，请参阅[用户模型](/build/core-features/common/game-save/game-saves-developer-guide#user-models)。

有关存储的信息，请参阅[游戏存档存储系统](/build/core-features/common/game-save/game-saves-storage-systems)。

<img src="https://mintcdn.com/microsoft-4404708b/UZTRJSf0emX1fheE/images/gdk/features/common/sync-flow-1-title-start.jpg?fit=max&auto=format&n=UZTRJSf0emX1fheE&q=85&s=e73bde01a012a367ec751c0f00a760c5" alt="同步流程第一步的流程图。" width="663" height="1258" data-path="images/gdk/features/common/sync-flow-1-title-start.jpg" />

## 连接检查

接下来，标题确定它是否可以连接到 XBOX 网络，以确认是否可以同步到云端。如果标题无法连接，用户可选择重试或在离线模式下恢复标题。游戏存档可以在离线模式下运行。

相关系统对话框： <img src="https://mintcdn.com/microsoft-4404708b/UZTRJSf0emX1fheE/images/gdk/features/common/sync-failed-network-dialogue.jpg?fit=max&auto=format&n=UZTRJSf0emX1fheE&q=85&s=2d1a2c71ac69baac7aa3863e5308554d" alt="我们现在无法将你的数据与云端同步。" width="1006" height="559" data-path="images/gdk/features/common/sync-failed-network-dialogue.jpg" />

<img src="https://mintlify.s3.us-west-1.amazonaws.com/microsoft-4404708b/build/core-features/common/game-save/game-saves-dialogues#we-couldnt-get-your-latest-saved-data" alt="我们无法获取你最新的保存数据。" />

### 离线行为

| XBOX 网络访问 | 数据同步模式                                 |
| --------- | -------------------------------------- |
| 是         | 正常云同步流程。继续进行数据所有权检查。                   |
| 否         | 离线模式：标题将数据保存到用户的本地游戏存档存储，但当前会话不会与云端同步。 |

<img src="https://mintcdn.com/microsoft-4404708b/UZTRJSf0emX1fheE/images/gdk/features/common/sync-flow-2-connection-check.jpg?fit=max&auto=format&n=UZTRJSf0emX1fheE&q=85&s=abc4d0abd4bcce59bce850fb348d19fb" alt="同步流程中连接检查步骤的流程图。" width="598" height="444" data-path="images/gdk/features/common/sync-flow-2-connection-check.jpg" />

## 数据所有权检查

在连接确认之后，标题会确定设备是否有权修改数据。如果设备有权修改，它可以获取标题的锁。要使标题获取和释放锁，标题需要访问 XBOX services。

标题会检查是否有另一台设备持有用户数据的锁。这另一台设备可能仍持有锁，原因如下。

* 与 XBOX 网络断开连接，使该设备无法调用 `WebReleaseLock`。
* 另一台设备正在上传大型游戏存档，无法调用 `WebReleaseLock`。

如果另一台设备持有锁，用户有以下选项。

* 强制从另一台设备获取锁，会导致另一台设备丢失会话数据。
* 尝试再次正常获取锁。
* 取消获取锁。

如果用户取消获取锁，则标题以离线模式启动。

有关更多连接丢失和锁场景，请参阅[连接丢失和锁场景](/build/core-features/common/game-save/game-saves-syncing#connection-loss-and-lock-scenarios)。

相关系统对话框：

<img src="https://mintcdn.com/microsoft-4404708b/UZTRJSf0emX1fheE/images/gdk/features/common/lock-contention-dialogue.jpg?fit=max&auto=format&n=UZTRJSf0emX1fheE&q=85&s=38894f740f55a181c2137b3c9b84cb18" alt="你的另一台 XBOX 主机同步到云端花费的时间较长" width="639" height="563" data-path="images/gdk/features/common/lock-contention-dialogue.jpg" />

有关在 XBOX 网络上监视锁获取的详细信息，请参阅[检查游戏存档网络流量](/build/core-features/common/game-save/game-saves-tools#inspecting-game-saves-network-traffic)。

<img src="https://mintcdn.com/microsoft-4404708b/UZTRJSf0emX1fheE/images/gdk/features/common/sync-flow-3-data-ownership-check.jpg?fit=max&auto=format&n=UZTRJSf0emX1fheE&q=85&s=b21137181a92b3e1afaad2618bea46ae" alt="同步流程中数据所有权检查的流程图。" width="846" height="1092" data-path="images/gdk/features/common/sync-flow-3-data-ownership-check.jpg" />

## 与云同步数据

标题获取用户数据的锁后，会将该数据与云端同步。然后标题决定它执行以下操作之一：

* 上传本地游戏存档数据。
* 下载云端数据并更新本地游戏存档数据。
* 不采取任何操作。
* 解决任何数据冲突。

标题通过比较两个时间戳来做出此决定。

* **本地保存时间**：此设备上次写入存档的时间
* **云端保存时间**：云端副本上次更新的时间

### 四种同步结果

| 本地 vs. 云端 | 操作      | 含义                         |
| --------- | ------- | -------------------------- |
| 两者都未更改    | 不执行任何操作 | 两个位置的数据匹配。没有新进度。           |
| 仅本地已更改    | 上传本地>云端 | 用户已离线游玩。将较新的本地游戏存档数据发送到云端。 |
| 仅云端已更改    | 下载云端>本地 | 用户在另一台设备上游玩。从云端获取其游戏存档数据。  |
| 两者都已更改    | 冲突>提示用户 | 每个位置都显示进度。而另一个未显示。用户解决冲突。  |

<Note>
  如果从云端下载，会出现同步对话框：[正在同步 ... 的数据](/build/core-features/common/game-save/game-saves-dialogues#syncing-data)。如果用户使用此对话框取消游戏存档，则标题继续以离线模式运行。
</Note>

### 已更改和保存状态

此场景假设用户在两台设备（设备 A 和设备 B）上进行游玩。

**本地已更改**

用户在设备 A 上离线时取得了进度。例如，用户在设备 A 上没有互联网连接的情况下升到了 126 级。

**云端已更改**

自用户上次同步设备 A 以来，进度已从设备 B 上传。例如，用户在设备 B 上升到 99 级并上传到了云端。

**两者都已更改**

用户在设备 A 上离线游玩。自上次同步设备 A 以来，用户也在设备 B 上进行了游玩。例如，设备 A 是 126 级。云端是 99 级。

如果存在冲突，系统会用对话框提示用户解决冲突：[你想使用哪一个？](/build/core-features/common/game-save/game-saves-dialogues#which-one-do-you-want-to-use)

### 原子性

游戏存档在容器（文件夹）级别是原子的。如果云端文件夹包含匹配的本地文件夹中不包含的 blob，则系统将这两个文件夹视为独立的。此差异会造成冲突。

<img src="https://mintcdn.com/microsoft-4404708b/UZTRJSf0emX1fheE/images/gdk/features/common/sync-flow-4-sync-data-with-cloud.jpg?fit=max&auto=format&n=UZTRJSf0emX1fheE&q=85&s=2e20d3966826e47b9b79c5bf30cc9227" alt="同步流程中云同步的流程图。" width="930" height="1119" data-path="images/gdk/features/common/sync-flow-4-sync-data-with-cloud.jpg" />

## 游戏循环

*游戏循环*是游戏会话的活动部分。它在标题完成与云端同步存档数据后开始。

在活动游戏会话期间，标题在本地读取和写入存档数据。在此期间创建或更新的所有数据都保留在游戏存档本地存储中，直到系统执行云同步。

当满足以下主机或 PC 条件之一时，游戏循环在用户的游戏会话结束时结束。当主机或 PC 触发状态更改（如挂起、终止、注销或其他系统事件）时，会话结束。

### 定期同步到云端

每 30 分钟游玩时间，标题尝试自动同步到云端。此行为基于以下场景。

| 游戏存档 API                | 操作      | 时机                      |
| ----------------------- | ------- | ----------------------- |
| `XGameSaveFiles`、无代码云存档 | 上传本地>云端 | 自游戏写入指定存档区域以来已过去 30 分钟。 |
| `XGameSave`             | 上传本地>云端 | 每 30 分钟游玩时间。            |

<img src="https://mintcdn.com/microsoft-4404708b/UZTRJSf0emX1fheE/images/gdk/features/common/sync-flow-5-gameplay-loop.jpg?fit=max&auto=format&n=UZTRJSf0emX1fheE&q=85&s=3a0165fb65cfb429d4455e018b4fd95f" alt="游戏循环与游戏存档交互的流程图。" width="714" height="977" data-path="images/gdk/features/common/sync-flow-5-gameplay-loop.jpg" />

## 会话结束

游戏会话结束后，标题将新数据上传到云端。当设备有连接时，设备会尝试将数据上传到云端。数据上传后，锁被释放。

有关调试查看 XBOX 网络上的锁释放，请参阅[检查游戏存档网络流量](/build/core-features/common/game-save/game-saves-tools#inspecting-game-saves-network-traffic)。

<img src="https://mintcdn.com/microsoft-4404708b/UZTRJSf0emX1fheE/images/gdk/features/common/sync-flow-6-session-end.jpg?fit=max&auto=format&n=UZTRJSf0emX1fheE&q=85&s=fb2ca714223c6846bcf37775a7d98c6f" alt="同步流程中会话结束行为的流程图。" width="1384" height="587" data-path="images/gdk/features/common/sync-flow-6-session-end.jpg" />

## 连接丢失和锁场景

在连接丢失期间写入的数据存储在游戏存档本地存储中，并在连接恢复后上传。但是，如果用户尝试使用另一台设备，则当前设备因连接丢失而无法释放锁。用户能够强制将锁转移到另一台设备。根据这些锁转移发生的时间，标题可能会经历不同的行为。

### 标题启动前连接丢失

> **时机：** 用户在没有连接的情况下启动标题。

由于没有连接，标题为用户提供以离线模式启动的选项。当设备重新连接到 XBOX 网络并且云端包含较新的数据时，标题会将本地数据视为过时。在这种情况下，标题会通过挂起操作终止应用来结束游戏会话。

相关系统对话框：[我们需要关闭此游戏或应用](/build/core-features/common/game-save/game-saves-dialogues#we-need-to-close-this-game-or-app)

### 游戏循环期间连接丢失

> **时机：** 用户处于活动游戏会话中，且标题仍持有锁。在某个时刻，连接丢失。然后标题允许在此丢失期间继续游玩。

| 离线设备 | 重新连接时的锁状态 | 重新连接时的标题操作           | 用户体验/UI   |
| ---- | --------- | -------------------- | --------- |
| 主机   | 仍持有锁      | 继续在本地保存。             | 存档进入本地存储。 |
| 主机   | 锁被另一台设备获取 | 标题终止。                | 退出到主屏幕。   |
| PC   | 仍持有锁      | 继续在本地保存。             | 存档进入本地存储。 |
| PC   | 锁被另一台设备获取 | 游玩正常继续。冲突解决在下次同步时完成。 | 游玩继续。     |

### 会话结束（终止或挂起）前连接丢失

> **时机：** 玩家在设备断开连接时退出/挂起标题。设备仍有未同步的本地数据。

| 离线设备 | 连接丢失时机 | 重新连接时的锁状态 | 重新连接时的设备操作             |
| ---- | ------ | --------- | ---------------------- |
| 主机   | 终止前    | 仍持有锁      | 数据上传并释放锁。              |
| 主机   | 终止前    | 锁被另一台设备获取 | 数据在下次标题启动时经过合并解决。      |
| 主机   | 挂起前    | 仍持有锁      | 数据上传并释放锁。              |
| 主机   | 挂起前    | 锁被另一台设备获取 | 标题终止，数据在下次标题启动时经过合并解决。 |
| PC   | 终止前    | 仍持有锁      | 数据上传并释放锁。              |
| PC   | 终止前    | 锁被另一台设备获取 | 数据在下次标题启动时经过合并解决。      |
| PC   | 挂起前    | 仍持有锁      | 数据上传并释放锁。              |
| PC   | 挂起前    | 锁被另一台设备获取 | 数据在下次标题启动时经过合并解决。      |

## 断电

断电的行为类似于连接丢失。主要区别是任何正在进行的保存操作都会丢失。


## Related topics

- [游戏存档概述](/zh-CN/build/core-features/common/game-save/game-saves-overview.md)
- [游戏存档调试](/zh-CN/build/core-features/common/game-save/game-saves-debugging.md)
- [游戏存档系统对话框](/zh-CN/build/core-features/common/game-save/game-saves-dialogues.md)
- [XGameSaveFiles API 概述](/zh-CN/build/core-features/common/game-save/xgamesavefiles.md)
- [XGameSave API 概述](/zh-CN/build/core-features/common/game-save/xgamesave.md)
