# MINIMA AI level authoring

Use `minima.ai-level/v1` as the source format. Do not generate the game's concatenated row strings directly. This format is readable, compact, ordered, and deterministically compiled into the runtime level format.

Level construction is deliberately staged. Read and follow [`LEVEL_DESIGN_PROMPT.md`](./LEVEL_DESIGN_PROMPT.md) before creating geometry. The required MCP sequence is concept, topology, challenge chain, theme and decoys, then final validation and import.

## Required shape

```json
{
  "format": "minima.ai-level/v1",
  "name": "A specific level name",
  "description": "One sentence about the puzzle",
  "intent": {
    "difficulty": "easy",
    "puzzleThesis": "The insight the player should discover",
    "theme": {
      "name": "A mechanically meaningful theme",
      "primaryMechanic": "key-door",
      "primaryTiles": ["K0", "D0"],
      "supportingMechanics": [],
      "tilePalette": ["__", "10", "X0", "S0", "W0", "K0", "D0"],
      "spatialMotif": "Nested sealed chambers"
    },
    "regions": [],
    "challengePlan": [],
    "criticalPath": [],
    "decoys": []
  },
  "stages": []
}
```

Each stage uses either `grid` for a small hand-shaped puzzle or `size` plus `operations` for a large or geometric level. Coordinates are zero-based `[x, z]`, with `(0, 0)` at the north-west corner. Operations run in order, so broad fills come first and `S0`/`W0` placements come last.

## Compact operations

- `{"op":"fill","tile":"10"}` fills the entire stage.
- `{"op":"rect","tile":"10","x":2,"z":2,"width":8,"height":5}` fills a rectangle.
- `{"op":"border","tile":"X0","x":0,"z":0,"width":12,"height":9}` draws a rectangle outline.
- `{"op":"line","tile":"X0","from":[2,2],"to":[8,7]}` draws a Bresenham line.
- `{"op":"path","tile":"10","points":[[1,1],[8,1],[8,6]]}` connects multiple points.
- `{"op":"points","tile":"I0","points":[[3,2],[4,2],[5,2]]}` paints separate cells.
- `{"op":"set","tile":"S0","x":1,"z":1}` paints one cell.

The `fill`, `rect`, and `border` operations accept integer `x`, `z`, `width`, and `height`. A `fill` without them covers the full stage.

## Grid form

Use space-separated two-character tokens. Use `__` for void, never literal spaces.

```json
"grid": [
  "X0 X0 X0 X0 X0",
  "X0 S0 10 W0 X0",
  "X0 X0 X0 X0 X0"
]
```

## Essential tiles

| Token | Meaning | Rule |
|---|---|---|
| `__` | Void | Safe empty representation |
| `10` | Ground | Walkable path |
| `S0` | Start | Exactly one in the complete level |
| `W0` | Goal | At least one |
| `X0` | Wall | Blocks movement |
| `I0` | Ice | Slides the player |
| `H0` | Heat | Heats the cube |
| `A0` | Water | Material-dependent traversal |
| `G0` | Glass | Breakable terrain |
| `K0`…`K9` | Key | Config must match a door |
| `D0`…`D9` | Door | Config must match a key |
| `T0`…`T9` | Teleporter | Exactly two of each config |
| `MM`, `MW`, `MR` | Transform | Metal, wood, or redstone |
| `FP`, `FN`, `FS`, `FE`, `FL` | Flying plate | Any, north, south, east, west |
| `P0` | Pushable cube | Requires room to push |
| `B0` | Boat | Used with water |
| `R0`, `O0`, `L0`, `N0`, `Q0`, `V*`, `U0`, `Y0`, `C0` | Redstone | Plate, switch, wire, door, cube, transistor, bridge, torch, fire |

Jump pads have specialized configs. Prefer `J0` for a weak pad following entry direction and `JS` for a strong pad until a directional jump is necessary.

## Generation discipline

1. State the intended insight and critical path in `intent` before drawing.
2. Use one or two mechanics in an easy puzzle. Add mechanics only when they interact meaningfully.
3. Make the required item reachable before its gate and prevent a route around the gate.
4. Leave landing space after jumps, ice, and pushable cubes.
5. Put broad operations first. Place unique and paired tiles last so they cannot be overwritten.
6. Compile, fix every error, then play-test. A structurally valid level is not automatically an interesting or solvable puzzle.

The machine-readable schema is at [`/ai/level-format.schema.json`](./level-format.schema.json). Working examples are at [`/ai/example-small.json`](./example-small.json) and [`/ai/example-large.json`](./example-large.json).

Compile outside the editor with:

```bash
node tools/compile-ai-level.mjs public/ai/example-small.json --output /tmp/minima-level.json
node tools/level-validator.mjs /tmp/minima-level.json
```
