# 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 # dev build (fast to recompile) cargo run --release # smooth, optimized build ``` A window opens with the demo room. **Walk the robot with the arrow keys or by clicking** — and stroll *behind the column* to watch the priority system place you correctly in depth. `N` toggles CRT scanlines. `Esc` quits. ## How it works (the AGI model, faithfully) Every room is drawn into **two buffers at once**: | Buffer | What it holds | Why | |--------|---------------|-----| | **visual** | palette indices (0–15, EGA) | what you see | | **priority** | depth bands (4–15) + control lines (0–3) | 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 | File | Role | |------|------| | `palette.rs` | the 16-color EGA palette (indices → RGBA) | | `framebuffer.rs` | the visual + priority buffers and the `band(y)` depth table | | `picture.rs` | vector room painting (`PicOp` rectangles / lines / pixels) | | `view.rs` | sprites as loops + cels, authored from tiny ASCII grids | | `sprite.rs` | the ego: movement, click-to-walk, collision, walk animation | | `room.rs` | the hand-authored demo room | | `main.rs` | window, game loop, fixed-step cycles, compositing, HUD | ## 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 - [ ] **Text parser**: vocabulary with synonyms → `said("open","door")` matching, plus an on-screen input line - [ ] **Rhai room logic**: rooms scripted in an AGI-flavored embedded language (`if said(...) { print(...) }`), hot-reloadable - [ ] **Room transitions** (`new_room`), inventory, flags & vars - [ ] **AI parser adapter**: when the classic parse misses, an LLM maps free text onto an *already-allowed* room command (deterministic core stays authoritative; works offline without it) - [ ] **3-voice + noise chiptune synth** - [ ] **Loadable game folders** (text/JSON resources) so games ship without recompiling the engine