> ## 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 實作指南

> 使用 2025 年 10 月 GDK 在 Steam Deck 上實作 PlayFab Game Saves 的完整指南，包括驗證、UI 回呼和同步策略

<Info>
  本指南專門涵蓋使用 2025 年 10 月 GDK 實作 PlayFab Game Saves 時的 Steam Deck 實作需求。實作 Steam Deck 支援之前，請確定您已完成基本的 [2025 年 10 月 GDK 實作](/zh-TW/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. **完成 2025 年 10 月 GDK 設定**：依照 [2025 年 10 月 GDK 實作指南](/zh-TW/services/playfab/player-progression/game-saves/october-2025-gdk-changes)操作
2. **Steam API 整合**：基本的 Steam API 初始化和 Steam Deck 偵測
3. **選擇整合做法**：在 XBOX 生態系統或自訂身分識別整合之間做出決定 (請參閱下方)
4. **所有必要的 DLL**：Unified SDK DLL 必須與您的 Steam 組建一起部署

## 實作做法

Steam Deck 提供兩種實作做法，具有不同的複雜度和跨平台功能。PlayFab Game Saves 對於 Steam 生態系統之外的跨平台存檔同步很有價值——您需要 XBOX Live 整合 (做法 1) 或您自己的自訂玩家身分識別系統 (做法 2)。

### 做法 1：XBOX 生態系統整合 (建議)

**優點**：

* **完整的跨平台同步**：存檔資料會在 Steam Deck、XBOX 主機、Microsoft Store PC 和其他支援 XBOX 的平台之間同步
* **XBOX Live 整合**：玩家使用其 XBOX 玩家代號，並可存取 XBOX 社交功能
* **統一的玩家身分識別**：所有平台上使用相同的玩家設定檔
* **經過驗證的驗證機制**：運用 XBOX Live 成熟的驗證基礎結構
* **XBOX Game Studios 相容性**：為 XBOX 第一方和合作夥伴工作室提供順暢的整合

**複雜度**：

* **複雜的驗證**：需要自訂 XUser 事件處理常式和 UI 回呼
* **開發沙箱設定**：非零售測試環境所必需
* **系統管理員權限**：在沙箱設定期間修改登錄所必需
* **額外的 UI 實作**：QR 碼驗證和玩家代號選取對話方塊

**何時選擇**：以包括 XBOX 主機在內的多個平台為目標的遊戲、XBOX Game Studios 遊戲，或需要完整 XBOX Live 生態系統整合的遊戲。

### 做法 2：自訂身分識別實作 (替代方案)

**優點**：

* **可能降低登入複雜度**：不需要 XBOX 使用者驗證
* **不需要登錄設定**：不需要沙箱設定
* **不需要 XUser API**：消除複雜的事件處理常式
* **自訂身分識別的彈性**：實作您自己的跨平台玩家身分識別系統

**複雜度**：

* **手動管理玩家**：必須實作您自己的跨平台玩家身分識別系統
* **有限的生態系統整合**：無法存取 XBOX Live 社交功能或現有的 XBOX 玩家群
* **平台橋接**：需要自訂解決方案來連接不同平台上的玩家
* **額外的身分識別基礎結構**：需要建置或整合第三方身分識別系統

**何時選擇**：以 Steam 為主的遊戲、已有自訂身分識別系統的遊戲，或不需要或不想要 XBOX Live 整合的開發案例。

**OpenID Connect**：對於做法 2，PlayFab 透過 `LoginWithOpenIdConnect` API 呼叫支援 OpenID Connect 驗證，可與支援 OpenID Connect 標準的自訂身分識別提供者整合。

## 通用設定 (兩種做法)

無論您選擇哪種實作做法，都需要下列設定步驟。

## 1. DLL 部署需求

Steam Deck 需要將所有 Unified 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 需求**：無論您選擇哪種實作做法，在 Steam Deck 上所有 PlayFab Game Saves UI 回呼都是**必要的**。這是因為 Steam Deck 沒有可用於 Game Saves 作業的內建 UI，因此您的應用程式必須提供所有 UI 對話方塊。
</Info>

### Game Saves UI 回呼 (兩種做法都需要)

自訂身分識別和 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`
* **值**：開發沙箱識別碼 (例如 "XDKS.1")
* **時機**：必須在 XBOX Live 服務初始化之前設定
* **權限**：需要系統管理員存取權
* **用法**：只有在非零售沙箱 (開發/測試環境) 中測試時才需要

### 2. XUser 平台事件處理常式

Steam Deck 需要兩組關鍵的事件處理常式來進行 XBOX 驗證：

#### 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：自訂身分識別實作 - 完整實作

此做法可讓您在沒有 XBOX Live 整合的情況下使用自己的玩家身分識別系統。如果您的遊戲以 Steam 為主，或您已有自訂身分識別系統，請選擇此做法。

### 概觀

**先決條件**：

* 已完成通用設定 (上方第 1-3 節)
* 供生產使用的自訂玩家身分識別系統

**優點**：

* 不需要 XBOX 驗證
* 不需要登錄設定
* 不需要系統管理員權限
* 較簡單的 UI (沒有 QR 碼或玩家代號選取)

**限制**：

* 必須實作您自己的跨平台玩家身分識別
* 沒有 XBOX Live 社交功能
* 需要自訂平台橋接解決方案

### 1. 自訂身分識別驗證

實作您自己的身分識別系統，以進行跨平台玩家驗證：

```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. 測試檢查清單

使用此檢查清單驗證您的自訂身分識別實作：

* [ ] **自訂身分識別系統**：測試您的自訂玩家驗證和身分識別系統
* [ ] **PlayFab 驗證**：使用 LoginWithOpenIdConnect (如果使用 OpenID Connect) 或自訂驗證方法測試 PlayFab 登入
* [ ] **跨平台 Game Saves 同步**：測試所有目標平台之間的存檔同步
* [ ] **UI 回呼**：確認所有 Game Saves UI 對話方塊都正確顯示
* [ ] **衝突解決**：測試不同平台上裝置之間的存檔衝突
* [ ] **同步行為**：測試頻繁同步模式和關閉前同步
* [ ] **防止資料遺失**：確認在強制關閉案例中遺失的進度最少
* [ ] **自訂驗證**：測試您身分識別系統的登入/登出流程
* [ ] **平台涵蓋範圍**：在您的遊戲所針對的所有平台上進行測試 (不只是 Steam 裝置)
* [ ] **網路案例**：測試離線/線上轉換
* [ ] **效能**：確認同步作業不會影響遊戲效能

***

## 範例程式碼參考

如需兩種做法的完整實作範例，請參閱範例專案：

* **位置**：[PlayFabGameSaveSample-Windows](https://github.com/PlayFab/PlayFab-Samples/tree/master/Samples/All/PlayFabGameSaveSample-Windows)
* **主要檔案**：
  * `SteamIntegration.cpp/.h` - Steam Deck 偵測、登錄設定、驗證處理常式
  * `GameSaveIntegrationUI.cpp/.h` - 兩種做法的 UI 回呼實作

***

## 相關文件

* [2025 年 10 月 GDK 實作指南](/zh-TW/services/playfab/player-progression/game-saves/october-2025-gdk-changes)
* [Game Saves 概觀](/zh-TW/services/playfab/player-progression/game-saves/overview)
* [Game Saves 快速入門](/zh-TW/services/playfab/player-progression/game-saves/quickstart)


## Related topics

- [使用 2025 年 10 月 GDK 實作 Game Saves](/zh-TW/services/playfab/player-progression/game-saves/october-2025-gdk-changes.md)
- [Game Saves UI 回呼](/zh-TW/services/playfab/player-progression/game-saves/ui-callbacks.md)
- [PlayFab Game Saves 的帳戶連結策略](/zh-TW/services/playfab/player-progression/game-saves/linking.md)
- [Steam 移植指南概觀](/zh-TW/build/steam-porting-guide/overview.md)
- [Game Saves 概觀](/zh-TW/services/playfab/player-progression/game-saves/overview.md)
