Verse Wiki — 写给蓝图作者的 Verse 手册
拔高 · EXTRA

为什么文本比节点图更适合 AI:diff、review 与版本控制

主课下了一个结论:文本能被机器处理,节点图不能。这一页把结论拆开,讲清楚机制——行级 diff 与三方合并到底怎么工作,二进制资产为什么只剩「锁文件」一条路,代码评审的粒度差在哪,以及为什么语言模型处理文本的能力远好于处理图结构。

一、「行」是原子单位:diff 与三方合并

先看 diff。给定同一个文件的两个版本,diff 工具要解决的是一道很具体的题:找出一份最短的编辑脚本,把旧版变成新版。经典解法(Myers 于 1986 年给出的算法,今天仍是 git diff 的默认路线)把每一行当成一个不可分割的符号,先求两个版本的最长公共子序列,剩下的就是删除与新增。

注意这里的前提:存在一个稳定、可对齐的最小单位。行就是这个单位。行有明确的边界(换行符),有明确的顺序,而且——这一点最关键——大多数改动只影响少数几行。你改一个变量名,文件里其它 200 行原封不动,于是 diff 输出是 2 行红、2 行绿,而不是「整个文件都变了」。

合并是 diff 的延伸。Git 的默认做法是三方合并:除了你的版本和对方的版本,它还去找两条分支的共同祖先。有了这三份,每一块改动都能被归类:

于是就有了那个很实在的结果:你在 door_controller.verse 里改 OnBegin,同事在同一个文件里改另一个函数,合并是自动的,谁都不需要等谁。冲突只发生在你们改到同一块的时候——而这时候你也不是二选一,你能看着三个版本,把两边的意图各取一半,拼出第三种写法。

二、二进制资产为什么只剩「锁文件」

现在把同样的题目交给一个 .uasset。它是一个序列化后的对象包:文件里有包头、名称表、导入表与导出表,还有大量指向文件内部位置的偏移量。你在 Details 面板上改一个默认值,可能只改动了几个字节;但你新加一个节点、改一个变量名,序列化出来的结构就变了——名称表多一项、导出表的条目大小变了,后面所有偏移量跟着位移。

对文本 diff 工具来说,这等于「整个文件都变了」。它没有可对齐的最小单位:二进制里没有行,而字节这个单位太细,细到失去意义——两个字节相同不代表它们是「同一样东西」。没有稳定的最小单位,就没有可归类的改动块;没有可归类的改动块,三方合并的四条规则一条都用不上。

那 Blueprint Diff 工具算什么?它确实能比较两个蓝图版本,但它走的是完全不同的路:它把两份资产分别反序列化回内存里的对象图,再在图的层面上比较,把结果画成一个界面给你看。这解决了「看」的问题,没解决另外两个问题:

所以团队最终都会落到同一个做法:独占签出——Perforce 里给资产文件设成独占锁定,Git 项目里用 Git LFS 的 lock 机制。签出即上锁,一个人改的时候其他人只能等。这不是流程设计得保守,这是格式本身没有给出可合并的粒度,只好用「同一时间只允许一个人改」把冲突从根上避免掉。代价你已经知道了:并行度归零,而且忘了解锁的人会变成团队公敌。

三、评审的粒度:结论能不能留下来

合并的问题很显性,评审的问题更隐蔽,但影响更长期。

文本评审的最小单位也是行:评论挂在具体某一行上,「这里为什么不用 if 包住?」这句话和它指向的那一行绑定在一起,随着文件一起被保存、被检索、被后来的人读到。半年后有人问「当初为什么这么写」,答案就在那一行的评论里。

节点图的评审只能是「你打开来,我在旁边看一遍」。它有两个致命属性:结论无法定位(你只能说「那个 Branch 后面那块」),结论无法归档(说过就散了)。而评审的真正价值从来不是抓 bug——是知识传递。留不下痕迹的评审,等于没有发生过。

