MRPGI/games/README.md
type-two 2fdd730cde Add the updated manual and a teaching game: The DJ's Lost Fuse
- 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>
2026-07-05 09:18:50 +10:00

88 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
```sh
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`](lost-fuse/rooms/room0.json) |
| An item lock (`needs`) | `amp` in [`rooms/room1.json`](lost-fuse/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`](lost-fuse/rooms/room2.json) |
| Rooms linked by edges (`exits`) | every room: `[N, E, S, W]` room numbers |
| Painted look + walkability (`strokes`) | every room: `Rect`s 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`](lost-fuse/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`](lost-fuse/expansion/roof.jsonl)
adds a roof afterparty above the club:
```sh
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_flag`
> names 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](../docs/CONTROL.md).
## Make your own
```sh
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.