# 5. Worked Example: Cosmetic Pack
Part of [[Modding with Addressables]]. Prev: [[4. Discovery Trust and Updates]]. Next: [[6. Modding Pitfalls]].
A vertical slice: the player boots, then tries to load one additional catalog and instantiate one prefab with label `cosmetics`. Scripts were **not compiled** and no live pack was hosted as part of writing this note.
## 5.1 Pack
1. A prefab `Hat_Cone` that uses only built-in components plus, optionally, one script that **already exists** in the player.
2. Remote (or at least catalog-exported) Addressables group, label `cosmetics`, address `cosmetics/hat_cone`.
3. Content build. Note `catalog.json` (or the exact filename your 2.9.1 build produced) and the sibling `.hash` if present.
## 5.2 Loader
```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
/// <summary>
/// Loads one additional catalog, then instantiates a known address.
/// NOT compiled in Unity; not play-tested against a live catalog.
/// </summary>
public sealed class CosmeticPackBootstrap : MonoBehaviour
{
[SerializeField] string catalogPath;
[SerializeField] string hatAddress = "cosmetics/hat_cone";
[SerializeField] Transform attachPoint;
AsyncOperationHandle<GameObject> _instance;
public IEnumerator Start()
{
var catalog = Addressables.LoadContentCatalogAsync(catalogPath, true);
yield return catalog;
if (catalog.Status != AsyncOperationStatus.Succeeded)
{
Debug.LogWarning(
quot;No cosmetic pack ({catalogPath}). Continuing.");
yield break;
}
_instance = Addressables.InstantiateAsync(hatAddress, attachPoint);
yield return _instance;
if (_instance.Status != AsyncOperationStatus.Succeeded)
Debug.LogWarning(quot;Hat missing at {hatAddress}.");
}
void OnDestroy()
{
if (_instance.IsValid())
Addressables.ReleaseInstance(_instance);
}
}
```
`Start` as an `IEnumerator` is a Unity coroutine hook; if you prefer `Awaitable` / Task, use the patterns in [[Async Code]] and [[3. Loading Instantiating and Releasing]], still without `ToAwaitable()` unless you are on 4.0+.
## 5.3 Playtest checklist
1. Boot **without** the catalog reachable: the game still runs; a warning is enough.
2. Boot **with** the catalog: the hat instantiates; quitting releases the instance.
3. A typo address fails the hat, not the whole boot.
4. If you used a second project: Built-In Bundle Naming Prefix differs; Editor and Addressables versions match; the secondary group is **remote** with **Build Remote Catalog**.
5. No IAP button.
## 5.4 Exercise
Host the catalog on a local HTTP server **or** a file path, then point a second machine (or a player build) at it. Optionally add `Addressables.LoadAssetsAsync` with label `cosmetics` ([[4. Labels and Loading Many Assets]]) to list hats in a menu.
## Sources
- [[3. Loading Instantiating and Releasing]]
- https://docs.unity3d.com/Packages/[email protected]/manual/LoadContentCatalogAsync.html