用 curl 就能玩的 DOOM

查看原文 HN 讨论

文章摘要

curl-doom 是一个脑洞大开的项目:它让你可以通过 HTTP 协议玩经典游戏 DOOM——整个游戏画面以 ANSI 终端字符形式传输,而玩家则通过一条 curl 命令与服务器进行双向交互。作者 xsawyerx 把一条普通的 curl 请求变成了”一条线两个方向”的游戏通道:键盘输入沿着请求体(request body)流向服务器,而渲染好的 ANSI 帧则沿着响应体(response body)源源不断地流回终端。

项目采用客户端-服务器架构。HTTP 服务器会为每个会话启动一个独立的无头 DOOM 实例(基于 doomgeneric),把原本 640×400 的 BGRA 像素帧降采样并转成终端兼容的 ANSI 半格字符。为了在终端中获得更高的垂直分辨率,作者使用了”上半格字符”(▀)这一经典技巧——把每个字符格当作上下两个像素来用,让分辨率翻倍;再配合带色彩感知的增量压缩(delta compression),响应体积能缩减到原始数据的约 1/5。此外还引入了虚拟时钟系统,消除了 DOOM 原本 wait loop 里的实际 sleep 调用,让游戏帧率响应更灵敏。每个会话在 60 秒无活动后会自动超时。

游戏提供两种玩法。”友好模式”是 curl | bash——拉下来一段脚本,它会自动完成终端配置和按键循环。”硬核模式”则是完全依赖 curl 自己的双向流能力,把 stdin 作为按键输入,响应流作为渲染输出。默认帧率被刻意限制在 15 fps,原因是 curl 的 stdin 缓冲行为在更高帧率下会出现问题——这是一个被约束倒逼出的优雅设计决策。项目代码构成大约为 65% JavaScript/Node.js(HTTP 服务端)、15% C(无头 DOOM 二进制及 doomgeneric)、17% Shell(客户端脚本),并提供了 Docker 部署支持。

作为 DOOM 又一个”奇葩运行平台”的案例,curl-doom 在技术趣味之外也再次证明了 curl 作为通用 HTTP 工具的惊人灵活性——它不仅仅是下载工具,还可以是全双工的流式终端应用客户端。

HN 评论精华

  1. 关于 AI 写作的争议:用户 varun_ch 指出 README 中有些段落”解释得过度细致”,怀疑是 AI 辅助生成,并感慨这类项目的吸引力已经大不如前,因为”Claude 5 分钟就能稳定产出类似的东西”。作者 xsawyerx 亲自下场回复,反驳了”整个项目都是 AI 生成”的揣测——那些带有作者个人风格的文档不应该被简单地当作 LLM 输出。

  2. curl | bash 的安全争议:用户 z3c0 最初批评 curl | bash 的模式是”客观上的糟糕实践”,并暗示这是”过度雄心的 prompt”产物。后来他在看清项目的真实实现后撤回了批评,承认代码比表面看起来更加讲究。作者的合作者 moeffju 进一步澄清:bash 管道只是可选的便捷方式,用户完全可以手动输入命令来完成相同的事情,脚本主要做的只是把终端配置省下来。

  3. 作为远程终端应用模板的价值:评论者 thomasfl 认为这个项目可以当作构建”基于终端的远程服务器应用”的模板——毕竟要把一个完整的图形化游戏搬到 ANSI 终端里双向流式交互,其中包含的很多模式(增量帧压缩、会话管理、stdin 缓冲规避)对其他类似应用都很有参考价值。

  4. 对 curl 能力的惊叹:用户 BobbyTables2 表示惊讶——没想到 curl 居然支持”在请求还没发送完时就开始读取 HTTP 响应”。事实上这是 curl 长期支持的双向流能力,但在日常使用中鲜有人触及,curl-doom 把这种能力推到了极致。

  5. 极客精神的共鸣:虽然评论区出现过对 AI 参与度和 curl | bash 实践的质疑,但整体氛围依然带着 HN 一贯的极客式赞赏——把 DOOM 塞进又一个意料之外的环境里运行,本身就是一种致敬 id Software 这款传奇游戏的方式。