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

# 內容更新最佳做法

> 內容更新最佳做法

<Tip>**使用 MSIXVC2 嗎？** 本頁所述的對齊和配置限制適用於原始 MSIXVC 格式。MSIXVC2 使用以內容為基礎的分段，消除了這些需求。如需 MSIXVC2 內容更新指引，請參閱[使用 MSIXVC2 的內容更新](/zh-TW/build/core-features/common/packaging/packaging-updates-msixvc2)。</Tip>

## 概觀

您可以在發行後透過修改、新增或移除資料來更新內容套件。若要起始更新，請將完整的更新套件上傳至 Partner Center 並發行。之後該內容的數位安裝會直接下載更新後的套件。系統的內容更新技術會修改現有的安裝，使其與更新後的套件一致。

Microsoft Game Development Kit (GDK) 內容會封裝成以子檔案細微度運作的 XVC 或 MSIXVC 套件。
您可以就地覆寫資料。您也可以以 4 kibibyte (KiB) (4,096 個位元組) 的倍數在檔案中插入或移除資料。
您無法有效率地移動資料。

當使用者從原始遊戲光碟安裝已有內容更新的遊戲時，安裝程序會同時從光碟和雲端提取資料。套件中未變更的部分會從光碟安裝，而更新的資料則透過串流安裝從雲端下載。此程序在系統 UI 和所有遊戲內 API 中的行為，就如同一般的串流安裝。

當主機或 PC 更新先前安裝的內容時，此程序會就地修改已安裝的 XVC 或 MSIXVC 套件檔案以容納新增或移除的資料，然後下載新資料。從更新開始安裝到更新完成安裝之間，遊戲無法執行。

## 有效率地製作套件

內容更新會盡量不干擾遊戲開發流程。無論您對遊戲內容進行何種變更，都可以正確地更新套件。不過，此程序在下載大小 (對應玩家無法玩遊戲的時間) 或耗用的硬碟空間方面可能不夠有效率。下列祕訣可協助您封裝遊戲，以確保最佳的使用者體驗。

**簡單：**

