DOOMQL:用 SQLite 驱动的类 Doom 游戏
SQLite 不只是存数据,也能“跑游戏”
Peter Gostev 使用 GPT-5.6 Sol 构建了 DOOMQL。这个项目从一个有意“离谱”的问题出发:如果 SQLite 不是游戏存档或状态数据的容器,而是直接作为游戏引擎,会发生什么?
最终结果是一个小型、原创的类 Doom 游戏:
- 移动由 SQL 处理
- 碰撞由 SQL 处理
- 敌人、战斗和进度由 SQL 处理
- 屏幕上的每一个 RGB 像素也由 SQL 生成
运行方式
它实现为一个 Python 终端脚本,可以这样尝试:
cd /tmp
git clone https://github.com/petergpt/doomql
cd doomql
uv run host/doomql.py
运行后,终端中会出现一个复古的第一人称类 Doom 画面:灰色墙面、红色门、拾取物、准星、武器,以及状态栏,例如生命值、弹药、分数和任务提示等。
用递归 CTE 在 SQLite 里做光线追踪
项目中有一段很大的 SQL 查询,用 SQLite 的递归 CTE 实现完整的 ray tracer。也就是说,画面不是传统游戏引擎渲染出来的,而是通过 SQL 查询计算得到。
这让 DOOMQL 更像是一个技术实验:它并不是为了证明 SQLite 适合做游戏引擎,而是展示 SQL、递归查询和数据库视图可以被推到多远。
游戏状态也是一个 SQLite 数据库
运行脚本后,会生成一个 SQLite 数据库:
/tmp/doomql/.doomql/doomql.sqlite
可以用 Datasette 打开这个数据库进行探索:
uvx --prerelease=allow --with datasette-apps datasette \
/tmp/doomql/.doomql/doomql.sqlite \
-p 4444 --root --secret 1 --internal internal.db
其中 --with datasette-apps 会安装 Datasette Apps 插件。该插件支持在 Datasette 界面中创建自定义 HTML + JavaScript 应用,并让这些应用直接执行 SQL 查询。
用 Datasette 做实时画面查看器
作者还创建了一个 Datasette App,用 frame_pixels 视图读取当前画面状态。这个视图包含:
xyrgb
也就是每个像素的位置和 RGB 颜色。
给 Claude 的提示大意是:
构建一个应用,使用 frame_pixels 视图中的 x、y、r、g、b 列显示当前屏幕状态,并每秒刷新一次。
这样就能在终端玩游戏的同时,在 Datasette 页面中看到同步刷新的游戏画面。
随后又追加了一个提示:
添加一个小地图。
最终的 Datasette App 可以展示:
- 第一人称游戏画面
- 每秒自动刷新
- 战术小地图
- 玩家、敌人、拾取物、门和出口等标记
- 当前像素数量、敌人数量、查询耗时等状态信息
示例状态中,画面尺寸为 160×54,共 8,640 个像素,并显示查询耗时约 89 ms、每秒刷新一次。
这个项目有意思在哪里
DOOMQL 的看点不在于它要替代真正的游戏引擎,而在于它把数据库系统当成了计算和渲染环境:
- SQL 不只是查询数据,也参与游戏逻辑
- SQLite 不只是存储层,也承担渲染与状态推进
- Datasette 不只是浏览数据库,也能成为实时可视化界面
- AI 辅助编程参与了工具和界面的快速搭建
对于关注 SQLite、SQL、生成式 AI、游戏实验或 Datasette 生态的人来说,这是一个很有趣的技术玩具。
