World Architect
Builds levels for the Phaser tilemap loader. Inputs a GDD, outputs a JSON array of levels.
When to use
After game-designer produces a valid GDD. The orchestrator passes the GDD; you produce levels.json.
Output contract
Single JSON array. Each element:
{
"id": "<e.g. '1-1'>",
"theme": "<matches gdd.levelHints.themes[i]>",
"size": [<width>, <height>], // tiles, must match levelHints.size
"tiles": number[][], // 2D array of palette indices, [row][col]
"spawns": [
{ "entity": "<ENTITY_ID>", "x": <col>, "y": <row>, "facing"?: "up"|"down"|"left"|"right" }
],
"goal": { "kind": "tile" | "entity", "x"?: <col>, "y"?: <row>, "entityId"?: "<ID>" }
}
Hard constraints
tiles[][]dimensions matchsize. Outer rings are impassable tiles.- All tile values are integer indices into
gdd.tilesetPalette(0-based). - Exactly one player spawn per level, on a passable tile, not overlapping any other spawn.
- All other spawns on passable tiles.
- Coordinates:
(x = column, y = row), origin top-left. - Platformer: bottom row solid (impassable). Player one tile above the floor. Sprinkle 2-4 floating platforms.
- Top-down: open rooms with wall obstacles. Corridors ≥ 2 tiles wide.
- 2-6 enemies per level.
goal: ifkind === "tile", must be reachable from spawn; ifkind === "entity", that entity must be inspawns.
Process
- Read the GDD from
game-state.json. - For each
levelHints.themes[i](orcountif no themes), build one level. - Start with the impassable border, then carve out walkable interior, then place obstacles, then place spawns, then place goal.
- Run
scripts/validate_levels.mjs <levels-file> <gdd-file>before returning. - Save to
game-state.jsonunderlevels, also writepublic/data/levels.json.
Validation rules (encoded in scripts/validate_levels.mjs)
tiles.length === size[1]and every row's length ===size[0].- Every tile value in
[0, palette.length). - Exactly one player spawn per level, on a passable tile.
- All spawn coordinates within bounds and on passable tiles.
- Border ring is impassable.
- For platformer:
tiles[height-1][*]all impassable.
Examples
See references/level-examples.md for a 16×12 top-down level and a 22×12 platformer level (used by the playtester fixtures).
NPC dialogue (RPG genre)
For top-down-rpg games, after levels are written, run the NPC dialogue generator. It reads NPC entity personality fields from the GDD and generates 6-8 dialogue lines per NPC using Claude Haiku, writing them to public/data/npc-dialogue.json:
node --env-file=~/.all-skills/.env scripts/gen_npc_dialogue.mjs <project-dir>
Game.js loads this file at runtime and falls back to built-in lines if absent. The personality block on each NPC entity drives the dialogue style — ensure the game-designer includes it for best results.
Scripts
scripts/validate_levels.mjs <levels-file> <gdd-file>— fails non-zero with reason if invalid.scripts/gen_npc_dialogue.mjs <project-dir>— generates NPC dialogue from personality (RPG).
References
references/level-schema.json— JSON Schema.references/level-examples.md— one level per genre with annotation.