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

# PlayFab Game Saves の Steam Deck 実装ガイド

> 認証、UI コールバック、同期戦略を含む、October 2025 GDK での Steam Deck 上での PlayFab Game Saves 実装に関する包括的なガイド

<Info>
  このガイドでは特に、October 2025 GDK を使用した PlayFab Game Saves の Steam Deck 実装要件について説明します。Steam Deck サポートを実装する前に、基本的な [October 2025 GDK 実装](/services/playfab/player-progression/game-saves/october-2025-gdk-changes) 要件を完了していることを確認してください。
</Info>

## 概要

Steam Deck の Game Saves 統合は、クロスプラットフォーム要件に応じてさまざまな複雑さのレベルで実装できます。単純化された Steam 専用アプローチと、より複雑な認証フローを伴う完全な XBOX エコシステム統合のいずれかを選択できます。

<Info>
  **重要な違い - 同期動作**: Windows 上の Game Saves は完全にアウトオブプロセスで実行でき、ゲームのライフタイム後も同期を継続できます。Steam Deck では、Game Saves はインプロセスでのみ実行されます。つまり、ゲームがシャットダウンすると保存の同期が停止するため、未同期の進捗を失わないように、ゲームは頻繁な同期パターンを採用する必要があります。**すべてのプラットフォームでのベストプラクティス**: これらの同期パターンは Steam Deck では必須ですが、すべてのプラットフォーム、特にハンドヘルドデバイスや突然のシャットダウン (バッテリー切れ、システムクラッシュ、強制終了イベント) が発生する可能性のあるシナリオで強く推奨されます。
</Info>

## 同期エンジンの動作の違い

| プラットフォーム       | 同期モード     | シャットダウン後の同期        | 推奨パターン          |
| -------------- | --------- | ------------------ | --------------- |
| **Windows PC** | アウトオブプロセス | ✅ ゲームシャットダウン後も継続   | 信頼性のために頻繁な同期を推奨 |
| **Steam Deck** | インプロセス    | ❌ ゲームがシャットダウンすると停止 | **頻繁な同期が必須**    |

**共通の同期に関する推奨事項** (すべてのプラットフォームで有益):

* 保存データを頻繁に同期する (例: 各レベル、チェックポイント、または重要な進捗の後)
* 「ゲーム終了」の確認を表示する前には必ず同期する
* ゲームプレイの遷移中にバックグラウンド同期を検討する
* シャットダウン前に完了を確実にするための同期進行状況インジケーターを実装する
* バッテリー切れや突然のシャットダウンが一般的なハンドヘルドデバイスでは特に重要

## 前提条件

Steam Deck サポートを実装する前に、以下を確認してください:

1. **October 2025 GDK セットアップの完了**: [October 2025 GDK 実装ガイド](/services/playfab/player-progression/game-saves/october-2025-gdk-changes) に従ってください
2. **Steam API 統合**: 基本的な Steam API の初期化と Steam Deck の検出
3. **統合アプローチの選択**: XBOX エコシステムまたはカスタム ID 統合のいずれかを選択します (下記参照)
4. **必要なすべての DLL**: 統合された SDK DLL を Steam ビルドと一緒にデプロイする必要があります

## 実装アプローチ

Steam Deck では、複雑さのレベルとクロスプラットフォーム機能が異なる 2 つの実装アプローチが提供されます。PlayFab Game Saves は Steam のエコシステムを超えたクロスプラットフォームの保存同期に有用です - XBOX Live 統合 (アプローチ 1) または独自のカスタムプレイヤー ID システム (アプローチ 2) のいずれかが必要になります。

### アプローチ 1: XBOX エコシステム統合 (推奨)

**利点**:

