Skip to content

monteslu/md_lua_web

Repository files navigation

mdlua web

A browser IDE for making Sega Mega Drive / Genesis games in mdlua's PICO-8-flavored Lua. Write code, draw sprites, compose the sheet, drop in music and sound, build a real .bin ROM, and play it in the emulator — all in a tab. No SGDK, no cross-compiler, no server, no install: the real m68k-elf-gcc toolchain (cc1 → as → ld → objcopy, plus the Z80 driver tools) runs as WebAssembly in a Web Worker, and the ROM boots on the Genesis Plus GX core.

The browser build is byte-identical to an mdlua CLI build of the same source and assets — it is the exact same compiler and build driver (buildGenesisC from romdev-toolchain-m68k-gcc, every seam env-injected), just hosted in a worker instead of node. CI enforces this on every push.

the mdlua web IDE running the Starfall shmup example

What's in it

  • Projects. Saved in the browser (IndexedDB), started blank or cloned from a gallery of the SDK's example games (with live emulator-screenshot thumbnails). Export/import as a plain .zip.
  • Code editor. Monaco with mdlua completions — the entire SGDK API (732 verbs) plus the curated PICO-8 verbs — and live diagnostics from the real compiler on every keystroke, plus a problems panel.
  • Build & run. Play (Ctrl+Enter / Ctrl+R) compiles Lua → C → m68k-gcc WASM → .bin with a live progress bar, then runs it on Genesis Plus GX. Keyboard and any standard-layout gamepad drive the 6-button pad (a mapper handles non-standard controllers); fullscreen grabs the controls. The toolchain prewarms at startup; a warm edited rebuild is ~350 ms (the SDK runtime units are cached).
  • Sprite editor. Pencil / eraser / fill / line / rect / eyedropper, marquee select with copy/cut/paste, zoom, an 8px spr(n) cell grid, and a palette manager that enforces the Genesis's 16-color line budget (15 colors
    • transparent). Import PNG or Aseprite; export sheet.png.
  • Animation. Pick a sprite range and preview it cycling at any fps in the SDK's three modes (loop / once / pingpong), with flip-X/Y toggles; copy the ready-to-paste spr(anim(...)) line.
  • Music. A song-bank manager: import .vgm / .vgz / .xgc (compose in DeflemMask or Furnace, export VGM) — the list order is the music(n) index, converted to XGM2 byte-identically to SGDK's xgm2tool. Preview builds a tiny player cart and runs it on the real YM2612 + PSG.
  • SFX. A WAV bank (order = sfx(n) index); each entry previews the actual on-cart sound (down-converted to 8-bit 13.3 kHz), not the source.
  • Palette. A 9-bit BGR-accurate CRAM designer (8 levels/channel, 4 lines of 16), the PICO-8 palette on PAL0, and pal() / backdrop() / fade() snippets — the Genesis's live-CRAM control.
  • Raster lab. An hscroll(line, x) designer with wave / parallax / split presets, a live preview, and a generated _draw() loop to copy — plus fade / shade_mode / hud / camera snippets.
  • SGDK API browser. Every one of the 732 SGDK verbs, grouped by header, searchable, insert-at-cursor — the discoverability surface for the SDK's 100% coverage.
  • Debugger. A live hex view of the running game's 68000 work RAM ($FF0000, 64 KB), ~10 Hz refresh, click a byte to poke it.
  • Battery saves. save()/load() SRAM persists per project across sessions (into the browser), restored when you reopen the game.
  • Import. Bring in a project .zip, or a PICO-8 .p8 / .p8.png cart — code (glyphs neutralized) and __gfx__ (the P8 16-color palette maps 1:1 onto a Genesis palette line) convert into a new project to port from.
  • Cheatsheet. The SDK's full verb reference, rendered in a tab.

Run it

npm install    # also stages the WASM toolchain into public/md (postinstall)
npm run dev    # open the printed localhost URL

Clone an example from the New Project gallery, edit, Ctrl+Enter to build & run. Click the game screen for sound and keys (arrows = d-pad, Z/X/C = A/B/C, V/B/N = X/Y/Z, Enter = Start, Shift = Mode) — or plug in a gamepad. ⬇ .bin downloads the ROM for a flashcart/EverDrive or any emulator.

How it works

Everything comes from npm packages — this repo is the UI:

piece source
Lua → C compiler, diagnostics, completions mdlua/compiler (pure JS, runs in-page)
asset converters (PNG/Aseprite/Tiled/WAV/VGM) mdlua/compiler browser-safe modules
Genesis runtime C sources mdlua/md-sdk (staged)
THE build driver (buildGenesisC, env-injected) romdev-toolchain-m68k-gcc/build
cc1-m68k / as / ld / objcopy + sjasm / bintos WASM romdev-toolchain-m68k-gcc/wasm (staged)
SGDK library tree (headers, libmd seed, ld script, crt) romdev-toolchain-m68k-gcc/share (staged as one manifest)
Genesis Plus GX emulator core romdev-core-gpgx/wasm (staged)

scripts/stage-toolchain.mjs (postinstall) stages those artifacts into public/md/. The build worker fetches them once, compiles each tool's WASM once, then calls buildGenesisC() with env.runTool / loadGlue / share / hash injected — the identical pipeline the mdlua CLI and the romdev MCP server run.

Tests

Playwright drives real headless Chromium:

npm test
  • test/browser-build.mjs — hello AND starfall-with-its-sheet-and-map build in the browser byte-identical to the CLI's ROMs, and the ROM renders on the core.
  • test/ui-drive.mjs — end-to-end through the real UI: gallery, clone, Play, diagnostics gating, all editor tabs, SGDK insert, the anim example builds.
  • test/emu-audio.mjs — a browser-built music (VGM bank) and sfx (WAV bank) cart are both audible on the core.
  • test/browser-sram.mjs — a save() survives an SRAM round-trip and a load() reads it back.
  • test/browser-perf.mjs — a warm edited rebuild stays under 800 ms.
  • test/gen-thumbs.mjs (npm run thumbs) — regenerates the gallery thumbnails by building + running every example headlessly.

License

MIT (this repo). The staged toolchain, SGDK library, and emulator core are their own projects under their own licenses (the m68k GCC toolchain is GPL-3.0 + the GCC Runtime Library Exception, so built ROMs are not encumbered; SGDK is MIT; Genesis Plus GX is under its non-commercial license) — they are npm dependencies staged at install, never vendored in this repo.

About

Browser IDE for mdlua: write PICO-8-flavored Lua, build a real Sega Genesis ROM in the browser, and play it - byte-identical to the CLI.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors