DOOMQL: SQL as a game engine, practical experiment with GPT-5.6 Sol
Peter Gostev built DOOMQL using GPT-5.6 Sol: a small Doom-like game where SQLite is the graphics engine, not the place to save data. Movement, collisions, enemies, combat, and every RGB pixel live inside SQL queries, including a complete ray tracer implemented as a recursive CTE.
The database can be inspected with Datasette: a public demo shows an HTML+JavaScript app that reads the frame_pixels view in real time while the game runs in the terminal, with a minimap added with Claude Fable 5 in minutes.
Why it matters to you. It’s not a ready-made tool, it’s a case study on what happens when you give a model a precise technical objective and the space to work on it. The code is public on GitHub, clones and runs in five minutes (uv run host/doomql.py). It’s not the feasibility that counts — SQL isn’t designed for rendering frames — it’s the process: an unrealistic problem decomposed into executable steps, with the model writing code that actually runs.
If you’re experimenting with coding agents, this is the kind of experiment that shows practical limits: where the model solves things, where you need to verify, and how far you can push before the output becomes too fragile.
In detail
The context. Frontier models like GPT-5.6 Sol, Claude Fable 5, and Muse Spark 1.1 have changed the scale of projects you can hand to a coding assistant: from “write this function” to “build this system.” DOOMQL is an experiment at the edge of that capability: a complete system where the model had to figure out how to represent 3D graphics, basic physics, and game logic inside an engine not designed for any of those things.
How it works. The game is a Python terminal script that creates a SQLite database. Each frame is a query: a recursive CTE implements ray casting (projecting rays from the player’s viewpoint), calculates distances from walls, determines column heights on screen, and generates RGB values for each pixel. The result ends up in a frame_pixels(x, y, r, g, b) view you can query or visualize.
The database can be inspected with Datasette and the datasette-apps plugin, which lets you create HTML+JavaScript interfaces inside Datasette itself. In the demo, a prompt to Claude (“build an app that shows the screen state from the frame_pixels view, updates every second”) produced a working visualizer in one go. The minimap came with “add a minimap,” without rewriting the app.
What it really shows. The experiment doesn’t prove SQL is a good graphics engine — it isn’t. It proves a strong model can translate an absurd problem into executable code, if you give it:
- A precise technical objective (“SQL as a graphics engine”).
- A language with rigid semantics (SQL, where a correct query always does the same thing).
- An isolated workspace to try and fix (the local database).
The generated code is readable and public: you can follow the ray tracer logic inside the CTE, see how it represents game state, and where the model made design choices (for example, how it handles collisions with recursive queries instead of imperative loops).
The limits. We don’t know how many attempts it took to reach a working version, or how much human oversight was needed to fix logical errors or performance issues. A project like this requires many rounds of verification: SQL is precise but unforgiving, and a bug in a recursive CTE is hard to isolate even for a human. The repo doesn’t document the development process, only the final result.
Also, the experiment is deliberately small: one level, basic enemies, no complex opponent AI. Adding complexity (more levels, richer interactions) could push the system beyond what SQL can handle with acceptable performance.
What to do with it. If you work with coding agents, this case is useful for two reasons:
- It shows you where to look when evaluating output. DOOMQL’s code is verifiable: you can run it, inspect the database, read the queries. An assistant producing code at this scale must generate artifacts you can execute and understand, not just paste.
- It gives you an example of an unrealistic problem solved well. Building a game in SQL is a problem with strong constraints and a non-trivial solution. If you’re testing a model on non-standard tasks, pick problems with this structure: clear objective, immediate verification (it runs or it doesn’t), and enough complexity to surface the limits.
To try it, clone the repo and follow the README: five minutes to have the game running, another five to open the database in Datasette and see what’s inside. It’s not a tool you’ll use in production, but it’s a good example of what you can ask a model when you know what to verify.