|
| 1 | +# PR 11.95 — Flatten Manifest Assets and Fix Loaders |
| 2 | + |
| 3 | +## Purpose |
| 4 | +Correct the manifest asset contract so `asset-browser.assets` is the single flat source of truth for all game assets, including images, fonts, audio, SVG, and any future asset kinds. |
| 5 | + |
| 6 | +This PR must fix the code that still expects nested `media` sections instead of restoring or preserving `media` as a special case. |
| 7 | + |
| 8 | +## Scope |
| 9 | +- Update game manifests to use a flat `asset-browser.assets` map. |
| 10 | +- Remove nested `asset-browser.assets.media` usage. |
| 11 | +- Update runtime loaders to read assets directly from `asset-browser.assets`. |
| 12 | +- Update Workspace Manager / Asset Browser / SVG Asset Studio consumers to read the same flat map. |
| 13 | +- Preserve existing asset IDs such as: |
| 14 | + - `image.asteroids.bezel` |
| 15 | + - `image.asteroids.background` |
| 16 | + - `font.asteroids.vector-battle` |
| 17 | + - `audio.*` |
| 18 | + - `svg.*` |
| 19 | +- Keep `kind` as the asset type discriminator. |
| 20 | +- Keep bezel stretch data on `image.*.bezel` entries only. |
| 21 | + |
| 22 | +## Required Manifest Shape |
| 23 | + |
| 24 | +```json |
| 25 | +{ |
| 26 | + "asset-browser": { |
| 27 | + "assets": { |
| 28 | + "image.asteroids.bezel": { |
| 29 | + "path": "/games/Asteroids/assets/images/bezel.png", |
| 30 | + "kind": "image", |
| 31 | + "source": "workspace-manager", |
| 32 | + "stretchOverride": { |
| 33 | + "uniformEdgeStretchPx": 10 |
| 34 | + } |
| 35 | + }, |
| 36 | + "image.asteroids.background": { |
| 37 | + "path": "/games/Asteroids/assets/images/deluxe.png", |
| 38 | + "kind": "image", |
| 39 | + "source": "workspace-manager" |
| 40 | + }, |
| 41 | + "font.asteroids.vector-battle": { |
| 42 | + "path": "/games/Asteroids/assets/fonts/vector_battle.ttf", |
| 43 | + "kind": "font", |
| 44 | + "source": "workspace-manager" |
| 45 | + }, |
| 46 | + "audio.asteroids.fire": { |
| 47 | + "path": "/games/Asteroids/assets/audio/fire.mp3", |
| 48 | + "kind": "audio", |
| 49 | + "source": "workspace-manager" |
| 50 | + } |
| 51 | + } |
| 52 | + } |
| 53 | +} |
| 54 | +``` |
| 55 | + |
| 56 | +## Explicitly Forbidden |
| 57 | +- Do not restore `asset-browser.assets.media`. |
| 58 | +- Do not create separate contracts for audio vs image/font/svg. |
| 59 | +- Do not hardcode fallback asset paths. |
| 60 | +- Do not guess `bezel.png`, `background.png`, `deluxe.png`, or any audio file path outside the manifest. |
| 61 | +- Do not add alias/pass-through loaders that simply remap `media` to `assets`. |
| 62 | +- Do not place bezel stretch under `asset-browser.assets.bezel`. |
| 63 | + |
| 64 | +## Loader Fix Requirements |
| 65 | +Search for and update all code paths that read any of these old shapes: |
| 66 | + |
| 67 | +```text |
| 68 | +assetBrowser.assets.media |
| 69 | +asset-browser.assets.media |
| 70 | +assets.media |
| 71 | +manifest.media |
| 72 | +media.audio |
| 73 | +media.image |
| 74 | +media.font |
| 75 | +media.svg |
| 76 | +``` |
| 77 | + |
| 78 | +Replace with flat iteration/filtering over: |
| 79 | + |
| 80 | +```text |
| 81 | +manifest["asset-browser"].assets |
| 82 | +``` |
| 83 | + |
| 84 | +Asset consumers must filter by `kind`: |
| 85 | + |
| 86 | +```js |
| 87 | +const assets = manifest?.["asset-browser"]?.assets ?? {}; |
| 88 | +const imageAssets = Object.entries(assets).filter(([, asset]) => asset.kind === "image"); |
| 89 | +const audioAssets = Object.entries(assets).filter(([, asset]) => asset.kind === "audio"); |
| 90 | +const fontAssets = Object.entries(assets).filter(([, asset]) => asset.kind === "font"); |
| 91 | +``` |
| 92 | +
|
| 93 | +## Asteroids Requirements |
| 94 | +- `image.asteroids.bezel.path` must be `/games/Asteroids/assets/images/bezel.png`. |
| 95 | +- Do not use `bezel1.png`. |
| 96 | +- `image.asteroids.background.path` must be `/games/Asteroids/assets/images/deluxe.png`. |
| 97 | +- `font.asteroids.vector-battle` must exist and point to `/games/Asteroids/assets/fonts/vector_battle.ttf`. |
| 98 | +- Existing Asteroids audio files must be listed as flat `audio.asteroids.*` entries if they are currently nested under media. |
| 99 | +
|
| 100 | +## Tool Requirements |
| 101 | +- SVG Asset Studio must list visible assets from the flat map. |
| 102 | +- Asset Browser must list visible assets from the flat map. |
| 103 | +- Workspace Manager tile counts must count flat assets by kind/id pattern. |
| 104 | +- Runtime game loading must load image/font/audio assets from the flat map. |
| 105 | +
|
| 106 | +## Validation |
| 107 | +Run targeted checks only. |
| 108 | +
|
| 109 | +Required checks: |
| 110 | +
|
| 111 | +```powershell |
| 112 | +Select-String -Path .\* -Recurse -Pattern "assets\.media" |
| 113 | +Select-String -Path .\* -Recurse -Pattern "asset-browser.*media" |
| 114 | +Select-String -Path .\* -Recurse -Pattern "bezel1.png" |
| 115 | +Select-String -Path .\* -Recurse -Pattern "image\.asteroids\.bezel" |
| 116 | +Select-String -Path .\* -Recurse -Pattern "font\.asteroids\.vector-battle" |
| 117 | +``` |
| 118 | +
|
| 119 | +Expected: |
| 120 | +- No remaining runtime/tool dependency on nested `media`. |
| 121 | +- No `bezel1.png` references. |
| 122 | +- Asteroids launches with no 404s for bezel/background/font/audio assets declared in manifest. |
| 123 | +- SVG Asset Studio shows manifest assets instead of only saying assets exist. |
| 124 | +- Background and bezel still load only from manifest. |
| 125 | +
|
| 126 | +## Full Samples Test |
| 127 | +Do not run the full samples suite by default. This PR modifies manifest loading code and selected game/tool consumers; use targeted checks for Asteroids, Workspace Manager, Asset Browser, and SVG Asset Studio. |
| 128 | +
|
| 129 | +Run full samples only if Codex modifies shared sample loader/framework code broadly enough that targeted validation cannot establish correctness. |
| 130 | +
|
| 131 | +## Acceptance |
| 132 | +- One flat `asset-browser.assets` contract exists for all asset kinds. |
| 133 | +- Runtime loads audio/images/fonts from the flat contract. |
| 134 | +- Tools display/list assets from the flat contract. |
| 135 | +- `media` is removed as a manifest asset grouping contract. |
| 136 | +- Asteroids assets load correctly. |
| 137 | +- No hidden fallback or guessed paths remain. |
0 commit comments