MRPCI/CLAUDE.md
type-two ce42d69a3a v0.5 — playtest-driven fixes + engine/UX upgrades
Bugs found by playing the game over the bus:
- hotspots now have positions: 'walk to precinct door' pathfinds there,
  and touch verbs walk over to hotspots like they do to props/NPCs
- GameState::settle(): the MCP surface resolves walk-then-act in one call
  instead of returning zero events on a distant verb
- typed 'use X on Y' walks over like a clicked use (was unlimited range)
- taking/deleting a solid prop rebakes — no more lingering invisible walls
- sergeant dialogue no longer loops back to its greeting
- serde-facing maps are BTreeMap: room JSON and --sample are byte-stable

Engine:
- sprite-sheet actor views: <name>-sheet<C>x<R>.png slices into C frames x
  R direction loops (vend-bot now rolls on animated treads)
- pixel-accurate click targeting with 1px slop; typed commands click
  mid-sprite (a feet click lands between an actor's legs)
- parser: compass walking (go east / n), 'bye' ends conversations,
  'look' lists exits

GUI:
- hover hot-text: cursor reads the sentence a click would say
- death banner + '+N' score toast

Tests: full-playthrough regression suite (win path, death rewind,
walk-over dialogue, solid-prop footprint) + sheet slicing unit test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 13:38:33 +10:00

2.4 KiB

MRPCI — working notes for Claude

SCI-generation adventure engine (sibling of MRPGI). Rust workspace: mrpci-core (headless sim — must never depend on macroquad; that's the architectural guardrail) and mrpci (the macroquad GUI, a thin bus client).

Build / test / run

cargo build --workspace
cargo test --workspace          # includes full-playthrough regression tests
cargo run -p mrpci              # play Neon Precinct in a window
target/debug/mrpci-headless --game games/neon-precinct --render-room out.png

Invariants — do not break

  • Everything goes through the bus. All mutation is a Command on GameState::apply; all output is Events. GUI, stdio, HTTP, MCP and the in-engine editor are thin adapters with zero private powers.
  • Determinism. Fixed 30Hz cycles; timers count ticks; the only RNG is the seeded xorshift in ScriptCtx. --script replays must stay byte-identical (the AI parser lane is force-disabled there). Weather particles run a separate RNG stream on purpose.
  • Deterministic serialization. Serde-facing maps are BTreeMap so room JSON/bundles are diffable and --sample output is byte-stable.
  • Scripts can't corrupt the sim. rhai reads a ScriptCtx snapshot, writes queue as Fx — keep that airlock.
  • Missing resources degrade, never crash (placeholders + error event).

Gotchas

  • games/neon-precinct/ is generated by mrpci-headless --sample (source: mrpci-core/src/bin/mrpci-headless/sample.rs). Edit the generator, then regenerate — don't hand-edit the JSON.
  • Distant verbs queue a walk-then-act (pending_verb); real-time surfaces resolve it on later ticks, the MCP adapter calls GameState::settle(). Raw stdio/HTTP callers must send tick.
  • Sprites named <base>-sheet<C>x<R>.png are sliced into animated actor views (rows: front/back/left/right, right falls back to mirrored left). Sheets are for egos/NPCs; props/portraits use plain single-cel sprites.
  • Solid props stamp CTL_BLOCK footprints; anything that can remove one must rebake(), not just re-stamp (else invisible walls linger).
  • Hit-testing is pixel-accurate with 1px slop (cel_hit); typed commands "click" mid-sprite via target_click_pos (a feet-point click lands between an actor's legs).

Docs

README.md (architecture + game-folder format), docs/CONTROL.md (bus reference: every Command, all four surfaces), docs/EDITOR.md (F8 editor).