全部文章0

Simon Willison's Weblog未知作者··访问 1

DOOMQL

原网页

DOOMQL

Peter Gostev built this using GPT-5.6 Sol. This is a lot of fun:

DOOMQL started with a deliberately unreasonable question: what if SQLite were the game engine, not merely the place where a game stores data?

The result is a small, original Doom-like game in which SQL owns movement, collision, enemies, combat, progression and every RGB pixel on screen.

It's implemented as a Python terminal script - I tried it out like this:

cd /tmp
git clone https://github.com/petergpt/doomql
cd doomql
uv run host/doomql.py

Screenshot of a macOS terminal window titled "doomql — python3.14 ◂ uv run host/doomql.py — 134×31" showing a retro Doom-style game rendered as text-mode pixel art. The scene is a pixelated first-person corridor with gray paneled walls, dark red doors on the far left and right, a floating cyan-and-gold coin pickup on the right side, a white crosshair near the center, and a dark weapon barrel rising from the bottom center. A status bar below the scene reads "HP 100/100 AMMO 037 SCORE 00225 INDEX MISSING TICK 0028450", followed by an orange line "FIND THE INDEX TOKEN" and a cyan controls line "WASD MOVE J/L OR ARROWS TURN SPACE FIRE E USE P PAUSE CTRL-C EXIT".

Here's the huge SQL query that implements a full ray tracer in SQLite using a recursive CTE.

Running the above script creates a /tmp/doomql/.doomql/doomql.sqlite SQLite database, which you can explore using Datasette like this:

uvx --prerelease=allow  --with datasette-apps datasette \
  /tmp/doomql/.doomql/doomql.sqlite \
  -p 4444 --root --secret 1 --internal internal.db

The --with datasette-apps option installs the new Datasette Apps plugin, which supports creating custom HTML+JavaScript apps that can run SQL queries directly within the Datasette interface.

I created a new app, pasted the copy-paste prompt into Claude chat (Fable 5) and told it:

Build an app that displays the current state of the screen using the frame_pixels view with its x, y, r, g, b columns. have it refresh once a second.

This got me a working HTML+JavaScript app inside Datasette that could reflect the current state while I played the game in my terminal. Then I added:

add a minimap

And now my Datasette App looks like this:

Screenshot of a dark-themed web app running a retro Doom-style game rendered from SQL queries. The page header reads "DOOMQL" with buttons "All apps", "Edit app", "Pin", and "Full screen". Inside the game panel, the title "DOOMQL" sits above the subtitle "auto-refreshing once a second · frame and tactical map straight from SQL". The left side shows a pixelated first-person corridor view with gray walls, dark red doors, a floating cyan-and-gold coin pickup, a white crosshair, and a weapon barrel at bottom center. A status bar below reads "HP 100/100 AMMO 037 SCORE 00225 INDEX MISSING TICK 0027847". On the right, a panel titled "TACTICAL MAP" shows a top-down grid map with a player triangle, a red enemy circle, yellow pickup dots, red wall markers, and a green exit square, with a legend reading "you", "enemy", "pickup", "locked door", "door", "exit". Below the game view, an orange banner reads "FIND THE INDEX TOKEN", followed by the cyan line "READ-ONLY VIEWER · SELECT x, y, r, g, b FROM frame_pixels". At the bottom, a green "RUNNING" badge appears beside the stats "160×54 · 8,640 pixels · 3 hostiles · query 89 ms · refreshing every 1 s".

Here's the HTML app code - paste that into your own Datasette instance (using the uvx --with datasette-apps recipe from above) to try it yourself.

Via @petergostev

Tags: games, sql, sqlite, ai, datasette, generative-ai, llms, ai-assisted-programming, gpt, datasette-apps