> ## 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 ロールバック

> add user API の RollbackToLastKnownGood または RollbackToLastConflict オプションを使って、PlayFab Game Saves のプレイヤーセーブを以前の状態に復元します。

ロールバックを使うと、プレイヤーのゲームセーブを以前の状態に復元できます。プレイヤーのセーブが破損した場合、タイトル更新でセーブデータを損傷するバグが発生した場合、またはプレイヤーが競合解決の判断を元に戻したい場合に使用してください。

## ロールバックの仕組み

Game Saves はプレイヤーのセーブデータのファイナライズされたバージョンを追跡します。ロールバックをトリガーすると、サービスは復元しようとしている以前の状態と内容が同一な **新しいバージョン** を作成します。ロールバックは元のバージョン履歴を保持します。以前のバージョンを削除したり上書きしたりしません。ロールバック後に同期する他のデバイスからは、通常の更新として扱われます。

ロールバックには 2 つのタイプがあります。それぞれ `PFGameSaveFilesAddUserWithUiAsync` にオプションフラグを渡してトリガーします:

| オプション                                                    | 説明                                                                     |
| -------------------------------------------------------- | ---------------------------------------------------------------------- |
| `PFGameSaveFilesAddUserOptions::RollbackToLastKnownGood` | 直近で検証された以前のクラウドセーブを復元します。このセーブは以前に読み込まれ、後にさらに新しいアップロードによって置き換えられたものです。 |
| `PFGameSaveFilesAddUserOptions::RollbackToLastConflict`  | 直近の競合解決で敗れたセーブ状態を復元します。                                                |

適格な復元ポイントが存在しない場合、両方のオプションはデフォルトの動作 (現在の最新バージョンを同期する) にフォールバックします。

## 各ロールバックタイプの使用時機

### last known good へのロールバック

最新のアップロードが不良であると疑われる場合は `RollbackToLastKnownGood` を使用してください。よくあるトリガーは以下のとおりです:

* セーブのダウンロード後のロード失敗または整合性チェック失敗。
* セーブ操作中または直後のクラッシュ。
* 状態が破損または退行したというプレイヤー報告。

サービスは、どのバージョンが「known good」であるかを自動的に追跡します。明示的にマークする必要はありません。あるバージョンを正常にロードし、後で新しいアップロードによって置き換えられると、そのバージョンは known good になります。

### last conflict へのロールバック

競合解決の際にプレイヤーが誤った選択をした場合は `RollbackToLastConflict` を使用してください。[Game Saves の競合](/services/playfab/player-progression/game-saves/conflicts) で説明されているように、両方の解決選択肢は破棄されたブランチを保持します。このロールバックオプションは、その保持されたブランチを復元します。

## API の呼び出し

適切なオプションを `PFGameSaveFilesAddUserWithUiAsync` に渡してロールバックをトリガーします。この関数はユーザーごとに 1 回しか呼び出せないため、既に追加済みのユーザーに対してロールバックするには、まず `PFGameSaveFilesUninitializeAsync` を呼び出し、その完了を待ちます。

```cpp theme={null}
// Rollback to last known good version
XAsyncBlock async{};
async.queue = queue;
async.callback = [](XAsyncBlock* async)
{
    HRESULT hr = PFGameSaveFilesAddUserWithUiResult(async);
    if (SUCCEEDED(hr))
    {
        // Save data is now restored to the last known good version.
        // Read files from the game save folder as usual.
    }
};

HRESULT hr = PFGameSaveFilesAddUserWithUiAsync(
    localUserHandle,
    PFGameSaveFilesAddUserOptions::RollbackToLastKnownGood,
    &async
);
```

代わりに直近の競合で敗れた側にロールバックするには、オプションフラグを置き換えます:

```cpp theme={null}
HRESULT hr = PFGameSaveFilesAddUserWithUiAsync(
    localUserHandle,
    PFGameSaveFilesAddUserOptions::RollbackToLastConflict,
    &async
);
```

