WowCube Technical Prompter
This skill is Stage 2 of the cube_orchestrator pipeline. The orchestrator invokes it (via the Skill tool) when a GDD exists but plans/<game>_prompts.md / plans/<game>_assets.json do not. It is not a user-facing entry point — the user enters through cube_orchestrator, which routes here.
Decompose a Game Design Document into the smallest possible vertical-slice implementation prompts, where each prompt produces a testable increment. The prompts and asset manifest are the Stage 2 artifacts; cube_orchestrator checkpoints them with the user and then drives Stage 3 (cube_asset-builder).
When to Use
cube_orchestrator routed here because a GDD exists but plans/<game>_prompts.md or plans/<game>_assets.json is missing
- The orchestrator needs prompts and the asset manifest before it can drive Stage 3 (assets)
Do not trigger this skill directly for "implement this" / "start coding" requests — those are owned by cube_orchestrator, which routes here as Stage 2.
When NOT to Use
- No GDD exists yet — the orchestrator will route to Stage 1 (
cube_game-designer) first
- The request is to modify existing running code — this produces fresh implementation prompts
Constraints
- Assets (PNG sprites, WAV sounds — encoded to
sound/assets/<name>.mp3 at pack time) are prototyped by cube_asset-builder before this skill's output is consumed by cube_orchestrator. This skill owns the ASSET MANIFEST (plans/<game>_assets.json) — a complete, validated list of every sprite and sound the game needs.
- Prompts MUST reference assets by exact final identifier:
- Single sprite:
BMP_<name> (e.g. BMP_coin).
- Animation sequence:
BMP_<base> (first frame alias) and BMP_<base>_end (last frame alias) — both auto-generated by pack.py for zero-padded _NN sequences starting at _00.
- Sound: string literal
"<name>.mp3" passed to SND_getAssetId("<name>.mp3") — NO enum constant.
- Every
BMP_* or "<name>.mp3" referenced in a prompt MUST exist in the manifest. The orchestrator's code will fail to compile otherwise.
app_<game>_ids.h is generated by the asset packing tool — prompts MUST NOT instruct agents to edit it. The same protection covers the src/app.h defines (APP_VERSION, APP_TITLE, APP_DIR, APP_GUID1, APP_CATEGORIES, APP_COLORS — the scaffolder guarantees all six) and the packed asset index index.bin: prompts MUST NEVER instruct agents to hand-edit any of these.
- Code agents work only with
src/app_<game>.h.
Core Principle
Each prompt = the smallest testable vertical slice.
The first prompt produces something visible. Every subsequent prompt adds exactly one testable behavior. An agent executing any single prompt can verify their work before moving to the next.
Workflow
Step 1: Read the GDD
Locate and read the game design document (typically plans/<game_name>_gdd.md).
Extract:
- Game objects — types, behaviors, visual descriptions
- Game states — flow between menu, playing, win, lose
- Mechanics — each gameplay mechanic described
- Controls — what each input does
- Assets — full sprite and sound list
- UI elements — score display, menus, feedback
- Progression — levels, difficulty, generation
Step 2: Study the API
Read OCT_wowcube-agent-skills/templates/app_ai_template/src/app_ai_template.h — this is the SOURCE OF TRUTH for all OctaviOS API usage, patterns, and constraints. Do NOT copy demo code from it. Use it as a guide to understand what is technically possible and what API calls are available.
Step 3: Plan the Decomposition
Break the game into the smallest logical vertical slices. Follow this ordering principle:
- Foundation — project scaffold, data structures, engine init, background color
- First visual — something appears on screen (even one sprite on one face)
- Static layout — all faces show their initial state
- First input — one input type produces a visible response
- Core mechanic — the primary gameplay loop, one piece at a time
- Secondary mechanics — boosters, blockers, special behaviors
- Game states — win/lose detection, state transitions
- UI — score display, menus, game over screen
- Audio — sound effects tied to events
- Polish — animations, edge cases, balance tuning
Decomposition rules:
- Each slice must produce something the agent can SEE or HEAR when testing
- If a mechanic has sub-parts, split them (e.g., "gravity" = "detect empty space" + "move figures down" + "spawn new figures" as 3 prompts)
- Never combine unrelated behaviors in one prompt
- If a prompt takes more than ~100 lines of code to implement, split it further
Step 4: Write the Asset Manifest
Before writing prompts, extract every sprite and sound from the GDD and emit plans/<game>_assets.json conforming to schema_version 1.
Required format (see cube_asset-builder spec for full details):
{
"game": "<game>",
"schema_version": 1,
"sprites": [
{"name": "hero_idle_00", "size": [64, 64], "description": "...",
"gen_prompt": "Pixel-art sprite of a small round blue hero standing idle, ...",
"group": "hero", "anim": "hero_idle", "frame": 0, "pivot": [32, 32]}
],
"sounds": [
{"name": "sfx_coin", "description": "...", "duration_ms": 400,
"event_type": "pickup", "group": "ui"}
]
}
Naming rules — ENFORCED by cube_asset-builder's validator:
Names match [a-z0-9_]+. No uppercase, no -, space, or % & = # $ !.
Animation frames: zero-padded 2-digit suffix starting at _00 (e.g. hero_idle_00, hero_idle_01). Set anim: "<base>" and frame: <N> (0-based).
Sprite size: authored (pre-upscale) pixels, both dimensions 1..120 unless flags.fullsize is set. The engine upscales every non-fullsize sprite ×2 at draw time, so size is HALF the on-screen size: authored size = intended on-screen size ÷ 2, with a hard max of 120×120 (a full-screen sprite). Examples: full screen → [120, 120]; half the screen each side → [60, 60]; a quarter of the screen each side → [30, 30]. Never write the on-screen size (e.g. a quarter-screen sprite as [60, 60]) — halve it. A flags.bg background without fullsize is [120, 120], NOT [240, 240]. (The only sprites authored above 120 are flags.fullsize sprites — see the tier table below.)
Sprite color (optional): "palette" (default) or "full". Together with flags.fullsize it selects one of the engine's three art tiers:
| Tier |
Manifest |
size (authored) |
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 bytes/texel), NO transparency |
1:1 |
opaque backdrops, tiles, photographic full-screen art |
"full" = full-color RGB565 with NO transparency — 0x0000 renders as opaque black, so the alpha flag is forbidden on full-color sprites (palette sprites, fullsize or not, keep alpha).
- Any side > 120 requires
flags.fullsize (any color). A fullsize sprite draws 1:1 (no ×2 upscale), so its size is the native on-screen size, up to [240, 240].
- A small full-color sprite (each side ≤ 120, no
fullsize) is legal but still draws at ×2 — its size follows the ÷2 rule like any palette sprite.
- Sprite
dither (optional, full-color only): true runs the RGB565 conversion through Floyd–Steinberg error diffusion. Recommended for photographic full-color art (smooth gradients, photos — kills 565 banding); skip it for flat-color art. Costs a slightly larger RLE payload. Setting dither on a "palette" sprite is a validation error.
- Maximum quality (no compromises) =
color: "full" + flags.fullsize + dither: true. That is the whole recipe: nearest-level RGB565 + dithering + lossless RLE, nothing else — no smoothing or lossy steps of any kind (a degraded full-color sprite looks like a palette-fullsize sprite at twice the bytes, which defeats the tier). When the user asks for max quality, write exactly this; never trade tier-3 fidelity for pack size unless the user explicitly asks.
- Use
"full" for opaque backgrounds, tiles, and full-screen art; anything that needs transparency stays "palette" (fullsize if it must be native-resolution).
- Pick the cheapest tier that does the job (the table is ordered cheapest-first). There is no hard packer-side cap on total pack size — it is bounded only by the cube's flash software region (contiguous free 512 KB cells) — but lean packs are good practice; don't bloat every sprite to fullsize just because 240×240 exists.
Sound duration_ms: 1..2000 (default 500 if omitted).
Reserved names forbidden: pal, 0, icon, bmp_none, bmp_last, bmp_0, map_none, map_last.
description is a short placeholder-generator hint (color, shape, mood).
gen_prompt (sprites only) is a full, ready-to-run AI image-generation prompt — see Step 4a. When present it must be a non-empty string; the validator rejects empty/blank values.
Prefer explicit group for visually or tonally related assets.
Write the manifest to plans/<game>_assets.json. The cube_asset-builder skill will validate it on first run.
Step 4a: Write a gen_prompt for every sprite
Each sprite manifest entry MUST carry a gen_prompt — a complete, standalone text prompt that an image generator (e.g. scripts/genimg.py) can run as-is to produce that one sprite. This replaces the era of hand-drawn placeholders: the manifest becomes a full set of per-asset generation prompts, one per sprite, keyed by asset name.
Sounds do NOT get a gen_prompt. This skill writes generation prompts for sprites only; sounds stay described by description (and are produced as deterministic placeholders downstream).
Derive each prompt from the GDD, not from imagination. Pull the visual contract from:
- GDD §1 Style & References → art style, genre, color palette, mood (apply this to EVERY sprite so the set is cohesive).
- GDD §3 Game Objects and §7 Assets → what this specific object looks like and does.
- The manifest entry's own
size, group, anim/frame, and flags.
Every gen_prompt must specify, explicitly:
- Subject — what the object is, from its GDD description (e.g. "a small round blue hero with two eyes").
- Art style — the GDD's global style verbatim (e.g. "flat pixel-art", "minimal vector", "soft cartoon"). Keep it identical across all sprites.
- Palette & mood — the GDD's colors/mood, narrowed to this object's colors.
- Exact dimensions — "exactly WxH pixels" from
size (the authored, pre-upscale size — the engine upscales non-fullsize sprites ×2 at draw time, so a full-screen sprite is generated at 120×120, never 240×240; the exception is a flags.fullsize sprite of either color, which draws 1:1 and is generated at its native size, up to 240×240). The cube's screens are tiny and regular sprites are authored at half resolution, so add "single centered object, no padding, readable at small size, high contrast, bold simple shapes, no fine detail".
- Background — "transparent background" by default (alpha sprite, including palette fullsize sprites). Only say "fills the whole frame" when
flags.bg is set or the sprite is a full-frame backdrop. For a color: "full" sprite the prompt MUST instead state the art is opaque and fills the whole rectangular frame — full-color sprites have no transparency, so never request a transparent background for them.
- Framing — "centered, object fills most of the frame, no cropping, no drop shadow beyond the sprite bounds".
- Negative constraints — "no text, no watermark, no border, no UI frame, no background scenery".
For animation frames (anim set), write one gen_prompt per frame, and within an animation:
- Keep style, palette, scale, framing, and dimensions byte-for-byte identical across all frames — only the pose/phase changes.
- Describe the specific phase this frame represents ("frame 2 of 4: legs mid-stride, arms back") so the packed sequence reads as motion.
- State the loop context ("part of a 4-frame walk-cycle loop; frame 0 and the last frame must connect seamlessly").
Keep each prompt to a few tight sentences — concrete and unambiguous, no storytelling. The goal is that running every sprite's gen_prompt yields a visually consistent, cube-ready asset set with zero manual editing.
Step 5: Write the Prompts
Create the output file at plans/<game_name>_prompts.md with this structure:
# <Game Name> — Implementation Prompts
## Overview
- Source GDD: `plans/<game_name>_gdd.md`
- Total prompts: N
- Estimated total sprites: X
- API reference: `OCT_wowcube-agent-skills/templates/app_ai_template/src/app_ai_template.h`
---
## Prompt 1: <Descriptive Name>
### Category
foundation
### Dependencies
none
### Current State
None — fresh project. Skeleton copied from `OCT_wowcube-agent-skills/src/app_structure_example.h` to `src/app_<game>.h`.
### Goal
<One sentence: what this prompt adds. Must be testable.>
### Instructions
<Step-by-step technical instructions:>
1. Define the `appObject_t` struct extending `octSprite_t` with fields: ...
2. Define the `appvars_t` struct with fields: ...
3. In `on_init()`:
- Call `OCT_restart(...)` with ...
- Call `OCT_viewports_layout(SCHEME_CUBE, GAP, GAP)`
- Call `OCT_background(0x____)` for color ...
- Add sprite using `OCT_add(layer, twistable, plane, x, y, ...)` at ...
4. ...
<Include exact API function calls, parameter values, coordinates.>
<Reference: "See `OCT_wowcube-agent-skills/templates/app_ai_template/src/app_ai_template.h` for API details and engine patterns. Do NOT copy demo code.">
### Platform Reminders
<Only include constraints relevant to THIS prompt, e.g.:>
- gObjects[0] is invalid — start iteration from index 1
- All globals must use the `TL` macro
- SPRITES_CAP = 400 max objects
- No GAP offset needed in OCT_add x/y — the engine handles it automatically
- OCT_TM_move is in-plane only — for cross-plane movement use OCT_TM_walk
- Angle convention: positive = CCW, 0 = right (+X)
- OCT_background color uses RGB565 format
- OCT_random upper bound is exclusive
- Transparency: 0 = opaque, OCT_TRANSP_MAX = transparent
- XSIGN/YSIGN are declared in oct_shared.h — do not redeclare
- CW/CCW defined looking from outside the cube (right-hand rule)
<ALWAYS include these three reminders in every prompt:>
- Use explicit type casts — never rely on implicit conversions
- Use only fixed-width types (int32_t, uint8_t, etc.) — never plain int/short/long
- All 7 handlers must be present (on_init, on_tick, on_tap(tapid, count), on_twisted, on_pretwisted, on_shake stub, on_proc_draw stub); suppress unused params (e.g., `twid;`)
### Verification
<Exactly what the agent should see/hear when this prompt is correctly implemented:>
- "You should see a blue background on all 24 screens"
- "A red sprite should appear at the center of the top-right screen on the front face"
- "Twisting the front face clockwise should move the sprite to the right face"
---
## Prompt 2: <Descriptive Name>
### Category
core
### Dependencies
[1]
### Current State
<Brief summary of what exists after all previous prompts — for human reference.
The orchestrator builds its own prior_context from context JSON, so this section
is a convenience summary, not a machine-parsed field.>
### Goal
<What this prompt adds>
### Instructions
...
### Platform Reminders
...
### Verification
...
---
(continue for all prompts)
Category Values
Each prompt MUST have exactly one category. The orchestrator uses this to make pipeline decisions:
| Category |
Description |
Orchestrator behavior |
foundation |
Scaffold, data structures, engine init |
Always waits for verification before next prompt |
core |
Primary gameplay mechanic |
Always waits for verification |
secondary |
Boosters, blockers, special behaviors |
Waits for verification |
ui |
Score display, menus, game over |
May pipeline (prepare next while verifying) |
audio |
Sound effects tied to events |
May pipeline |
polish |
Animations, edge cases, balance |
May pipeline |
Dependencies Format
none — no dependencies (only valid for prompt 1)
[1] — depends on prompt 1
[1, 3] — depends on prompts 1 and 3
- Dependencies are always explicit prompt numbers, never implicit
Step 6: Validate the Prompts
Before finalizing, verify:
- Complete coverage — every GDD section is covered by at least one prompt
- Asset coverage — every sprite and sound from the GDD asset list appears in at least one prompt
- Dependency order — no prompt references code/objects that weren't created in a previous prompt
- Dependencies are explicit — every prompt lists its dependencies; no hidden assumptions
- Categories are correct — each prompt has the right category from the table above
- Self-contained context — each prompt's "Current State" accurately summarizes prior work
- Testable verification — every prompt has a concrete "you should see/hear" verification
- No gaps — executing all prompts in order produces the complete game described in the GDD
- Smallest slices — no prompt could be reasonably split into two smaller testable prompts
- Correct API usage — all referenced functions match
OCT_wowcube-agent-skills/templates/app_ai_template/src/app_ai_template.h
- Manifest ↔ prompts cross-check:
- Every
BMP_<name> referenced in any prompt exists in <game>_assets.json.
- Animation aliases:
BMP_<base> requires at least a <base>_00 entry; BMP_<base>_end implies a contiguous sequence exists.
- Every
"<name>.mp3" referenced in any prompt exists in <game>_assets.json sounds.
- Manifest validity:
- All sprite/sound names match
[a-z0-9_]+.
- Animation frames are zero-padded and contiguous from
_00.
- No duplicate names within sprites or within sounds.
- No reserved names (see Step 4).
- No non-fullsize sprite larger than 120×120 (authored sizes; the engine upscales ×2 at draw time). A full-screen/
bg sprite without fullsize is [120, 120]. Any size > 120, or a size that looks like on-screen pixels (e.g. a quarter-screen sprite at [60, 60] instead of [30, 30]), is a sizing error — halve it. The one exception: a flags.fullsize sprite (any color) draws 1:1 and is authored at native size, up to [240, 240].
- Tier constraints: every sprite with a side > 120 has
flags.fullsize; no color: "full" sprite carries the alpha flag (full-color has no transparency — palette fullsize keeps it); every color: "full" sprite's gen_prompt describes opaque, frame-filling art.
- No sound longer than 2000 ms.
- Generation-prompt coverage (see Step 4a):
- Every sprite has a non-empty
gen_prompt.
- Each
gen_prompt states the subject, the GDD's global art style, palette/mood, exact WxH dimensions, and background (transparent unless flags.bg is set or the sprite is color: "full", which is always opaque).
- Across one animation, all frames share identical style/palette/scale/dimensions and differ only in the described pose/phase.
- The art style string is identical across all sprites (cohesive set).
Prompt Writing Rules
- Be explicit — specify exact API calls, parameter values, coordinates, colors. No ambiguity.
- Include coordinates — when placing sprites, provide exact plane, x, y using XSIGN/YSIGN. Note: XSIGN/YSIGN are already declared in
oct_shared.h — never redeclare them.
- One behavior per prompt — each prompt has a single clear goal.
- Current State is for humans — the orchestrator maintains its own JSON context. The "Current State" section is a convenience summary so a human reader can understand the progression.
- Reference the API — every prompt must include: "See
OCT_wowcube-agent-skills/templates/app_ai_template/src/app_ai_template.h for API details and engine patterns. Do NOT copy demo code."
- Remind constraints — include only the platform constraints relevant to the current prompt (don't repeat everything every time). BUT always include the three mandatory reminders (type casts, fixed-width types, handler completeness).
- Verification is mandatory — every prompt must end with exactly what the agent should observe.
- Category is mandatory — every prompt must have a category from the table above.
- Dependencies are mandatory — every prompt must list its dependencies explicitly.
- Explicit type casts — all prompts must instruct agents to use explicit casts for every narrowing, widening, or cross-type assignment. Never rely on implicit conversions.
- Fixed-width types only — all prompts must instruct agents to use
int8_t, int16_t, int32_t, uint8_t, uint16_t, uint32_t, size_t — never plain int, short, long.
- All handlers present — every prompt must assume all 7 handler functions exist:
on_init(), on_tick(), on_tap(int32_t tapid, int32_t count), on_twisted(int32_t twid, uint32_t disconnected_ms), on_pretwisted(int32_t twid), on_shake(int32_t shakeid), and on_proc_draw (stub). on_shake and on_proc_draw are link-required stubs — never write a prompt that builds gameplay on shake input (the engine currently always runs the system default go-home), and on_proc_draw is only active under #define APP_HAS_PROC_DRAW. If a handler has no game logic, every parameter must be referenced as a statement to suppress unused-variable warnings.
- No GAP in sprite placement — when specifying OCT_add coordinates, do NOT add GAP offsets. The engine handles GAP automatically.
- Angle convention — when specifying angles (Tm.A, OCT_add 'a' param, OCT_TM_walk direction), note that positive = CCW, 0 = right (+X).
- Asset references are manifest-exact — every
BMP_<name> or "<name>.mp3" in a prompt must literally match an entry in plans/<game>_assets.json. Do NOT invent names, do NOT rely on pack.py's name normalization.
Output
The final output is TWO files:
plans/<game_name>_prompts.md — implementation prompts
plans/<game_name>_assets.json — asset manifest (schema_version 1)
After writing, provide a summary:
- Total number of prompts generated
- Manifest totals: N sprites (K animations), M sounds — confirm all N sprites carry a
gen_prompt
- Rough grouping (e.g., "Prompts 1-3: foundation, 4-7: core mechanic, 8-10: UI")
- Dependency graph overview
- Any GDD gaps or ambiguities resolved with assumptions
- Estimated complexity (sprite count, function count)
Then return control to cube_orchestrator — do NOT invoke cube_asset-builder yourself. The orchestrator will run the Stage 2→3 boundary checkpoint with the user and route to Stage 3 when approved.
Why gen_prompt quality is non-negotiable. At Stage 3 the orchestrator gates on this manifest before generating: it refuses to proceed unless (a) every sprite carries a non-empty gen_prompt (a blank one makes gen_sprites.py fail) and (b) OPENROUTER_API_KEY is set. After the external image model renders the sprites, the orchestrator runs an asset-consistency review subagent that compares the rendered set against the GDD's global art style and each gen_prompt, and forces a regen of any group that drifts. The single canonical art-style sentence you reuse verbatim across every gen_prompt (validation rule 13) is exactly the cohesion contract that reviewer keys on — so keep it identical, concrete, and GDD-derived.
1---2name: technical-prompter3description: Stage 2 component of the WowCube pipeline, invoked by cube_orchestrator — not a standalone user entry point. Use only when the orchestrator routes to prompt generation because a GDD exists but the prompts file and asset manifest do not. Decomposes a GDD into implementation prompts plus the asset manifest, where every sprite carries a ready-to-run AI generation prompt (gen_prompt).4---56# WowCube Technical Prompter78> **This skill is Stage 2 of the `cube_orchestrator` pipeline.** The orchestrator invokes it (via the Skill tool) when a GDD exists but `plans/<game>_prompts.md` / `plans/<game>_assets.json` do not. It is not a user-facing entry point — the user enters through `cube_orchestrator`, which routes here.910Decompose a Game Design Document into the smallest possible vertical-slice implementation prompts, where each prompt produces a testable increment. The prompts and asset manifest are the Stage 2 artifacts; `cube_orchestrator` checkpoints them with the user and then drives Stage 3 (`cube_asset-builder`).1112## When to Use1314- `cube_orchestrator` routed here because a GDD exists but `plans/<game>_prompts.md` or `plans/<game>_assets.json` is missing15- The orchestrator needs prompts and the asset manifest before it can drive Stage 3 (assets)1617Do not trigger this skill directly for "implement this" / "start coding" requests — those are owned by `cube_orchestrator`, which routes here as Stage 2.1819## When NOT to Use2021- No GDD exists yet — the orchestrator will route to Stage 1 (`cube_game-designer`) first22- The request is to modify existing running code — this produces fresh implementation prompts2324## Constraints2526- **Assets (PNG sprites, WAV sounds — encoded to `sound/assets/<name>.mp3` at pack time) are prototyped by `cube_asset-builder`** before this skill's output is consumed by `cube_orchestrator`. This skill owns the ASSET MANIFEST (`plans/<game>_assets.json`) — a complete, validated list of every sprite and sound the game needs.27- **Prompts MUST reference assets by exact final identifier**:28 - Single sprite: `BMP_<name>` (e.g. `BMP_coin`).29 - Animation sequence: `BMP_<base>` (first frame alias) and `BMP_<base>_end` (last frame alias) — both auto-generated by `pack.py` for zero-padded `_NN` sequences starting at `_00`.30 - Sound: string literal `"<name>.mp3"` passed to `SND_getAssetId("<name>.mp3")` — NO enum constant.31- **Every `BMP_*` or `"<name>.mp3"` referenced in a prompt MUST exist in the manifest.** The orchestrator's code will fail to compile otherwise.32- **`app_<game>_ids.h` is generated by the asset packing tool** — prompts MUST NOT instruct agents to edit it. The same protection covers the **`src/app.h` defines** (APP_VERSION, APP_TITLE, APP_DIR, APP_GUID1, APP_CATEGORIES, APP_COLORS — the scaffolder guarantees all six) and the packed asset index **`index.bin`**: prompts MUST NEVER instruct agents to hand-edit any of these.33- **Code agents work only with `src/app_<game>.h`**.3435## Core Principle3637**Each prompt = the smallest testable vertical slice.**3839The first prompt produces something visible. Every subsequent prompt adds exactly one testable behavior. An agent executing any single prompt can verify their work before moving to the next.4041## Workflow4243### Step 1: Read the GDD4445Locate and read the game design document (typically `plans/<game_name>_gdd.md`).4647Extract:481. **Game objects** — types, behaviors, visual descriptions492. **Game states** — flow between menu, playing, win, lose503. **Mechanics** — each gameplay mechanic described514. **Controls** — what each input does525. **Assets** — full sprite and sound list536. **UI elements** — score display, menus, feedback547. **Progression** — levels, difficulty, generation5556### Step 2: Study the API5758Read `OCT_wowcube-agent-skills/templates/app_ai_template/src/app_ai_template.h` — this is the SOURCE OF TRUTH for all OctaviOS API usage, patterns, and constraints. Do NOT copy demo code from it. Use it as a guide to understand what is technically possible and what API calls are available.5960### Step 3: Plan the Decomposition6162Break the game into the smallest logical vertical slices. Follow this ordering principle:63641. **Foundation** — project scaffold, data structures, engine init, background color652. **First visual** — something appears on screen (even one sprite on one face)663. **Static layout** — all faces show their initial state674. **First input** — one input type produces a visible response685. **Core mechanic** — the primary gameplay loop, one piece at a time696. **Secondary mechanics** — boosters, blockers, special behaviors707. **Game states** — win/lose detection, state transitions718. **UI** — score display, menus, game over screen729. **Audio** — sound effects tied to events7310. **Polish** — animations, edge cases, balance tuning7475**Decomposition rules:**76- Each slice must produce something the agent can SEE or HEAR when testing77- If a mechanic has sub-parts, split them (e.g., "gravity" = "detect empty space" + "move figures down" + "spawn new figures" as 3 prompts)78- Never combine unrelated behaviors in one prompt79- If a prompt takes more than ~100 lines of code to implement, split it further8081### Step 4: Write the Asset Manifest8283Before writing prompts, extract every sprite and sound from the GDD and emit `plans/<game>_assets.json` conforming to schema_version 1.8485Required format (see [cube_asset-builder spec](../cube_asset-builder/SKILL.md) for full details):8687```json88{89 "game": "<game>",90 "schema_version": 1,91 "sprites": [92 {"name": "hero_idle_00", "size": [64, 64], "description": "...",93 "gen_prompt": "Pixel-art sprite of a small round blue hero standing idle, ...",94 "group": "hero", "anim": "hero_idle", "frame": 0, "pivot": [32, 32]}95 ],96 "sounds": [97 {"name": "sfx_coin", "description": "...", "duration_ms": 400,98 "event_type": "pickup", "group": "ui"}99 ]100}101```102103Naming rules — ENFORCED by `cube_asset-builder`'s validator:104105- Names match `[a-z0-9_]+`. No uppercase, no `-`, space, or `% & = # $ !`.106- Animation frames: zero-padded 2-digit suffix starting at `_00` (e.g. `hero_idle_00`, `hero_idle_01`). Set `anim: "<base>"` and `frame: <N>` (0-based).107- Sprite `size`: **authored (pre-upscale) pixels, both dimensions 1..120** unless `flags.fullsize` is set. The engine upscales every non-fullsize sprite ×2 at draw time, so `size` is HALF the on-screen size: **authored size = intended on-screen size ÷ 2**, with a hard max of **120×120** (a full-screen sprite). Examples: full screen → `[120, 120]`; half the screen each side → `[60, 60]`; a quarter of the screen each side → `[30, 30]`. Never write the on-screen size (e.g. a quarter-screen sprite as `[60, 60]`) — halve it. A `flags.bg` background without `fullsize` is `[120, 120]`, NOT `[240, 240]`. (The only sprites authored above 120 are `flags.fullsize` sprites — see the tier table below.)108- Sprite `color` (optional): `"palette"` (default) or `"full"`. Together with `flags.fullsize` it selects one of the engine's three art tiers:109110 | Tier | Manifest | `size` (authored) | Colors / transparency | Drawn at | Use for |111 |------|----------|-------------------|-----------------------|----------|---------|112 | Palette (default) | `color: "palette"` | ≤ `[120, 120]` (= on-screen ÷ 2) | shared palette, index 0 transparent | ×2 upscale | characters, items, HUD — anything needing transparency |113 | 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 |114 | Full-color fullsize | `color: "full"` + `flags.fullsize` | native, up to `[240, 240]` | RGB565 (2 bytes/texel), **NO transparency** | 1:1 | opaque backdrops, tiles, photographic full-screen art |115116 - `"full"` = full-color RGB565 with **NO transparency** — 0x0000 renders as opaque black, so the **alpha flag is forbidden** on full-color sprites (palette sprites, fullsize or not, keep alpha).117 - Any side > 120 **requires** `flags.fullsize` (any color). A `fullsize` sprite draws **1:1 (no ×2 upscale)**, so its `size` is the **native on-screen size, up to `[240, 240]`**.118 - A small full-color sprite (each side ≤ 120, no `fullsize`) is legal but still draws at ×2 — its `size` follows the ÷2 rule like any palette sprite.119 - Sprite `dither` (optional, full-color only): `true` runs the RGB565 conversion through Floyd–Steinberg error diffusion. **Recommended for photographic full-color art** (smooth gradients, photos — kills 565 banding); skip it for flat-color art. Costs a slightly larger RLE payload. Setting `dither` on a `"palette"` sprite is a validation error.120 - **Maximum quality (no compromises) = `color: "full"` + `flags.fullsize` + `dither: true`.** That is the whole recipe: nearest-level RGB565 + dithering + lossless RLE, nothing else — no smoothing or lossy steps of any kind (a degraded full-color sprite looks like a palette-fullsize sprite at twice the bytes, which defeats the tier). When the user asks for max quality, write exactly this; never trade tier-3 fidelity for pack size unless the user explicitly asks.121 - Use `"full"` for opaque backgrounds, tiles, and full-screen art; anything that needs transparency stays `"palette"` (fullsize if it must be native-resolution).122 - Pick the **cheapest tier that does the job** (the table is ordered cheapest-first). There is no hard packer-side cap on total pack size — it is bounded only by the cube's flash software region (contiguous free 512 KB cells) — but lean packs are good practice; don't bloat every sprite to fullsize just because 240×240 exists.123- Sound `duration_ms`: 1..2000 (default 500 if omitted).124- Reserved names forbidden: `pal`, `0`, `icon`, `bmp_none`, `bmp_last`, `bmp_0`, `map_none`, `map_last`.125- `description` is a short placeholder-generator hint (color, shape, mood).126- `gen_prompt` (sprites only) is a full, ready-to-run AI image-generation prompt — see Step 4a. When present it must be a non-empty string; the validator rejects empty/blank values.127- Prefer explicit `group` for visually or tonally related assets.128129Write the manifest to `plans/<game>_assets.json`. The `cube_asset-builder` skill will validate it on first run.130131### Step 4a: Write a `gen_prompt` for every sprite132133Each sprite manifest entry MUST carry a `gen_prompt` — a complete, standalone text prompt that an image generator (e.g. `scripts/genimg.py`) can run as-is to produce that one sprite. This replaces the era of hand-drawn placeholders: the manifest becomes a full set of per-asset generation prompts, one per sprite, keyed by asset name.134135**Sounds do NOT get a `gen_prompt`.** This skill writes generation prompts for sprites only; sounds stay described by `description` (and are produced as deterministic placeholders downstream).136137**Derive each prompt from the GDD, not from imagination.** Pull the visual contract from:138- GDD §1 *Style & References* → art style, genre, color palette, mood (apply this to EVERY sprite so the set is cohesive).139- GDD §3 *Game Objects* and §7 *Assets* → what this specific object looks like and does.140- The manifest entry's own `size`, `group`, `anim`/`frame`, and `flags`.141142**Every `gen_prompt` must specify, explicitly:**1431. **Subject** — what the object is, from its GDD description (e.g. "a small round blue hero with two eyes").1442. **Art style** — the GDD's global style verbatim (e.g. "flat pixel-art", "minimal vector", "soft cartoon"). Keep it identical across all sprites.1453. **Palette & mood** — the GDD's colors/mood, narrowed to this object's colors.1464. **Exact dimensions** — "exactly WxH pixels" from `size` (the authored, pre-upscale size — the engine upscales non-fullsize sprites ×2 at draw time, so a full-screen sprite is generated at 120×120, never 240×240; the exception is a `flags.fullsize` sprite of either color, which draws 1:1 and is generated at its native size, up to 240×240). The cube's screens are tiny and regular sprites are authored at half resolution, so add "single centered object, no padding, readable at small size, high contrast, bold simple shapes, no fine detail".1475. **Background** — "transparent background" by default (alpha sprite, including palette fullsize sprites). Only say "fills the whole frame" when `flags.bg` is set or the sprite is a full-frame backdrop. For a `color: "full"` sprite the prompt MUST instead state the art is **opaque and fills the whole rectangular frame** — full-color sprites have no transparency, so never request a transparent background for them.1486. **Framing** — "centered, object fills most of the frame, no cropping, no drop shadow beyond the sprite bounds".1497. **Negative constraints** — "no text, no watermark, no border, no UI frame, no background scenery".150151**For animation frames** (`anim` set), write one `gen_prompt` per frame, and within an animation:152- Keep style, palette, scale, framing, and dimensions byte-for-byte identical across all frames — only the pose/phase changes.153- Describe the specific phase this frame represents ("frame 2 of 4: legs mid-stride, arms back") so the packed sequence reads as motion.154- State the loop context ("part of a 4-frame walk-cycle loop; frame 0 and the last frame must connect seamlessly").155156Keep each prompt to a few tight sentences — concrete and unambiguous, no storytelling. The goal is that running every sprite's `gen_prompt` yields a visually consistent, cube-ready asset set with zero manual editing.157158### Step 5: Write the Prompts159160Create the output file at `plans/<game_name>_prompts.md` with this structure:161162```markdown163# <Game Name> — Implementation Prompts164165## Overview166- Source GDD: `plans/<game_name>_gdd.md`167- Total prompts: N168- Estimated total sprites: X169- API reference: `OCT_wowcube-agent-skills/templates/app_ai_template/src/app_ai_template.h`170171---172173## Prompt 1: <Descriptive Name>174175### Category176foundation177178### Dependencies179none180181### Current State182None — fresh project. Skeleton copied from `OCT_wowcube-agent-skills/src/app_structure_example.h` to `src/app_<game>.h`.183184### Goal185<One sentence: what this prompt adds. Must be testable.>186187### Instructions188<Step-by-step technical instructions:>1891. Define the `appObject_t` struct extending `octSprite_t` with fields: ...1902. Define the `appvars_t` struct with fields: ...1913. In `on_init()`:192 - Call `OCT_restart(...)` with ...193 - Call `OCT_viewports_layout(SCHEME_CUBE, GAP, GAP)`194 - Call `OCT_background(0x____)` for color ...195 - Add sprite using `OCT_add(layer, twistable, plane, x, y, ...)` at ...1964. ...197198<Include exact API function calls, parameter values, coordinates.>199<Reference: "See `OCT_wowcube-agent-skills/templates/app_ai_template/src/app_ai_template.h` for API details and engine patterns. Do NOT copy demo code.">200201### Platform Reminders202<Only include constraints relevant to THIS prompt, e.g.:>203- gObjects[0] is invalid — start iteration from index 1204- All globals must use the `TL` macro205- SPRITES_CAP = 400 max objects206- No GAP offset needed in OCT_add x/y — the engine handles it automatically207- OCT_TM_move is in-plane only — for cross-plane movement use OCT_TM_walk208- Angle convention: positive = CCW, 0 = right (+X)209- OCT_background color uses RGB565 format210- OCT_random upper bound is exclusive211- Transparency: 0 = opaque, OCT_TRANSP_MAX = transparent212- XSIGN/YSIGN are declared in oct_shared.h — do not redeclare213- CW/CCW defined looking from outside the cube (right-hand rule)214215<ALWAYS include these three reminders in every prompt:>216- Use explicit type casts — never rely on implicit conversions217- Use only fixed-width types (int32_t, uint8_t, etc.) — never plain int/short/long218- All 7 handlers must be present (on_init, on_tick, on_tap(tapid, count), on_twisted, on_pretwisted, on_shake stub, on_proc_draw stub); suppress unused params (e.g., `twid;`)219220### Verification221<Exactly what the agent should see/hear when this prompt is correctly implemented:>222- "You should see a blue background on all 24 screens"223- "A red sprite should appear at the center of the top-right screen on the front face"224- "Twisting the front face clockwise should move the sprite to the right face"225226---227228## Prompt 2: <Descriptive Name>229230### Category231core232233### Dependencies234[1]235236### Current State237<Brief summary of what exists after all previous prompts — for human reference.238The orchestrator builds its own prior_context from context JSON, so this section239is a convenience summary, not a machine-parsed field.>240241### Goal242<What this prompt adds>243244### Instructions245...246247### Platform Reminders248...249250### Verification251...252253---254255(continue for all prompts)256```257258### Category Values259260Each prompt MUST have exactly one category. The orchestrator uses this to make pipeline decisions:261262| Category | Description | Orchestrator behavior |263|----------|-------------|----------------------|264| `foundation` | Scaffold, data structures, engine init | Always waits for verification before next prompt |265| `core` | Primary gameplay mechanic | Always waits for verification |266| `secondary` | Boosters, blockers, special behaviors | Waits for verification |267| `ui` | Score display, menus, game over | May pipeline (prepare next while verifying) |268| `audio` | Sound effects tied to events | May pipeline |269| `polish` | Animations, edge cases, balance | May pipeline |270271### Dependencies Format272273- `none` — no dependencies (only valid for prompt 1)274- `[1]` — depends on prompt 1275- `[1, 3]` — depends on prompts 1 and 3276- Dependencies are always explicit prompt numbers, never implicit277278### Step 6: Validate the Prompts279280Before finalizing, verify:2812821. **Complete coverage** — every GDD section is covered by at least one prompt2832. **Asset coverage** — every sprite and sound from the GDD asset list appears in at least one prompt2843. **Dependency order** — no prompt references code/objects that weren't created in a previous prompt2854. **Dependencies are explicit** — every prompt lists its dependencies; no hidden assumptions2865. **Categories are correct** — each prompt has the right category from the table above2876. **Self-contained context** — each prompt's "Current State" accurately summarizes prior work2887. **Testable verification** — every prompt has a concrete "you should see/hear" verification2898. **No gaps** — executing all prompts in order produces the complete game described in the GDD2909. **Smallest slices** — no prompt could be reasonably split into two smaller testable prompts29110. **Correct API usage** — all referenced functions match `OCT_wowcube-agent-skills/templates/app_ai_template/src/app_ai_template.h`29211. **Manifest ↔ prompts cross-check**:293 - Every `BMP_<name>` referenced in any prompt exists in `<game>_assets.json`.294 - Animation aliases: `BMP_<base>` requires at least a `<base>_00` entry; `BMP_<base>_end` implies a contiguous sequence exists.295 - Every `"<name>.mp3"` referenced in any prompt exists in `<game>_assets.json` sounds.29612. **Manifest validity**:297 - All sprite/sound names match `[a-z0-9_]+`.298 - Animation frames are zero-padded and contiguous from `_00`.299 - No duplicate names within sprites or within sounds.300 - No reserved names (see Step 4).301 - **No non-fullsize sprite larger than 120×120** (authored sizes; the engine upscales ×2 at draw time). A full-screen/`bg` sprite without `fullsize` is `[120, 120]`. Any size > 120, or a size that looks like on-screen pixels (e.g. a quarter-screen sprite at `[60, 60]` instead of `[30, 30]`), is a sizing error — halve it. The one exception: a `flags.fullsize` sprite (any color) draws 1:1 and is authored at native size, up to `[240, 240]`.302 - **Tier constraints**: every sprite with a side > 120 has `flags.fullsize`; no `color: "full"` sprite carries the alpha flag (full-color has no transparency — palette fullsize keeps it); every `color: "full"` sprite's `gen_prompt` describes opaque, frame-filling art.303 - No sound longer than 2000 ms.30413. **Generation-prompt coverage** (see Step 4a):305 - Every sprite has a non-empty `gen_prompt`.306 - Each `gen_prompt` states the subject, the GDD's global art style, palette/mood, exact `WxH` dimensions, and background (transparent unless `flags.bg` is set or the sprite is `color: "full"`, which is always opaque).307 - Across one animation, all frames share identical style/palette/scale/dimensions and differ only in the described pose/phase.308 - The art style string is identical across all sprites (cohesive set).309310## Prompt Writing Rules3113121. **Be explicit** — specify exact API calls, parameter values, coordinates, colors. No ambiguity.3132. **Include coordinates** — when placing sprites, provide exact plane, x, y using XSIGN/YSIGN. Note: XSIGN/YSIGN are already declared in `oct_shared.h` — never redeclare them.3143. **One behavior per prompt** — each prompt has a single clear goal.3154. **Current State is for humans** — the orchestrator maintains its own JSON context. The "Current State" section is a convenience summary so a human reader can understand the progression.3165. **Reference the API** — every prompt must include: "See `OCT_wowcube-agent-skills/templates/app_ai_template/src/app_ai_template.h` for API details and engine patterns. Do NOT copy demo code."3176. **Remind constraints** — include only the platform constraints relevant to the current prompt (don't repeat everything every time). BUT always include the three mandatory reminders (type casts, fixed-width types, handler completeness).3187. **Verification is mandatory** — every prompt must end with exactly what the agent should observe.3198. **Category is mandatory** — every prompt must have a category from the table above.3209. **Dependencies are mandatory** — every prompt must list its dependencies explicitly.32110. **Explicit type casts** — all prompts must instruct agents to use explicit casts for every narrowing, widening, or cross-type assignment. Never rely on implicit conversions.32211. **Fixed-width types only** — all prompts must instruct agents to use `int8_t`, `int16_t`, `int32_t`, `uint8_t`, `uint16_t`, `uint32_t`, `size_t` — never plain `int`, `short`, `long`.32312. **All handlers present** — every prompt must assume all 7 handler functions exist: `on_init()`, `on_tick()`, `on_tap(int32_t tapid, int32_t count)`, `on_twisted(int32_t twid, uint32_t disconnected_ms)`, `on_pretwisted(int32_t twid)`, `on_shake(int32_t shakeid)`, and `on_proc_draw` (stub). `on_shake` and `on_proc_draw` are link-required stubs — never write a prompt that builds gameplay on shake input (the engine currently always runs the system default go-home), and `on_proc_draw` is only active under `#define APP_HAS_PROC_DRAW`. If a handler has no game logic, every parameter must be referenced as a statement to suppress unused-variable warnings.32413. **No GAP in sprite placement** — when specifying OCT_add coordinates, do NOT add GAP offsets. The engine handles GAP automatically.32514. **Angle convention** — when specifying angles (Tm.A, OCT_add 'a' param, OCT_TM_walk direction), note that positive = CCW, 0 = right (+X).32615. **Asset references are manifest-exact** — every `BMP_<name>` or `"<name>.mp3"` in a prompt must literally match an entry in `plans/<game>_assets.json`. Do NOT invent names, do NOT rely on `pack.py`'s name normalization.327328## Output329330The final output is TWO files:331- `plans/<game_name>_prompts.md` — implementation prompts332- `plans/<game_name>_assets.json` — asset manifest (schema_version 1)333334After writing, provide a summary:335- Total number of prompts generated336- Manifest totals: N sprites (K animations), M sounds — confirm all N sprites carry a `gen_prompt`337- Rough grouping (e.g., "Prompts 1-3: foundation, 4-7: core mechanic, 8-10: UI")338- Dependency graph overview339- Any GDD gaps or ambiguities resolved with assumptions340- Estimated complexity (sprite count, function count)341342Then **return control to `cube_orchestrator`** — do NOT invoke `cube_asset-builder` yourself. The orchestrator will run the Stage 2→3 boundary checkpoint with the user and route to Stage 3 when approved.343344**Why `gen_prompt` quality is non-negotiable.** At Stage 3 the orchestrator gates on this manifest before generating: it refuses to proceed unless (a) every sprite carries a non-empty `gen_prompt` (a blank one makes `gen_sprites.py` fail) and (b) `OPENROUTER_API_KEY` is set. After the external image model renders the sprites, the orchestrator runs an **asset-consistency review subagent** that compares the rendered set against the GDD's global art style and each `gen_prompt`, and forces a `regen` of any group that drifts. The single canonical art-style sentence you reuse verbatim across every `gen_prompt` (validation rule 13) is exactly the cohesion contract that reviewer keys on — so keep it identical, concrete, and GDD-derived.