> ## 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.

# Game Saves 衝突

> 當本機和雲端存檔資料不一致時，解決 PlayFab Game Saves 衝突，並使用同步策略保護跨裝置的玩家進度。

# Game Save 衝突和不可部分完成單位

## 概觀

當您在多部裝置上修改相同的遊戲資料時，就會發生存檔衝突。系統需要決定要保留哪個版本。若要設計您的存檔資料結構，您需要了解系統如何偵測和解決衝突。

## 衝突何時發生

只有在下列所有條件都成立時，同步作業 (`PFGameSaveFilesAddUserWithUiAsync`) 期間才會發生衝突：

1. **存在本機變更**：您自上次同步以來在本機修改了檔案。
2. **存在雲端變更**：另一部裝置自上次同步以來上傳了較新的資料。
3. **相同的不可部分完成單位**：兩項變更都位於相同的根層級資料夾中。

### 衝突偵測矩陣

| 本機裝置變更 | 雲端在相同不可部分完成單位中有變更 | 結果 |
| - | - | - |
| 已修改檔案 | 是 | **衝突** |
| 已刪除檔案 | 是 | **衝突** |
| 無變更 | 是 | 繼續下載 |
| 已修改檔案 | 否 | 繼續上傳 |
| 已刪除檔案 | 否 | 繼續刪除 |

## 什麼是不可部分完成單位？

某些檔案同步系統會逐一檔案處理衝突。如果同一個檔案需要上傳和下載，就會發生衝突。在 Game Saves 中，每個根層級子資料夾都被視為一個*不可部分完成單位*。

<Note>
  **每個根層級子資料夾都是一個不可部分完成單位。**
</Note>

如果根層級子資料夾內的任何檔案或子資料夾需要下載，且該相同根子資料夾中的任何檔案或資料夾需要上傳，則整個不可部分完成單位都會發生衝突。

此做法可讓您：

* **維護資料完整性**：相互依存的檔案會一起保持一致
* **提供隔離**：個別資料夾中的獨立資料可以同步而不會發生衝突
* **將衝突降至最低**：不同裝置上對不同不可部分完成單位的變更會自動合併

### 存檔結構範例

```
SaveRoot/
├── save.dat              ← Atomic unit: root
├── player.dat            ← Atomic unit: root
├── Save1/
│   ├── stats.json        ← Atomic unit: Save1
│   └── inventory.json    ← Atomic unit: Save1
├── Save2/
│   ├── stats.json        ← Atomic unit: Save2
│   └── inventory.json    ← Atomic unit: Save2
└── WorldState/
    ├── map.dat           ← Atomic unit: WorldState
    └── npcs/
        └── positions.dat ← Atomic unit: WorldState
```

### 衝突案例

| 裝置 A 變更 | 裝置 B 變更 | 衝突？ | 原因 |
| - | - | - | - |
| `Save1/stats.json` | `Save1/inventory.json` | **是** | 相同的不可部分完成單位：Save1 |
| `Save1/stats.json` | `Save2/stats.json` | 否 | 不同的單位：Save1 與 Save2 |
| `WorldState/map.dat` | `WorldState/npcs/positions.dat` | **是** | 相同的不可部分完成單位：WorldState |
| `save.dat` | `Save1/stats.json` | 否 | 不同的單位：根目錄與 Save1 |
| `player.dat` | `save.dat` | **是** | 相同的不可部分完成單位：根目錄 |

## 根層級檔案：特殊情況

**存檔根目錄中的所有檔案共用一個不可部分完成單位。**

系統會將您直接放在存檔根目錄 (不在任何子資料夾中) 的所有檔案一起分組為單一不可部分完成單位。如果您在本機修改一個根層級檔案，而另一部裝置修改另一個不同的根層級檔案，此差異就會觸發衝突。

| 裝置 A (本機) | 裝置 B (雲端) | 相同的不可部分完成單位？ | 結果 |
| - | - | - | - |
| 修改 `rootfile1.txt` | 修改 `rootfile2.txt` | ✅ 是 | **衝突** |
| 修改 `rootfile1.txt` | 修改 `save1/config.ini` | ❌ 否 | 無衝突，兩者都會同步 |
| 刪除 `save.dat` | 修改 `progress.dat` | ✅ 是 | **衝突** |

## 使用者選擇選項

發生衝突時，玩家可以選擇：

* **使用本機資料 (保留本機)**：保留裝置目前的存檔資料。
* **使用雲端資料 (保留雲端)**：下載並使用雲端存檔資料。

### 重要：解決方式是全有或全無

<Note>
  ⚠️ **重要**：雖然不可部分完成單位決定*何時*偵測到衝突，但使用者的衝突解決選擇會套用至**整個存檔**，而不是個別的不可部分完成單位。
</Note>

### 範例：混合衝突案例

```
SaveRoot/
├── SlotA/ ← Local: modified, Cloud: modified  → CONFLICT
├── SlotB/ ← Local: modified, Cloud: unchanged → Local-only change
├── SlotC/ ← Local: unchanged, Cloud: modified → Cloud-only change
└── SlotD/ ← Local: modified, Cloud: unchanged → Local-only change
```

