Work in progress: this page is under construction · noindex · access code required.
← Back to portfolio

Case study

UMORIA — the real Moria (1983) in a CRT shell

A genuine 1983 roguelike, compiled to WebAssembly and running in any browser inside a hand-built phosphor-CRT terminal.

WebAssembly WebGL WebAudio PWA C++/Emscripten
UMORIA — the real Moria (1983) in a CRT shell
Role
Solo — design, engineering, build pipeline, deployment, docs
Stack
WebAssembly · WebGL · WebAudio · PWA · GitHub Pages
Timeline
~4 days part-time (≈ 1 day of focused work)
Year
2026
Status
Live

A 40-year-old C++ game, running unmodified in any modern browser inside a hand-built CRT terminal — with a live-synthesised soundtrack, an atmospheric narrator, and zero install.

The challenge

Run the genuine 1983 Umoria — not a remake — in a modern browser, and make it feel like sitting at an amber CRT terminal: alive, atmospheric, installable and instant, with no download. A faithful remake is effectively impossible (every monster, item, formula and quirk would have to match), so the original code had to run as-is — wrapped in a presentation layer good enough to stand on a portfolio.

The approach

  • Compiled the original C++ to WebAssembly. The unmodified Umoria 5.7.15 source, built to WASM/asm.js with Emscripten, behind a reproducible build script.
  • A thin “shell” over the engine. It reads the engine’s hidden 80×24 text grid every frame and re-renders it through a custom WebGL CRT shader — scanlines, tube curvature, phosphor glow, flicker and vignette.
  • A live, evolving soundscape (no audio files). Layered WebAudio score that darkens with depth, dungeon ambience, per-creature death cries, and a spoken narrator streamed from public-domain readings — music ducking underneath.
  • Gameplay touches as clean C++ patches. Multiple lives, an extra life every 50 kills, per-life screen tint, plus arrow-key movement for numpad-less keyboards and adjustable CRT distortion — without breaking save compatibility.
  • Shipped as a real product. Installable PWA (chrome-less window), IndexedDB save persistence, per-file content-hash cache-busting, and graceful fallbacks for blocked storage or stale caches.
  • Automated quality + assets. Headless Chrome (DevTools Protocol) for interactive smoke tests and screenshot capture; bilingual documentation.

The result

  • A complete, authentic roguelike that loads in seconds in any modern browser — clickable and playable instantly, no install.
  • Installable as a desktop/mobile app for a clean, distraction-free window.
  • A distinctive, atmospheric presentation (CRT + fully procedural audio) that reads as craft, not a template.
  • A reproducible build and thorough, bilingual docs — easy for anyone to pick up, rebuild and extend.

What this demonstrates

  • I can take something hard or legacy and ship a polished, fast, installable web product end-to-end.
  • Full ownership: architecture, build pipeline, performance, deployment, docs.
  • Comfort across graphics (shaders), audio (synthesis), systems (WASM/C++) and tooling — and a strong eye for UX and detail.
  • Modern, AI-assisted delivery that turns ideas into working software quickly, steered and curated by a human.

Tech at a glance

C++ · Emscripten · WebAssembly / asm.js · WebGL (custom CRT shader) · WebAudio (procedural synthesis) · Progressive Web App · IndexedDB · Chrome DevTools Protocol (headless testing) · GitHub Pages