把 AI 放进这个位置,差距会被放大一次。一个能读 diff 的助手可以对着 8 行改动说「你这里少了一个失败上下文」;而面对一份「这个 .uasset 变了」的版本记录,它连你改了什么都不知道。AI 能参与的评审,和人能参与的评审,受限于同一个东西:改动有没有一份可读的表示。

四、为什么模型处理文本远好于处理图

这一节回答一个更基础的问题:为什么语言模型对代码这么在行,对节点图却基本使不上劲?三个层面。

第一,输入形状对得上。模型吃的是 token 序列。文本天然就是序列,喂进去是一一对应的、零损耗的转换。图结构不是序列,要喂给模型必须先线性化成某种写法——邻接表、DOT、JSON 都行。麻烦在于线性化不唯一:同一张图,节点先后顺序换一下、内部标识符换一批,就是完全不同的一段文本,而它们表示的是同一件事。模型得先学会「这些写法等价」,这是白白多出来的一层负担。

第二,语料量差着好几个数量级。这一条其实比第一条更决定性。公开可训练的文本代码以亿行计,而公开的节点图数据几乎不存在——它们躺在各家公司的私有仓库里,以二进制形式。模型的能力来自见过的数据;没见过的东西,它就是不会。

第三,输出侧同样卡住。模型的输出也是 token 序列,而源代码恰好就是 token 序列——它可以直接把答案写出来,你直接粘回去就能编译。要输出一张节点图,它得先输出某种序列化格式,再由一个工具把它还原成资产:多一层转换,就多一层出错的机会,还多一个「这个工具存在吗」的前提。

这三条合起来还有一个具体后果,值得单独说:对文本,模型能做局部编辑;对图,它只能整份重来。「把第 24 行的 set 挪进 if 里」是一个精确、可验证、可回退的操作。而生成一张图没有「局部」可言——它只能重新生成整份,于是你连 diff 都做不了,只能整份接受或整份拒绝。这就绕回了本页的第一节:一切都取决于有没有一个稳定的最小单位。

五、那 Visual Verse 来了会怎样

一个合理的疑问:Epic 已提及会给 Verse 做一个可视化脚本层(社区称之为 Visual Verse),形态尚未公布。如果将来又能连线了,这一页讲的优势是不是就白讲了?

先把话说明白:它的形态没有公布,所以下面是推断,不是消息。但推断的依据很硬——Verse 是一门文本定义的语言,它的语法、语义、编译流程都建立在源文本之上;而 Scene Graph 是从零基于 Verse 构建的。只要可视化层是Verse 的一层视图而不是另一套独立的资产格式,那么磁盘上躺着的仍然是 .verse 文本,diff、三方合并、行级评审、AI 读写这四样一样都不会丢。

这个模式在别处很常见:网页的可视化编辑器背后是 HTML 与 CSS 文本,界面设计工具生成的也是可读的布局文件。「用什么方式编辑」和「以什么格式存储」是两个独立的决定,而决定命运的是后者。蓝图当年把这两个决定绑在了一起——画出来的东西,直接以二进制资产的形式存下来——今天所有的麻烦都源于此。

所以这一课真正的落点不是「别用节点图」。节点图有它无可替代的优点:上手快、结构一眼可见、非程序员也能读。这一课的落点是:你的逻辑最终以什么格式躺在磁盘上,决定了未来十年有多少工具能帮你干活。文本这个选择看起来朴素,但它是那个让版本控制、代码评审、自动化和 AI 全部可用的选择——而且它一直如此,在 AI 出现之前就如此。

六、小测验

团队里两个人同时改了同一个 .uasset,为什么工具没法像合并文本那样自动合并?

来源

Verse 的语言事实参见 Epic 官方文档:Verse Language Quick Reference(官方文档)↗

关于可视化脚本层:Epic 已提及会为 Verse 提供可视化层(社区称 Visual Verse),形态尚未公布;本页第五节的推断已在文中标明为推断。关于蓝图:Actor 与 Blueprint 在 UE6 Early Access(官方路线图目标 2027 年底)及早期版本中完整支持,弃用需等 Scene Graph 足够成熟、时间未定;Epic 已承诺在弃用前提供转换工具,但尚未发布