**使用者看到衝突提示** (由於 SlotA)。

| 使用者選擇 | SlotA | SlotB | SlotC | SlotD |
| - | - | - | - | - |
| **保留本機** | ✅ 保留本機 | ✅ 上傳本機 | ❌ 雲端變更**遺失** | ✅ 上傳本機 |
| **保留雲端** | ✅ 下載雲端 | ❌ 本機變更**被覆寫** | ✅ 下載雲端 | ❌ 本機變更**被覆寫** |

### 為什麼這很重要

1. **保留本機會遺失僅限雲端的變更**：如果您因為 SlotA 中的衝突而選擇「保留本機」，就不會收到另一部裝置對 SlotC 所做的雲端更新。

2. **保留雲端會遺失僅限本機的變更**：如果您選擇「保留雲端」，雲端狀態會覆寫您對 SlotB 和 SlotD 的本機變更。

3. **可以回復**：這兩種選擇都會保留捨棄的分支，以供日後回復使用。

### 設計摘要

| 層面 | 細微度 |
| - | - |
| 衝突**偵測** | 依不可部分完成單位 (根子資料夾) |
| 衝突**解決** | 整個存檔 (全有或全無) |

這種全有或全無的做法簡化了玩家體驗。雖然依不可部分完成單位解決在技術上能維持資料一致性 (因為不可部分完成單位定義了一致性界限)，但它會造成使用者體驗上的挑戰：

* 玩家需要了解不可部分完成單位和資料夾界限的概念。
* 混合的結果 (某些資料夾來自本機，其他來自雲端) 可能會讓玩家對最終狀態感到困惑。
* 針對每個衝突的不可部分完成單位分別提示，會讓衝突解決變得令人不知所措。

透過提供單一的**保留本機**與**保留雲端**選擇，玩家只需做出一個明確的決定，而不需要了解底層的存檔結構。

## 不會發生衝突的情況

### 兩端都刪除

如果兩部裝置都刪除相同的檔案 (或相同不可部分完成單位中的檔案)，**就不會發生衝突**。系統會識別出兩部裝置都同意應移除該檔案。

### 不同不可部分完成單位中的變更

如果裝置 A 修改 `SlotA/` 中的檔案，而裝置 B 修改 `SlotB/` 中的檔案，就不會發生衝突。同步會自動合併這兩項變更。

## 最佳做法

### 1. 仔細設計資料夾結構

針對獨立的存檔單位使用子資料夾：

```
SaveRoot/
├── Slot1/           ← Each slot is independent
│   └── save.dat
├── Slot2/
│   └── save.dat
```

每個存檔欄位都是一個根層級子資料夾的欄位型遊戲存檔系統，是如何有效使用不可部分完成單位的簡單範例。

其他範例包括：

* **共用參考資料**：將任何存檔欄位都可能使用的資料 (例如已解鎖的內容或成就) 儲存在其自己的子資料夾中，使其獨立於個別存檔欄位進行同步。
* **大型資產集合**：如果您的遊戲儲存了獨立更新的大型檔案集 (例如下載的內容套件或使用者建立的關卡)，請考慮將它們分割成多個根子資料夾，讓某個集合的更新不會與另一個集合的更新發生衝突。

### 2. 避免將經常修改的資料放在根層級檔案中

所有根層級檔案共用一個不可部分完成單位。如果您想要獨立同步經常修改的檔案，請避免將它們放在根目錄中。

**與其使用：**

```
SaveRoot/
├── autosave.dat     ← All root files = 1 atomic unit
└── save1.dat
└── save2.dat
```

**請考慮：**

```
SaveRoot/
├── AutoSave/
│   └── autosave.dat     ← Independent unit
└── Save1/
    └── gamesave.dat ← Independent unit
```

### 3. 將相關資料分組在一起

對必須一起保持一致的檔案使用相同的資料夾。

```
SaveRoot/
├── Save1/
│   ├── stats.json       ← These files are interdependent
│   ├── inventory.json   ← and should conflict together
│   └── quests.json
```

### 4. 將衝突降至最低

經常上傳以降低發生衝突的機會。同步的頻率越高，兩部裝置產生分歧變更的可能性就越低。

### 5. 監視衝突率

使用 [PlayStream 事件](/zh-TW/services/playfab/player-progression/game-saves/playstream-events)追蹤衝突發生的頻率，以及玩家如何解決衝突。衝突率上升，或強烈偏向「保留本機」而非「保留遠端」，可能表示有值得調查的 UX 或存檔頻率問題。


## Related topics

- [Game Saves 回復](/zh-TW/services/playfab/player-progression/game-saves/rollback.md)
- [Game Saves 快速入門](/zh-TW/services/playfab/player-progression/game-saves/quickstart.md)
- [Game Saves UI 回呼](/zh-TW/services/playfab/player-progression/game-saves/ui-callbacks.md)
- [Game Saves 錯誤處理常見問題集](/zh-TW/services/playfab/player-progression/game-saves/error-handling-faq.md)
- [Game Saves 系統對話方塊](/zh-TW/build/core-features/common/game-save/game-saves-dialogues.md)
