Lukas Vogel ported the original Doom’s game logic and 320×200 renderer to SQL. Python handles only timing, input, and displaying the bitmap. The impressive part isn’t that SQL can run a game; it’s the unusually clear account of where a relational model helps and where it becomes an expensive workaround.
The architecture makes the trade-offs visible:
- A fixed 35 Hz game loop updates state tables; rendering is a separate query over that state.
- Doom’s map data and entity behaviors map naturally to tables, joins, and bulk updates. Weapons and animations become inspectable, editable data.
- The renderer uses 89 CTEs to generate pixels; window functions stand in for mutable clipping state, and a per-pixel
MINresolves overlapping fragments. - That depth-resolution step alone costs about 8.2 ms on average. The original renderer avoids the work through careful ordering.
The database earns its keep somewhere less flashy: transactions give multiplayer clients consistent snapshots of each game tic, while restricted roles expose only a small input API. Vogel reports roughly 60 FPS on his laptop in typical scenes, dropping to 35 in busy ones — measurements of this implementation, not an argument to build every game in SQL.
A good constrained-engineering experiment admits which abstractions fit the problem and measures the price of the ones that don’t.