- MANUAL.md brought up to the workspace era: game folders + manifest, flags & gated puzzles, hidden dialogue choices, audio file overrides, a Programmatic control section (CLI/HTTP/MCP/Python), and the new two-crate architecture map. - games/lost-fuse: three rooms that demonstrate every mechanic in one chain — item, needs-lock, object sets_flag, a dialogue choice hidden behind requires_flag, dialogue sets_flag, and a flag-locked wins finale. Verified winnable headlessly, gate included. - games/lost-fuse/expansion/roof.jsonl: a live lore drop that upserts a fourth room into a running game and rewires an exit — the "drop JSON lore in" workflow, runnable as a one-liner. - games/README.md: the guided tour — mechanic-to-JSON map, the live expansion demo, and how to prompt an LLM (or point Claude's MCP at the engine) to write valid lore. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| lost-fuse | ||
| README.md | ||
Games are folders. Lore is JSON.
Every MRPGI game is a folder you can zip, share, hand-write, or have an LLM
generate. This directory holds examples; lost-fuse/ is the guided one —
three rooms that demonstrate every mechanic the engine has, in one small
puzzle chain.
Play it
cargo run -p mrpgi -- --game games/lost-fuse # in the GUI
cargo run -p mrpgi-core --bin mrpgi-headless -- --game games/lost-fuse # in a terminal, JSON in/out
(Spoilers below — play it first! It's five minutes.)
The anatomy of a quest
The whole game is ~200 lines of JSON. The chain:
take fuse an item → inventory (room 0)
use amp needs: fuse → sets_flag music_on (room 1)
talk bouncer a choice gated by requires_flag music_on
"I fixed your amp." → sets_flag on_the_list
use turntable requires_flag on_the_list → wins: true (room 2)
Each step is one field on an object or dialogue choice — no code anywhere:
| Mechanic | Where to look |
|---|---|
| A takeable item | fuse in rooms/room0.json |
An item lock (needs) |
amp in rooms/room1.json |
An object setting a flag (sets_flag) |
same amp |
A hidden dialogue choice (requires_flag) |
the bouncer's second choice — try talking to it before and after fixing the amp |
| Dialogue setting a flag | same choice (sets_flag: on_the_list) |
A flag-locked finale (requires_flag + wins) |
turntable in rooms/room2.json |
Rooms linked by edges (exits) |
every room: [N, E, S, W] room numbers |
Painted look + walkability (strokes) |
every room: Rects with meaning Floor/Wall/None |
| Per-room music moods | "music": 2/3/4 (eerie street → tense door → jolly club) |
| Manifest (name, intro, extra verb synonyms) | game.json — try typing fix amp |
Dropping lore into a RUNNING game
Rooms can be added live over any control surface — this is the "drop JSON
lore in" workflow. lost-fuse/expansion/roof.jsonl
adds a roof afterparty above the club:
target/debug/mrpgi-headless --script games/lost-fuse/expansion/roof.jsonl --game games/lost-fuse
It upserts room 3 (validated: a room with no walkable spawn, or exits pointing
at rooms that don't exist, is rejected with an error event), then wires
room 2's north exit to it. The same two commands work over HTTP
(POST /rooms/3, POST /command) or MCP (mrpgi_upsert_room) against a live
session.
Asking an LLM for lore
The formats are plain serde types, so generated JSON either loads or fails loudly. A prompt that works well:
Here is a room from my MRPGI game: (paste a room JSON). Write a new room in exactly this format: (describe the room, its objects, its puzzle role, which exits connect where). Rooms are 160×168; sprites available: altar, barrel, chest, key, orc, sign, villager. Only use
requires_flag/sets_flagnames that exist in my game.
Or skip the copy-paste entirely: register the MCP server
(claude mcp add mrpgi -- mrpgi-headless --mcp --game games/lost-fuse) and
the model can upsert rooms, render frames to see them, and playtest its own
puzzle chain. Full command reference: ../docs/CONTROL.md.
Make your own
mkdir -p games/mygame
cargo run -p mrpgi-core --bin mrpgi-headless -- --sample --game games/mygame # a starting skeleton
cargo run -p mrpgi -- --game games/mygame # paint it in the editor
Sprites: drop PNGs in games/mygame/sprites/ (auto-quantized to EGA, alpha =
transparent, bottom edge = feet). Audio: drop files in sfx/ / music/ to
replace the chiptune synth (see MANUAL.md §13). Everything else is the JSON
you just read.