### フォールバック動作

要求されたロールバックタイプに対して適格な復元ポイントが存在しない場合、この呼び出しは `PFGameSaveFilesAddUserOptions::None` を渡した場合と同じように動作します。現在の最新バージョンが通常どおり同期されます。ロールバックが発生したかどうかを確認するには、呼び出し完了後に同期されたファイルを確認してください。

## タイトル構成

2 つの構成フラグを通じて、クライアント起点のロールバックを制限できます。いずれかのフラグを有効にすると、サポートツールと Game Manager のみがその種類のロールバックを実行できます。

| フラグ                                        | 効果                                                |
| ------------------------------------------ | ------------------------------------------------- |
| `DisableClientRollbackToLastKnownGood`     | ゲームクライアントが last known good バージョンにロールバックすることを防ぎます。 |
| `DisableClientRollbackToLastConflictLoser` | ゲームクライアントが直近の競合解決の判断を反転することを防ぎます。                 |

これらのフラグは Game Manager の **Progression > Game Saves** の下で設定します。

## エラー処理

| HRESULT                                                            | 意味                                                  |
| ------------------------------------------------------------------ | --------------------------------------------------- |
| `E_PF_GAME_SAVE_MANIFEST_NOT_ELIGIBLE_FOR_ROLLBACK`                | 要求されたロールバックタイプに対して適格な復元ポイントが存在しません。                 |
| `E_PF_GAME_SAVE_NOT_FINALIZED_MANIFEST_NOT_ELIGIBLE_AS_KNOWN_GOOD` | 対象のバージョンは known good 復元ポイントとして適格ではありません。            |
| `E_PF_GAME_SAVE_SERVICE_NOT_ENABLED_FOR_TITLE`                     | このタイトルで Game Saves が有効化されていません。まずオンボーディングを完了してください。 |
| `E_PF_GAME_SAVE_SERVICE_ONBOARDING_PENDING`                        | タイトルのオンボーディングが進行中です。                                |

## 考慮事項

* **ロールバックは新しいバージョンを作成します。** 履歴は消去しません。プレイヤーのバージョンシーケンスは前に進み続けます。
* **サービスは known good を自動的に追跡します。** 正常なロードと後続の置換のサイクルに基づいて、どのバージョンが該当するかを決定します。ゲーム側で明示的にバージョンをマークする必要はありません。
* **add-user 呼び出しごとに 1 回のロールバック。** `PFGameSaveFilesAddUserWithUiAsync` はユーザーごとに 1 回しか呼び出せないため、2 回目のロールバックをトリガーするには、まず `PFGameSaveFilesUninitializeAsync` を呼び出す必要があります。
* **UI コールバックも発火します。** ロールバックは通常の add-user 呼び出しと同じ同期フローを通過します。API を呼び出す前に [UI コールバック](/services/playfab/player-progression/game-saves/ui-callbacks) を登録してください。
* **必要に応じてロールバックを制限してください。** ゲームがサーバーサイドまたはサポートツールを通じて復旧を処理する場合は、タイトル構成フラグを使用してクライアントロールバックを無効にし、プレイヤーが誤って進行状況を戻すのを防ぎます。
* **ロールバックはすべてのプラットフォームで動作します。** この API にはプラットフォーム固有のガードはありません。


## Related topics

- [Game Saves の UI コールバック](/ja-jp/services/playfab/player-progression/game-saves/ui-callbacks.md)
- [Game Saves の PlayStream イベント](/ja-jp/services/playfab/player-progression/game-saves/playstream-events.md)
- [GameInput コールバック](/ja-jp/build/core-features/common/input/advanced/input-callbacks.md)
- [Game Saves クイックスタート](/ja-jp/services/playfab/player-progression/game-saves/quickstart.md)
- [PlayFab Game Saves の Steam Deck 実装ガイド](/ja-jp/services/playfab/player-progression/game-saves/steam-deck-implementation.md)
