Stars! is a 1995 4X game written for 16-bit Windows 3.1, and it is effectively unplayable today: x64 Windows cannot run 16-bit binaries, so you need retro hardware or an emulation stack. Chris Wellons built Stars!VM instead — a custom 80286 emulator plus a Win16-to-Win32 bridge, shipped as a native 32-bit executable with a compressed copy of the original game embedded inside. One signed EXE, no setup, with a modern file chooser and 4K scaling.

How it works:

  • x87 runs on the host. 80-bit floating point is not implemented in software; those instructions execute directly on the host’s x87 hardware — simple, fast, precise.
  • Differential fuzzing validates the whole thing. Random 16-bit instructions are generated, emulated, run JIT on the host, and the results compared.
  • The bridge maps 16-bit handles to host handles, marshals between different struct layouts, services the DOS interrupts the game needs, and copies data in and out of guest memory. His description: “rather like running a Wasm instance.”
  • The bridge is MCP-addressable. Agents can read the UI as it is built and inject synthetic events into the event pump, bypassing desktop control entirely, plus read and write guest memory. Opus 5 played a complete game through it, asking for help at two points when it got stuck in the UI.
  • Hot code gets hand-written fast paths. Turn generation is the bottleneck, so he traced executed instructions, used an LLM to identify and reverse-engineer the hottest routines (including the game’s L’Ecuyer MCG PRNG), rewrote each in C, and mapped them into the decoder as new 80286 instructions. The emulator patches them in at load time — roughly 2x faster turn generation.
  • I/O is buffered. The original issues many small unbuffered reads and writes; passing them straight through to Win32 made I/O about 5% of turn generation.
  • A custom LZ compression tuned to the game’s assets halves the release to about 1.5MB, smaller than the original EXE.

The idea worth stealing is the shortcut on performance. Rather than build a general JIT, he exploits the fact that he is emulating one specific known program: profile it, find the routines that dominate runtime, promote those to native code as if they were new instructions. He calls it “JIT performance without JIT complexity.”

Two smaller details stand out. The Win16-to-Win32 bridge is what makes the copy protection a non-issue — the emulator injects a fixed serial code and reports a fixed hardware signature, so nobody triggers the game’s usurper penalty. And the whole thing is a weekend project, which says something about how far emulator scaffolding has come. Also worth noting: 1990s constraint-driven UI holds up, because they could not afford otherwise.