Level designer
@gameforge/level-designer
Design tile-grid game levels as plain JSON and check them with a validator: equal-width rows, known tiles, one start, an exit you can actually reach (keys and doors included), reachable coins, and a closed border. Writes a JSON report you can keep in CI.
- Activity
- New: be the first to try it
- Installs
- 0 installs
- Likes
- 0 likes
- Clones
- 0 clones
- 1---
- 2name: level-designer
- 3description: Design tile-grid levels for 2D games (top-down, puzzle, roguelike, maze, Sokoban-style) as plain JSON, then prove each one is playable with a validator that checks bounds, tiles, a single start, a reachable exit through keys and doors, and reachable coins. Use when the user says "design some levels", "make level 3 harder", "is this level beatable?", "check my levels", or adds files to levels/.
- 4license: MIT
- 5---
- 7# Level designer
- 9Levels live in `levels/*.json`, one file per level. Every level Claude writes or edits is run through the validator before it is called done, so nobody ships a level with an exit behind a wall.
- 11## Level format
- 13```json
- 14{
- 15 "name": "1-2 Key and door",
- 16 "tiles": [
- 17 "#######",
- 18 "#S..#E#",
- 19 "#.#.#D#",
- 20 "#K#...#",
- 21 "#######"
- 22 ]
- 23}
- 24```
- 26| Tile | Meaning |
- 27| ---- | ------- |
- 28| `#` | wall |
- 29| `.` | floor |
- 30| `S` | start, exactly one |
- 31| `E` | exit, at least one |
- 32| `^` | spikes, blocks the path |
- 33| `C` | coin, should be reachable |
- 34| `K` | key, opens any door |
- 35| `D` | door, passable after a key |
- 37If the user's engine already has a format, map it to this one in a small converter, or ask before changing the legend. Extra JSON keys (enemies, music, par time) are fine; the validator ignores them.
- 39## Steps
- 411. **Ask for the brief** if missing: how many levels, grid size (default 12x9 for phone screens), which tiles the game supports, and the difficulty curve (default: teach, test, twist).
- 422. **Plan the set** in a short table before drawing: level name, the one new idea it teaches, size, target shortest path. One new idea per level.
- 433. **Draw each level** in `levels/NN-short-name.json`. Rules of thumb:
- 44 - Close the border with walls.
- 45 - Show the goal early: the player should see the exit or the key within the first few moves.
- 46 - Put a coin on the risky path and leave a safe path without it.
- 47 - Make the shortest path grow 20 to 40% per level, not double.
- 484. **Validate every level:**
- 50 ```bash
- 51 node scripts/validate-levels.mjs levels --report out/level-report.json
- 52 ```
- 54 Exit code 1 means at least one level has errors. Add `--exit-zero` only when the user wants a report without failing (for example in a draft folder).
- 555. **Fix and rerun** until there are no errors. Treat warnings as questions for the user (an unreachable coin may be a deliberate tease).
- 566. **Report** with the table below, using `shortest_path` from the report as the difficulty number.
- 58## Output
- 60```markdown
- 61| Level | Teaches | Size | Shortest path | Coins reachable | Status |
- 62| ----- | ------- | ---- | ------------- | --------------- | ------ |
- 63| 1-1 First steps | moving | 10x7 | 11 | 3/3 | ok |
- 64| 1-2 Key and door | keys open doors | 7x5 | 12 | 0/0 | ok |
- 65```
- 67Then one line on the curve: "Paths grow 11, 12, 16, 21. Level 1-2 may feel like a breather; want it longer?"
- 69## What the validator checks
- 71- Errors: invalid JSON, missing or ragged `tiles`, size outside 3 to 128, unknown tile, not exactly one `S`, no `E`, a door with no key, no exit reachable (breadth-first search over position and key state, four directions).
- 72- Warnings: open border tiles, unreachable coins or keys, an exit fewer than 3 steps away, a missing `name`.
- 74## Guardrails
- 76- Write only in `levels/` and `out/`. Ask before overwriting a level the user made by hand; propose the change as a diff first.
- 77- A level is not done until the validator passes it. Say so plainly if you could not make one pass.
- 78- The validator proves reachability, not fun. Suggest a playtest (the playtest-feedback kit helps) after big changes.
