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>
77 lines
3.3 KiB
HTML
77 lines
3.3 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<title>MRPCI — Monster Robot Party Creative Interpreter</title>
|
||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><text y='14' font-size='14'>🎨</text></svg>" />
|
||
<link rel="stylesheet" href="arcade.css" />
|
||
<style>
|
||
html, body { margin: 0; height: 100%; background: #05070b; overflow: hidden; }
|
||
/* miniquad sizes its drawing buffer from the canvas's *CSS* box, so the
|
||
canvas needs real dimensions — `max-width` inside a centring grid
|
||
resolves to zero and the engine renders a 0x0 frame. Give it the
|
||
whole area below the arcade bar, like MRPGI does. */
|
||
canvas {
|
||
position: absolute; inset: 34px 0 24px 0;
|
||
width: 100%; height: calc(100% - 58px);
|
||
display: block; outline: none; image-rendering: pixelated; background: #0b0d11;
|
||
}
|
||
body.arcade-standalone-page canvas { inset: 0 0 24px 0; height: calc(100% - 24px); }
|
||
#boot {
|
||
position: absolute; inset: 34px 0 0 0; display: grid; place-items: center;
|
||
background: #05070b; color: #8296aa; z-index: 20;
|
||
font: 12px/1 ui-monospace, Menlo, monospace; letter-spacing: 0.16em;
|
||
text-transform: uppercase; transition: opacity 400ms ease; pointer-events: none;
|
||
}
|
||
#keys {
|
||
position: fixed; bottom: 0; left: 0; right: 0; z-index: 30;
|
||
padding: 4px 10px; background: rgba(6,10,16,0.86); color: #6f8296;
|
||
border-top: 1px solid rgba(120,190,255,0.18);
|
||
font: 11px/1.5 ui-monospace, Menlo, monospace;
|
||
}
|
||
#keys b { color: #9fb4c8; font-weight: 600; }
|
||
</style>
|
||
</head>
|
||
<body class="arcade-inset">
|
||
<canvas id="glcanvas" tabindex="1"></canvas>
|
||
<div id="boot">starting the interpreter…</div>
|
||
<div id="keys">
|
||
<b>click</b> verb at pixel · <b>right-click</b> cycle verb · <b>F1–F4</b> walk/look/do/talk ·
|
||
<b>I</b> inventory · <b>Enter</b> type a command · <b>F5/F7</b> save/restore · <b>M</b> mute · <b>N</b> scanlines
|
||
</div>
|
||
|
||
<script src="mq_js_bundle.js"></script>
|
||
<script>
|
||
// miniquad resolves the engine's undefined imports at runtime; register
|
||
// before the wasm loads or the instantiation fails.
|
||
miniquad_add_plugin({ register_plugin: () => {}, version: '1', name: 'mrpci_bridge' })
|
||
|
||
/** Hand a WorldBundle JSON to the running engine. */
|
||
function sendBundleToEngine(json) {
|
||
const bytes = new TextEncoder().encode(json)
|
||
const ptr = wasm_exports.mrpci_alloc(bytes.length)
|
||
new Uint8Array(wasm_memory.buffer, ptr, bytes.length).set(bytes)
|
||
wasm_exports.mrpci_world_in(ptr, bytes.length)
|
||
}
|
||
|
||
load('mrpci.wasm')
|
||
|
||
const engineReady = () => typeof wasm_exports !== 'undefined' && !!wasm_exports
|
||
const t = setInterval(() => {
|
||
if (!engineReady()) return
|
||
document.getElementById('boot').style.opacity = '0'
|
||
clearInterval(t)
|
||
}, 200)
|
||
</script>
|
||
<script src="picker.js"></script>
|
||
<script>
|
||
MRPArcade.init({
|
||
engine: 'mrpci',
|
||
ready: () => typeof wasm_exports !== 'undefined' && !!wasm_exports,
|
||
load: (json) => sendBundleToEngine(json),
|
||
})
|
||
</script>
|
||
</body>
|
||
</html>
|