* **完全なクロスプラットフォーム同期**: 保存データが Steam Deck、XBOX コンソール、Microsoft Store PC、およびその他の XBOX 対応プラットフォーム間で同期されます
* **XBOX Live 統合**: プレイヤーは XBOX ゲーマータグを使用し、XBOX のソーシャル機能にアクセスできます
* **統合されたプレイヤー ID**: すべてのプラットフォームで同じプレイヤープロファイル
* **実績のある認証**: XBOX Live の成熟した認証インフラストラクチャを活用
* **XBOX Game Studios との互換性**: XBOX ファーストパーティおよびパートナースタジオのシームレスな統合

**複雑さ**:

* **複雑な認証**: カスタムの XUser イベントハンドラーと UI コールバックが必要
* **開発サンドボックスのセットアップ**: 非小売テスト環境で必要
* **管理者権限**: サンドボックスセットアップ中のレジストリ変更に必要
* **追加の UI 実装**: QR コード認証とゲーマータグ選択ダイアログ

**選択するタイミング**: XBOX コンソールを含む複数のプラットフォームをターゲットとするゲーム、XBOX Game Studios タイトル、または完全な XBOX Live エコシステム統合を必要とするゲーム。

### アプローチ 2: カスタム ID 実装 (代替)

**利点**:

* **サインインの複雑さを軽減できる可能性**: XBOX ユーザー認証は不要
* **レジストリ設定なし**: サンドボックスのセットアップが不要
* **XUser API なし**: 複雑なイベントハンドラーを排除
* **カスタム ID の柔軟性**: 独自のクロスプラットフォームプレイヤー ID システムを実装

**複雑さ**:

* **手動プレイヤー管理**: 独自のクロスプラットフォームプレイヤー ID システムを実装する必要があります
* **エコシステム統合の制限**: XBOX Live のソーシャル機能や既存の XBOX プレイヤーベースへのアクセスなし
* **プラットフォームブリッジング**: 異なるプラットフォーム間でプレイヤーを接続するためのカスタムソリューションが必要
* **追加の ID インフラストラクチャ**: 独自のシステムを構築するか、サードパーティの ID システムを統合する必要があります

**選択するタイミング**: Steam 中心のゲーム、既存のカスタム ID システムを持つゲーム、または XBOX Live 統合が必要または望まれない開発シナリオ。

**OpenID Connect**: アプローチ 2 では、PlayFab は `LoginWithOpenIdConnect` API 呼び出しを通じて OpenID Connect 認証をサポートし、OpenID Connect 標準をサポートするカスタム ID プロバイダーとの統合を可能にします。

## 共通セットアップ (両方のアプローチ)

以下のセットアップ手順は、選択する実装アプローチに関係なく必要です。

## 1. DLL デプロイ要件

Steam Deck では、統合された SDK DLL をすべてゲームと一緒にデプロイする必要があります:

**必要な DLL**:

* `libHttpClient.dll` - HTTP 操作
* `PlayFabCore.dll` - 認証とコアサービス
* `PlayFabGameSave.dll` - Game Saves 機能
* `xgameruntime.dll` - コア SDK 機能と XBOX サインイン

**オプションの DLL**:

* `PlayFabServices.dll` - 追加の PlayFab サービス (推奨)

**Steam Deck デプロイ構造**:

```
YourGame/
├── YourGame.exe
├── libHttpClient.dll     // Required for HTTP operations
├── PlayFabCore.dll       // Required for authentication
├── PlayFabServices.dll   // Optional: For additional PlayFab services
├── PlayFabGameSave.dll   // Required for Game Saves
├── xgameruntime.dll      // Required for Xbox Live services
├── Steam_api64.dll
└── Other game files...
```

## 2. Steam 統合の前提条件

### Steam API 統合

```cpp theme={null}
// Initialize Steam API
bool steamAvailable = SteamAPI_Init();
```

### プラットフォーム検出

初期化の早い段階でプラットフォーム検出を実装します:

```cpp theme={null}
bool DetectSteamDeck() {
    if (!SteamAPI_Init()) {
        return false;
    }
    
    return SteamUtils()->IsSteamRunningOnSteamDeck();
}
```

