Playground Runtime Embedded Demo
This example shows the new reusable
Playground(...) runtime layer.
It keeps the live-code style API, but without Monaco or the current
Playground UI.
The idea is to make code written for Tetorica easier to move into a browser game or another small app.
Pass { execution: "worker" } to
pg.play() to keep game code off the main thread. The
default remains main-thread execution for compatibility.
Minimal Usage
import {
Playground,
} from "../js/playground_runtime.js";
const pg =
Playground({
audioWorkletUrl:
"../js/ym2612-worklet.js",
ym2612WasmUrl:
"../generated/ym2612_wasm.wasm",
segaPsgWasmUrl:
"../generated/segapsg_wasm.wasm",
});
await pg.initialize();
pg.load("stage1", `
setBpm(120);
fm.setPreset(CH1, FM_PRESETS["one-op-basic"]);
liveLoop("lead", async () => {
await play("C4", {
channel: CH1,
duration: 0.18,
});
await beat(0.5);
await play("E4", {
channel: CH1,
duration: 0.18,
});
await beat(0.5);
await play("G4", {
channel: CH1,
duration: 0.18,
});
await beat(1);
});
`);
await pg.play("stage1", {
execution: "worker",
});
Ready.
{
"audio": "idle",
"playback": "stopped",
"currentSourceName": null,
"loadedSourceNames": []
}
What This Layer Hides
Application / Game
|
v
Playground runtime
|
+-- source registry
+-- play / stop control
+-- liveLoop helpers
+-- YM2612 / PSG access
|
v
MegaDriveSynth
|
+-- AudioContext
+-- AudioWorklet
+-- WASM loading
|
v
YM2612 / PSG output