用 Zig 编程
Turian 使用 Zig 编写,你的游戏脚本也使用 Zig 编写——同一门语言,同一个编译器,无需学习绑定或 DSL。
兼容的编辑器
Zig 通过 Zig Language Server(zls)获得编辑器支持:
| 编辑器 | 设置方法 |
|---|---|
| Zed | 内置 Zig 支持——安装 Zig 二进制文件后 Zed 会自动检测。 |
| VS Code | 安装 ziglang.vscode-zig 扩展。 |
| Neovim | 使用 zls 配合你的 LSP 配置。 |
| Helix | 内置 Zig 支持。 |
| IntelliJ | Zig 插件提供语言支持。 |
所有编辑器都由同一个 zls 驱动,因此无论你选择哪个编辑器,都能获得自动补全、转到定义、悬停类型和内联错误提示。
Zig 基础
Zig 是一种通用系统编程语言,没有隐藏的控制流、隐藏的内存分配和垃圾回收器。你将遇到的关键概念:
结构体作为构建块
没有类。组件就是一个普通的 struct:
pub const Health = struct {
pub const is_component = true;
max: f32 = 100.0,
current: f32 = 100.0,
};
pub const is_component = true; 标记告诉引擎将这个结构体视为可以附加到场景节点的组件。没有此标记时,该结构体只是一个普通的 Zig 类型——对内部数据有用,但对编辑器和组件系统不可见。
Comptime
Zig 模糊了编译时和运行时的界限。comptime 关键字让你可以在编译期间运行任意代码——Turian 利用它进行组件发现、GUID 解析和零成本抽象。
无隐藏分配
std.heap.GeneralPurposeAllocator、竞技场、栈分配器——由你选择。引擎通过 Frame 上下文提供分配器,以便脚本无需猜测即可分配内存。
错误处理
错误是值,而非异常。函数返回带标签的联合体:
const file = try std.fs.cwd().openFile("config.json", .{});
defer file.close();
Turian 脚本中的 Zig
你的游戏代码位于项目 assets/ 文件夹中的 .zig 文件内。每个文件可以导出一个或多个组件结构体。编辑器解析你的源代码(而非正则表达式)以发现 pub const is_component = true 标记——只有带此标记的结构体才被视为组件。
引擎作为一个模块导入:
const engine = @import("engine");
这让你可以访问 engine.Vec3、engine.Time、engine.Frame、engine.GameObjectRef 以及所有内置类型——与引擎本身使用的 API 完全相同。用户代码和引擎代码之间没有抽象层。
请参阅教程了解编写第一个组件的详细步骤。