## 3. UI コールバックの実装

<Info>
  **Steam Deck UI 要件**: すべての PlayFab Game Saves UI コールバックは、選択する実装アプローチに関係なく Steam Deck で**必須**です。これは、Steam Deck には Game Saves 操作に使用できる組み込みの UI がないため、アプリケーションがすべての UI ダイアログを提供する必要があるためです。
</Info>

### Game Saves UI コールバック (両方のアプローチで必須)

カスタム ID と XBOX エコシステムの両方の実装で、同じ PlayFab Game Saves UI コールバックが必要です:

```cpp theme={null}
// Required Game Saves UI callbacks for Steam Deck (both approaches)
PFGameSaveUICallbacks callbacks{};
callbacks.progressCallback = OnPFGameSaveFilesUiProgress;                    // Sync progress
callbacks.syncFailedCallback = OnPFGameSaveFilesUiSyncFailed;               // Sync errors
callbacks.activeDeviceContentionCallback = OnPFGameSaveFilesUiActiveDeviceContention;  // Device conflicts
callbacks.conflictCallback = OnPFGameSaveFilesUiConflict;                   // Save conflicts
callbacks.outOfStorageCallback = OnPFGameSaveFilesUiOutOfStorage;           // Storage quota

HRESULT hr = PFGameSaveFilesSetUiCallbacks(&callbacks);
if (FAILED(hr)) {
    // Handle callback setup failure
}

// Optional: Additional active device changed callback
hr = PFGameSaveFilesSetActiveDeviceChangedCallback(&OnActiveDeviceChanged, nullptr);
```

**必要な Game Saves UI ダイアログ** (両方のアプローチ):

* **進行状況ダイアログ**: 保存操作中に同期の進行状況を表示
* **エラー処理**: 同期失敗メッセージと再試行オプションを表示
* **競合解決**: デバイス間の保存の競合を処理
* **デバイスの競合**: 複数のデバイスによるアクセスシナリオを処理
* **ストレージ管理**: ストレージクォータの問題をユーザーに通知

***

## アプローチ 1: XBOX エコシステム統合 - 完全な実装

このアプローチは、Steam Deck、XBOX コンソール、Microsoft Store PC、およびその他の XBOX 対応プラットフォーム間で完全なクロスプラットフォーム同期を提供します。ゲームが XBOX プラットフォームをターゲットとする場合、または XBOX Live 統合が必要な場合は、このアプローチを選択してください。

### 概要

**前提条件**:

* 共通セットアップの完了 (上記のセクション 1〜3)
* テスト用の開発サンドボックスへのアクセス
* レジストリ設定用の管理者権限 (開発/テストのみ)

### 1. レジストリ設定

Steam Deck では、非小売サンドボックステスト用の XBOX Live サンドボックス設定が必要です:

```cpp theme={null}
// Set sandbox before Xbox Live services initialization
// Only required when testing with non-retail sandboxes
if (isSteamDeck) {
    HRESULT hr = SteamIntegration::SetSandboxForSteamDeck("XDKS.1");
    if (FAILED(hr)) {
        // Handle sandbox setup failure - requires admin privileges
        return hr;
    }
}
```

**設定の詳細**:

* **キー**: `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\XboxLive\Sandbox`
* **値**: 開発サンドボックス ID (例: "XDKS.1")
* **タイミング**: XBOX Live サービスの初期化前に設定する必要があります
* **権限**: 管理者アクセスが必要
* **用途**: 非小売サンドボックス (開発/テスト環境) でのテストにのみ必要

### 2. XUser プラットフォームイベントハンドラー

Steam Deck では、XBOX 認証に 2 つの重要なイベントハンドラーセットが必要です:

#### A. リモート接続イベントハンドラー

リモート認証フロー (QR コード/URL 表示) を処理します:

