> ## 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 のチュートリアルとサンプル

> Game Saves のチュートリアルとサンプル

この記事では、Game Saves を使用する際の一般的な開発およびマイグレーションシナリオについて、ステップバイステップの手順を説明します。Microsoft Partner Center での必要なセットアップ、データを安全に書き込むためのベストプラクティス、プラットフォーム固有のセーブ管理、および推奨されるテスト手順について解説します。

## Partner Center の構成

### タイトルの XBOX サービスと Game Saves を有効化する

Game Saves API を使用するには、Partner Center で次の手順を完了してください。

* XBOX サービスを有効化します。
  1. [Partner Center](https://partner.microsoft.com/dashboard/home) にサインインします。
  2. 自分のタイトルに移動し、設定で XBOX サービスを有効化します。この手順の詳細については、[Setting up an app or game at Partner Center, for Managed Partners](/services/xbox-services/fundamentals/portal-config/live-setup-partner-center-partners#2-contact-your-microsoft-representative-to-enable-your-app-or-game) を参照してください。
* サービス構成識別子 (SCID) を取得します。すべての読み取りおよび書き込み操作は、SCID に関連付けられている必要があります。SCID は Game Saves の初期化にも使用されます。
  * Partner Center では、タイトルの **XBOX services** > **XBOX settings** タブに SCID があります。このページでは、Microsoft アカウント (MSA) の App ID (MSAAppID) も確認できます。
    <img src="https://mintcdn.com/microsoft-4404708b/UZTRJSf0emX1fheE/images/gdk/features/common/partner-center-xbox-services-view.png?fit=max&auto=format&n=UZTRJSf0emX1fheE&q=85&s=7ba30f0150039b4e968e6915ad0eb4dd" alt="Partner Center XBOX サービスビュー。" width="622" height="293" data-path="images/gdk/features/common/partner-center-xbox-services-view.png" />

SCID と MSAAppID を取得したら、この App ID をタイトルの構成 (.mgc) ファイルに追加します。

ゲーム構成ファイルの詳細については、[Creating the Microsoft Game Config .mgc](/build/core-features/common/game-config/MicrosoftGameConfig-Overview) を参照してください。

## 開発シナリオ

### コード内のどこに Game Saves を統合すべきか?

Game Saves のロジックはユーザーのサインインに依存します。ユーザーサインインフローの近くに Game Saves コードを追加してください。

### ゲームセーブデータが破損しないようにするにはどうすればよいか?

データを安全に保存し、破損を回避するには、以下の手順に従います。このガイダンスは、すべてのセーブ操作に適用されます。

1. 一時ファイルに書き込みます。
   * ライブセーブを上書きするのではなく、新しいファイル (例: `save.tmp`) にセーブデータをシリアライズします。この手順により、書き込み途中でプロセスが中断された場合に既存のセーブが保護されます。
2. 書き込みがディスクに完全にコミットされたら、書き込みハンドルを閉じます。
3. Win32 の [ReplaceFile](https://learn.microsoft.com/windows/win32/api/winbase/nf-winbase-replacefilea) を使用して、古いセーブファイルを新しい一時ファイルにアトミックに置き換えます。

### オフラインデバイスをサポートするにはどうすればよいか?

Game Saves の初期化前と後の両方で接続が失われた場合に、タイトルがどのように動作するかを決定するのは開発者の責任です。

オフラインの動作の詳細については、[Understanding the Game Saves sync flow](/build/core-features/common/game-save/game-saves-syncing#connection-check) を参照してください。

### 認識しておくべきユーザー操作は?

OS は、操作にユーザー入力が必要な場合にシステムプロンプトを表示します。これらのプロンプトの詳細については、[Game Saves dialogs](/build/core-features/common/game-save/game-saves-dialogues) を参照してください。

### ローカルおよびデバイスのみに保存する方法はあるか?

Game Save の初期化プロセスに `null` のユーザーハンドルを渡すと、システムはマシン専用のプロバイダーを作成します。データはローカルに保存され、デバイス上に永続化されます (最大 256 MB)。データはクラウドに同期されません。

Game Saves ストレージの詳細については、[Game Saves storage systems](/build/core-features/common/game-save/game-saves-storage-systems) を参照してください。

### デバイス経由でのゲームセーブの管理

#### File Explorer を使用して PC 上のローカルゲームセーブにアクセスする

タイトルが PC 上で動作する場合、ファイルに直接アクセスできます。Game Saves API の実装によっては、次の場所でローカルゲームセーブにアクセスできます。

| Game Saves API | ファイルパス                                                                        |
| :------------- | :---------------------------------------------------------------------------- |
| XGameSaveFiles | `%AppData%\Local\Packages\<PACKAGE_NAME>\SystemAppData\xgs\<HexXuid>_<Scid>\` |
| XGameSave      | `%AppData%\Local\Packages\<PACKAGE_NAME>\SystemAppData\wgs\<HexXuid>_<Scid>\` |

PC 上でデータを操作しても、同期ロジックは引き続き適用されます。たとえば、タイトルがロックを持っていない状態でデータを変更すると、競合が発生します。

#### コンソール上のローカルゲームセーブにアクセスする

コンソールのセーブデータは XBOX UI から管理します。以下の手順でアクセスします。

1. XBOX コントローラーの **Home** ボタンを選択します。
2. **My games & apps** > **See all** を選択します。
3. 自分のゲームにカーソルを合わせて、**View** ボタンを選択します。
4. **Saved data** を選択します。

<img src="https://mintcdn.com/microsoft-4404708b/sIrPFR_ir_sNKVEv/images/gdk/features/common/console-storage-management.png?fit=max&auto=format&n=sIrPFR_ir_sNKVEv&q=85&s=1440050534d3c4d168d1e964d3638afe" alt="コンソールストレージの Game Saves 管理ビュー。" width="1314" height="377" data-path="images/gdk/features/common/console-storage-management.png" />

コンソール上でデータを直接操作する場合、以下の点を考慮してください。

* システム UI を使用してコンソール上のデータを削除しても、クラウドに保存されているコピーは削除されません。タイトルを再起動すると、クラウドからデータが同期されます。
* マシンプロバイダーのデータは、名前のないユーザーとして表示されます。このデータはデバイス上に留まり、クラウドに同期されず、デバイスに紐付けられます。

マシンプロバイダーの詳細については、[Game Saves storage systems](/build/core-features/common/game-save/game-saves-storage-systems#game-saves-storage-systems) を参照してください。

ゲームセーブをさらに詳細に制御するには、[Game Saves tools](/build/core-features/common/game-save/game-saves-tools#manipulating-game-saves) を使用してください。

## テストシナリオ

テストケースを作成する際には、データ検証をゲームセーブロジックから分離してください。

### ゲームセーブがクラウドと正しく同期されるかテストする

正しく同期されるかをテストするには、以下の手順を実行してください。テストフローによって動作を検証します。

`XGameSaveFiles`:

1. SCID が正しいことを確認します。
2. 正しいユーザーハンドルを使用していることを確認します。
3. 現在のゲームセッション中に、タイトルが `XGameSaveFilesGetFolderWithUIAsync` を呼び出していることを確認します。タイトルがサスペンド状態から復帰した場合は、この関数を呼び出してください。
   1. Fiddler を使用して、ロックが取得されたことを確認します。
   2. このパスを保存し、データがアップロードされていることを後で確認するために使用します。
4. `XGameSaveFilesGetFolderWithUIAsync` から提供されたファイルパスにデータを書き込みます。
5. タイトルを終了またはサスペンドします。
6. OS がデータを自動的にクラウドへアップロードしてロックを解放するまで、10～30 秒間待機します。
   1. Fiddler を使用して、データがアップロードされ、ロックが解放されたことを確認します。
7. `XGameSaveFilesGetFolderWithUIAsync` によって提供されたフォルダー内のデータを手動で削除します。
   1. コンソールでは、プレイヤー設定からこのデータにアクセスします。
8. タイトルを再度起動し、ユーザーのサインインを試みます。
9. クラウドからのアクティブなダウンロード同期を示す同期ダイアログが表示されます。

同期が正常に行われているかのテストを支援するリソースは、以下を参照してください。

* [Game Saves tools to inspect traffic and manipulate saves](/build/core-features/common/game-save/game-saves-tools)
* [Understanding the Game Saves sync flow](/build/core-features/common/game-save/game-saves-syncing)

### ゲームセーブが正しくローミングするかテストする

データがローミングするかを確認するためのテスト計画については、[XR-052-06 Test Plan](https://learn.microsoft.com/build/store/policies/XR/XR052#052-06-cloud-storage-roaming) を参照してください。

## マイグレーションシナリオ

### タイトル間でゲームセーブを共有する

あるタイトルから別のタイトルへデータを転送またはアクセスするには、2 つの手順を完了します。

1. Partner Center で、アクセスしたいタイトルのアクセスポリシーを変更します。
2. ソースコードで両方のタイトルの Game Saves プロバイダーを初期化します。

#### アクセスポリシーを変更する

タイトルは、アクセスポリシーを構成することで、自身のゲームセーブデータにアクセスできるタイトルを制御します。

1. [Partner Center](https://partner.microsoft.com/dashboard) に移動します。
2. **Apps and games** > **\<your title>** > **Gameplay settings** を選択します。
3. **Gameplay Settings** で **Access Policies** を選択し、**Connected Storage** を展開します。
4. **Add app/service** を選択し、アクセスを提供したいタイトルを追加します。
5. タイトルの追加が完了したら、**Save** を選択してから **Publish** を選択します。変更は 1 時間以内に反映されます。

次のスクリーンショットは、GameSaveFilesCombo タイトルを GameSaveSample タイトルから完全にアクセス可能にする例を示しています。

<img src="https://mintcdn.com/microsoft-4404708b/UZTRJSf0emX1fheE/images/gdk/features/common/partner-center-access-policy.png?fit=max&auto=format&n=UZTRJSf0emX1fheE&q=85&s=25eae43c7e7d88b824558596d849cbfa" alt="タイトルのアクセスポリシーを変更する Partner Center のビュー。" width="1280" height="598" data-path="images/gdk/features/common/partner-center-access-policy.png" />

#### Game Save プロバイダーを初期化する

これで最初のタイトルにアクセスする権限が得られたので、もう一方のタイトルから `XGameSave` データを読み取ることができます。

* `XGameSave` を使用している場合は、各タイトルに対して `XGameSaveInitializeProvider` または `XGameSaveInitializeProviderAsync` を呼び出します。
* `XGameSaveFiles` を使用している場合、プロバイダーは暗黙的に初期化されます。各タイトルに対して `XGameSaveFilesGetFolderWithUiAsync` を呼び出します。

### XGameSave と XGameSaveFiles の相互運用

タイトルによっては、`XGameSave` と `XGameSaveFiles` を併用する必要がある場合があります。典型的な理由は次のとおりです。

* パブリッシャーがコンソール上にすでに `XGameSave` を使用している既存タイトルを持っている。
* パブリッシャーがその既存タイトルを `XGameSaveFiles` を使用するように更新したくない。
* パブリッシャーが、PC タイトルに `XGameSaveFiles` を追加する方が `XGameSave` を使用するより簡単だと考えているが、それでも PC、コンソール、および XBOX ゲームストリーミング間でのクロスセーブをサポートしたい。

`XGameSave` と `XGameSaveFiles` の間の移行は比較的簡単です。タイトルが [XGameSaveFilesGetFolderWithUiAsync](/reference/system/xgamesavefiles/functions/xgamesavefilesgetfolderwithuiasync) を呼び出すと、次のルールを使用してコンテナーとブロブがディレクトリとファイルにマッピングされます。

* コンテナー名内のスラッシュ (/) は、そのファイルが配置されるディレクトリ構造を作成します。
* 次の文字は `XGameSaveFiles` で無効です。システムがこれらの文字を検出した場合、アンダースコア (\_) にマッピングされます。
  * \0 から \001f までの文字 (両端を含む)。
* 次の文字は `XGameSaveFiles` で有効ではありません。システムがこれらの文字を検出した場合、ピリオド (.) にマッピングされます。
  * 二重引用符 (")
  * 未満記号 (\<)
  * より大きい記号 (>)
  * パイプ (|)
  * アスタリスク (\*)
  * クエスチョンマーク (?)
  * バックスラッシュ (\\)
* ブロブ名内のスラッシュ (/) は、ファイル名内のピリオド (.) にマッピングされます。
* ファイルは 16 MB に制限されています。`XGameSave` の最大アップロードサイズは 16 MB です。

タイトルが `XGameSaveFiles` から `XGameSave` に戻る場合、ファイル名が変更されていない、または移動されていなければ、元のコンテナー名とブロブ名が復元されます。

### 以前のタイトルをノーコードクラウドセーブで PC Game Saves に移植する

PC Game Pass に移植する一部のタイトルでは、ノーコードクラウドセーブソリューションが必要になる場合があります。この要件は、以下のシナリオで発生する可能性があります。

* タイトルが x86 アプリケーションとして動作する。パッケージ形式でのみ Microsoft Game Development Kit (GDK) を使用している。
* Unreal Engine の Blueprint や Unity の Bolt などのツールを使用して、カスタムコードなしで作成されたタイトル。

ノーコードクラウドセーブを使用するタイトルは、標準の Win32 ファイル I/O API を通じて、指定されたセーブディレクトリに対して読み取り/書き込みを行います。システムはデータを自動的に同期します。同期およびアップロードを処理する特別なコードを記述する必要はありません。同期はタイトルの起動前に発生します。

ノーコードクラウドセーブは、タイトルが PC 上で実行されなくなった時点でアップロードされます。次のいずれかの条件が満たされるとアップロードが実行されます。

* タイトルが終了された。
* 追跡対象のユーザーがサインアウトした。
* PC の電源状態が変化した。
* タイトルが指定されたセーブ領域に最後に書き込みを行ってから 30 分が経過した。

ノーコードクラウドセーブソリューションは `XGameSaveFiles` の上に構築されており、ファイルサイズおよびユーザーごとのストレージ制限に関するすべての制限を共有します。ファイルは 64 MB に制限されています (`XGameSave` または Connected Storage との相互運用が必要な場合は 16 MB)。デフォルトでは、ユーザーごとのストレージは 256 MB に制限されています。より大きなユーザーごとのストレージ制限が必要なタイトルは、Developer Partner Manager (DPM) と協力して例外を申請できます。

<Note>
  ディレクトリおよびファイル名には特定の命名規則と文字制限があります。詳細については、[XGameSaveFiles path logic](/build/core-features/common/game-save/xgamesavefiles#xgamesavefiles-path-logic) を参照してください。
</Note>

ノーコードクラウドセーブは PC でのみサポートされています。このタイトルには [Simplified User Model](/build/core-features/common/user/users-opting-into-simplified-model) が必要です。これにより、タイトル起動前にユーザーがサインインしていることが保証されます。ユーザーがタイトルにサインインできない場合、タイトルは起動しません。ゲームプレイ中にユーザーがサインアウトされると、タイトルは終了されます。

<Info>
  ノーコードクラウドセーブでは、`wdapp install` を使用してタイトルをパッケージ化されたビルドとして起動する必要があります。`.exe` を直接起動しても、クラウドセーブのリダイレクトは有効化されません。

  パッケージ化されたビルドが実行される場合、`NoCodePCRoot` を通じて書き込まれるセーブは、`XGameSaveFiles` が管理するストレージにリダイレクトされます。その後に `.exe` を直接起動すると、物理的な `NoCodePCRoot` フォルダーが読み取られますが、これは空である可能性があり、セーブが見つからないように見える原因となります。この問題を回避するには、常に `wdapp install` を使用してパッケージ化されたビルドでノーコードクラウドセーブをテストしてください。
</Info>

### ノーコードクラウドセーブを有効化する

ノーコードクラウドセーブを有効化するには、次の手順を完了してください。

1. `MicrosoftGame.config` ファイルを変更します。
2. シンプル化ユーザーモデルを有効化します。
3. セーブファイルのルートフォルダーを指定します。
4. タイトルに対応する SCID を指定します。

次のコード例は、このプロセスを示しています。

```xml theme={null}
<Game configVersion="1">
   <Identity Name="SampleNameOne" Publisher="CN=NoPublisher"/>
   <SaveGameStorage>
      <NoCodePCRoot RelativeTo="SavedGames">test\path</NoCodePCRoot>
      <SCID>DF9D8061-4790-4B84-86B4-CD060B00B4DD</SCID>
      <MaxUserQuota>256</MaxUserQuota>
   </SaveGameStorage>
   <!-- Content removed for brevity -->
   
   <!-- Must also opt into requiring a default user at launch -->
   <AdvancedUserModel>false</AdvancedUserModel>
</Game>
```

`NoCodePCRoot` に指定するルートフォルダーは、少数のオプションのいずれかを基準とする必要があります。

| RelativeTo        | PC 上のフォルダーの場所                         |
| ----------------- | ------------------------------------- |
| `AppData`         | 環境変数 %APPDATA% にマッピング                 |
| `Public`          | 環境変数 %PUBLIC% にマッピング                  |
| `LocalAppData`    | 環境変数 %LOCALAPPDATA% にマッピング            |
| `LocalAppDataLow` | %USERPROFILE%\AppData\LocalLow にマッピング |
| `ProgramData`     | 環境変数 %PROGAMDATA% にマッピング              |
| `SavedGames`      | %USERPROFILE%\Saved Games にマッピング      |
| `UserProfile`     | 環境変数 %USERPROFILE% にマッピング             |

<Info>
  `RelativeTo` の値には `SavedGames` を使用してください。Saved Games フォルダー (`%USERPROFILE%\Saved Games`) は Windows の既知のフォルダー ID `FOLDERID_SavedGames` に対応します。OneDrive はデフォルトではこのフォルダーを同期しません。

  `AppData` (`%APPDATA%`) などの他の場所の使用は避けてください。OneDrive がこれらの場所を同期し、クラウドセーブの同期と競合を引き起こす可能性があります。

  `FOLDERID_SavedGames` の詳細については、[SHGetKnownFolderPath](https://learn.microsoft.com/windows/win32/api/shlobj_core/nf-shlobj_core-shgetknownfolderpath) を参照してください。
</Info>

*ファイルをルートディレクトリに直接配置することはできません*。ルートフォルダーから少なくとも 1 つのサブフォルダー内にネストしてください。たとえば、`<NoCodePCRoot RelativeTo="SavedGames">savegame1.sav</NoCodePCRoot>` のようにファイル名を直接使用することは無効です。savegame1.sav は無視されます。`<NoCodePCRoot>` は、特定のファイルではなく、ディレクトリパスを定義することを目的としています。

## コードサンプル

* [GameSaveCombo](https://learn.microsoft.com/samples/microsoft/xbox-gdk-samples/gamesavecombo/)
* [GameSaveFilesCombo](https://learn.microsoft.com/samples/microsoft/xbox-gdk-samples/gamesavefilescombo/)

## リファレンス API ドキュメント

* [XGameSaveFiles (API contents)](/reference/system/xgamesavefiles/xgamesavefiles_members)
  * Functions
    * [XGameSaveFilesGetFolderWithUiAsync](/reference/system/xgamesavefiles/functions/xgamesavefilesgetfolderwithuiasync)

## 関連項目

[Game Saves TOC](/build/core-features/common/game-save/game-saves-toc)
