Skip to content

Asset Manifest

The asset manifest is a JSON file generated by npm run build (and served dynamically by npm run dev) that describes every asset the game needs, organized by tier.

{
"version": "1734567890123",
"shell": [
{
"path": "/assets/images/studio-logo.png",
"type": "image",
"size": 42301,
"tier": 1
}
],
"game": [
{
"path": "/assets/images/tavern-banner.jpg",
"type": "image",
"size": 185432,
"tier": 2
}
],
"shellSize": 42301,
"totalSize": 227733
}
FieldTypeDescription
versionstringBuild timestamp used for cache busting
shellAssetEntry[]Tier 1 assets (shell screens), loaded first
gameAssetEntry[]Tier 2 assets (gameplay), loaded with progress
shellSizenumberTotal bytes of shell assets
totalSizenumberTotal bytes of all assets

Each AssetEntry:

FieldTypeDescription
pathstringPath relative to public root (starts with /)
type'image' | 'audio' | 'video'Determined from file extension
sizenumber | undefinedFile size in bytes (undefined if file not found)
tier1 | 2Loading tier

The CLI scans these sources to build the manifest:

Shell assets (tier 1): read from config.shell in game.yaml:

  • shell.splash.logo, shell.splash.background, shell.splash.sound
  • shell.loading.background, shell.loading.music
  • shell.title.logo, shell.title.background, shell.title.music
  • shell.uiSounds.*

Game assets (tier 2): extracted from the content registry:

  • location.banner, location.music, location.ambient
  • character.portrait
  • item.icon, item.image
  • map.image
  • interlude.background, interlude.banner, interlude.music, interlude.voice, interlude.sounds[]
  • dialogueNode.voice, dialogueNode.portrait

Assets referenced in shell config are never duplicated in the game tier.

Empty strings and undefined fields are skipped.

In development (npm run dev), the manifest is generated on-the-fly by GET /api/manifest. The version is always "dev", so no caching occurs.

In production (npm run build), the manifest is written to:

  • dist/api/manifest (served at /api/manifest)
  • dist/asset-manifest.json (human-readable copy)
import type { AssetManifest, AssetEntry } from '@doodle-engine/core';

Both types are exported from @doodle-engine/core.