# Cube Orchestrator

> Use as the single entry point for ANY WowCube game work — when the user says "make a game", "design a game", "create a game", "build the game", "implement this", "start coding", "run the prompts", or wants to resume a WowCube project. ALSO the entry point for modding an existing, already-working game — when the user wants to change, tweak, reskin, or extend one ("замодить", "swap this sprite", "change the speed", "add a level"); it detects build-from-scratch vs modding and routes accordingly. The master controller for the whole pipeline: it routes through design, prompts, assets, and implementation, and manages every sub-skill and subagent. Supports an opt-in YOLO mode that runs the whole pipeline autonomously with no checkpoints until the final device .oct.

- Skill: `wowcube/cube-orchestrator` (Agent Skill)
- Install (CLI): `npx skillmds@latest add wowcube/cube-orchestrator`
- Raw SKILL.md: https://api.skillmd.com/api/skills/wowcube/cube-orchestrator/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: wowcube (https://skillmd.com/u/wowcube)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/wowcube/cube-orchestrator

---


# WowCube Cube Orchestrator

The orchestrator is the **single master controller** for all WowCube game work. The user always talks to the orchestrator; it never hands the user off to another skill. Instead, it detects which pipeline stage the project is in and drives the appropriate sub-skill or subagents itself.

**Core principle:** The orchestrator never writes game code, never designs the game, never authors prompts, and never generates assets *itself*. It reads, plans, routes, dispatches, and coordinates. Every stage of work is done by a sub-skill (`cube_game-designer`, `technical_prompter`, `cube_asset-builder`, `wowcube-boilerplate`) or by a subagent (coder, verifier, fixer). Parallelism must never compromise correctness — when in doubt, wait.

## Mode Detection (do this FIRST on every entry — before Stage Detection)

Before routing into the pipeline, decide which of two modes the request is in. Run this on every entry, including resumption:

- **Build mode** — create a game (from scratch or resume a partially-built one). This is the five-stage pipeline below; route via **Stage Detection & Routing**.
- **Mod mode** — change an existing, already-working game. Route to **Mod Mode Workflow** (near the end of this skill).

**Choose Mod mode when a signal OR the heuristic points to it:**
- **Signal in the prompt:** the user asks to *change / tweak / add to / fix / reskin* an existing game ("замодить", "поменяй спрайт", "доработай готовую игру", "add a level to `<game>`"), or names a specific already-built game/folder.
- **Heuristic:** the workspace already holds a *working* `app_<game>/` — a `.target` marker, a built simulator (`bin/app_<game>.exe` on Windows or `build-sim/octavios_sim` on Linux) and/or `app_<game>.oct`, and a non-trivial `app_<game>/src/app_<game>.h` — and the request is about altering it, not starting something new.

**When it's ambiguous** — e.g. a working project exists but the wording reads like a brand-new game — **ask the user which they mean.** Never guess between building fresh and modifying working code: picking wrong is expensive in both directions (clobbering a working game, or grafting a mod onto the wrong base).

Default: if nothing indicates an existing project (greenfield workspace, "make a game"), it's **Build mode**.

**Run mode (orthogonal to Build/Mod):** YOLO mode turns on **only if the literal token `YOLO` (case-insensitive) is present in the body of the current user prompt** — see the HARD ACTIVATION RULE in `## YOLO Mode`. No paraphrase, translation, or inferred intent activates it. When OFF (the default) every checkpoint in this skill is in full force. When ON, the autonomous rules in `## YOLO Mode` override the checkpoints in both Build and Mod mode.

## The Pipeline (what the orchestrator manages)

The orchestrator owns a five-stage pipeline. It is the only skill the user invokes; the other four skills are components the orchestrator drives.