```cpp theme={null}
// Handle remote authentication flow (QR code/URL)
XUserPlatformRemoteConnectEventHandlers remoteConnect{};
remoteConnect.context = nullptr;
remoteConnect.show = &OnRemoteConnectShow;     // Display QR code/URL dialog
remoteConnect.close = &OnRemoteConnectClose;   // Close authentication dialog
HRESULT hr = XUserPlatformRemoteConnectSetEventHandlers(nullptr, &remoteConnect);
if (FAILED(hr)) {
    // Handle event handler setup failure
}
```

#### B. SPOP (サインインプロンプト) イベントハンドラー

ユーザーのアカウントがすでに別のデバイスでサインインしているときに使用される SPOP サインインプロンプトを処理します:

```cpp theme={null}
// Handle SPOP sign-in prompt. See sample: ShowSpopPromptDialogForXUserOnSteamDeck
HRESULT hr = XUserPlatformSpopPromptSetEventHandlers(nullptr, &OnSpopPrompt, nullptr);
if (FAILED(hr)) {
    // Handle SPOP setup failure
}
```

ハンドラーは、プレイヤーがアクション (ここでサインイン、アカウントを切り替え、またはキャンセル) を選択できる UI を表示し、選択された結果で `XUserPlatformSpopPromptComplete(operation, result)` を呼び出す必要があります。

### 3. 認証 UI の実装

Game Saves UI コールバック (セクション 3) に加えて、XBOX エコシステム統合には以下が必要です:

* **リモート接続ダイアログ**: ユーザーが別のデバイスで認証するための QR コードと URL を表示
* **SPOP プロンプトダイアログ**: ユーザーが XBOX ゲーマータグを選択/確認できるようにする

### 4. 初期化シーケンス

XBOX エコシステム統合には、次の初期化シーケンスに従ってください:

```cpp theme={null}
// 1. Check Steam availability and platform
bool steamAvailable = SteamIntegration::CheckSteamAvailability();
bool isSteamDeck = SteamIntegration::CheckIfSteamDeck();

// 2. Set Xbox Live sandbox (Steam Deck only, required for non-retail sandbox testing)
if (isSteamDeck) {
    HRESULT hr = SteamIntegration::SetSandboxForSteamDeck("XDKS.1");
    if (FAILED(hr)) {
        // Handle sandbox setup failure
        return hr;
    }
}

// 3. Initialize Xbox runtime
hr = XGameRuntimeInitialize();
if (FAILED(hr)) {
    return hr;
}

// 4. Initialize PlayFab Core and Services
hr = PFInitialize(nullptr);
if (FAILED(hr)) {
    return hr;
}
hr = PFServicesInitialize(nullptr); // Optional

// 5. Initialize XUser for Steam Deck
if (isSteamDeck) {
    hr = SteamIntegration::InitializeXUserForSteamDeck();
    if (FAILED(hr)) {
        return hr;
    }
}

// 6. Initialize Game Saves with appropriate callbacks
bool setUiCallbacks = isSteamDeck;
hr = InitializeGameSaves(setUiCallbacks);
if (FAILED(hr)) {
    return hr;
}
```

### 5. サインアウトの実装

Steam Deck では、保存された XBOX 認証情報をクリアするための特別なサインアウト処理が必要です:

```cpp theme={null}
void SignOutFromSteamDeck() {
    // Enumerate and delete Windows credentials with target names starting with "Xbl"
    DWORD count = 0;
    PCREDENTIALW* credentials = nullptr;
    
    if (CredEnumerateW(L"Xbl*", 0, &count, &credentials)) {
        for (DWORD i = 0; i < count; i++) {
            CredDeleteW(credentials[i]->TargetName, credentials[i]->Type, 0);
        }
        CredFree(credentials);
    }
    
    // Close Xbox user handles
    if (xboxUser) {
        XUserCloseHandle(xboxUser);
        xboxUser = nullptr;
    }
    
    // Close PlayFab user handles
    if (pfUser) {
        PFLocalUserCloseHandle(pfUser);
        pfUser = nullptr;
    }
    
    // Reset authentication state for clean re-authentication
    authenticationState = AuthState::NotAuthenticated;
}
```

