How is Zig working out after 3 years and 100k lines of game code?

Lobsters Hottest 新闻

摘要

经过3年、10万行Zig代码的游戏开发实践,Zig作为游戏逻辑层与C++引擎混用表现出轻量高效的开发体验,尽管语言尚未稳定,但积极变化远大于不便。

<p><a href="https://lobste.rs/s/q8eiqk/how_is_zig_working_out_after_3_years_100k">Comments</a></p>
查看原文
查看缓存全文

缓存时间: 2026/07/05 10:30

**TL;DR:** 经过3年、10万行Zig代码的游戏开发实践,Zig作为游戏逻辑语言表现出轻量、高效、舒适的开发体验,尽管标准库和语言仍在变化中,但积极变化远大于不便,特别适合与C++引擎混用。 ## 背景与项目简介 大家好,我是Medical的Sebastian。很久没做视频了,因为一直在埋头开发《Traction Point》——就是现在看到的这个白盒阶段的游戏。今天想聊聊Zig这门编程语言,因为经常被问到:“用Zig做游戏到底怎么样?开发体验如何?”之前我不太想回答,因为那时我还没用Zig交付过正式产品,Zig也还没到1.0。但现在很多非常大型、成熟的代码库已经用Zig编写,所以我觉得可以聊聊了。 我的项目即将发布pre-alpha 4版本,作为一个Steam试玩版。现在已经超过10万行Zig代码(我知道讨论代码行数有点傻,但至少能让你对规模有个概念)。我觉得现在对用Zig做游戏这件事,多少有点发言权了。 ## 我是怎么开始用Zig的 大多数人知道Zig是因为它出色的C语言互操作性——你可以直接把一个C库丢给Zig,Zig会吃进去、编译、使用,一切完美。但我在《Traction Point》里基本没用这些功能,因为我把Zig和一个叫Basis的C++游戏引擎结合使用。 2019年我了解Zig时,已经在Basis上工作了大约10年。那是一个相当成熟的引擎,带有关卡编辑器、完整的资源管线等。我不想扔掉它,也不想非得用C++写游戏逻辑(C++太复杂,有历史包袱和复杂的构建系统)。我想找更简单的语言来写游戏逻辑——可以大量迭代、写起来有意思的语言。我觉得Zig就是那种语言。 于是我在Zig和Basis游戏引擎之间做了一个绑定层。2019年Zig还不够稳定,所以没怎么推进。但到2023年我开始做《Traction Point》时,绑定层已经相当完善了。于是决定:好,我们要用Zig来做这个游戏。现在代码库是C++和Zig混用,C++代码大概是Zig的两倍(未精确统计),还不包括外部库(比如物理引擎Fusex)。 ## 语言稳定性:房间里的大象 Zig仍然不稳定。这对我有什么影响?我认为需要分成两类:语言变化和标准库变化。 - **语言变化**:几乎全都是积极的。偶尔有语法小改动,需要查找替换某些函数调用或细节。但几乎所有改动之后代码都变得更好了——更简洁、更容易推理。有时Zig的格式化工具还能帮我自动搞定,只需要保存文件,它就会自动转换一些东西。非常棒。 - **标准库变化**:稍微麻烦一些。特别是构建系统(用Zig编写,使用Zig脚本),那里的API偶尔变动,在文档更新之前要搞清楚怎么修复并不明显。 我一直尽量紧跟Zig的master分支,完全是我自己的选择。一旦知道他们下一步要做什么,我就不太想停留在某个发布版上。我想提前准备,这样将来不得不更新时不会一次性要修补一大堆东西。这意味着时不时会有小问题出现,但没什么能让你打退堂鼓。如果你有点动手折腾的精神,应付这些小问题完全不是问题。 ## 日常开发体验:轻量、舒适、小巧 写Zig的感受可以用“轻量、舒适、小巧”来描述。你想新建一个文件,直接建一个`new_file.zig`就行。放一个声明:`thing = 1`,然后在某处`import new_file.zig`,输入`thing.`就能看到thing在那里。没有项目文件,没有需要重新生成的CMake脚本,一切都很简单。 开始用Zig只需去ziglang.org下载Zig本身(可以先从稳定版16.0开始,如果你想冒险可以下载master)。它会给你编译器、标准库和整个工具链。然后安装ZLS(Zig语言服务器),如果你用的是VS Code,Zig扩展可以帮你自动安装ZLS。这三样加起来就给了你写Zig代码所需的一切,无论你在Windows、Linux还是Mac上。而且它比Windows上的Visual Studio(好几个GB)小得多得多,快速又轻量。 在《Traction Point》中,我使用组件模型(类似Unity的MonoBehaviour,但只是类似)。比如有一个轮胎痕迹组件,用Zig写,用来在车辆后面绘制轮胎痕迹、擦除草地等。它是一个结构体,包含一些声明、非公开内部结构体、字段和函数。代码里到处都是`_`这样的行。我有个代码片段专门用来添加它们。 ## 几个可能让你惊讶的地方 ### 没有运算符重载 如果你是从C++过来的,Zig里完全没有运算符重载。例如,数学代码中,`state_info.contact_point`是一个三维向量,要相加只能`a.add(b)`,或者用自由函数`add(a, b)`。如今Zig对SIMD向量类型有很好的支持,可以直接用`@vector`并给定长度,比如`const ve3 = @Vector(3, f32)`,SIMD向量支持标准数学运算。但我当初搞绑定层时SIMD向量还不稳定,所以没用。如果从头开始,我可能会用SIMD向量配合自由函数`dot(a, b)`。Zig gamedev里有一个zmath SIMD数学库,基本能处理这些。记住:Zig没有运算符重载,刚开始可能有点遗憾,但现在已经很习惯了。 ### 未使用参数必须显式忽略 Zig会警告未使用的函数参数。你必须用`_`显式忽略。例如: ```zig tick(self: *Self, _tick_delta_time: f32) void { // 未使用tick_delta_time } ``` 如果去掉`_`,编译器会报错。ZLS会自动修复,加上`_`并添加注释。这设计思路是:如果你本应该在某个地方使用`tick_delta_time`,但忘记用了,ZLS会帮你在保存时自动去掉忽略号(如果你后来使用了它)。这几次救了我,当我犯复制粘贴错误,没使用传入的参数时。 但初次使用时会觉得有点烦人:新建一个函数,加几个参数,保存后它们全变成了`_`。不过你可以先留着它们,然后写`const s = a + @intFromBool(b)`,保存时忽略注释会自动消失。现在我已经习惯了,还挺喜欢这种工作方式。 ## 总结 用Zig做游戏,特别是作为游戏逻辑层与成熟C++引擎混用,体验非常好。虽然语言尚未稳定,但积极的语言变化和轻量的工具链让开发很愉快。标准库偶尔有变动,但完全可应付。如果你想尝试用Zig做游戏,可以从ziglang.org下载,配合ZLS开始写代码。我在Steam上发布的试玩版《Traction Point》就是最好的证明。 --- Source: [YouTube视频](https://www.youtube.com/watch?v=HXpUShkr2VQ)

相似文章

重返Zig

Lobsters Hottest

作者描述了从Zig到Rust再回到Zig的历程,探讨了编程语言中稳定性与表达力之间的权衡。

Zig 示例教程

Hacker News Top

通过带注释的示例,对 Zig 编程语言进行实践性介绍,涵盖从基础到高级的主题。灵感来源于 Go by Example。

Zig 构建速度正在提升

Mitchell Hashimoto

Zig 0.15 相比 0.14 在编译时性能有显著提升,构建脚本编译时间从约 7 秒降至约 1.7 秒,完整构建时间从 41 秒降至 32 秒,且仍使用 LLVM。本文重点介绍了自托管后端和增量编译方面的进展。

2026 年的 Zig 与 Rust

Lobsters Hottest

本文在 2026 年的背景下对比了 Zig 和 Rust,认为编程代理通过自动化生成 Rust 代码,削弱了 Zig 在人机交互体验上的优势。