| Stage | Produces | Driven by | How |
|-------|----------|-----------|-----|
| 1. Design | `plans/<game>_gdd.md` | `cube_game-designer` | Skill tool (interactive, main context) |
| 2. Prompts | `plans/<game>_prompts.md` + `plans/<game>_assets.json` | `technical_prompter` | Skill tool (main context) |
| 3. Assets | `assets/packed/*.png`, `assets/wav/*.wav`, `sound/assets/*.mp3`, `src/app_<game>_ids.h`, `app_<game>/index.bin` | `cube_asset-builder` + asset-consistency review subagent | Skill tool: AI sprite generation (OpenRouter image model from each sprite's `gen_prompt`), then an agent consistency review, then the mandatory user review — see [Stage 3: Asset Generation](#stage-3-asset-generation-ai) |
| 4. Implement | `app_<game>/src/app_<game>.h` (per-prompt) | coder / verifier / fixer | Agent tool (subagents) |
| 5. Package | `app_<game>/app_<game>.oct` (ARM code embedded, verified) | `wowcube-boilerplate` | Skill tool (runs `build_device.ps1` / `build_device.sh`) |

**Invocation mechanism:**
- **Stages 1–3 and Stage 5 run in the main context via the Skill tool.** Stages 1–3 each require user interaction (the designer's discovery interview, the asset-review checkpoint); Stage 5 invokes `wowcube-boilerplate` to run the device build. In each case the orchestrator invokes the sub-skill, lets it run to completion, then returns here.
- **Stage 3 additionally dispatches one read-only subagent via the Agent tool** — the asset-consistency reviewer — after AI generation and before the user review. See [Stage 3: Asset Generation](#stage-3-asset-generation-ai).
- **Stage 4 dispatches subagents via the Agent tool**, exactly as described in the implementation workflow below.

## Stage Detection & Routing (Build mode — runs after Mode Detection)

On entry — including resumption — determine the active `<game>` (ask the user if ambiguous or multiple games exist; otherwise infer from `plans/` and `context/`). Then inspect the filesystem and route to the FIRST stage whose output is missing:

| Detected state | Route to | Action |
|----------------|----------|--------|
| No `plans/<game>_gdd.md` | **Stage 1** | Invoke `cube_game-designer` via the Skill tool |
| GDD exists, but no `plans/<game>_prompts.md` or no `plans/<game>_assets.json` | **Stage 2** | Invoke `technical_prompter` via the Skill tool |
| Prompts + manifest exist, but `assets/packed/pal.png` is missing | **Stage 3** | Run the [Stage 3: Asset Generation](#stage-3-asset-generation-ai) workflow (gate the manifest + key, drive `cube_asset-builder`, run the consistency review, then user review) |
| All Stage 1–3 outputs present, but prompts remain unimplemented | **Stage 4** | Run the implementation workflow below |
| All prompts implemented, but no verified device `.oct` exists (or it was last touched by a sim run) | **Stage 5** | Invoke `wowcube-boilerplate` via the Skill tool to run the device build (`build_device.ps1` on Windows / `build_device.sh` on Linux) |

After each stage completes, **re-run this detection** to find the next stage — do not assume the next stage; verify its inputs exist.

## Stage-Boundary Checkpoint (MANDATORY between every stage)

After a stage produces its artifact and BEFORE invoking the next stage, the orchestrator MUST:
1. Summarize what the completed stage produced (GDD path, prompt count, asset counts, etc.)
2. **STOP. Do NOT invoke the next stage's sub-skill or any agent.**
3. Present the next stage and wait for explicit user approval ("ok", "continue", "next", etc.)
4. Only after approval, route into the next stage

This is the same non-negotiable discipline as the per-prompt checkpoint in Stage 4. Never auto-advance across a stage boundary. The user reviews each artifact (design, prompts, assets, device package) before the pipeline proceeds.

**Exception — YOLO Mode:** this stage-boundary checkpoint is SUSPENDED when the user explicitly activated YOLO (see `## YOLO Mode`). In YOLO, after a stage's artifact is produced the orchestrator re-runs Stage Detection and auto-advances to the next stage without stopping.

**MANDATORY RULE — CHECKPOINT AFTER EVERY PROMPT:**
After each prompt cycle (coder → verifier → context save), you MUST:
1. Present the summary and test instructions to the user
2. **STOP. Do NOT dispatch the next coder agent.**
3. Wait for the user's explicit approval ("ok", "continue", "next", etc.)
4. Only after receiving approval, proceed to the next prompt

This is NON-NEGOTIABLE. Never batch multiple prompts. Never skip the checkpoint. Never assume the user wants to continue. The user needs to test every build **in the simulator** before proceeding. (Per-prompt iteration uses the simulator; the authoritative physical-cube test happens once at **Stage 5**, when the device `.oct` is built and verified — see below for why it cannot be built per-prompt without being clobbered.)

**Exception — YOLO Mode:** this per-prompt checkpoint, and every "wait for user approval" instruction in this skill, is SUSPENDED in YOLO (see `## YOLO Mode`). YOLO runs all prompts back-to-back and only reports once, at the final device build.

## YOLO Mode (Autonomous Run — opt-in)

**Default OFF.** YOLO is an explicit, opt-in override of every checkpoint and approval in this skill.

**HARD ACTIVATION RULE — the only way YOLO turns on:** activate YOLO **if and only if the literal token `YOLO` (case-insensitive) appears in the body of the user's prompt.** Nothing else activates it:
- No paraphrase, synonym, or translation activates YOLO — "автономный режим", "no checkpoints, just build it", "фигачь до финального билда / .oct", "go autonomous", etc. do **NOT** count. Only the literal string `YOLO`.
- Never infer it from intent, tone, or context.
- Never carry it across turns or unrelated requests — the token must be present in the current prompt body. A prior prompt's `YOLO` does not keep the mode on.
- If the user clearly wants autonomy but did not write `YOLO`, do **not** enter YOLO; proceed with normal checkpoints (you may note that they can write `YOLO` to enable it).

When activated this way, it applies to both Build and Mod mode.

### Mandatory pre-activation double-check (risk disclosure + explicit confirmation)

Even when the literal `YOLO` token is present, **the orchestrator does NOT go autonomous immediately.** It MUST first stop, explain the risks in plain language, and get one explicit confirmation. This is the single allowed prompt between seeing `YOLO` and going silent — never skip it, never assume the answer.

Present the risks clearly (adapt wording, but cover all of these):
- **Result is not guaranteed.** The pipeline runs unattended; the final game may not match what you pictured, and YOLO won't stop to course-correct.
- **No per-stage verification by you.** Design, prompts, assets, and gameplay are auto-accepted at each boundary — without your eyes on each stage, the cumulative result can drift far from your expectations, and a wrong early decision propagates through everything downstream.
- **It can take a long time.** A full design → prompts → assets → implement → device-build run is long-running with no interaction in between.
- **It can burn a lot of tokens / cost.** Autonomous generation, multi-agent verification, and up-to-5 fix cycles per prompt consume significantly more tokens than a checkpointed run.
- **Rework risk.** If the outcome is off, you may have to redo or heavily mod the game afterward — possibly costing more total than running with checkpoints.

Then ask for an explicit go/no-go, e.g. *"YOLO means I run the whole pipeline unattended to the final `.oct` — no result guarantee, no per-stage review from you, it can take a while and burn a lot of tokens. Confirm you want YOLO, or I'll proceed with normal checkpoints."*

- Proceed into YOLO **only on a clear affirmative** ("yes", "да", "go", "confirm").
- On anything ambiguous, silence, or "no" → **do NOT enter YOLO**; fall back to the normal checkpointed flow.

Only after this confirmation do the One-time intake and the autonomous run begin.

When YOLO turns on, the orchestrator runs the **entire pipeline in one session** and does not prompt the user again until it delivers the final device package `app_<game>/app_<game>.oct`. The only thing it removes is the human checkpoints — it does NOT remove the correctness gates that decide whether that `.oct` actually runs on the cube.

### One-time intake (gather BEFORE going autonomous)

A truly autonomous run still needs the few inputs that cannot be invented. Collect these once, up front, then go silent:

1. **Game concept** (Build mode, if not already given) — ask for the brief now (genre, core mechanic, vibe, length). YOLO does not run the designer's interview turn-by-turn; it takes the brief once and lets `cube_game-designer` produce the GDD from it.
2. **Asset source + key** (Stage 3) — default to **Path A (AI generation)**, the autonomous path, and obtain `OPENROUTER_API_KEY` now. Path B (self-supplied art) is inherently non-autonomous (it waits on human-made files); use it in YOLO only if complete assets are already on disk.

Then announce YOLO once ("YOLO ON — running design → prompts → assets → implement → device build autonomously; next stop is the final .oct") and proceed without further prompts.

### What YOLO suspends

| Checkpoint (default) | YOLO behavior |
|---|---|
| Stage-Boundary Checkpoint (between every stage) | **Suspended** — re-run Stage Detection, auto-advance. |
| Per-prompt checkpoint (Stage 4, Step 5) | **Suspended** — save context, go straight to the next prompt. |
| Stage 3 user asset review (Step 3.4) | **Suspended** — auto-accept any set the consistency reviewer passes (the review→regen loop, max 3, still runs). |
| Mod-mode mini-plan & per-change checkpoints (M3, M5) | **Suspended** — auto-advance through plan and per-change review. |
| 5-attempt verification failure → ask user | **Auto-decide** per the Failure policy below. |

### What YOLO NEVER drops (hard invariants — these decide whether the .oct runs)

Dropping any of these yields a package that won't load or won't run on the cube, defeating the whole point of an autonomous run.

- **Both verifier agents** (Requirements + Template) run every prompt, threshold **90/90**, max **5** fix attempts.
- The orchestrator still **never writes code, design, prompts, or assets itself**.
- **`_ids.h` is never hand-edited; assets stay valid; the asset-set completeness check still blocks a partial set** (a missing sprite/sound = uncompilable build).
- **Stage 5 device build + ARM-embed verification still runs and must exit 0** — a sim-only `.oct` is never delivered.
- All mandatory platform reminders, explicit casts, fixed-width types, and all seven handlers (`on_init`, `on_tick`, `on_tap(tapid, count)`, `on_twisted`, `on_pretwisted`, `on_shake`, `on_proc_draw` stub) — still enforced.

### Safe parallelism (Stage 4)

All game code is one file (`app_<game>/src/app_<game>.h`), so **coding stays sequential** — only one coder writes the file at a time. YOLO extracts parallelism from everything else:

1. Build a prompt dependency graph up front (foundational vs. cosmetic/isolated, per the Pipeline Model table).
2. **Verifiers (Requirements + Template) and fixers fan out** in parallel; verification of prompt N overlaps task-JSON prep for N+1.
3. **Independent cosmetic/isolated prompts** (audio, visual polish, UI text — touching disjoint code regions, no mutual dependency) batch their verify+fix in parallel.
4. Coders for independent prompts are still serialized on the file but dispatched back-to-back with no waiting between them.
5. **Foundational prompts** (scaffold, data structures, core init) stay strictly sequential and fully verified before anything downstream is dispatched.
6. Never dispatch two coders that could both edit the file concurrently. When in doubt, serialize the coding and parallelize only the checking.

### Failure policy in YOLO (no user to ask)

When a prompt fails verification after the 5-attempt limit:
- **Foundational prompt** → **abort the run**, save context, surface immediately. This is the one time YOLO breaks silence before the `.oct` — downstream prompts can't be trusted.
- **Non-foundational prompt** → keep the best-scoring version, record it as a known issue for the final report, and **continue**.

A **Stage 5 ARM build failure** (missing toolchain, asset-only pack) is always a hard stop — surface it; never ship a sim-only `.oct`.

### YOLO completion

After the device build verifies, present a single end-of-run report: stages run, per-prompt verification scores, total fix cycles, any prompts that finished below threshold (with best scores), the consistency-review outcome, and the absolute path to the verified `app_<game>/app_<game>.oct`.

## When to Use

- ANY WowCube game request, at any stage — this is the entry point
- User says "make a game," "design a game," or "create a game" (→ routes to Stage 1)
- User says "implement this," "start coding," "run the prompts," or "build the game from prompts" (→ routes to the first incomplete stage)
- Resuming a partially-completed project at any stage (read `context/<game>_context.json` and re-run stage detection)

## When NOT to Use

- The request is not about a WowCube game
- (There is no "use another skill first" case — the orchestrator owns the whole pipeline and routes into the sub-skills itself.)

## Stage 4 Prerequisites

These files must exist before the **implementation workflow (Stage 4)** runs. They are produced by Stages 1–3, so under normal flow they will already be present when stage detection routes here.

| File | Produced by | Required |
|------|-------------|----------|
| `plans/<game>_prompts.md` | Stage 2 (`technical_prompter`) | Yes |
| `plans/<game>_gdd.md` | Stage 1 (`cube_game-designer`) | Yes |
| `plans/<game>_assets.json` | Stage 2 (`technical_prompter`) | Yes |
| `app_<game>/src/app_<game>_ids.h` | Stage 3 (`cube_asset-builder`) | Yes |
| `assets/packed/pal.png` | Stage 3 (`cube_asset-builder`) | Yes |
| `OCT_wowcube-agent-skills/templates/app_ai_template/src/app_ai_template.h` | Project template | Yes |
| `app_<game>/` scaffolded, assets packed, **simulator builds and launches** | `wowcube-boilerplate` skill | Yes |

If any Stage 4 prerequisite is missing when implementation is expected, do NOT proceed — re-run **Stage Detection & Routing** above and drive the missing stage's sub-skill yourself (Stage 1 → `cube_game-designer`, Stage 2 → `technical_prompter`, Stage 3 → `cube_asset-builder`), checkpointing at each boundary.

**Infrastructure gate (do this before Step 1):** Verify the build environment is
ready — `app_<game>/` exists with its `.target` marker, `art/packed/*.raw` and
the asset index `app_<game>/index.bin` are present (the index is as load-bearing
as the `.raw` files — the simulator dies without it), and the simulator builds
and launches (`app_<game>/bin/app_<game>.exe` on
Windows, `app_<game>/build-sim/octavios_sim` on Linux). If any of these
is missing, **invoke the `wowcube-boilerplate` skill (Skill tool)** to scaffold and
verify the infra, then return here. Never dispatch the first coder agent against an
unverified or non-existent project — a broken toolchain discovered mid-implementation
is far more expensive to untangle than one caught before any code is written.

## Constraints

- **Assets (PNGs, WAVs) are prototyped by `cube_asset-builder`** BEFORE this skill runs. By the time this skill starts, the following are on disk and valid:
  - `assets/packed/*.png` and `assets/packed/pal.png` (packed sprites)
  - `assets/wav/*.wav` (source sounds, ≤ 2 seconds) — packing encodes each to `app_<game>/sound/assets/<name>.mp3` (22050 Hz mono CBR 32k, via ffmpeg); the app ships the mp3, never the raw `.wav`
  - `src/app_<game>_ids.h` (BMP_* enum, generated by `pack.py`)
  Agents NEVER create sprite or sound files and NEVER edit `_ids.h`.
- Code agents work only with `app_<game>/src/app_<game>.h` — they reference existing `BMP_<name>` constants from the ids file and sounds via `SND_getAssetId("<name>.mp3")`, with names taken from `plans/<game>_assets.json`. They do NOT create new asset names.

## Architecture

All game code lives in a single file (`app_<game>/src/app_<game>.h`). This means:
- **Coding is always sequential** — only one coder agent modifies the file at a time
- **Verification can overlap with preparation** — while verifier checks prompt N, orchestrator can prepare the task JSON for prompt N+1
- **Quality over speed** — if the next prompt depends on verification results (e.g., the verifier might find issues that change the code), WAIT for verification before dispatching the next coder

### Pipeline Model

```
Time →

Prompt 1:  [===CODER===][==VERIFIER==]
Prompt 2:               [prep JSON..][===CODER===][==VERIFIER==]
Prompt 3:                                         [prep JSON..][===CODER===][==VERIFIER==]
```

The orchestrator decides at each step whether to pipeline or wait:

| Situation | Decision |
|-----------|----------|
| Prompt N verification is running, prompt N+1 does NOT depend on N's verified output | **Pipeline**: prepare N+1 JSON now, dispatch coder as soon as N's coder is done |
| Prompt N verification is running, prompt N+1 builds directly on N's code | **Wait**: verification might trigger fixes that change the code N+1 depends on |
| Prompt N verification failed, fix agent deployed | **Wait**: do not prepare N+1 until fix is verified |
| Prompt N is a foundational prompt (scaffold, data structures, core init) | **Always wait**: later prompts depend heavily on getting this right |
| Prompt N is cosmetic/isolated (audio, visual polish, UI text) | **Safe to pipeline**: failures here won't cascade |

> **In YOLO mode** this same table drives parallelism: "Pipeline" / "Safe to pipeline" rows become parallel verifier+fixer batches, while "Wait" / "Always wait" rows stay strictly sequential. The decision criteria do not change — only the per-prompt user checkpoint between them is removed.

## JSON Communication Protocol

All data between orchestrator and agents is JSON.

### Coding Task JSON (orchestrator → coder agent)

```json
{
  "task": "code",
  "game": "<game_name>",
  "prompt_number": N,
  "prompt_title": "...",
  "total_prompts": M,
  "instructions": "<full prompt instructions text>",
  "platform_reminders": ["..."],
  "verification_criteria": "<what the user should see/hear>",
  "files_to_read": [
    "OCT_wowcube-agent-skills/templates/app_ai_template/src/app_ai_template.h",
    "app_<game>/src/app_<game>.h"
  ],
  "files_to_write": [
    "app_<game>/src/app_<game>.h"
  ],
  "prior_context": [
    {
      "prompt": 1,
      "title": "...",
      "structs_added": [],
      "fields_added": {},
      "functions_added": [],
      "globals_changed": [],
      "sprites_used": 0,
      "notes": "..."
    }
  ]
}
```

### Verification Task JSON (orchestrator → verifier agent)

```json
{
  "task": "verify",
  "game": "<game_name>",
  "prompt_number": N,
  "prompt_title": "...",
  "instructions": "<original prompt instructions>",
  "verification_criteria": "<what the user should see/hear>",
  "files_to_read": [
    "app_<game>/src/app_<game>.h",
    "plans/<game>_gdd.md",
    "OCT_wowcube-agent-skills/templates/app_ai_template/src/app_ai_template.h"
  ],
  "prior_context": [ ... ]
}
```

### Coder Response JSON (coder agent → orchestrator)

```json
{
  "status": "done|error",
  "prompt": N,
  "files_modified": ["app_<game>/src/app_<game>.h"],
  "summary": {
    "structs_added": [],
    "fields_added": {},
    "functions_added": [],
    "globals_changed": [],
    "sprites_used": 0,
    "notes": "..."
  },
  "error": null
}
```

### Requirements Verifier Response JSON (requirements agent → orchestrator)

```json
{
  "agent": "requirements",
  "prompt": N,
  "scores": {
    "completeness": 45,
    "gdd_alignment": 25,
    "no_regressions": 20,
    "verification_criteria": 10
  },
  "total": 100,
  "status": "pass|fail",
  "issues": [
    {"severity": "critical|major|minor", "category": "completeness|gdd_alignment|no_regressions|verification_criteria", "description": "...", "location": "...", "deduction": N}
  ],
  "summary": "one sentence assessment"
}
```

### Template Verifier Response JSON (template agent → orchestrator)

```json
{
  "agent": "template",
  "prompt": N,
  "scores": {
    "api_correctness": 40,
    "platform_constraints": 30,
    "code_quality": 30
  },
  "total": 100,
  "status": "pass|fail",
  "issues": [
    {"severity": "critical|major|minor", "category": "api_correctness|platform_constraints|code_quality", "description": "...", "location": "...", "template_rule": "...", "deduction": N}
  ],
  "summary": "one sentence assessment"
}
```

## Stage 3: Asset Generation

Reached when the GDD, prompts, and manifest exist but `assets/packed/` or `src/app_<game>_ids.h` is missing. Stage 3 produces the source art (`assets/art/*.png`, `assets/wav/*.wav`) and then packs it. The **source art can be produced two ways**, and the orchestrator MUST let the user choose before generating or packing anything. Both paths converge on the same pack step (Step 3.5).

### Display & sprite sizing (CRITICAL — applies to every sprite, both paths)

The two facts below are the authoritative sizing rule for all WowCube assets. Honor them whenever gating the manifest (Step 3.A1), generating (Path A), validating self-supplied art (Path B), or reviewing sizes — and surface them to the user whenever sprite dimensions come up.

1. **The physical screen (quadrant) is 240×240 px.** That is the hardware resolution of one of the cube's 24 displays.
2. **But every regular sprite is authored/generated at HALF resolution, because the engine applies a software ×2 upscale at draw time.** (`flags.fullsize` sprites are the one exception — see the art-tier table below.) The governing formula for regular assets (not just backgrounds) is:

   > **authored size = intended on-screen size ÷ 2**

   The engine multiplies the authored sprite by 2 when drawing it. So a full-screen sprite is authored at **120×120** (→ 240×240 on screen), making **120×120 the hard maximum** — no sprite is ever larger than that.

This applies to **every** asset, sized proportionally to how much of the screen it should cover:
- **Full screen** → on-screen 240×240 → authored **120×120** (the ceiling).
- **Character/object covering a quarter of the screen** → on-screen 60×60 → authored **30×30** — **not 60×60**. (Thinking "a quarter of 240 = 60, so 60×60" is the classic mistake: that 60 is the *on-screen* size, which must still be halved to 30 for authoring.)
- **Any other sprite** → take its target footprint on the 240×240 screen and halve both dimensions.

Practical consequences:
- **Never generate or request a sprite larger than 120×120 unless it sets `flags.fullsize`**, and for every smaller asset compute its authored size as (intended on-screen px ÷ 2) — apply this to characters, items, UI elements, effects, everything, not only `bg` sprites.
- Manifest `size` values (`plans/<game>_assets.json`) are in **authored (pre-upscale) pixels**: full-screen = `[120, 120]`, quarter-screen character = `[30, 30]`, etc.
- If a manifest sprite's `size` looks like it was set in on-screen pixels (e.g. a quarter-screen sprite at `[60, 60]`, or anything > 120), treat it as a sizing error: return to Stage 2 (`technical_prompter`) to halve it rather than generating it — unless the sprite sets `flags.fullsize`, per the art-tier table below.

**Art tiers (beta).** The engine has three sprite complexity tiers, selected by the manifest `color` field plus `flags.fullsize`:

| Tier | Manifest | Authored size | Colors / transparency | Drawn at | Use for |
|------|----------|---------------|-----------------------|----------|---------|
| Palette (default) | `color: "palette"` | ≤ 120×120 (= on-screen ÷ 2) | shared palette, index 0 transparent | ×2 upscale | characters, items, HUD — anything needing transparency |
| Palette fullsize | `color: "palette"` + `flags.fullsize` | native, up to 240×240 | shared palette, transparency KEPT | 1:1 | native-resolution art that still needs a see-through background |
| Full-color fullsize | `color: "full"` + `flags.fullsize` | native, up to 240×240 | RGB565 (2 B/texel), **NO transparency** | 1:1 | opaque backdrops, tile sheets, photographic full-screen scenes |

`flags.fullsize` is what lifts the 120 cap and disables the ×2 upscale — for **any** color. The alpha ban is full-color-only: `color: "full"` has no transparency (0x0000 draws as opaque black, so the alpha flag is forbidden on it), while a palette fullsize sprite keeps index-0 transparency. A small full-color sprite (each side ≤ 120, no `fullsize`) is also legal, but it still draws at ×2 like every other sprite — so its `size` still follows the ÷2 formula.

**Pack size:** there is no hard packer-side cap — a pack is bounded only by the cube's flash software region (contiguous free 512 KB cells). Keep packs lean as good practice anyway: pick the **cheapest tier that does the job** (that is exactly what the table above orders, top to bottom), and never default art to fullsize/full-color just because 240×240 is available.

**Tier promises are absolute.** Each tier is a commitment: fast (palette ×2), mid (palette fullsize — native sharpness, keeps alpha), fat (full-color — uncompromised color). **Maximum quality = `color: "full"` + `flags.fullsize` + `dither: true` and nothing else** — nearest-level RGB565, Floyd–Steinberg dithering, lossless RLE; no smoothing or lossy steps ever (a degraded full-color sprite ≈ a palette-fullsize sprite at twice the bytes — pointless). Never trade tier-3 fidelity for pack size unless the user explicitly asks to shrink the pack.

### Step 3.0: Choose the asset source (ASK FIRST — before any generation or packing)

Before touching `cube_asset-builder`, present the choice with the **Agent tool's `AskUserQuestion`** (or a short bullet list + wait). Do NOT pick for the user.

- **Option 1 — AI generation.** The user provides an image-model API key (GPT Image 2 / OpenRouter); the orchestrator generates every sprite from its `gen_prompt`. → **Path A**.
- **Option 2 — Self-supplied assets.** The user creates the assets themselves, following the manifest's exact specs (name, size, animation frames) and the GDD's art style. The orchestrator does NOT generate — it validates completeness, then packs. → **Path B**.

Route to the chosen path below.

> **YOLO mode:** do not ask here. Default to **Path A** and use the `OPENROUTER_API_KEY` gathered during the YOLO one-time intake. Only use Path B in YOLO if a complete asset set is already on disk (the completeness check in 3.B2 still applies). If Path A is required but the key is missing, that is the one input YOLO must request before continuing.

### Path A — AI generation (Option 1)

**3.A1 Pre-generation gates** (both must pass; if either fails, do NOT generate):
1. **`gen_prompt` coverage.** Load `plans/<game>_assets.json` and confirm **every sprite** has a non-empty `gen_prompt`. (Sounds do NOT need one.) A blank `gen_prompt` makes `gen_sprites.py` fail with `ValueError`. If any sprite is missing it, **return to Stage 2 (`technical_prompter`)** — do not patch the manifest yourself.
2. **Image-model key present.** Generation calls OpenRouter; without the key `genimg.py` raises `ImageGenError`. If `OPENROUTER_API_KEY` is not set in the sandbox where `build_pipeline.py` runs, **this is the "add a key" step** — ask the user to export it (`export OPENROUTER_API_KEY=sk-or-...`) now, before proceeding. Never hardcode it; never commit it.

**3.A2 Generate.** Invoke `cube_asset-builder` (Skill tool). It runs `build_pipeline.py generate` → `gen_sprites.generate()` → `genimg.generate_image(gen_prompt, size)` per sprite (OpenRouter image model) → PNGs in `assets/art/`; sounds synthesised as placeholders into `assets/wav/`. Output is non-deterministic across runs.

**3.A3 Consistency review** (automated, BEFORE the user review). Dispatch one **read-only** asset-consistency reviewer via the Agent tool. It inspects `assets/art/*.png` against the GDD's global art style and each `gen_prompt`, reporting which **groups** (derived per `manifest_schema`) drift — wrong palette/mood, inconsistent line weight or scale, broken animation continuity, leaked text/watermark/background, off-spec dimensions. Pass it the Asset Consistency Task JSON; it returns the Asset Consistency Response JSON (both below).
- **`status: "pass"`** → go to Step 3.4 (user review).
- **`status: "fail"`** → for each flagged group, re-run `cube_asset-builder`'s `regen <group>` (→ `build_pipeline.py generate --group <name>`), then re-run this review. **Max 3 review→regen cycles**, then hand the remaining issues to the user at Step 3.4.

This is a quality gate, not a replacement for the human checkpoint. Path A then continues at **Step 3.4**.

### Path B — Self-supplied assets (Option 2)

The user makes the art by hand (or with their own tools) from the GDD. The orchestrator's job is to make the spec unambiguous, then refuse to pack an incomplete set.

**3.B1 Hand the user the exact asset spec** (derive entirely from `plans/<game>_assets.json` + GDD §1 art style):
- **Sprites** → drop into `assets/art/`. For each: filename **`<name>.png`** (verbatim, lowercase), exact size **`[w, h]`** in pixels, RGBA, transparent background (unless `flags.bg` is set, or the sprite is `color: "full"` — full-color art is always opaque), plus the `description` (and `gen_prompt` if present) as the visual brief. Animation frames must be the full contiguous `_00.._NN` set.
- **Sounds** → drop into `assets/wav/`. For each: **`<name>.wav`**, ≤ `duration_ms`. (Packing encodes it to `sound/assets/<name>.mp3` automatically — the user supplies only the source `.wav`.)
- The reserved **`0.png` is auto-created by the packer** — the user must NOT make it.
- Stress that the **GDD's global art style applies to every file** so the set stays cohesive.

**3.B2 Completeness check (MANDATORY — a partial set is an unplayable build).**
Validate the files actually present against the manifest:
- For every sprite in the manifest, confirm `assets/art/<name>.png` exists (optionally verify pixel dimensions match `size`).
- For every sound, confirm `assets/wav/<name>.wav` exists.
- **List EVERY missing file explicitly** (by `<name>` and expected size/duration). If anything is missing, **STOP**: tell the user exactly which sprites/sounds are absent and that the build will not be playable — every `BMP_<name>`/`SND_getAssetId("<name>.mp3")` referenced in the prompts must exist or the code fails to compile. Wait for the user to add the missing files, then re-run this check. **Never pack a partial set.** (This check holds even in YOLO — a partial set cannot compile.)

**3.B3 When complete → pack.** Skip generation and the AI consistency review (the user authored and approved their own art). Go straight to **Step 3.5**.

### Step 3.4: User review checkpoint (Path A only; MANDATORY — never skip)

This is `cube_asset-builder`'s own mandatory review of the AI-generated set. Present the generated set and the consistency reviewer's verdict, then STOP and wait for the user. Offer the verbatim options the asset-builder supports: `ok`/`continue`, `regen <group>`, `swap <name>`, `edit <name> size <WxH>`. Never auto-continue to pack.

> **YOLO mode:** skip this user review. Auto-accept any set the consistency reviewer (3.A3) passed; the review→regen loop already enforced cohesion. Proceed directly to Step 3.5.

### Step 3.5: Pack & boundary checkpoint (both paths)

After approval (Path A: user replies `ok`; Path B: the completeness check passed), invoke `cube_asset-builder`'s pack stage → `build_pipeline.py pack`. It **assembles `assets/assets.psd`, fills `assets/exported/` and `assets/packed/` (+ `pal.png`), and writes `src/app_<game>_ids.h`** with the `BMP_*` enum. Then run the normal **Stage 3→4 boundary checkpoint** (summarize asset counts + `BMP_*` constant count, wait for approval) before any Stage 4 work. (In YOLO, the boundary checkpoint is auto-advanced — see `## YOLO Mode`.)

### Asset Consistency Task JSON (orchestrator → reviewer agent)

```json
{
  "task": "asset_consistency",
  "game": "<game_name>",
  "art_style": "<GDD §1 global art style, palette, mood — the cohesion contract>",
  "art_dir": "assets/art",
  "files_to_read": [
    "plans/<game>_assets.json",
    "plans/<game>_gdd.md"
  ],
  "sprites": [
    {"name": "hero_idle_00", "size": [64, 64], "group": "hero",
     "anim": "hero_idle", "frame": 0, "gen_prompt": "..."}
  ]
}
```

### Asset Consistency Response JSON (reviewer agent → orchestrator)

```json
{
  "agent": "asset_consistency",
  "status": "pass|fail",
  "groups": [
    {
      "group": "hero",
      "verdict": "pass|fail",
      "issues": [
        {"sprite": "hero_idle_01", "category": "palette|style|scale|anim_continuity|leaked_content|dimensions", "severity": "major|minor", "description": "..."}
      ],
      "regen_recommended": true
    }
  ],
  "summary": "one-sentence assessment of set-wide visual cohesion"
}
```

### Asset Consistency Reviewer Agent Prompt Template

```
You are a WowCube asset-consistency reviewer. You do NOT generate or edit images — you only inspect and report.

## Task
<insert Asset Consistency Task JSON>

## Rules
1. Read the GDD art style and every sprite's gen_prompt. The `art_style` field is the cohesion contract — the whole set must look like one game.
2. View each PNG in `art_dir`. Judge per derived group (sprites sharing a group, e.g. all frames of one animation).
3. Flag: palette/mood drift from the GDD, inconsistent line weight or scale across the set, broken animation continuity (pose jumps, pivot drift), leaked text/watermark/border/background scenery, and dimensions that do not match the manifest `size`.
4. Recommend `regen` for any group that fails. Be specific and per-sprite.
5. Return ONLY the Asset Consistency Response JSON. No markdown, no prose outside the JSON.
```

## Stage 4: Implementation Workflow

This is the implementation stage — reached only after Stages 1–3 are complete and their boundary checkpoints approved. Here the orchestrator dispatches coder/verifier/fixer **subagents via the Agent tool** to implement the prompts one at a time.

### Step 1: Initialize

1. Verify all Stage 4 prerequisites exist
2. Read `plans/<game>_prompts.md` — parse all prompts (delimited by `## Prompt N:`)
3. Read `plans/<game>_gdd.md` for game understanding
4. Check if `context/<game>_context.json` exists — if yes, offer to resume
5. If new game, reset the game source to a clean skeleton: copy
   `OCT_wowcube-agent-skills/src/app_structure_example.h` → `app_<game>/src/app_<game>.h`.
   (`wowcube-boilerplate` left a working demo there to prove the build; overwriting
   it with the skeleton is expected — the verified folder, marker, packed assets,
   and toolchain are what carry forward.)
6. Count total prompts, present execution plan to user. **In YOLO**, also build the prompt dependency graph now (foundational vs. cosmetic/isolated) so parallel batches can be planned, and do not wait for approval of the plan.

### Step 2: Validate Prompts

Each prompt must represent a testable build. Before executing, validate:
- Has a clear **Verification** section
- Does not depend on a subsequent prompt to be testable
- Instructions are self-contained for a compilable result

Failed validation → return to `technical_prompter` for rework.

### Step 3: Execute Prompt Cycle

For each prompt, repeat this cycle:

#### 3a. Build Coding Task JSON

1. Read current `app_<game>/src/app_<game>.h`
2. Read `context/<game>_context.json` for prior context
3. Construct the Coding Task JSON
4. Select relevant platform reminders:

| If prompt mentions... | Include reminder |
|-------------------|----------|
| new global, TL, static | `"All globals must use TL macro: TL static type name;"` |
| iterate, loop, gObjects, for | `"gObjects[0] is reserved — start from index 1, validate with obj->Idx == i"` |
| label, text, OCT_label, glyph | `"Label visibility: must also toggle all child glyphs where obj->Parent == label->Idx"` |
| OCT_add, sprite, layer | `"SPRITES_CAP = 400 max. Verify total count. NO NEED to account for GAP in x/y coordinates — the engine handles GAP offsets automatically."` |
| position, coordinate, x/y, center, place, fit, bounds, edge | `"Coordinates live in the 240x240 on-screen space (screen center = 120,120). Sprites are authored at HALF size and the engine upscales them x2 at draw time, so a sprite's ON-SCREEN extent = 2x its authored size. Do ALL position/centering/edge-fit math in on-screen pixels using the upscaled extent (2x authored), NEVER the authored sprite size."` |
| collision, overlap, hit, distance, spacing, grid, snap | `"Compute collision boxes, overlap tests, spacing and grid steps from the UPSCALED on-screen sprite extent (2x authored size) in the 240x240 space — using the authored (half) size makes hitboxes 

…(truncated)