### 6. テストチェックリスト

このチェックリストを使用して、XBOX エコシステム実装を検証します:

* [ ] **認証フロー**: リモート接続 (QR コード/URL) 認証をテスト
* [ ] **UI コールバック**: すべての Game Saves UI ダイアログが正しく表示されることを確認
* [ ] **SPOP プロンプト**: ゲーマータグの選択と確認をテスト
* [ ] **認証情報の永続性**: アプリ再起動間でのサインイン永続性をテスト
* [ ] **サインアウト**: サインアウト時に適切に認証情報がクリーンアップされることを確認
* [ ] **同期動作**: 頻繁な同期パターンとシャットダウン前の同期をテスト
* [ ] **データ損失防止**: 強制終了シナリオ中に失われる進捗が最小限であることを確認
* [ ] **クロスプラットフォーム同期**: Steam Deck、XBOX コンソール、Microsoft Store PC 間の保存同期をテスト
* [ ] **レジストリ設定**: 開発環境でサンドボックス設定が機能することを確認
* [ ] **XUser イベントハンドラー**: リモート接続と SPOP ハンドラーが正しく機能することを確認

***

## アプローチ 2: カスタム ID 実装 - 完全な実装

このアプローチでは、XBOX Live 統合なしで独自のプレイヤー ID システムを使用できます。ゲームが Steam 中心の場合、または既存のカスタム ID システムを持っている場合は、このアプローチを選択してください。

### 概要

**前提条件**:

* 共通セットアップの完了 (上記のセクション 1〜3)
* 本番環境で使用するカスタムプレイヤー ID システム

**利点**:

* XBOX 認証は不要
* レジストリ設定は不要
* 管理者権限は不要
* よりシンプルな UI (QR コードやゲーマータグの選択なし)

**制限事項**:

* 独自のクロスプラットフォームプレイヤー ID を実装する必要があります
* XBOX Live のソーシャル機能はありません
* カスタムプラットフォームブリッジングソリューションが必要

### 1. カスタム ID 認証

クロスプラットフォームプレイヤー認証のために独自の ID システムを実装します:

```cpp theme={null}
// Custom identity authentication
if (isSteamDeck) {
    // Development/Testing: Use Steam user identity temporarily
    // Production: Implement your own cross-platform player identity system
    // Required for production since Steam Cloud handles Steam-only sync
    
    // Option 1: OpenID Connect Integration (Recommended)
    // If your identity system supports OpenID Connect, use LoginWithOpenIdConnect:
    // PFAuthenticationLoginWithOpenIdConnectRequest request = {};
    // request.connectionId = "YourOpenIdConnectConnectionId";
    // request.idToken = "YourOpenIdConnectToken";
    // PFAuthenticationLoginWithOpenIdConnectAsync(serviceConfigHandle, &request, ...);
    
    // Option 2: Custom Integration
    // Initialize your custom authentication system
    // Connect to your user accounts/login system
    // Integrate with PlayFab Game Saves using your player identity
    
    // Initialize Game Saves with your custom identity system
    // (Implementation details depend on your specific identity integration)
}
```

### 2. 初期化シーケンス

```cpp theme={null}
// 1. Check Steam availability and platform
bool steamAvailable = SteamIntegration::CheckSteamAvailability();
bool isSteamDeck = SteamIntegration::CheckIfSteamDeck();

// 2. Initialize Xbox runtime (still required for Game Saves infrastructure)
HRESULT hr = XGameRuntimeInitialize();
if (FAILED(hr)) {
    return hr;
}

// 3. Initialize PlayFab Core and Services
hr = PFInitialize(nullptr);
if (FAILED(hr)) {
    return hr;
}
hr = PFServicesInitialize(nullptr); // Optional

// 4. Initialize your custom player identity system
hr = InitializeCustomPlayerIdentity();
if (FAILED(hr)) {
    return hr;
}

// 5. Initialize Game Saves with custom identity system
// Option A: OpenID Connect (if your identity system supports it)
// hr = PFAuthenticationLoginWithOpenIdConnectAsync(serviceConfigHandle, &openIdRequest, ...);
// Option B: Custom authentication integration
hr = InitializeGameSavesWithCustomIdentity();
if (FAILED(hr)) {
    return hr;
}
```

