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

# XBOX 遊戲生命週期

> 提供有關遊戲生命週期事件的狀態、轉換和處理方式的詳細資料，以及可用於偵錯這些事件的工具。

# XBOX 遊戲生命週期

本主題介紹構成遊戲生命週期的概念和事件。它示範如何在遊戲中實作遊戲狀態和狀態變更事件，為使用者提供流暢的體驗。它也說明如何通過認證需求，並介紹可用於偵錯這些事件的工具和功能。

Microsoft Game Development Kit (GDK) 遊戲在其整個存留期間會在各種資源狀態之間轉換。在這些狀態之間切換，可讓 XBOX 主機提供使用者期望的回應迅速的多工體驗。這也能確保使用者在玩遊戲時，遊戲能從主機取得最多的資源。不過，為了達成這個目的，Microsoft Game Development Kit (GDK) 遊戲必須準備好處理一些事件和互動。

<br />

[簡介](#introduction)

[遊戲生命週期狀態](#game-life-cycle-states)

[生命週期狀態轉換](#life-cycle-state-transitions)

[生命週期事件回呼](#life-cycle-event-callbacks)

[回應暫停和繼續](#responding-to-suspend-and-resume)

[回應受限和解除受限](#responding-to-constrain-and-unconstrain)

[啟動](#launching)

[與生命週期相關的事件](#events-related-to-life-cycle)

[使用 GDK 逾時](#timeouts)

[Quick Resume](#quick-resume)

[偵錯工具和功能](#debugging-tools-and-features)

[附錄](#appendix)

<br />

<a id="introduction" />

## 簡介

遊戲生命週期狀態和事件可讓使用者快速且有效率地在遊戲、XBOX 殼層和其他應用程式之間切換。此程序需要遊戲和應用程式採取一些動作，才能處理生命週期狀態之間的轉換。如果處理得當，這些工作可讓使用者在切換進出您的遊戲時，獲得順暢無縫的體驗。本主題說明管理遊戲生命週期的各個層面，並描述可用於支援這些層面的工具。如果您熟悉 XBOX One 軟體開發套件或通用 Windows 平台 (UWP) 應用程式中的處理序存留期管理 (PLM)，就會對這些資訊感到熟悉。請注意，GDK 應用程式有一些重要的差異和改進。

本主題首先討論：

* 不同的生命週期狀態。
* 狀態之間的轉換。
* 與其相關聯的回呼。

接著，本主題說明成功處理這些轉換以通過 XBOX 需求 (XR) 的要求，並討論大多數遊戲都應該考量的常見使用案例。

最後，本主題介紹可讓您更容易了解和修正狀態轉換問題的工具和偵錯功能。

<br />

<a id="game-life-cycle-states" />

## 遊戲生命週期狀態

安裝在 XBOX 主機上的 Microsoft Game Development Kit (GDK) 遊戲，一律處於下列五種可能狀態之一。

1. 執行中
2. 受限
3. 暫停中
4. 已暫停
5. 未執行

您可以透過檢查下列項目來判斷遊戲的狀態：

* [XBOX Manager](/zh-TW/tools/tools-console/xbom/xbom) **首頁**檢視中列出的**狀態**。
* [Dev Home](/zh-TW/tools/tools-console/devhome/devhome) 中**遊戲與應用程式**檢視裡遊戲旁邊列出的值。
* [XBOX Device Portal](/zh-TW/tools/tools-console/wdp/wdp)。
* [xbapp query](/zh-TW/tools/tools-console/commandlinetools/xbapp) 命令列工具。

### 執行中

當遊戲處於執行中時，它會在資源完全可用的情況下執行。遊戲擁有輸入焦點，且其視窗對使用者可見。資源完全可用表示遊戲在執行時擁有：

* 六個實體 CPU 核心 (core0-core5)，在 XBOX One 系列裝置上再加上 CPU core6 的 50–90%，在 XBOX Series 主機上則為 CPU core6 的 100%。
* 97–100% 的 GPU 使用率。請注意，作業系統最多可能使用 3% 的 GPU。
* 5–13 GB 的記憶體，視 MicrosoftGame.config 中的設定以及遊戲執行所在的主機而定。如需詳細資訊，請參閱[設定遊戲記憶體](/zh-TW/build/console-features/memory/system-memory-tooling)。

為了更清楚說明執行中狀態與受限狀態之間的 CPU 資源變化，請參考下圖，其中顯示遊戲處於執行中狀態時 CPU 核心的狀態。

<img src="https://mintcdn.com/microsoft-4404708b/-_0FrcE2bDxzGxv-/images/gdk/lifecycle/cpu-resource-diagram-x1-running.png?fit=max&auto=format&n=-_0FrcE2bDxzGxv-&q=85&s=860d4002788745eb605483ca4d85c1d3" alt="顯示遊戲處於執行中狀態時 CPU 核心狀態的圖表" width="600" height="171" data-path="images/gdk/lifecycle/cpu-resource-diagram-x1-running.png" />

XBOX Series 主機可以啟用同時多執行緒 (SMT)，這會稍微改變此圖表。如需 SMT 的詳細資訊，請參閱 XBOX One 與 XBOX Series X|S 的 CPU 和記憶體比較，以及[附錄](#smt-diagrams)中詳細說明使用 SMT 時 CPU 核心的圖表。

### 受限

當遊戲以受限執行狀態執行時，它會在資源可用性降低的情況下執行。遊戲在此狀態下無法接收使用者輸入。遊戲的視窗很可能被部分遮蔽，或對使用者不可見。當使用者與某些功能互動，或體驗作用中遊戲以外的任何內容時 (例如與指南之類的功能表、設定之類的系統應用程式，或帳戶選擇器之類的遊戲可呼叫 UI (TCUI) 互動)，遊戲就會進入此狀態。當遊戲受限時，其可用資源會減少為下列狀態。

* 四個實體 CPU 核心。執行緒會以下列模式摺疊。
  * core0 和 core1 上的執行緒不受影響。
  * core2 和 core3 上的執行緒會分時共用一個實體 CPU 核心。
  * core4、core5 和 core6 上的執行緒會分時共用一個實體 CPU 核心。
* 約 45% 的 GPU。
* 與執行中狀態相同的可用記憶體。請注意，受限並不會改變遊戲可用的記憶體量。

下圖顯示遊戲處於受限狀態時 CPU 核心的狀態。

<img src="https://mintcdn.com/microsoft-4404708b/-_0FrcE2bDxzGxv-/images/gdk/lifecycle/cpu-resource-diagram-x1-constrained.png?fit=max&auto=format&n=-_0FrcE2bDxzGxv-&q=85&s=208b833caebeb949daa6877a76ceed6c" alt="顯示遊戲處於受限狀態時 CPU 核心狀態的圖例" width="595" height="128" data-path="images/gdk/lifecycle/cpu-resource-diagram-x1-constrained.png" />

### 暫停中

當遊戲以暫停中執行狀態執行時，它會使用與受限相同的資源執行，差別在於這表示主機已開始將遊戲轉換為已暫停狀態的程序。暫停中是暫時性的狀態。因此，視您查詢執行狀態的頻率而定，可能很難觀察到暫停中執行狀態。

### 已暫停

當遊戲處於已暫停執行狀態時，它仍常駐於記憶體中，但已不再執行。其執行緒不會被排程，因此不會使用任何 CPU 或 GPU 時間。如果遊戲已暫停，遊戲執行所在的整個遊戲作業系統也會同樣被暫停，且作業系統和記憶體的狀態會保持不變，直到發生另一次狀態轉換為止。

### 未執行

這是遊戲未在執行、未載入記憶體，且未使用任何主機資源時的狀態。請注意，某些工具 (例如 `xbapp query`) 可能會將此執行狀態回報為套件執行狀態 0 (未知)。

<br />

<a id="life-cycle-state-transitions" />

## 生命週期狀態轉換

本節說明每個生命週期狀態轉換，並提供每個轉換的範例原因。使用者與主機的某些互動可能會導致許多這類事件依序發生，有時速度非常快，但遊戲仍會逐步經歷所有這些轉換。下圖顯示生命週期狀態之間的狀態轉換。為了簡單起見，此圖表只顯示非錯誤的轉換。請注意，遊戲仍可能因當機而從任何狀態轉換為未執行狀態。

<img src="https://mintcdn.com/microsoft-4404708b/-_0FrcE2bDxzGxv-/images/gdk/lifecycle/gdk-life-cycle-state-transition-diagram.png?fit=max&auto=format&n=-_0FrcE2bDxzGxv-&q=85&s=45f4a5b0c2d951728a177354e447153d" alt="顯示每個生命週期狀態轉換的圖表" width="624" height="552" data-path="images/gdk/lifecycle/gdk-life-cycle-state-transition-diagram.png" />

### 從執行中轉換為受限 (受限)

此轉換代表遊戲可用資源的減少。遊戲可以呼叫 [RegisterAppConstrainChangeNotification](#life-cycle-event-callbacks) 進行註冊，以便在發生此情況時收到回呼。此轉換會在下列情況發生：

* 使用者開啟指南。
* 出現 TCUI (例如帳戶選擇器)。
* 使用者返回首頁。
* 遊戲失去焦點。

### 從受限轉換為暫停中 (暫停已開始)

當遊戲正在被暫停時，它會先轉換為暫停中狀態。任何透過 [RegisterAppStateChangeNotification](#life-cycle-event-callbacks) 註冊的回呼都會觸發。遊戲會維持在暫停中狀態，直到它從所有回呼處理常式返回，或直到發生一秒的逾時為止。如果處理常式在逾時之前返回，遊戲就會完成暫停。否則，遊戲會被終止。遊戲會在下列情況開始暫停：

* 主機進入連線待命狀態。
* 遊戲已有 10 分鐘不可見。
* 發生終止遊戲的第一個階段，例如啟動新遊戲時。

<Note>
  此轉換有時稱為「*靜止*」。
</Note>

### 從暫停中轉換為已暫停 (暫停已完成)

當處於暫停中狀態的遊戲從透過 [RegisterAppStateChangeNotification](#life-cycle-event-callbacks) 註冊的回呼處理常式返回時，就會自動發生此轉換。遊戲一進入此狀態，其執行緒就會停止執行。

### 從已暫停轉換為未執行 (終止)

此轉換代表將遊戲從記憶體中移除。遊戲無法控制此轉換，也不會與之互動，因為已暫停的遊戲並未在執行。終止會在下列情況發生：

* 使用者選擇從首頁結束遊戲時。
* 主機關機時 (而非轉換為連線待命)。
* 在關閉遊戲的最後階段，例如啟動新遊戲時。
* 遊戲儲存資料與雲端不同步時。如需詳細資料，請參閱[由 Connected Storage 系統終止](#termination-connected-storage)。

### 從未執行轉換為執行中 (啟動)

此狀態轉換代表在遊戲作業系統內載入並執行遊戲，而且通常與遊戲作業系統本身的啟動同時發生。每當使用者執行下列動作時，就會發生此轉換：

* 選取遊戲的磚。
* 接受遊戲邀請。
* 在 XBOX 殼層和系統中與遊戲的參照互動。

### 從已暫停轉換為受限 (繼續)

此狀態轉換之後最常接著發生解除受限事件。它代表遊戲的執行緒再次開始執行，而轉換會從呼叫 [RegisterAppStateChangeNotification](#life-cycle-event-callbacks) 的任何處理常式開始。當遊戲先前處於已暫停狀態，並被帶到前景時 (通常是透過與遊戲處於未執行狀態時會啟動遊戲的相同互動)，遊戲就會繼續。

### 從受限轉換為執行中 (解除受限)

此狀態轉換與受限轉換相反。它代表將遊戲的可用資源提升回執行中狀態的完整數量。此轉換也有對 [RegisterAppConstrainChangeNotification](#life-cycle-event-callbacks) 之任何處理常式的相關回呼，且每當遊戲成為前景應用程式時就會發生。

當遊戲因一般主機互動 (例如啟動另一個遊戲或關閉主機) 而被終止時，它仍會先轉換為已暫停狀態，然後才終止。這可確保目前正在執行的遊戲能夠在關閉之前儲存狀態。不過，如果遊戲當機或無法暫停，它會直接轉換為未執行狀態。

<a id="termination-connected-storage" />

### 由 Connected Storage 系統終止

如果遊戲的本機儲存資料與雲端不同步，Connected Storage 系統會在遊戲下次暫停時將其終止。這讓系統可以在遊戲再次啟動時同步最新的儲存資料。因此原因而終止並非當機，也不會導致 [XR-001](#xrs) 失敗。

這種情況並不常見，但如果您在主機未連線到 XBOX 網路 (也稱為 XBOX Live) 時啟動遊戲，然後在遊戲執行期間重新連線，就可能發生。如果未針對遊戲正確設定 Connected Storage，在開發期間也可能發生這種情況。

您可以在 [xbWatson](/zh-TW/tools/tools-console/xbWatson/xbwatson) 或 Visual Studio 內的 XBOX 系統監視器視窗中尋找類似下列內容的行，來辨識這種情況：

```text theme={null}
 [ConsoleEtw] [1] SuspendComplete
 [ConsoleEtw] TerminateApplicationAfterSuspend <package name>
 [ConsoleEtw] Eviction of package <package name> because -2138890207
 [ConsoleEtw] [1] TerminateBegin Successful
 [ConsoleEtw] [1] TerminateComplete
```

<code>SuspendComplete</code> 表示遊戲已成功暫停，並未當機或逾時。<code>TerminateApplicationAfterSuspend</code> 表示終止是由系統在成功暫停後起始的。-2138890207 值是 HRESULT CS\_E\_TERMINATEDTITLE\_NOLOCK，顯示終止的原因。

<br />

<a id="life-cycle-event-callbacks" />

## 生命週期事件回呼

本節說明遊戲如何在狀態之間轉換。它也會說明遊戲如何判斷這些轉換何時發生，以及遊戲接著如何回應這些轉換。

對於 Microsoft Game Development Kit (GDK) 遊戲，您可以註冊兩個事件來接收狀態變更資訊。如下列程式碼範例所示。

```cpp theme={null}
ULONG RegisterAppStateChangeNotification(
    _In_ PAPPSTATE_CHANGE_ROUTINE Routine,
    _In_opt_ PVOID Context,
    _Out_ PAPPSTATE_REGISTRATION* Registration
    );

ULONG RegisterAppConstrainedChangeNotification(
    _In_ PAPPCONSTRAIN_CHANGE_ROUTINE Routine,
    _In_opt_ PVOID Context,
    _Out_ PAPPCONSTRAIN_REGISTRATION* Registration
    );
```

如需詳細資訊，請參閱 [RegisterAppStateChangeNotification](https://learn.microsoft.com/windows/win32/api/appnotify/nf-appnotify-registerappstatechangenotification)。

<Note>
  受限變更通知是 XBOX 主機專屬的，目前沒有 API 參考頁面。此 API 非常相似，只是在名稱和參數中將「State」稍微改為「Constrained」。
</Note>

`PVOID Context` 可以是任何內容，並會在呼叫 `Routine` 函式時傳遞給它。您可以保留 `Registration`，以便使用 `UnregisterAppStateChangeNotification` 和 `UnregisterAppConstrainedChangeNotification` 取消註冊這些事件。

傳入註冊函式的 `Routine` 會在相關事件發生時，於遊戲內預設執行緒集區的執行緒上被呼叫。透過此函式註冊的所有常式，都會在不同的執行緒集區執行緒上以非同步方式呼叫。這可能在畫面中的任何時間點發生。對於 `RegisterAppStateChangeNotification`，一旦主機將遊戲設定為暫停中狀態並開始暫停逾時，就會以布林值 `true` 呼叫 `Routine`。將遊戲從已暫停狀態繼續為執行中狀態時，則會以布林值 `false` 呼叫 `Routine`。

對於 `RegisterAppConstrainedChangeNotification`，當主機將遊戲設定為受限狀態時，會以布林值 `true` 呼叫 `Routine`。將遊戲從受限狀態解除受限為執行中狀態時，則會以布林值 `false` 呼叫 `Routine`。

如需示範如何設定和處理這些事件，並確保在遊戲畫面的一致時間點於主執行緒上處理這些事件的範例，請參閱 [XBOX One 的 Microsoft Game Development Kit 移植指南](/zh-TW/build/console-features/porting-from-xbox-one-era/porting-guide-for-existing-era)中的範例程式碼。您也可以查看 SimplePLM 範例的 main.cpp，或 Visual Studio 中 Microsoft Game Development Kit (GDK) 的 Direct3D 12 XBOX 遊戲專案範本的 main.cpp。您可以從 [XBOX 開發人員下載](https://aka.ms/gdkdl)下載範例。

查看靜止停止回應的小型傾印時，您可能會遇到相當令人困惑的情況：在任何執行緒的堆疊中都看不到您註冊的回呼。這是由於尾端呼叫最佳化所致；若要解決此問題，只需將您的回呼包在下列程式碼中：

```cpp theme={null}
#pragma optimize( "", off ) 
/* ... */
#pragma optimize( "", on )
```

<Note>
  在 Windows PC 上執行的 Microsoft Game Development Kit (GDK) 遊戲不會被暫停。在 Windows PC 上，這些遊戲仍可呼叫 `RegisterAppStateChangeNotification`，但請注意 `PAPPSTATE_CHANGE_ROUTINE` 回呼不會觸發。
</Note>

<br />

<a id="responding-to-suspend-and-resume" />

## 回應暫停和繼續

遊戲必須執行一些動作才能暫停，以便為切換進出遊戲的使用者提供無縫的體驗，並確保遊戲通過 XR。

### 暫停逾時

若要完成暫停 (這是通過 [XR-001](#xrs) 的必要條件)，遊戲必須至少透過 `RegisterAppStateChangeNotification` 註冊一個回呼常式。回呼觸發時，所有已註冊的常式都會在不同的預設執行緒集區執行緒上以非同步方式呼叫。遊戲有一秒的時間從所有已註冊的常式返回，藉此向系統發出訊號，表示遊戲可以轉換為已暫停狀態。如果遊戲未在一秒內從暫停常式返回，或未註冊回呼，遊戲就會被終止並轉換為未執行狀態 (這會導致 [XR-001](#xrs) 失敗)。此程序可確保主機能夠快速在遊戲之間切換，同時確保遊戲在進入已暫停狀態之前已做好暫停的準備。

### Direct3D

為了回應暫停常式的呼叫，遊戲必須在從該常式返回之前，從其轉譯執行緒對其 `ID3D12CommandQueue` 呼叫 SuspendX。這可確保儲存 GPU 狀態以準備暫停。繼續時，遊戲必須呼叫 ResumeX 來還原狀態。在呼叫 `SuspendX` 和 `ResumeX` 之間呼叫任何 Direct3D API 都會擲回例外狀況，導致當機。在從暫停常式返回之前未呼叫 `SuspendX`，會導致暫停失敗且遊戲被終止 (同樣會導致 [XR-001](#xrs) 失敗)。如需詳細資訊，請參閱 Direct3D 對暫停和繼續的支援。

### XGameSave API

當遊戲收到暫停通知時，它在需要暫停之前有一秒的執行時間。當遊戲處於已暫停狀態時，它可能會在沒有任何額外執行時間的情況下轉換為未執行狀態。這表示在這一秒的暫停時間內，遊戲必須在進入已暫停狀態之前儲存任何未儲存的使用者資料。

[XGameSave](/zh-TW/build/core-features/common/game-save/game-saves-overview) API 是設計來支援在這段有限時間內進行儲存的。`XGameSave` API 會使用遊戲保留區以外的 RAM 作為第一個儲存點，以在短暫的暫停時間範圍內將遊戲寫入速度最大化。[XR-052：使用者狀態](#xrs)規定，遊戲不得造成使用者資料意外遺失，這包括適當的使用者進度和狀態。一般而言，遊戲必須確保其暫停處理的一部分包括儲存使用者資料。除了在暫停期間儲存之外，更頻繁地儲存也是個好主意。這可確保遊戲不必在逾時期間準備大量的儲存資料，也能避免停電等狀況造成大量使用者資料遺失。如需詳細資訊，請參閱[遊戲儲存概觀](/zh-TW/build/core-features/common/game-save/game-saves-overview)和 [GameSave 範例](https://aka.ms/gdkdl)。

請注意，建議使用 `XGameSave` API 的非同步版本。這可讓遊戲在系統寫出遊戲儲存資料的同時，繼續執行其餘的暫停程式碼。如需相關做法的範例，請參閱 XGameSaveSubmitUpdateAsync。

在繼續遊戲之前，作業系統會檢查在遊戲暫停期間，儲存的遊戲是否已在其他裝置上被修改。如果裝置處於線上狀態，且此檢查指出儲存資料已被修改，遊戲將會被終止並重新啟動，使遊戲進入一致的狀態。如果進行檢查時裝置處於離線狀態，仍會允許遊戲啟動。

繼續時，遊戲應一律嘗試呼叫 XGameSaveInitializeProvider 或 XGameSaveInitializeProviderAsync，重新取得其遊戲儲存提供者。重新初始化提供者可確保能取得最新的儲存資料。

### 使用者和使用者控制器配對

[XR-112：在初始啟用和繼續期間建立使用者和控制器](#xrs)規定，當遊戲繼續時，必須驗證使用者/控制器配對，並據此做出反應，繼續先前使用者的工作階段，或取得新的使用者 (一或多位)。確切的行為可能取決於遊戲如何處理其使用者和控制器。請務必不要依賴暫停之前有關使用者或控制器狀態的任何資訊，並在繼續時重新建立使用者和控制器的狀態。您應該在暫停/繼續週期中保留 `XUserHandle`，因為遊戲是透過它取得使用者狀態的更新。此外，透過 XUserRegisterForChangeEvent 和 XUserRegisterForDeviceAssociationChanged 註冊的回呼會在繼續期間觸發，以將已發生的狀態變更更新給遊戲。如需管理使用者和裝置的詳細資訊，請參閱使用者身分識別和 XUser 以及使用者和輸入裝置。如需遊戲可能如何處理此問題的範例，請參閱 [UserManagement 範例](https://aka.ms/gdkdl)。

### 權限和特殊權限

遊戲暫停期間，使用者可以變更帳戶設定，這些設定決定了他們在線上可以做什麼，以及如何與他人通訊。遊戲繼續時，應在啟用或停用相關功能之前重新檢查所有權限或特殊權限，讓遊戲的行為反映使用者設定的目前狀態。[XR-015：管理玩家通訊](#xrs)詳細說明文字和語音通訊的權限。[XR-045：XBOX Live 和帳戶特殊權限](#xrs)詳細說明允許或禁止與 XBOX services 相關動作的特殊權限。

### 網路功能

由於已暫停的遊戲沒有任何已排程的執行緒，因此遊戲繼續時，應預期網路通訊已受到影響。如需處理此情況的指引，請參閱[網路 API 簡介](/zh-TW/build/console-features/networking/introduction-networking)。如需 XBOX services 專屬的詳細資料，請參閱開始使用 XBOX services API。如需多人遊戲工作階段的詳細資訊，請參閱多人遊戲工作階段進階主題。

### 非同步 API

某些需要與系統作業系統通訊的非同步 API，如果在遊戲暫停時正在進行中，可能會失敗。如果發生這種情況，`Xasync` API 應該會以 `E_ABORT` 失敗。這與任何 XR 無關。而是在呼叫非同步 API 時需要注意的事項。請確保您已備妥錯誤處理機制，以妥善處理這種可能性。如果呼叫以這種方式失敗，通常最好的做法就是在遊戲繼續後直接重試。

### Gaming Runtime API

遊戲完成暫停事件的 AppStateChangedNotification 處理常式後，Gaming Runtime 會自動暫停。Runtime 會在叫用遊戲的繼續事件處理常式之前立即繼續。如果在 Runtime 暫停期間於其他執行緒上呼叫任何 Gaming Runtime API，它們將會以 E\_GAMERUNTIME\_SUSPENDED 失敗。例如，如果在暫停處理常式完成前不久呼叫非同步 API，就可能發生這種情況。回呼可能會在 Runtime 已暫停之後、但在遊戲停止排程執行緒之前觸發。

請盡可能避免進行可能在 Gaming Runtime 暫停的這段期間內執行的 Gaming Runtime 呼叫。如果無法避免，您可以偵測錯誤，並在收到繼續事件的 AppStateChangedNotification 之後重試呼叫。

### 音訊

暫停時，遊戲不應保留任何從 [IMMDeviceEnumerator](https://learn.microsoft.com/windows/win32/api/mmdeviceapi/nn-mmdeviceapi-immdeviceenumerator) 取得的物件，包括 `IMMDevice`、`IMMDeviceCollection` 或 `IMMEndpointDevice`。在繼續之後未先使用 `IMMDeviceEnumerator` 重新整理這些介面就嘗試使用它們，會導致未定義的行為。不過，如果遊戲保留 `IMMNotificationClient`，該用戶端在暫停和繼續期間會繼續正常運作。在暫停期間停止所有音訊串流，並在繼續時重新啟動它們，也是一種最佳做法 (雖然並非必要)。

繼續期間，遊戲的音訊串流也會失效，並需要重新初始化。遊戲應在執行其繼續處理常式期間或之後，處理從這些失效狀態復原的工作。如需詳細資訊，請參閱 XBOX One 軟體開發套件與 Microsoft Game Development Kit 音訊 API 的比較。

<Note>
  在繼續處理常式開始執行之前嘗試重新初始化音訊串流，可能會導致未定義的行為。
</Note>

<a id="dealing-with-time" />

### 處理暫停期間的時間變更

遊戲暫停期間可能會發生許多事情。唯一可以確定的是，在遊戲暫停期間時間會持續前進。遊戲需要將此納入考量，並確保在計算遊戲時間等計量時，不會意外地將遊戲暫停期間的時間包含在內。

從 2021 年 6 月 GDK 開始，遊戲暫停時，時間戳記計數器 (TSC) 會被凍結，直到之後遊戲繼續時才會前進。此外，TSC 不會包含暫停期間的時間。這表示遊戲可以依賴下列項目，準確回報遊戲執行期間的時間：

* \_\_rdtscp
* QueryPerformanceCounter

雖然 TSC 在暫停期間不會前進，但實際時鐘時間會前進。這表示如果遊戲呼叫 [GetSystemTime](https://learn.microsoft.com/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtime) 或 [GetLocalTime](https://learn.microsoft.com/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlocaltime)，就會看到時間已經前進。

<br />

<a id="responding-to-constrain-and-unconstrain" />

## 回應受限和解除受限

暫停通知預期遊戲執行特定動作，且主機會等待常式返回；與此不同的是，回應應用程式受限變更通知時不需要執行任何動作。收到事件時，轉換為受限狀態或執行中狀態的過程已經發生。相反地，此事件是通知遊戲其可用資源已變更，遊戲應據此減少或提升其資源使用量。

在決定遊戲應如何處理受限情況時，請考量遊戲只有在沒有輸入焦點時才會受限。因此，使用者無法在遊戲受限時與其互動。基於這個原因，大部分遊戲應在受限期間暫停遊戲進行 (或最接近暫停的動作)。不過，遊戲在受限期間仍可能可見，因此請務必繼續轉譯某些內容，讓使用者可以看到遊戲的狀態。使用者也很可能很快就會將遊戲帶回前景，因此維持多人遊戲對戰和其他網路通訊，可能會為使用者帶來更好的體驗。

最終，處理受限的唯一目標，就是在調整以因應減少的 CPU 和 GPU 時間的同時，讓遊戲繼續執行。達成此目標的最佳方式取決於您遊戲的個別需求。

<br />

<a id="launching" />

## 啟動

Microsoft Game Development Kit (GDK) 遊戲在設計上屬於 Win32，具備傳統的 Windows 訊息迴圈。因此，在啟動時，程式碼第一個面向開發人員的進入點是傳入 `WinMain` 的參數。或者，遊戲也可以使用 `GetCommandLine` 函式查詢其啟動時使用的參數。與 XBOX One ERA 或 UWP 不同，Microsoft Game Development Kit (GDK) 遊戲不受啟用逾時的限制，也沒有 Activated 事件處理常式。此外，與 XBOX One ERA 或 UWP 不同，Microsoft Game Development Kit (GDK) 遊戲不會使用啟用或啟動參數來處理遊戲邀請。相反地，必須處理遊戲邀請的 Microsoft Game Development Kit (GDK) 遊戲應使用 `XGameInviteRegisterForEvent` 註冊這些事件。遊戲執行註冊時，就會取得任何可用的擱置中邀請。

<br />

<a id="events-related-to-life-cycle" />

## 與生命週期相關的事件

這些事件實際上並不是生命週期事件。它們是與狀態轉換的原因和條件相關的事件。它們有助於判斷如何識別這些事件並據此做出回應。

#### 輸入焦點

若要知道遊戲何時擁有輸入焦點，Microsoft Game Development Kit (GDK) 遊戲可以在 `WindowProc` 回呼中接聽 `WM_ACTIVATEAPP` 視窗通知。這與 Win32 Windows PC 實作相同，且適用相同的文件。如需詳細資訊，請參閱 [WM\_ACTIVATEAPP 訊息](https://learn.microsoft.com/windows/win32/winmsg/wm-activateapp)。

下列程式碼範例示範如何接聽此事件。

```cpp theme={null}
// Windows procedure.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_ACTIVATEAPP:
        OutputDebugString((wParam) ? L"Activated\n" : L"Deactivated\n");
        break;
    ...
```

#### 可見性

若要判斷遊戲的視窗是否可見 (類似於輸入焦點)，Microsoft Game Development Kit (GDK) 遊戲可以在 `WindowProc` 回呼中接聽 `WM_SHOWWINDOW` 視窗通知。如需詳細資訊，請參閱 [WM\_SHOWWINDOW 訊息](https://learn.microsoft.com/windows/win32/winmsg/wm-showwindow)。

下列程式碼範例示範如何在 `WindowProc` 回呼中接聽 `WM_SHOWWINDOW` 視窗通知。

```cpp theme={null}
// Windows procedure.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_SHOWWINDOW:
        OutputDebugString((wParam) ? L"Visible\n" : L"Not Visible\n");
        break;
    ...
```

<br />

<a id="timeouts" />

## 使用 GDK 逾時

XBOX One ERA 和 UWP 開發人員會處理各種不同的啟用、暫停和停止回應偵測逾時。Microsoft Game Development Kit (GDK) 遊戲在設計上屬於 Win32，大致上沒有類似的概念，除非是在主機上執行；在主機上，必須能夠變更資源狀態，才能確保執行中的遊戲獲得最多的可用資源。下表比較不同平台之間的各種行為。

| 處理常式/逾時 | Microsoft Game Development Kit (GDK) | XBOX One ERA | UWP |
| - | - | - | - |
| 啟用處理常式 | 不適用 | `CoreApplicationView:: Activated` | `CoreApplicationView::Activated` |
| 啟用逾時 | 不適用 | 45 秒 | 10 秒 |
| 暫停處理常式 | `RegisterAppStateChangeNotification` | `CoreApplication:: Suspending` | `CoreApplication:: Suspending` |
| 暫停逾時 | 1 秒 | 1 秒 | 5 秒 |
| 繼續處理常式 | `RegisterAppStateChangeNotification` | `CoreApplication:: Resuming` | `CoreApplication:: Resuming` |
| 繼續逾時 | 不適用 | 不適用 | 不適用 |
| 受限處理常式 | `RegisterAppConstrainedChangeNotification` | `CoreApplication:: ResourceAvailabilityChanged` | 不適用 |
| 受限逾時 | 不適用 | 不適用 | 不適用 |
| 停止回應逾時 | 不適用 | 2 秒 | 2 秒 |

<br />

<a id="quick-resume" />

## Quick Resume

Quick Resume 是 XBOX Series 主機上 2020 年 6 月復原版本中的新功能。它可讓使用者在另一個遊戲執行時讓遊戲保持暫停，以比以往更快的速度在遊戲之間切換。在所有 XBOX One 系列裝置上，以及 6 月復原版本之前的 XBOX Series 主機上，當遊戲正在執行 (或受限或已暫停) 而使用者選取新遊戲時，第一個遊戲會被終止，並啟動新遊戲。在具有 2020 年 6 月及更新復原版本的 XBOX Series 主機上，第一個遊戲則可以被暫停，然後整個遊戲作業系統及其記憶體可以以已暫停狀態儲存。當使用者切換回來時，遊戲作業系統會被還原。接著遊戲就可以繼續。儲存的遊戲作業系統甚至可以在主機重新啟動後還原。從遊戲的角度來看，這與一般的暫停/繼續完全相同。不需要額外的步驟或程式碼。如果遊戲能成功暫停和繼續，它也就完全支援 Quick Resume。

由於 Quick Resume 的緣故，遊戲更容易在一次啟動工作階段中執行數百小時。遊戲可以一次保持暫停數天、數週，甚至數個月。這表示請務必確保在暫停之前建立的狀態資訊 (尤其是有關使用者的資訊) 在繼續時不會被假設為仍然正確。例如，如果您的遊戲利用深度的社交關係，可能已經新增了新朋友，也移除了其他朋友。如果您使用朋友的狀態資訊，他們上週在做的事情不太可能與遊戲繼續時他們正在做的事情完全相同。類似的問題也適用於協助工具喜好設定、特殊權限和排行榜。

<Warning>
  請務必重新查詢可能隨著時間輕易變更的狀態。
</Warning>

<br />

<a id="debugging-tools-and-features" />

## 偵錯工具和功能

本節說明一些有助於偵錯和測試遊戲生命週期的工具、記錄和功能。

### 生命週期轉換工具

在偵錯和測試時，請務必知道遊戲處於什麼狀態，並讓遊戲在狀態之間轉換。有一些工具可用來查詢目前的生命週期狀態並執行狀態轉換。[XBOX Manager](/zh-TW/tools/tools-console/xbom/xbom)、[XBOX Device Portal](/zh-TW/tools/tools-console/wdp/wdp) 和 [xbapp](/zh-TW/tools/tools-console/commandlinetools/xbapp) 命令列工具都會列出應用程式的目前狀態。它們都提供執行各種轉換的命令。例如，下列螢幕擷取畫面顯示 XBOX Manager 的狀態和動作功能表。

<img src="https://mintcdn.com/microsoft-4404708b/-_0FrcE2bDxzGxv-/images/gdk/lifecycle/xbom-life-cycle-tools.png?fit=max&auto=format&n=-_0FrcE2bDxzGxv-&q=85&s=bca79514d50eceeaaadd88e30150d4fe" alt="顯示 XBOX Manager 的狀態和動作功能表的螢幕擷取畫面" width="1024" height="443" data-path="images/gdk/lifecycle/xbom-life-cycle-tools.png" />

<Note>
  為了提供更快的反覆運算時間並支援測試的彈性，如果對未封裝的遊戲使用 'terminate' 命令，遊戲會直接轉換為未執行狀態，而不會先被暫停。若要以一般方式終止遊戲，只要先使用 `suspend` 命令將其暫停即可。
</Note>

也可以使用開發套件上的其中一個前面板按鈕，觸發從執行中到已暫停的轉換。Microsoft Game Development Kit (GDK) 隨附的 *Suspend\_Title* 指令碼可以使用 [XBOX Manager](/zh-TW/tools/tools-console/xbom/xbom) 或 [XBOX Device Portal](/zh-TW/tools/tools-console/wdp/wdp) 對應到前面板按鈕。請注意，無法從前面板按鈕觸發轉換為繼續狀態。繼續必須從主機的殼層進行，方法是從首頁或我的遊戲與應用程式中選取遊戲的磚，或使用其他工具，例如 [xbApp](/zh-TW/tools/tools-console/commandlinetools/xbapp)、[Visual Studio](/zh-TW/tools/tools-console/visualstudio/debugging-with-visualstudio) 或 [XBOX Manager](/zh-TW/tools/tools-console/xbom/xbom)。

### xbWatson 和 Visual Studio 中的狀態轉換記錄

知道狀態轉換何時發生，與知道目前的生命週期狀態同樣重要。[xbWatson](/zh-TW/tools/tools-console/xbWatson/xbwatson) 和 Visual Studio 內的 XBOX 系統監視器視窗中，提供了大量生命週期狀態轉換的記錄支援。現在，每當發生狀態轉換時，都會連同與應用程式相關之其他事件的資訊 (例如應用程式啟動的階段和整個系統中的焦點變更) 一起記錄下來。

下列螢幕擷取畫面顯示使用 xbWatson 查看狀態轉換何時發生。

<img src="https://mintcdn.com/microsoft-4404708b/-_0FrcE2bDxzGxv-/images/gdk/lifecycle/xbwatson-state-transition-logging.png?fit=max&auto=format&n=-_0FrcE2bDxzGxv-&q=85&s=ce4fb9b46af97e85c05c3c975306cbf4" alt="顯示使用 xbWatson 查看狀態轉換何時發生的螢幕擷取畫面" width="742" height="516" data-path="images/gdk/lifecycle/xbwatson-state-transition-logging.png" />

新的記錄功能也包括生命週期事件的錯誤和失敗。檢查此記錄可以協助您識別何時發生問題，或提供任何錯誤案例的進一步資訊。如果發生錯誤並回報 `HRESULT`，您可以查看 xberror 命令列工具以取得更多資訊。在上一個螢幕擷取畫面所示的錯誤案例中，`xberror` 顯示遊戲在其暫停處理常式期間逾時 (`E_GAME_SUSPEND_TITLE_TIMEOUT`)。

### 在暫停逾時時中斷

2020 年 6 月 Microsoft Game Development Kit (GDK) 的一項新功能，是當 Visual Studio 正在偵錯 Microsoft Game Development Kit (GDK) 遊戲，且遊戲因一秒逾時而無法暫停時，Visual Studio 能夠自動中斷。此設定預設為關閉。不過，您可以在專案的偵錯屬性中變更此設定，如下列螢幕擷取畫面所示。

<img src="https://mintcdn.com/microsoft-4404708b/-_0FrcE2bDxzGxv-/images/gdk/lifecycle/vs-break-on-suspend-timeout.png?fit=max&auto=format&n=-_0FrcE2bDxzGxv-&q=85&s=455bf244914b06fd15d160da94a39317" alt="顯示在暫停逾時時中斷的螢幕擷取畫面" width="832" height="245" data-path="images/gdk/lifecycle/vs-break-on-suspend-timeout.png" />

即使您沒有開啟已安裝遊戲的專案，也可以使用 XBOX Gaming Explorer 視窗變更該遊戲的此設定。在 XBOX Gaming Explorer 中選取遊戲，然後在**屬性**工具視窗中變更 **Break on Suspend Timeout** 設定。如需詳細資料，請參閱 [XBOX Gaming Explorer](/zh-TW/tools/tools-console/visualstudio/xbox-gaming-explorer)。

這非常適合用來偵錯暫停失敗，例如可能發生停止回應，或暫停程序的某個部分花費的時間比預期更長的情況。偵錯工具的做法是將一個含有 INT3 的新執行緒插入遊戲處理序中以造成中斷。這表示偵錯工具一開始會在一個看似空白的執行緒上中斷，但其他執行緒會在一秒逾時發生時，於其所在的位置中斷。如需使用 Visual Studio 偵錯遊戲生命週期狀態的詳細資訊，請參閱[使用 Visual Studio 偵錯 XBOX 專案](/zh-TW/tools/tools-console/visualstudio/debugging-with-visualstudio)。

<a id="automatic-suspend-failure-dumps" />

### 自動暫停失敗傾印

每當發生暫停失敗時，主機都會自動記錄診斷當機傾印。傾印也會上傳到開發人員入口網站。這些傾印會儲存在主機的 *D:\LocalDumps\\* 中。透過 2020 年 6 月更新，[xbWatson](/zh-TW/tools/tools-console/xbWatson/xbwatson) 也會列出主機上可用的傾印。它也提供從功能表下載傾印的選項。這些傾印稱為「*靜止記憶體傾印*」，因為靜止是暫停的另一個名稱。下列螢幕擷取畫面顯示主機上可用的靜止記憶體傾印。

<img src="https://mintcdn.com/microsoft-4404708b/-_0FrcE2bDxzGxv-/images/gdk/lifecycle/xbwatson-quiesce-memory-dumps.png?fit=max&auto=format&n=-_0FrcE2bDxzGxv-&q=85&s=bc878ec0e3a3f69493b625fb98c86233" alt="顯示主機上可用的靜止記憶體傾印的螢幕擷取畫面" width="940" height="637" data-path="images/gdk/lifecycle/xbwatson-quiesce-memory-dumps.png" />

當原本應叫用暫停回呼 (`PAPPSTATE_CHANGE_ROUTINE`)，但沒有已註冊的暫停處理常式時，也會建立診斷傾印。如果在結束暫停處理常式之前未呼叫 `ID3D12CommandQueue::SuspendX`，也會建立診斷傾印。

### 手動造成狀態轉換

您可以透過與主機互動，手動觸發每個狀態轉換。下表列出在不使用任何工具的情況下觸發每個狀態轉換的方式 (假設遊戲處於適合該轉換的起始狀態)。

| 轉換 | 動作 |
| - | - |
| 啟動 | 從**首頁**或**我的遊戲與應用程式**中選取遊戲的磚。 |
| 受限 | 按控制器上的 **XBOX** 按鈕以開啟**指南**。 |
| 暫停 | 在電源模式設定為**立即開機**時關閉主機。 |
| 終止 | 選取遊戲的磚後，按控制器上的**功能表**按鈕，然後選取**結束**。 |
| 繼續 | 從**首頁**或**我的遊戲與應用程式**中選取遊戲的磚。若要同時避免解除受限，請在轉換期間開啟**指南**。 |
| 解除受限 | 按控制器上的 **XBOX** 按鈕以關閉**指南**。 |

<br />

<a id="appendix" />

## 附錄

<a id="xrs" />

### 檢視 XR

#### 下載 XR 清單

1. 前往 [XBOX 開發人員下載](https://aka.ms/gdkdl)。
2. 針對檔案類型，選取**合作夥伴、發行和發行管理資訊**。
3. 選取**確認**。
4. 針對組建/版本號碼，選取與您所使用版本相符的 XGD 合作夥伴文件版本。
5. 選取**確認**。**立即下載**按鈕隨即出現，提示您下載文件。

### 生命週期事件的診斷遙測

主機平台會針對下表所示的事件傳送遙測。

| 事件 | 描述 |
| - | - |
| 啟動時間 | 從呼叫 `CreateProcess` 以啟動遊戲，到遊戲第一次呼叫 present 之間的時間。 |
| 繼續時間 | 從遊戲分割區繼續，到遊戲執行下一次 present 之間的時間。 |

<a id="smt-diagrams" />

### 已啟用 SMT 之 XBOX Series 主機的 CPU 資源圖表

如需 SMT 的詳細資訊，請參閱 XBOX One 與 XBOX Series X|S 的 CPU 和記憶體比較。

#### 執行中

下圖顯示執行中遊戲的 CPU 核心與虛擬核心之間的對應。

<img src="https://mintcdn.com/microsoft-4404708b/-_0FrcE2bDxzGxv-/images/gdk/lifecycle/cpu-resource-diagram-smt-running.png?fit=max&auto=format&n=-_0FrcE2bDxzGxv-&q=85&s=f74e206f1a1c658a3cfcac5513c9a381" alt="顯示執行中遊戲的 CPU 核心與虛擬核心之間對應的圖表" width="603" height="135" data-path="images/gdk/lifecycle/cpu-resource-diagram-smt-running.png" />

#### 受限

下圖顯示受限遊戲的 CPU 核心與虛擬核心之間的對應。

<img src="https://mintcdn.com/microsoft-4404708b/-_0FrcE2bDxzGxv-/images/gdk/lifecycle/cpu-resource-diagram-smt-constrained.png?fit=max&auto=format&n=-_0FrcE2bDxzGxv-&q=85&s=c479b8f5ea2e3834c68edd7745b0ffe7" alt="顯示受限遊戲的 CPU 核心與虛擬核心之間對應的圖表" width="593" height="130" data-path="images/gdk/lifecycle/cpu-resource-diagram-smt-constrained.png" />


## Related topics

- [XBOX 主機遊戲的認證測試 XBOX 需求](/zh-TW/publishing/certification/console-cert-tested-requirements.md)
- [最常失敗的測試案例](/zh-TW/publishing/certification/xr-top-failing.md)
- [XR-052 使用者狀態與遊戲存檔位置、漫遊及相依性](/zh-TW/publishing/certification/xr/xr-052.md)
- [NDA 主題目錄 - Microsoft Learn 線上連結](/zh-TW/nda/nda-topic-directory.md)
- [XBOX Rapid Updates](/zh-TW/publishing/game-publishing/concepts/certification/xbox-rapid-updates.md)
