项目结构
Lux 的项目结构遵循一个原则:能从目录和文件名表达的信息,不强迫开发者写进配置文件。
lux.toml 只描述项目边界和少量策略;模块、运行域和 part 关系主要来自源码树。
推荐布局
目录含义:
src是 Lux 源码根目录。shared、client、server是运行域目录;最近的运行域目录决定默认运行域。inventory/这样的普通目录是模块目录。module.lux、cl_module.lux、sv_module.lux、sh_module.lux是模块入口 part。cl_、sv_、sh_前缀也能声明 part 的默认运行域。
配置文件
当前 lux.toml 支持这些字段:
路径相对于 lux.toml 所在目录解析。out 是物理输出根;runtime_base 是生成
include / AddCSLuaFile 使用的 GMod 相对路径;autorun 控制是否额外生成 addon
风格入口。开发阶段建议把 out 放到独立位置,避免覆盖手写文件。
这两个路径刻意分离:out 可以指向生成目录、live addon 的 Lua 根,或 gamemode /
框架集成路径;生成 Lua 内部仍然只写 GMod 运行时能解析的相对路径。不要把
runtime_base 当成操作系统目录或 addon 根目录。
模块发现
Lux 项目构建会递归扫描 source_root 下的所有 .lux 文件。模块路径由文件相对路径
推断:
运行域目录不会进入模块路径。文件名前缀 cl_、sv_、sh_ 也不会进入模块路径;
它只影响默认运行域。
这意味着下面三个文件属于同一个模块:
它们共享一个模块私有作用域,可以互相看见顶层声明,但仍然受运行域检查约束。
模块入口
多 part 模块必须有且只有一个入口 part:
入口 part 的职责:
- 放
part order { ... },声明完整初始化顺序。 - 放模块级导出,让公开 API 集中可见。
- 放少量共享常量或轻量工具函数。
- 作为开发者打开模块时的“主文件”。
单文件模块不需要入口 part;该文件本身就是模块。
Part 顺序
函数声明会在整个模块内提升,所以函数之间可以跨 part 互相调用。非函数顶层局部值 不会按值提升,它们按 part 初始化顺序执行。
默认顺序是入口 part 在前,其余 part 按稳定路径排序。只要顶层初始化有依赖,就应该 在入口 part 写完整顺序。
part before 和 part after 适合很小的局部约束。
不要用一串 before / after 编排大型模块。完整编排应使用 part order。
运行域推断
默认运行域来自两类信息:
目录和前缀冲突会报错:
这里最近的目录表示 client,文件前缀表示 server,编译器会拒绝它。
输出目录
GMod 后端把所有产物写到 out 下面:
autorun/my_addon.lua 只是可选 forwarder。真正的模块注册、运行域分发和
AddCSLuaFile 在 runtime_base 下的 Lux loader tree 内完成。设置 autorun = false
时仍然生成 loader tree,只是不生成 autorun 入口;已有 gamemode、框架或手写 Lua
可以自己 include 生成的 loader。
Package 根目录
通过 luxc install 安装的 package root 会从 lux.lock 自动加载。package_roots
主要用于本地 package 开发 checkout:
包内部同样使用约定目录:
运行时代码进入生成 Lua;编译时代码只在 luxc 内执行;宿主变换用于把特定领域语法
折叠成更小的运行时代码。