### 3. サインアウトの実装

```cpp theme={null}
void SignOutFromSteamDeck() {
    // Sign-out for custom identity implementation
    // No Xbox credential cleanup needed
    
    // Clean up your custom identity system
    SignOutFromCustomIdentitySystem();
    
    // Close PlayFab user handles
    if (pfUser) {
        PFLocalUserCloseHandle(pfUser);
        pfUser = nullptr;
    }
    
    // Clear local game state as needed
    ClearLocalGameState();
}
```

### 4. テストチェックリスト

このチェックリストを使用して、カスタム ID 実装を検証します:

* [ ] **カスタム ID システム**: カスタムプレイヤー認証と ID システムをテスト
* [ ] **PlayFab 認証**: LoginWithOpenIdConnect (OpenID Connect を使用している場合) またはカスタム認証方法を使用した PlayFab ログインをテスト
* [ ] **クロスプラットフォーム Game Saves 同期**: すべてのターゲットプラットフォームで保存同期をテスト
* [ ] **UI コールバック**: すべての Game Saves UI ダイアログが正しく表示されることを確認
* [ ] **競合解決**: 異なるプラットフォーム間のデバイス間の保存の競合をテスト
* [ ] **同期動作**: 頻繁な同期パターンとシャットダウン前の同期をテスト
* [ ] **データ損失防止**: 強制終了シナリオ中に失われる進捗が最小限であることを確認
* [ ] **カスタム認証**: ID システムのログイン/ログアウトフローをテスト
* [ ] **プラットフォームカバレッジ**: ゲームがターゲットとするすべてのプラットフォーム (Steam デバイスだけでなく) でテスト
* [ ] **ネットワークシナリオ**: オフライン/オンラインの遷移をテスト
* [ ] **パフォーマンス**: 同期操作がゲームプレイのパフォーマンスに影響しないことを確認

***

## サンプルコードリファレンス

両方のアプローチの完全な実装例については、サンプルプロジェクトを参照してください:

* **場所**: [PlayFabGameSaveSample-Windows](https://github.com/PlayFab/PlayFab-Samples/tree/master/Samples/All/PlayFabGameSaveSample-Windows)
* **主要ファイル**:
  * `SteamIntegration.cpp/.h` - Steam Deck 検出、レジストリセットアップ、認証ハンドラー
  * `GameSaveIntegrationUI.cpp/.h` - 両方のアプローチの UI コールバック実装

***

## 関連ドキュメント

* [October 2025 GDK 実装ガイド](/services/playfab/player-progression/game-saves/october-2025-gdk-changes)
* [Game Saves 概要](/services/playfab/player-progression/game-saves/overview)
* [Game Saves クイックスタート](/services/playfab/player-progression/game-saves/quickstart)


## Related topics

- [October 2025 GDK での Game Saves の実装](/ja-jp/services/playfab/player-progression/game-saves/october-2025-gdk-changes.md)
- [Game Saves の UI コールバック](/ja-jp/services/playfab/player-progression/game-saves/ui-callbacks.md)
- [Steam 移植ガイド概要](/ja-jp/build/steam-porting-guide/overview.md)
- [XBOX GDK への移植ガイド](/ja-jp/home/build-first-title/porting-guides.md)
- [XAG 121: アクセシブルな機能ドキュメント](/ja-jp/build/game-principles/accessibility/xag-deep-dives/xag-121-accessible-feature-documentation.md)
