DONKEY.BAS 45 岁了——131 行代码的荣光
文章摘要
donkeybas.com 是一个极简的单页站点,把 1981 年那款随 IBM PC DOS 一起出厂的 BASIC 示例游戏 DONKEY.BAS 完整搬进了浏览器。作者 Joe Krauska(HN 用户名 jkrauska)做这件事的由头很清楚:2026 年 8 月 12 日是 IBM PC 发布 45 周年,他顺手把这个 45 岁的小游戏移植成了 JavaScript + Canvas 版本,代码托管在 GitHub 的 jkrauska/DONKEY.BAS 仓库,通过 GitHub Pages 部署。
页面本身内容极少:一块 320×200 的 canvas、几个开关(声音、CRT 扫描线滤镜、作弊模式、全屏),以及一段简短的 About。玩法说明只有一句话——按空格或点触屏切换车道,撞上驴子就 BOOM。站点同时提供了原始 DONKEY.BAS 源码的在线查看页面,让人可以对照着看那 131 行 BASIC 到底长什么样。
补充一点历史背景,这也是 HN 讨论的核心:DONKEY.BAS 由微软联合创始人比尔·盖茨与 Neil Konzen 于 1981 年合写(1.10 版为 1982 年),随早期 IBM PC DOS 附送,用途是演示 BASICA(Advanced BASIC)的彩色图形与声音能力。游戏逻辑简单到近乎原始:你开一辆车沿双车道公路往前,路上随机出现驴子,你唯一能做的操作就是换道。撞上就结束。它在计算机史上的地位远超其游戏性——它是无数 80 年代孩子第一次意识到「屏幕上的东西是可以被改写的」的那个瞬间。当年的 BASIC 环境里,你随时可以按键跳出游戏进入编辑器,看到代码,改一个数字,再运行,看到结果变了。这条从「玩家」到「程序员」的路径短到几乎不存在门槛。
这个浏览器移植版做了一些「自由发挥」:声音效果比原版 PC 蜂鸣器丰富得多;加入了作弊模式;还藏了彩蛋——你可以反过来操控驴子(用 A/D 键),输得够惨会出现一张灰度驴子照片,赢满 10 次会跳出一张抖动处理过的比尔·盖茨梗图。作者自己在评论里把这几个彩蛋概括为「你可以扮演驴子 / 作弊模式 / 性感盖茨」。
值得一提的是,作者坦承这个移植是「让 slopmachine(指 AI 编码工具)跑起来」做的,这个自述本身在评论区引发了一点小争议——毕竟原作只有 131 行。
HN 评论精华
这个帖子拿到 274 分。讨论几乎完全没有停留在这个移植版本身,而是迅速滑向了一场大规模的 80/90 年代 BASIC 集体怀旧,其中一条支线甚至喧宾夺主,成了整个帖子最亮眼的部分。
-
jkrauska(作者)开场自述:受 IBM PC 45 周年启发做了这个浏览器移植,「作为一个年轻人,我曾经着迷于用这么少的代码就能做出一个游戏」。有人(grimgrin)质疑「没什么新意吧?只是个生成的移植?」并列举了一堆已有的 GORILLAS.BAS 浏览器版;zahlman 也吐槽了那句「让 slopmachine 跑起来」——「就为了 131 行?」
-
喧宾夺主的那条支线:vunderba 先是指出移植版音效「太先进了」,因为早期 IBM 机器只有简陋的磁驱动扬声器,接着顺口提到自己花了四个月在做一个 100% 忠实还原 QBasic 和 QuickBasic 4.5 的浏览器实现,跑在虚拟 CPU 和硬件抽象层上。这条评论炸出了整个帖子最长最有料的讨论。被 physicles 追问「HAL 做到什么程度?SCREEN 12/13?直接写 VRAM?等垂直回扫?」时,vunderba 的回答让人叹为观止:虚拟 CPU 按 386SX、486DX 的真实时序精确校准(486 因为内建协处理器真的跑得更快);所有屏幕模式包括隐藏页绘制都支持;有完整模拟的 VGA 硬件层和合成的 VGA 光束时钟,所以
WAIT &H3DA, 8, 8这种等垂直回扫的技巧真的能用;Int 33h 鼠标中断通过虚拟 TSR 驱动完整支持;PEEK/POKE 和大部分 BIOS 都有模拟,甚至能用 int 19h 重启「电脑」;还接了一个 Hayes 兼容的 14.4k 调制解调器在 COM1 上,以及一台 LPT 口的点阵打印机。他说自己翻出了 80 年代末 90 年代初的一摞旧书(《Undocumented DOS》《The Programmer’s PC Sourcebook》)当圣经,项目完成度 99%,准备近期发 Show HN。khriss 的回复代表了很多人的心声:「这条评论就是 HN 的巅峰——对技术深度热爱的人写出的深思熟虑的评论,这才是 HN 之所以成为黑客聚集地的原因。」 -
131 行为什么值得惊叹:wk_end 的评论开启了另一条主线——「这说明早期 BASIC 是多么周到的开发环境,明明比现代语言弱得多,却能用 131 行做出一个完整的小游戏。我甚至不确定你能不能用 131 行非压缩的 C 打开一个 SDL 窗口并跑起游戏循环。我们这些年确实丢掉了一些东西。」krapp 用大约 30 行 SDL3 代码反驳了「打不开窗口」这一点,但同意 131 行做不出完整的 DONKEY。sltkr 则指出 DONKEY.BAS 在行数指标上其实有点作弊——一行里塞满了语句,比如把 INKEY$ 读键、ESC 判断、POKE、擦除、坐标翻转、PUT 和 SOUND 全挤在同一行。ligne 补充说 131 行里约 10% 是标题和版权横幅,commandlinefan 说还有近四分之一是在检查运行环境前提条件。
-
diegof79 给「我们丢掉了什么」一个更精准的答案:「丢掉的是整个技术栈的简单性。我用 BASIC 学的编程,它很糟糕,我很多年后才知道有多糟,所以我不怀念这门语言。但我怀念的是搞清楚你的机器在干什么有多容易——DOS 启动配置只涉及两个文件,CONFIG.SYS 和 AUTOEXEC.BAT,就这些。大部分程序是自包含的,把目录拷到软盘就能在另一台机器上跑。搞坏了就重新拷一遍再启动。我弄坏过很多次配置和程序,那是很好的学习方式。」ColdStream 呼应说,BASIC/QBasic 代表的是「让几乎任何人都能给计算机编程、不需要深入了解系统」的那种文化,「我不是说要回到 BASIC,但那种易上手的精神确实丢了一点。现在你得先拉进 40 个依赖才能真正开始动」。
-
GORILLA.BAS 与 NIBBLES.BAS 的怀旧洪流:gxd 解释了为什么 GORILLA.BAS 如此重要——当年电脑昂贵、游戏难得,孩子们对家长买来做文字处理的机器很好奇但无事可做,直到发现 MS-DOS 自带的 BASIC。「那时候你没法上网玩网页游戏——根本没有互联网!」pavel_lishin 补充:「乱改代码直到把它弄坏,也是极有教育意义的体验——你被迫搞明白怎么修好它,才能把游戏拿回来。」plasticchris 说自己最早的编程记忆就是改 GORILLA 代码来赢过弟弟;Induane 的第一次 hack 是关掉 nibbles.bas 的碰撞检测好穿墙;JoeDaDude 更狠——他改了办公室电脑上的 GORILLA.BAS,让对手的重力随机化,导致对方永远算不准香蕉落点,「我当了一阵子不可战胜的传奇」。
-
friarpuck 的故事是全场最好笑的:有人给他祖父一张 Games BASICA 软盘,上面的游戏被人「改造」过——DONKEY.BAS 在你撞到驴子时会骂你「YOU STUPID SONOFABITCH」。「我们觉得太搞笑了。我祖父不太高兴,发现后把盘没收了。」
-
关于比尔·盖茨的传说:sedatk 提到一个流传已久的说法——DONKEY.BAS 是盖茨在微软亲手写的最后一段代码,他好奇是否属实。ColdStream 认为这有都市传说的一切特征,「但何必让真相妨碍一个好故事呢」,并顺带评论盖茨「在技术上并不创新,但他确实把最无情的商业手法带进了软件业」。keeda 反驳说维基百科并没有这个「最后一段代码」的说法,还提醒大家别忘了盖茨学生时代发明的煎饼排序算法,那个结果 30 年没人改进。sedatk 后来找到了盖茨自己在一篇存档的微软文章里承认此事的链接,但也说不确定是否真是最后一段代码。
-
mempko 的入行故事很典型:小时候家里穷,父亲从朋友那弄来一台二手 386,他玩游戏时误按了一个键跳进 BASIC 编辑器,看不懂但开始乱改,改了一个数字后香蕉的爆炸变大了。朋友从电脑夏令营回来告诉他那叫代码。「30 年后我还在编程。」
-
bug 报告:flowofcontrol 抱怨「我明明已经开过驴子很远了,换道时车还是撞上去」。smackeyacky 一针见血地指出这不是移植的锅——「当年的碰撞检测本来就有 bug」,他甚至定位到了原始源码 1750 行那个简单的碰撞检查,确实没有判断你是否已经越过驴子。pavel_lishin 报了一个特定窗口尺寸下疯狂闪烁的渲染问题,作者当场提交 PR 修掉了。
-
marcuskaz 提出了一个哲学问题:「这游戏的博弈论全错了,这是个合作游戏,要么双赢要么双输。我不明白驴子被车撞了凭什么算『驴子赢』。」hahahaa 回敬:「Donkey 也是驴群的集合名词,所以是驴子组成的那支军队赢了。」