* 如果您使用封裝檔案將多個資產彙總為單一檔案，請確保封裝檔案建立工具將每個資產的起點對齊到 4-KiB 邊界。[簡單對齊範例](#AS)示範了此祕訣。
* 如果您壓縮資產，請確保壓縮具有決定性，而且每個資產都是獨立壓縮的。
* 請勿變更區塊 ID 或在區塊 ID 之間移動檔案。
* 請勿重新排序套件內的區塊、區塊內的檔案或檔案內的資產。請考慮依名稱或其他穩定的識別碼來排序資產。

**進階：**

* 如果您使用封裝檔案將多個資產彙總為單一檔案，請確保封裝檔案建立工具以一致的方式對齊每個資產的起點。此指引是一律對齊到 4 KiB 起點的進階版本。

  以一個資產為例，它在先前的套件中從位移 `PriorAssetOffset` 開始，而在包含更新的建置中套件中從 `AssetOffset` 開始。若要確保封裝檔案建立工具將每個資產的起點對齊到 4-KiB 邊界，請設定 `PriorAssetOffset % 4096 == 0` 和 `AssetOffset % 4096 == 0`。此條件一律滿足 `PriorAssetOffset % 4096 == AssetOffset % 4096`。任何其他能確保滿足此陳述式的方式也都可行。此條件可讓封裝檔案建立工具使用較少的填補。

  [具狀態對齊範例](#AAS)示範了此祕訣。
* 如果您使用非決定性壓縮，而未壓縮的資產沒有變更，請從先前的封裝複製其壓縮資料，讓壓縮資料也保持不變。
* 如果資產會自動排序以符合預期的執行階段載入順序，請考慮在首次發行時凍結自動排序。
* 如果封裝檔案有許多在更新中經常變更的小型資產，請考慮讓它們相鄰。修改 400 KiB 一次比修改 4 KiB 100 次更有效率。

## 封裝檔案中良好和不良對齊的範例

有些遊戲會將許多資產合併為稱為*封裝檔案*的大型檔案。子檔案內容更新可大幅改善此類遊戲下載更新時的下載大小和硬碟大小效率。若要利用此技術，遊戲的封裝檔案建立工具必須保留檔案內資產的 4-KiB 對齊。本節示範在封裝檔案內對齊資產的良好和不良方式。

為了說明起見，每個範例都以一系列含有字母的儲存格來呈現。為了簡化說明，圖表中每個儲存格為 1 KiB。儲存格之間的實線代表 4-KiB 邊界的位置。

### 資料覆寫

在下圖中，更新覆寫了單一儲存格。唯一的下載是包含此儲存格的 4-KiB 頁面。

<img src="https://mintcdn.com/microsoft-4404708b/sIrPFR_ir_sNKVEv/images/gdk/features/common/contentupdate_overwrite.png?fit=max&auto=format&n=sIrPFR_ir_sNKVEv&q=85&s=5f7f4411ee0a3d16b6451b7fea33d1ec" alt="圖表顯示單一儲存格為「已變更的資料」，以及構成 4 KiB 頁面的四個儲存格為「已下載的資料」。" width="1280" height="452" data-path="images/gdk/features/common/contentupdate_overwrite.png" />

### 插入

在下圖中，更新插入了單一儲存格。因此，插入點之後的每個儲存格都會位移一格。此位移使儲存格跨越 4-KiB 邊界，導致插入之後，舊套件和新套件中沒有任何 4-KiB 頁面相同。插入點之後的每個 4-KiB 頁面都會被下載。

<img src="https://mintcdn.com/microsoft-4404708b/sIrPFR_ir_sNKVEv/images/gdk/features/common/contentupdate_insert_non4k.png?fit=max&auto=format&n=sIrPFR_ir_sNKVEv&q=85&s=f59f2be0322605d3bc6145bac1900caf" alt="圖表顯示 &#x22;ABCD&#x22; &#x22;EFGH&#x22; &#x22;IJKL&#x22; &#x22;MNOP&#x22; &#x22;QRST&#x22; &#x22;UVXW&#x22;，資料 &#x22;Z&#x22; 插入在 &#x22;J&#x22; 和 &#x22;K&#x22; 之間，以及產生的下載 &#x22;IJZK&#x22; &#x22;LMNO&#x22; &#x22;PQRS&#x22; &#x22;TUVW&#x22; &#x22;X&#x22;，並以箭頭顯示字母在頁面之間的位移。" width="1280" height="480" data-path="images/gdk/features/common/contentupdate_insert_non4k.png" />

在下圖中，更新插入了單一儲存格。此外，也插入了三個填補儲存格。這四個儲存格合起來實際上就是 4-KiB 的插入，可防止後續儲存格跨越 4-KiB 邊界位移。只會下載包含插入和填補的 8 KiB。

<img src="https://mintcdn.com/microsoft-4404708b/sIrPFR_ir_sNKVEv/images/gdk/features/common/contentupdate_insert_4k.png?fit=max&auto=format&n=sIrPFR_ir_sNKVEv&q=85&s=ffd813c89872b96b018e47e31f222710" alt="圖表顯示 &#x22;ABCD&#x22; &#x22;EFGH&#x22; &#x22;IJKL&#x22; &#x22;MNOP&#x22; &#x22;QRST&#x22; &#x22;UVXW&#x22;，資料 &#x22;Z&#x22; 插入在 &#x22;J&#x22; 和 &#x22;K&#x22; 之間，以及產生的下載 &#x22;IJZK&#x22; 和 &#x22;L 填補 填補 填補&#x22;。" width="1280" height="480" data-path="images/gdk/features/common/contentupdate_insert_4k.png" />

### 刪除

在下圖中，更新刪除了單一儲存格。因此，刪除點之後的每個儲存格都會位移一格。此位移使儲存格跨越 4-KiB 邊界。刪除點之後的每個 4-KiB 頁面都會被下載。

<img src="https://mintcdn.com/microsoft-4404708b/sIrPFR_ir_sNKVEv/images/gdk/features/common/contentupdate_delete_non4k.png?fit=max&auto=format&n=sIrPFR_ir_sNKVEv&q=85&s=cc79ed7e3642c373f68cb8cf1f8fb375" alt="圖表顯示 &#x22;ABCD&#x22; &#x22;EFGH&#x22; &#x22;IJKL&#x22; &#x22;MNOP&#x22; &#x22;QRST&#x22; &#x22;UVXW&#x22;，資料 &#x22;K&#x22; 被刪除，以及產生的下載 &#x22;IJLM&#x22; &#x22;NOPQ&#x22; &#x22;RSTU&#x22; &#x22;VWX&#x22;，並以箭頭顯示字母在頁面之間的位移。" width="1280" height="510" data-path="images/gdk/features/common/contentupdate_delete_non4k.png" />

在下圖中，更新刪除了八個儲存格。只會下載 4 KiB，也就是位於刪除範圍起始和結束 4-KiB 頁面內的儲存格。

如果刪除範圍以 4 KiB 對齊，且其長度為 4 KiB 的倍數，則不需要下載任何資料。

<img src="https://mintcdn.com/microsoft-4404708b/sIrPFR_ir_sNKVEv/images/gdk/features/common/contentupdate_delete_4k.png?fit=max&auto=format&n=sIrPFR_ir_sNKVEv&q=85&s=7eef5d5ad6f21a30374495979f914188" alt="圖表顯示 &#x22;ABCD&#x22; &#x22;EFGH&#x22; &#x22;IJKL&#x22; &#x22;MNOP&#x22; &#x22;QRST&#x22; &#x22;UVXW&#x22;，資料 &#x22;KLMNOPQR&#x22; 被刪除，以及產生的下載 &#x22;IJST&#x22;。" width="1280" height="510" data-path="images/gdk/features/common/contentupdate_delete_4k.png" />

<a id="AS" />

### 對齊：簡單

下圖顯示六個資產。每個資產儲存在任意數目的儲存格中。每個資產的起點都位於 4-KiB 邊界上。因此，您可以獨立地新增、變更 (包括增加或減少大小) 或刪除資產。

此對齊方式是在封裝檔案內對齊資產最簡單的方式。

<img src="https://mintcdn.com/microsoft-4404708b/sIrPFR_ir_sNKVEv/images/gdk/features/common/contentupdate_packfile1.png?fit=max&auto=format&n=sIrPFR_ir_sNKVEv&q=85&s=38675f40bc9f2e9609f0bc39ddca37dc" alt="圖表顯示跨越多個儲存格的資產範例。每個資產都從 4 KiB 邊界開始。當前一個資產的長度不是 4 KiB 的倍數時，資產之間會有填補儲存格。" width="1280" height="290" data-path="images/gdk/features/common/contentupdate_packfile1.png" />

### 對齊：進階無狀態

下圖顯示七個資產。每個資產儲存在任意數目的儲存格中。每個大型資產的起點都對齊到 4-KiB 邊界，但小型資產 (圖表中的資產 6) 會緊接著前一個資產連續封裝，沒有填補。此對齊方法提供三項優點：

1. 它使用較少的空間進行填補。
2. 當您變更資產 5 時，下載資產 6 實際上不需要額外成本。
3. 當您變更資產 6 時，無論如何都會下載完整的 4 KiB。不論那是填補還是資產 5 的結尾都沒有差別。

如果資產可以放入原本所需的填補空間中，請在沒有任何填補的情況下封裝它。

<img src="https://mintcdn.com/microsoft-4404708b/sIrPFR_ir_sNKVEv/images/gdk/features/common/contentupdate_packfile2.png?fit=max&auto=format&n=sIrPFR_ir_sNKVEv&q=85&s=733719567c04e2f7ed2566277fc46ef3" alt="圖表顯示跨越多個儲存格的資產範例。每個資產都從 4 KiB 邊界開始。當前一個資產的長度不是 4 KiB 的倍數時，資產之間會有填補儲存格。資產 6 是緊接在資產 6 之後的單一儲存格，沒有填補。" width="1280" height="290" data-path="images/gdk/features/common/contentupdate_packfile2.png" />

<a id="AAS" />

### 對齊：進階具狀態

下圖顯示七個資產。每個資產儲存在任意數目的儲存格中。第一個套件中每個資產的起點都在沒有填補的情況下封裝。在新套件中，每個資產的起點都從與舊套件中相同的 4-KiB 頁面內位移開始。

例如，資產 3 在舊套件中從 4-KiB 頁面內的第一個儲存格之後開始。在新套件中，資產 3 之前加入了填補，使其同樣從 4-KiB 頁面內的第一個儲存格之後開始。

此方法可保留內容更新所需的對齊，同時將填補量降到最低。此方法的缺點是需要封裝檔案工具了解舊封裝檔案的配置，才能比對其位移。

<img src="https://mintcdn.com/microsoft-4404708b/sIrPFR_ir_sNKVEv/images/gdk/features/common/contentupdate_packfile3.png?fit=max&auto=format&n=sIrPFR_ir_sNKVEv&q=85&s=00cbcaaf404c9a2eb2b52e4efe0c2506" alt="圖表顯示跨越多個儲存格的資產範例。在第一個套件中，沒有填補儲存格。在新套件中，資產 3 和資產 5 之前有填補儲存格。從第一個套件連到新套件的線條強調，填補儲存格使資產 3 和資產 5 在兩個套件中都從距離最近 4 KiB 邊界相同的距離處開始。" width="1280" height="464" data-path="images/gdk/features/common/contentupdate_packfile3.png" />

## 片段化

對於有長期更新記錄、現有檔案隨時間經歷許多變更的遊戲，以及對大型檔案有大量小幅編輯的套件，內容更新演算法可能會產生次佳的更新大小。您可以透過兩種方式判斷次佳的更新大小：

1. 查看使用 `/priorpackage` 執行時 `makepkg pack` 的輸出。它會顯示警告："More than # page-level XTS entries. Page-level update efficiency will be compromised for # pages."
2. 查看 `makepkg pack` 或 `packageutil compare` 產生的比較報告。如果這些報告顯示您確知沒有變更的檔案被 100% 重新下載，這種情況可能是 XVC 檔案格式的加密片段資料結構空間不足的徵兆。

在您的 Microsoft 客戶代表指導下，請考慮對 `makepkg pack` 使用 `/maxencryptionfragments` 選項，以產生更佳的差異計算。將此值設定得太高，會增加遊戲啟動或 DLC 掛接期間發生記憶體不足錯誤的風險。

當您插入資料時，內容更新會導致套件資料在實體硬碟上產生片段。內容更新會在更新期間對套件執行部分重組，以嘗試將此影響降到最低。在有足夠可用硬碟空間的前提下，它保證任何兩個相鄰片段的大小總和至少為 100 mebibyte (MiB)。內容更新會嘗試讓所有片段至少為 100 MiB。

先前版本的 XBOX One ERA 內容更新不會執行重組。

## 工具使用方式

* **`makepkg /contentid GUID`：** 內容 ID 參數，與套件系列名稱一起用來跨版本識別套件。若要測試套件之間的更新，請使用相同的內容 ID 和套件系列名稱建立這兩個套件。
* **`packageutil compare`：** 此工具會產生更新計劃，描述如何從舊套件更新至新套件。它也會產生一份報告，列出為進行更新而下載的檔案及這些檔案內的範圍。使用此報告來識別非預期的變更。
* **`xbapp update` (PC：`wdapp update`)：** 此工具會將先前安裝在開發套件或 PC 上的套件更新為新套件。它使用與零售主機相同的方法，因此您可以用它來測試更新後的使用者體驗和 IO 效能。

## 詳細資料

本節說明內容更新運作方式的實作詳細資料。這些詳細資料可能會有所變更。本節適用於想要了解並微調所有細節、興趣濃厚的開發人員。

**什麼是更新串流計劃？**

更新串流計劃是 XBOX FastStart 技術的演進。Content Update v3 使用這些計劃來告訴 XBOX 主機和 PC 如何將舊套件轉換為新套件。此方法可讓雲端在發行時進行比主機或 PC 在下載期間所能進行的更密集的分析。

**為什麼選擇 4 KiB 作為插入或刪除所允許的倍數？**

4 KiB 是 XBOX 和支援的 PC 檔案系統上的 NTFS 叢集大小。若以不同於 NTFS 叢集大小的倍數進行插入或刪除，將需要大量的磁碟 IO 才能安裝更新。

內容套件以 4-KiB 區塊進行加密和完整性保護。若以不同於密碼編譯區塊大小的倍數進行插入或刪除，將需要重新加密資料才能安裝更新。在因正確的使用者未登入或無法使用遊戲光碟而無法取得授權的情況下，此需求會阻止背景更新。

有了此需求，套件就可以有效率地更新，而且不需要在更新程序結束時進行耗時的解壓縮步驟。

**makepkg/packageutil 期間與發行期間會發生什麼事？**

兩者都會進行相同的處理。在發行期間，會使用雲端為先前套件所做的最佳選擇資料來加密套件 (相當於 makepkg /priorpackage)。接著會從許多舊套件產生更新串流計劃 (相當於 packageutil compare)。

**makepkg 中指定的 /priorpackage 會影響零售套件嗎？**

不會。雲端中的發行程序一律會覆寫此指定。提供 `makepkg` 選項只是為了在發行之前進行本機估計。

**是否只會下載更新的遊戲資料？**

否。套件包含大量系統資料，包括所有資料頁面的密碼編譯雜湊、Game OS (僅限主機) 和內嵌的 NTFS 檔案系統。這些資料會在必要時下載。

此外，為了將 HTTP 要求的額外負荷降到最低，部分未變更的資料可能會重新下載。目前，被已變更資料包圍且小於 64 KiB 的未變更資料可能會重新下載，但此設定可能會為了最佳化*下載時間*而變更。

packageutil compare 產生的報告在其估計中包含上述資訊。

### 另請參閱

[建立、檢查和測試內容更新](/zh-TW/build/core-features/common/packaging/packaging-testing-updates)

[檢查更新](https://learn.microsoft.com/build/store/commerce/fundamentals/xstore-checking-for-updates)


## Related topics

- [内容更新最佳实践](/zh-CN/build/core-features/common/packaging/packaging-updates.md)
- [RTA 服务的最佳做法](/zh-CN/services/xbox-services/fundamentals/rta/concepts/live-rta-best-practices.md)
- [PlayFab 消费最佳做法](/zh-CN/services/playfab/pricing/consumption-best-practices.md)
- [创建、检查和测试内容更新](/zh-CN/build/core-features/common/packaging/packaging-testing-updates.md)
- [使用 MSIXVC2 进行内容更新](/zh-CN/build/core-features/common/packaging/packaging-updates-msixvc2.md)
