# Technical Prompter

> 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).

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

---


# 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:
1. **Game objects** — types, behaviors, visual descriptions
2. **Game states** — flow between menu, playing, win, lose
3. **Mechanics** — each gameplay mechanic described
4. **Controls** — what each input does
5. **Assets** — full sprite and sound list
6. **UI elements** — score display, menus, feedback
7. **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:

1. **Foundation** — project scaffold, data structures, engine init, background color
2. **First visual** — something appears on screen (even one sprite on one face)
3. **Static layout** — all faces show their initial state
4. **First input** — one input type produces a visible response
5. **Core mechanic** — the primary gameplay loop, one piece at a time
6. **Secondary mechanics** — boosters, blockers, special behaviors
7. **Game states** — win/lose detection, state transitions
8. **UI** — score display, menus, game over screen
9. **Audio** — sound effects tied to events
10. **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](../cube_asset-builder/SKILL.md) for full details):

```json
{
  "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:**
1. **Subject** — what the object is, from its GDD description (e.g. "a small round blue hero with two eyes").
2. **Art style** — the GDD's global style verbatim (e.g. "flat pixel-art", "minimal vector", "soft cartoon"). Keep it identical across all sprites.
3. **Palette & mood** — the GDD's colors/mood, narrowed to this object's colors.
4. **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".
5. **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.
6. **Framing** — "centered, object fills most of the frame, no cropping, no drop shadow beyond the sprite bounds".
7. **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:

```markdown
# <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:

1. **Complete coverage** — every GDD section is covered by at least one prompt
2. **Asset coverage** — every sprite and sound from the GDD asset list appears in at least one prompt
3. **Dependency order** — no prompt references code/objects that weren't created in a previous prompt
4. **Dependencies are explicit** — every prompt lists its dependencies; no hidden assumptions
5. **Categories are correct** — each prompt has the right category from the table above
6. **Self-contained context** — each prompt's "Current State" accurately summarizes prior work
7. **Testable verification** — every prompt has a concrete "you should see/hear" verification
8. **No gaps** — executing all prompts in order produces the complete game described in the GDD
9. **Smallest slices** — no prompt could be reasonably split into two smaller testable prompts
10. **Correct API usage** — all referenced functions match `OCT_wowcube-agent-skills/templates/app_ai_template/src/app_ai_template.h`
11. **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.
12. **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.
13. **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

1. **Be explicit** — specify exact API calls, parameter values, coordinates, colors. No ambiguity.
2. **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.
3. **One behavior per prompt** — each prompt has a single clear goal.
4. **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.
5. **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."
6. **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).
7. **Verification is mandatory** — every prompt must end with exactly what the agent should observe.
8. **Category is mandatory** — every prompt must have a category from the table above.
9. **Dependencies are mandatory** — every prompt must list its dependencies explicitly.
10. **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.
11. **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`.
12. **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.
13. **No GAP in sprite placement** — when specifying OCT_add coordinates, do NOT add GAP offsets. The engine handles GAP automatically.
14. **Angle convention** — when specifying angles (Tm.A, OCT_add 'a' param, OCT_TM_walk direction), note that positive = CCW, 0 = right (+X).
15. **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.

