MRPGI/README.md
type-two e9cf00e686 THE MRPGI BOOK: deep combined user/dev manual, linked from the live menus
- web/manual.html — 17 chapters: playing, the editor deeply, the
  authoring cookbook (full JSON reference + the five load-bearing
  puzzle patterns), dialogue trees, flags, the art pipeline with
  sprite-generation prompts, sound, driving the engine with code
  (real JSONL transcripts), AIs + MCP, prompt patterns with actual
  outputs (the roof room is the real shipped expansion), the web
  build & cloud saves, engine internals, extension recipes,
  troubleshooting, and full command/event/palette reference.
- Game menu gains "Manual": window.open on the web (via a JS plugin
  import), the default browser natively.
- README tab links the Book; repo README points at it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 11:49:24 +10:00

117 lines
6.9 KiB
Markdown
Raw Permalink 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.

# MRPGI — Monster Robot Party Game Interpreter
A **new-school, Apple-Silicon-native reimagining of Sierra's 1980s AGI engine**
the tech behind *King's Quest*, *Space Quest*, and *Police Quest* — rebuilt in
Rust + [macroquad](https://macroquad.rs) so you can make cool, fun adventure games.
It keeps the *soul* of AGI (vector rooms, the invisible priority/depth screen,
loops-and-cels sprites, a verb-noun parser, flags & vars, the ego) and bridges
it forward (Retina-crisp rendering, hand-editable text resources, a real
embedded scripting language, and an optional AI parser).
## Run it
```sh
cargo run -p mrpgi # the GUI (paint + play) — or ./run.sh
cargo run -p mrpgi --release # smooth, optimized build
```
A window opens in the editor. Paint a room (or launch with `--sample` for the
3-room demo game), then press **Tab** to walk it — arrows or click to move,
type verbs to play. `F1` toggles CRT scanlines, `F2` sound, `Esc` quits.
## Drive it from anywhere (headless)
The engine is a headless core behind a typed command/event bus; the GUI is
just one consumer. The same bus is exposed as JSONL stdio, HTTP, and MCP:
```sh
cargo run -p mrpgi-core --bin mrpgi-headless -- --sample --game games/demo
echo '{"cmd":"parse","text":"look"}' | cargo run -p mrpgi-core --bin mrpgi-headless -- --game games/demo
mrpgi-headless --serve 127.0.0.1:7777 --game games/demo # HTTP + /frame.png
claude mcp add mrpgi -- mrpgi-headless --mcp --game games/demo # Claude plays & authors
```
A game is a folder of JSON + PNGs — an LLM expansion is just JSON that
deserializes. See **[docs/CONTROL.md](docs/CONTROL.md)** for the full guide
(commands, events, HTTP routes, MCP tools, authoring JSON reference).
**📖 The deep read:** [THE MRPGI BOOK](web/manual.html) — the combined
user/dev manual with the authoring cookbook, AI prompt patterns with real
outputs, and engine internals. Live at
[monsterrobot.games/engine/manual.html](https://monsterrobot.games/engine/manual.html)
and under **Game → Manual** in the engine itself.
## How it works (the AGI model, faithfully)
Every room is drawn into **two buffers at once**:
| Buffer | What it holds | Why |
|--------|---------------|-----|
| **visual** | palette indices (015, EGA) | what you see |
| **priority** | depth bands (415) + control lines (03) | depth sorting & collision |
Lower on screen ⇒ higher priority ⇒ drawn nearer the camera. The ego is drawn a
pixel at a time, *only where its priority ≥ the scenery's* — that's the whole
"walk behind the tree" trick, with zero per-object Z bookkeeping. Control lines
(priority `0`) are walls the ego can't cross.
## Source map
Two crates: **`mrpgi-core`** (the headless engine — zero windowing deps, a
compile error is the guardrail) and **`mrpgi`** (the macroquad GUI).
| File | Role |
|------|------|
| `mrpgi-core/src/state.rs` | **the spine**: `GameState`, `Command`/`Event` bus, fixed-step `tick` |
| `mrpgi-core/src/world.rs` | rooms/objects/dialogue data model (all serde), `World`, game folders |
| `mrpgi-core/src/parser.rs` | data-driven verb table, verb-noun parser, dialogue state |
| `mrpgi-core/src/render.rs` | headless compositing → RGBA / PNG (the priority-buffer trick) |
| `mrpgi-core/src/framebuffer.rs` | the visual + priority buffers and the `band(y)` depth table |
| `mrpgi-core/src/picture.rs` | vector room painting (rects / lines / fills / stamps) |
| `mrpgi-core/src/view.rs` | sprites as loops + cels, authored from tiny ASCII grids |
| `mrpgi-core/src/sprite.rs` | the ego: movement, click-to-walk, collision, walk animation |
| `mrpgi-core/src/assets.rs` | PNG → EGA quantize + dither; sprite folders; kit art |
| `mrpgi-core/src/audio.rs` | chiptune synth + audio cues (played by front-ends, or files) |
| `mrpgi-core/src/ai.rs` | AI parser lane (Ollama / OpenRouter / off) on a worker thread |
| `mrpgi-core/src/kit.rs` | sample game + fantasy starter kit, built from the real types |
| `mrpgi-core/src/bin/mrpgi-headless/` | JSONL stdio, `--script` replay, `--render-room`, HTTP, MCP |
| `mrpgi/src/main.rs` | window, play loop over the bus, HUD |
| `mrpgi/src/editor.rs` | the in-engine paint tool (edits go through the same bus) |
| `mrpgi/src/sound.rs` | audio out: game-folder files override the built-in synth |
## Asset pipeline (the new-school bit)
Images don't sit *on top* of the game — they're folded *into* it. Any PNG is
quantized to the EGA palette (optional Bayer dithering for smooth retro
gradients) and becomes indexed pixels, so from that moment it depth-sorts, gets
occluded, and walks-behind exactly like hand-authored art. Three ways in:
- **Tile** an image across a region (textures — e.g. the floor)
- **Pour** an image into a shape via `stamp_cel_fit` with a fit mode
(stretch / tile / center) — *the shape also stamps depth & collision.*
This is the "draw a shape, load an image into it" idea, realized.
- **Objects** — a PNG becomes a `Prop` that sorts with the ego
Drop your own art into `assets/`, then press **R** in-game to hot-reload it.
## Roadmap
- [x] **v0.1 — rendering core**: vector room, priority depth, walkable ego, click-to-walk, CRT toggle
- [x] **v0.2 — asset pipeline**: PNG → EGA quantize + dither, tile / pour-into-shape / object insertion, hot-reload (`R`)
- [x] **v0.3 — room editor**: in-engine paint tool with edit/play modes, dual-layer LOOK+MEANING painting, flood-fill, tools (brush/line/rect/fill/pick/erase), undo, and JSON room save/load — see [EDITOR_GUIDE.md](EDITOR_GUIDE.md)
- [ ] **Priority-mask backgrounds**: a full-room art PNG + a companion mask PNG whose colors encode depth bands & control lines (the pro art workflow)
- [ ] **True-color "HD" layer mode**: skip quantization for painted backdrops; the priority buffer stays indexed
- [ ] **Polygon shapes** for `stamp_cel_fit` (not just rectangles)
- [ ] **Directional views** (4 loops + horizontal mirroring) for the robot
- [x] **Text parser**: data-driven verb table with synonyms, verb-noun matching, on-screen input line
- [x] **Room transitions**, inventory, flags (with `requires_flag`/`sets_flag` puzzle gating)
- [x] **AI parser adapter**: when the classic parse misses, an LLM maps free text onto an *already-allowed* command (deterministic core stays authoritative; works offline without it)
- [x] **Loadable game folders** (`game.json` + JSON rooms + PNGs) so games ship without recompiling the engine
- [x] **Headless core + control surfaces**: JSONL stdio, script replay, HTTP, MCP, headless PNG rendering — see [docs/CONTROL.md](docs/CONTROL.md)
- [ ] **Rhai room logic**: rooms scripted in an AGI-flavored embedded language (`if said(...) { print(...) }`), hot-reloadable
- [ ] **3-voice + noise chiptune synth** (per-game audio files already override the square-wave synth)
- [ ] **Strudel sink**: browser sidecar over the HTTP surface, driven by the same audio events
- [ ] **Vars & conditions on dialogue/objects** beyond boolean flags; cross-room NPC state
- [ ] **Pathfinding** for click-to-walk (today: greedy steering)