Skip to content

Agent-driven asset loop

The Asset studio tabs let you drive vendor-API generation by hand. The agent-driven asset loop lets the agent do the same thing, and wire the result straight back into your chat with a one-click open-in-tool button. You ask, you wait a few seconds, you preview, you click into the editor to tweak.

This page covers the loop end-to-end. Reference docs for the underlying primitives:

The agent calls a Forge MCP tool. Forge runs the operation, saves the file under <project>/.forge/generated/<kind>/, and returns a ready-to-paste forge-link block. The agent drops the block in chat; the chat renders an inline preview card with a one-click open button.

ToolWhatTier
forge.generate_voiceElevenLabs TTSfree
forge.generate_sfxElevenLabs SFX (0.5–22s)free
forge.generate_musicElevenLabs Music (10–300s)paid
forge.generate_palette5-color palette from a curated theme or explicit hexeslocal
forge.generate_spritesheetPack pre-generated frames into one PNG + JSON descriptorlocal
forge.generate_tilesetProcedural tileset PNG (forest / dungeon / platformer / cave / scifi)local
forge.generate_tilemapProcedural Tiled .tmj using a tilesetlocal
forge.generate_shaderSave an agent-authored GLSL fragment shaderlocal
forge.generate_parallax_layersStack pre-generated layer images with per-layer scroll multiplierslocal
forge.generate_platformer_levelBundle tilemap + parallax + character into one level descriptorlocal
forge.generate_animation_clipsDefine named clips (idle / run / jump) against a sprite sheetlocal
forge.generate_dialog_treeBranching dialog tree with per-node voice idslocal

local = no vendor API call, no key needed. free and paid = ElevenLabs key required.

Every successful tool call returns the same shape:

{
"savedPath": "D:\\projects\\forest\\.forge\\generated\\sfx\\1746450000000.mp3",
"projectRelativePath": ".forge/generated/sfx/1746450000000.mp3",
"byteCount": 28345,
"forgeLinkBlock": "```forge-link\npath: ...\npreview: audio\n..."
}

The agent drops forgeLinkBlock verbatim into chat. The chat parses the fenced block and renders the right preview:

  • audio — waveform thumb + play/pause + open-in-trimmer button.
  • image — thumbnail + open-in-image-viewer button.
  • palette — inline swatch row + open-in-palette-tool button.
  • spritesheet — composed sheet thumbnail + open-in-builder.
  • tileset — strip preview + open-in-tilemap.
  • tilemap — mini-rendered map (each tile drawn at preview scale)
    • open-in-tilemap.
  • shader — live WebGL2 preview at ~30fps + open-in-sandbox.
  • parallax — static stacked layers + open-in-editor.
  • level — composed level thumbnail + open-the-level-preview.
  • animation — sheet preview + clip count.
  • dialog — node count + character count.

Click the button → the matching editor tab opens with the asset already loaded. No file picker, no copy-paste of paths.

A worked example: a forest level in three turns

Section titled “A worked example: a forest level in three turns”

You ask:

Build me a 60×20 forest level: tileset, populated tilemap, four-layer parallax background, and a hero sprite with idle / run animations.

The agent works through the chain:

1. forge.generate_tileset(theme="forest")
→ savedPath A (forest tileset PNG + .json)
→ drops forge-link card #1: "Forest tileset · 8 tiles · 32px"
2. forge.generate_tilemap(tileset_path=A, width=60, height=20)
→ savedPath B (.tmj with painted forest level)
→ drops forge-link card #2: "Forest level · 60x20 · forest"
3. (4× image-generation calls — sky, hills, trees, foreground)
forge.generate_parallax_layers(layers=[sky, hills, trees, fg])
→ savedPath C (parallax descriptor + thumbnail)
→ drops forge-link card #3: "Forest parallax · 4 layers · 800x320"
4. (8× image-generation calls — hero idle/run frames)
forge.generate_spritesheet(frames=[idle1, idle2, ..., run4])
→ savedPath D (packed sheet + descriptor)
→ drops forge-link card #4: "Hero sheet · 8 frames · 4x2 grid"
5. forge.generate_animation_clips(sheet_path=D, clips=[
{ name: "idle", frames: [0,1], fps: 6 },
{ name: "run", frames: [2,3,4,5,6,7], fps: 12 },
])
→ savedPath E (animation JSON)
→ drops forge-link card #5: "Hero animations · 2 clips"
6. forge.generate_platformer_level(
tilemap_path=B, parallax_path=C, character_sheet_path=D,
)
→ savedPath F (level descriptor + composed thumbnail)
→ drops forge-link card #6: "Forest level · parallax · character"

Six cards in chat, in document order, each clickable. You preview the tileset, then the populated level, then the parallax, then the hero animations cycling, then the bundled level scene with everything composed. You click into card #6 → the level preview tab opens with sky-hills-trees-foreground in the back, the painted tilemap on top, hero sprite at the default position. Drag → parallax depth, tilemap panning, hero anchored to the camera.

If you don’t like the layout: click card #2 → tilemap editor opens with the same tileset + map data, you repaint, re-export. Re-open card #6 to see the new composition.

The agent’s forge-self.md skill tells it to pair every saved asset with a forge-propose ASSETS.md append in project mode, so your project’s memory keeps a durable log of what was generated, when, and what prompt produced it. The forge-link is for your eyes; the log is for the project’s memory.

  • Project source files: the asset loop never writes to src/ or Assets/. Generated files live under .forge/generated/ and the user copies them into their engine project explicitly. (Engines that use folder mirrors — Godot — pick them up automatically; Unity needs the explicit “Import to Assets/” button on each asset card.)
  • Code edits: those go through the existing forge-propose-edit per-hunk review flow. The asset loop is for content; code edits are for code.
  • Free-tier music: ElevenLabs Music is paid-only. The agent’s skill copy says to confirm with the user before calling generate_music if cost matters.
  • Edit the result. Every preview card opens its tab pre-loaded. The tools you’d use to author from scratch all support re-saving, so you can iterate on the agent’s output without starting over.
  • Override defaults. All tools accept a name and label. The curated theme tools accept overrides (colors, theme, seed).
  • Chain manually. You can call any tool independently — the agent prefers to chain, but each tool is standalone.
  • Disable the loop. Settings → MCP servers → toggle the forge entry off. The tools disappear from Codex’s tool list on next sidecar restart.

Every tool that takes a path argument accepts:

  • An absolute path (drive letter or POSIX root).
  • A project-relative path. Resolved against the active project’s root.
  • Project-relative paths require an active project; in open mode (no project), use absolute paths.

The chained workflow is simpler than it looks: each tool returns savedPath (absolute), and the agent passes that absolute path into the next tool. No path arithmetic needed.