All projects
February 2025 – March 2025 Shipped

STM32 Synthesiser, running DOOM

Real-time embedded C++, a full octave, and a 3D game engine in 64 kB

  • 18 ms average full-screen refresh (48 ms worst case)
  • 45 fps sustained gameplay
  • 48% peak CPU utilisation

The brief was a real-time synthesiser. We built a full-octave electronic piano with volume, octave and waveform control, a recording function and a graphical interface, running as a modular RTOS system so audio generation never misses a deadline because the UI is busy.

Then we noticed the board had headroom and put DOOM on it.

Constraints

An STM32 with 64 kB of RAM and 256 kB of flash. The original game does not fit, so I wrote my own version and my own 3D engine for it.

What I built

The graphical UI, and a custom 2.5D rendering engine with chunk-based world generation, perspective warping, obstacles, enemies, shooting and joystick control. Hand-optimising the render loop got a full-screen refresh to 48 ms worst case, ~18 ms typical, playable at 45 fps.

No dynamic memory allocation anywhere. Every buffer is fixed-size and statically owned. On 64 kB with hard deadlines, malloc is an unbounded latency spike and an eventual fragmentation failure, not a convenience.

The rest was chunked rendering so only the visible slice of the world is touched, a lean threading model that keeps the audio thread’s worst-case latency bounded, and a lot of time measuring which operations were costing frame budget. Peak 48% CPU, so there is real headroom rather than a system that only just fits.