Neverball 的关卡生成工具 curve.c 用了很多年,只会画一种曲线:圆弧。参数怎么调都逃不出这个形状。

有开发者做关卡时被这条限制卡住,先写了一堆脚本救急,后来把脚本整理成一个正经工具——Curveball。网页版、桌面版、GitHub 源码全公开,核心实现用 Rust。

Curveball 解决了什么,谁会用

老工具只能生成圆弧类曲线,想要别的形状只能手写脚本、手动试错。Curveball 把这些一次性脚本整理成通用生成逻辑,带可视化预览。

curve.c(老工具)Curveball
能生成的曲线只有圆弧任意 profile + path 组合
复杂曲线做法手写脚本、手动试错定义截面和路径,自动挤出
拆分 brush人工挑点,顺序不能错chull 库自动求凸包
纹理分配手动处理仍交给 TrenchBroom
使用门槛需要读源码改参数网页直接用,或下载/编译

受众很窄:Neverball 关卡制作者是核心用户,直接影响是拆 brush 的时间从小时级降到分钟级,不用再逐点核对切割顺序。对几何生成、Rust 小工具感兴趣的技术读者,能看到的是一个具体案例:怎么用凸包算法和 CAD 抽象解决一个小众但真实的工程痛点,值得参考的是思路,不是工具本身。

关卡是怎么“长”出来的

Neverball 关卡文件用 Quake map 格式,每块几何叫 brush。brush 靠平面切割半空间的交集定义,这决定了一件事:brush 必须是凸的,没法凹。

大多数曲线天生不凸。想做一条弯曲轨道,就得拆成一堆凸的小 brush 拼起来。curve.c 和作者早期脚本都靠人工挑点完成拆分,点的顺序还不能错——错了就可能切反半空间。

Curveball 换了思路,用 Rust 的 chull 库跑凸包算法,把点丢给它,自动算出怎么拆分。省掉了手工核对的步骤,代价是纹理分配变麻烦,作者索性放弃自己解决,交给专门的关卡编辑器 TrenchBroom 处理。

这里没有什么工程奇迹,只是把一个枯燥重复的手工步骤,换成了一行库调用。价值恰恰在这种“不炫技”。

从手动选点到 chull 自动求凸包 手动选点(旧脚本) 逐点核对切割顺序 顺序错就切错半空间 曲线一复杂就很痛苦 chull 自动凸包 只需给出点集合 算法自动拆出凸 brush 能快速试新曲线生成器 纹理分配仍交给 TrenchBroom

从脚本到抽象:extrusion

真正让工具从“一堆脚本”变成“一套系统”的,是作者从机械 CAD 软件(如 Solidworks)借来的思路。

定义一个 2D 截面(profile),沿一条路径(path)复制、挤出,就能生成 3D 形状。Profile 和 path 是两个独立变量,随便组合就是一种新曲线,不用逐个手写生成器。

Curveball 的核心抽象:extrusion 2D Profile 定义截面形状 沿 Path 复制 轮廓逐层平移/旋转 chull 凸包 拆成凸 brush 3D 曲线 brush 拼接完成

这套抽象也带来新麻烦:截面沿路径移动时该怎么转向。作者一开始漏算了一个自由度——挠率(torsion)。

后来用上 Frenet frame,给路径每一点定义切向、法向、副法向三个向量,靠矩阵旋转控制截面朝向。

工具没有把所有旧功能都塞进这套新抽象。它保留了三种例外实现(Curve Classic、Curve Slope、Rayto),比如 Curve Slope 的 brush 结构天生套不进 extrude 逻辑,只能单独写。这说明作者清楚抽象的边界,没有为了统一而硬凑。

这类工具真正的价值,不在名气

Curveball 不是通用建模软件,离开 Neverball 的 Quake map 格式基本没用。

它打动人的地方,是把一次性劳动升级成可复用系统。早期脚本能用,但每加一种新曲线就要重写一遍。有了 profile+path 的抽象,新曲线变成组合问题,不再是重复劳动。

“工欲善其事,必先利其器”——这句话说滥了,但放在这里恰好对症。curve.c 只能画圆弧这么多年没人动,不是需求不存在,是没人愿意花时间把工具本身重新设计一遍。

对 Neverball 关卡制作者来说,接下来最实际的动作是:想做复杂曲线轨道的,可以先去网页版试试效果,不用装环境;已经用惯 curve.c 的老用户,遇到圆弧就没必要迁移,遇到非圆弧形状再切过去。对关注 Rust 小工具和创作者工具链的技术读者来说,这个案例值得记的不是 chull 或 Frenet frame 本身,是那种“先攒脚本、再抽象成系统”的路径——这是大多数个人工具从能用走向好用的common path。

这也是开源生态一个老问题的翻版:真正被长期使用的工具,往往不是团队立项做出来的,是某个用户自己被卡住了才顺手补上的洞。

Curveball 能走多远,不取决于它写没写好,取决于作者接下来还愿不愿意为自己的关卡继续填坑。纹理适配、后续维护这些边角问题,一旦作者失去兴趣,工具很容易停在半成品状态——这是所有个人开源工具共享的风险,Curveball 也不例外。