DOOMQL:用 SQLite 驱动的类 Doom 游戏

Simon Willison13 天前

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 视图读取当前画面状态。这个视图包含:

  • x
  • y
  • r
  • g
  • b

也就是每个像素的位置和 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 生态的人来说,这是一个很有趣的技术玩具。

评论

请登录后发表观点

暂无数据