Commit Graph

14 Commits

Author SHA1 Message Date
m3ultra
cd121726be Web page: arcade picker is optional chrome (standalone deploys boot without picker.js)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 14:37:25 +10:00
m3ultra
5286d15892 Web: plain RGBA blit on wasm (the multi-texture CRT material fights the GL shim); CRT stays native
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 14:26:51 +10:00
m3ultra
f706a9ce55 Bundles carry pre-baked backgrounds (paintings survive filesystem-less boots)
RoomDoc gains baked_visual (quantized indices, exporter-written, skipped when empty); bake() falls back to it when pics/ can't load; --export-bundle folds every room's painting in via World::bake_backgrounds_for_bundle. A six-painting game bundles to 1.5MB. Tests green; alley renders from bundle alone with no pics/ on disk.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 14:18:06 +10:00
m3ultra
8f98380261 export: byte-stable bundles
A bundle is full of HashMaps — rooms, scripts, sprites, every prop's msgs —
and Rust randomizes their iteration per process, so exporting an unchanged
game twice produced two different files. These are committed build outputs;
a diff should mean the game changed.

Serializing through serde_json::Value fixes it at every depth in one hop,
because Value is BTreeMap-backed by default. Three consecutive exports are
now byte-identical, and the golden replay is unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 14:17:10 +10:00
m3ultra
caf4d5e558 web: savegames through the page, since there is no saves/ directory
mrpci_request_save / mrpci_save_out / mrpci_save_in carry a SaveData across
the wasm boundary, so the browser build can save and restore even though
Command::SaveGame's std::fs call goes nowhere there. The moment being stored
is exactly the one the native build writes to saves/<slot>.json — the same
GameState::save_data — so a slot means the same thing in both places.

F5 now asks the page instead of the filesystem; F7 points at the SAVES menu,
because restoring needs to know *which* slot and a function key can't say.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 14:17:10 +10:00
m3ultra
50ede0febf web: MRPCI runs in a browser, as a player
The macroquad GUI now builds for wasm32 the way MRPGI's does, with two
deliberate differences.

It boots into Play and the F8 editor toggle is compiled out of the web
build. What ships to someone playing a game should be the game, not the tool
that made it.

And it embeds a WorldBundle rather than a game *folder*. MRPGI reaches for
include_dir! because its bundle carries only manifest+rooms; MRPCI's already
carries scripts and sprites too, so one `--export-bundle` document is the
whole game. That is also the format MRP3GI boots from, which means one file
now feeds two engines.

mrpci_alloc/mrpci_world_in let the page hand over another bundle while the
engine is running — the arcade picker and drag-and-drop both arrive there,
and the session restarts on the new world.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 14:17:10 +10:00
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
m3ultra
6ea7aa6dd4 core: build rhai without ahash/runtime-rng
rhai's default feature set is ["std", "ahash/runtime-rng"]. The second half
seeds hash maps from OS entropy, which is a run-to-run variation source
living under a crate whose whole promise is byte-identical replays — and it
pulls getrandom, which has no backend on wasm32-unknown-unknown, so the
browser build could not compile at all.

Dropping it leaves ahash on its compile-time seed. The canonical Neon
Precinct playthrough produces byte-identical events before and after, and
the suite is green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 00:42:47 +10:00
m3ultra
f2b603a812 core: make save_data/restore_data public for filesystem-less saves
Save slots aren't always files. The MRP3GI browser build hands a SaveData
straight to localStorage instead of saves/<slot>.json, so the two halves of
the checkpoint machinery need to be reachable from outside the crate.

Native behavior is unchanged — SaveGame/RestoreGame still go through the
same two functions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 00:39:19 +10:00
m3ultra
662e6c4bc4 v0.4 — in-engine room editor, four screens deep
F8 toggles edit mode. Tools: brush/line/rect/ellipse/flood/gradient/picker; ink meanings write LOOK/FLOOR/WALL/WATER/DEPTH across the four screens; V overlays priority/control/hotspot; hotspot rects, prop placement, spawn, and a :colon command line (save/name/enter/music/weather/exit/room/hotmsg). Every editor action is a bus Command (paint_op, undo_op, clear_ops, set_spawn/exit/music/weather/room_name/enter_text, upsert/delete hotspot+prop) so MCP clients wield identical powers. PicOp::Brush added; docs/EDITOR.md. Verified: 5 suites green, playthrough events byte-identical to pre-editor build, GUI boots.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 00:38:35 +10:00
m3ultra
0191b4680d v0.3 — AI parser lane + dialogue talker portraits
AI lane (ported from MRPGI): unknown typed sentences go to a local LLM (MRPCI_AI: ollama default / openrouter / off) that maps them onto already-legal commands; one in flight, polled per tick, hard-off under --script so replays stay byte-identical. Portraits: NPCs/props gain a portrait sprite drawn beside the dialogue window in the GUI (6x) and annotated frames (2x); sergeant + vend-bot faces in the demo. Also: --script + --render-room renders the frame a replay ends on. Verified: 5 test suites green, deterministic 25/25 playthrough, GUI boots.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 00:26:03 +10:00
m3ultra
64a2db6605 Bundles carry sprites + --export-bundle/--bundle flags (MRP3GI M1 prereqs)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 23:59:07 +10:00
m3ultra
e014a0c54e v0.2 — procedural fills, weather, in-core font, GPU palette/CRT shader
Adaptations from the software-rendering playbook, at MRPCI's level of the
stack:

- pic.rs: fBm noise fill, jittered Voronoi fill (with mortar edges) and
  scatter — seeded, deterministic, Bayer-dithered through palette ramps
- particles.rs: rain/snow/embers layer on its own RNG stream; RoomDoc
  gains `weather`; visuals can never perturb gameplay replays
- font.rs: built-in 5x7 font stamped in index space; headless frames are
  now annotated (room chip, score, dialogue windows, transcript strip) so
  MCP render_frame shows what a player actually reads (--raw to skip)
- render.rs: compose split into index-space compositing + palette blit;
  effective_palette() exports the cycle-LUT-applied strip
- GUI: frame ships to the GPU as indices + a 256x1 palette texture; a
  fragment shader does the lookup plus CRT curvature/scanlines/vignette
  and room-change fades
- Neon Precinct: fBm night sky + stars, Voronoi sidewalk & wet cobbles,
  fBm asphalt, rain in Neon Row and Rain Alley

Verified: replay determinism (byte-identical events x2), 25/25 win path,
GUI boots with the shader.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 23:23:19 +10:00
m3ultra
c83c90711d MRPCI v0.1 — the SCI-generation Monster Robot Party engine
Headless core (mrpci-core) + macroquad GUI (mrpci), inheriting MRPGI's
Command/Event bus architecture and jumping a Sierra generation:

- 256-color palettes with live median-cut quantization + palette cycling
- four screens: visual / priority / control / hotspot
- A* pathfinding with LOS-verified edges and line-exact path following
- perspective scale tables (actors shrink toward the horizon)
- point-and-click verb bar AND a text parser, one shared verb pipeline
- rhai room scripts (on_enter/on_verb/on_trigger + after() tick timers)
- deterministic 30Hz cycles, seeded RNG — byte-identical script replays
- checkpoint at room entry; death rewinds instead of restarting
- save-anywhere slots; multi-voice chip synth; JSONL/HTTP/MCP surfaces
- demo game: Neon Precinct (3 rooms, 25 points, one merciful fusebox)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 22:52:39 +10:00