开发者生态
evening
56,000 行 DOOM,用我编写的语言
2026-07-16
1 阅读
约6分钟阅读
ghuntley
字号:
为什么我用自己编写的语言构建了 56,000 行《DOOM》的赌注。 bet 是一种小型的、真正的编程语言:表面上是俚语关键字,下面是一个严肃的编译器。它通过 LLVM 编译为本机代码,管理自己的内存、自托管并运行 DOOM。我将其构建为一个封闭的实验,并运行至完成。我打赌要放弃尝试制作畅销产品。我想要一个具有明显优势的项目,一个我实际上可以完成的项目,并且构建一个编译器已经在我的清单上很长时间了。一种笑话语言给了我借口:读起来像群聊的关键字,包裹在必须真正工作的编译器周围。我一开始就定下了一条规则:不做研究。我从来没有检查过是否有人之前构建过这个,因为我不想在我写下一行之前互联网就扼杀这个想法。事实证明,杰弗里·亨特利已经这么做了,我直到后来才知道这一点。一种只在语法层面起作用的语言实际上只是一种服装,所以我给了它一份真正的工作。游戏不断地分配和释放对象,手动记账和垃圾收集都会花费你无法节省的帧数。 bet 使用 arenas 来处理这个问题:分配到一个范围,将其用于一个框架,立即删除整个范围。这种模式本身并不新鲜。 Zig 提供了一个竞技场分配器,可以在一次调用中释放所有内容,而 Odin 在游戏代码中融入了相同的竞技场和临时分配器想法。我想打赌将其作为带有自己关键字的一流功能,这样该语言就会被视为自己的设计,而不是对已经存在的东西的俚语重新设计。这是一个笑话。我仍然希望它能真正做点什么。我构建它的另一个原因是进行实验。我想看看如果我不参与实施,人工智能编码代理可以在一个困难的、明确的项目上走多远。我的工作是成为架构师:我设定问题和验收标准,然后严格执行。我进行了零代码审查。仅当更改通过测试、满足验收标准并清除语料库时,才会发布。那是唯一的门。它有效的证据是《DOOM》,已完整移植。 id Software 的渲染器、游戏逻辑、WAD 加载和音频的原始 C 源代码在 bet 中被重写:超过 56,000 行,编译为在窗口中运行真正的共享软件游戏的本机二进制文件。启动它,《DOOM》就会以吸引模式自行播放。这些剪辑是游戏的原始录制输入,通过模拟重播。定点数学使其成为真正的测试:漂移一步,玩家就会开始撞墙。 bet 以与参考 C 构建同步的方式重放输入,逐帧进行,因此整个模拟结果是逐位相同的。不走捷径就能走到这一步,是玩具语言与可承载真实软件的语言的区别,也是我在从未进行代码审查的构建上最信任的结果。这样就完成了,从头到尾:编译器、自托管、文档和这个站点。这就是它停止的地方。如果收到功能请求,我会对其进行审核,但没有路线图,也没有第二版。打赌是一个笑话,也是一个实验,也是一种了解像这样的构建实际上需要什么的方法,它做到了这一切。如果我想让它表达关于我的一件事,那就是我完成了我开始的事情。我认真对待的部分内存模型才是真正的工作。手动 free() 簿记和 GC 暂停都会破坏框架预算。在打赌中,你分配到一个 crib ,一个范围在框架范围内的 arena ,并在 O(1) 内通过 evict 释放整个东西。没有每个对象的跟踪,帧中间没有停顿。 frame.bet crib wave // 此框架小队的竞技场 e in spawn(wave) { e.tick() } evict wave // 整个事情都消失了,O(1) 这就是实验。表面上是一个笑话,但实际上一个难题得到了妥善解决,而构建仅靠测试就可以完成。它编译为本机代码,自托管,并且运行《DOOM》。它从来没有打算成为一种产品,也不需要成为一种产品。完成了。它是如何建造的 时间实际去哪儿了。来自提交跟踪时间日志的实数,计算积极的工作量和空闲时间。这种限制有一个缺口:移植《DOOM》的三名代理因使用限制而停滞不前,而时钟仍在运行,因此移植游戏行运行了大约 12 小时。去掉这些,实际总数接近 22。 移植游戏 doom、oregon Trail、pong 18h 自托管编译器赌注、编译赌注 4h 安全审查 cwage 问题 #30–#48 3h 基础设施、工具和站点 ci、docker、freeze、文档 3h 前端词法分析器·解析器·语法 2h 语言和集合关键字、类型、容器 2h LLVM 后端实际的困难部分1h 竞技场内存婴儿床 · 驱逐 · 总共 29m 的点 ≈ 34h 跟踪 · 大部分都在移植游戏的现有技术 · 信用在哪里 我不知道诅咒的存在,直到赌注已经建立。 Geoffrey Huntley 首先达到了同样的想法:一种俚语关键字语言,通过 LLVM 编译,通过指导 AI 编写,
这篇文章对您有帮助吗?
订阅66必读
每日精选科技资讯,直达你的邮箱