开放世界游戏如何做好协作?
整理/秋秋&林致
今年的GDC(游戏开发者大会)上,Sucker Punch工作室的工具程序员Roland Munsil,做了一场关于《羊蹄山之魂》编剧管线的分享。

简单来说,他们给编剧做了一个编辑器,跑通了新管线。
曾经《对马岛之魂》的旧管线,需要策划手搓上万条代码,至少浪费600小时;而在《羊蹄山之魂》中,他们彻底变革工作流,让编剧、策划、制作人乃至音频团队,能在一套工作空间中协作——新工具细节到了界面上的一颗标点。
《羊蹄山之魂》的成绩有目共睹。发售两天收回全部开发成本,首月全球销量破330万份(PS5独占),总收入超16亿元,Metacritic媒体评分87,玩家评分8.5——这套编辑器管线支撑的,是一个经过市场验证的大体量产品。
对行业来说,这场分享的意义不止是怎么做一个编辑器。
开放世界仍是不少团队的主流立项方向,但世界越做越大,文本体量跟着涨,编剧、策划等岗位之间的空转和重复劳动,已经是很多大团队绕不开的协作问题。
怎么让数百人的团队少做无用功?这场分享给了一个很具体的回答。
以下为演讲实录,为方便阅读,内容有所调整:
01
不做《博德之门》
我是Sucker Punch工作室的工具程序员Roland Munsil,今天主要分享我们在开发《羊蹄山之魂》时,对剧本写作管线(Writing Pipeline)的重大重构。

先看一下我们的产品背景。
《羊蹄山之魂》是《对马岛之魂》的续作,两款游戏都是日本历史背景的开放世界动作游戏,带有电影化故事(Cinematic Story)和战斗玩法(Game play)。

同时,游戏的叙事内容占比较大(Narrative Heavy),基本上所有任务都包含大量对话。每个主线任务可能有几百句台词,哪怕是短支线也有几十句,而且任务量本身就不少——毕竟这是一个大型开放世界游戏。

不过有一点需要明确,我们不是《博德之门》(Baldur's Gate),也不是《质量效应》(Mass Effect),没打算做复杂的动态网状系统:如果你玩过这款游戏,那见过最多的对话选项,估计就是两个分支的回答,这些回答没有实质性的影响,很快就会回归主线。

02
原来的管线有多坑
首先,我们的核心团队约150-200人。其中负责对话管线的有5名编剧(Writers),12名任务策划(Mission Designers),2名制作人(Producers)。
在开发《羊蹄山之魂》的四年中,我们产出了约15万字对话和5万字文本素材。这其中,有75%是任务专属对话,玩家只会听一次;剩下25%是系统性对话(Systemic dialogue),比如战斗呼喊、商人叫卖、背景村民闲聊,可以在多个场景里重复播放。

这个体量和《对马岛之魂》几乎一模一样,因此很多做法可以直接复用。
背景介绍完毕,我们接下来聊一聊管线(Pipelines)。
在讲《羊蹄山之魂》的新管线之前,我们得先看看《对马岛之魂》的旧管线——后来做的很多决策,都是被旧流程逼出来的。
旧管线采用三方独立分工的模式(Three-way Split):
策划、程序和美术在Perforce(版本控制软件)里工作,处理代码、任务结构和资产,这是构建实际游戏的地方;
编剧在Google Docs里写剧本。策划会参照这些文档,先在游戏里搭好占位符对话(Placeholder Dialogue);
制作人则负责把Google Docs里的台词,手动录入内部的台词数据库(Line Database)。数据库里每条台词都有源文本和元数据(Metadata)。制作人再从数据库生成录音表(Recording Sheets),送去录制。之后制作人会把音频拉回数据库,这期间也可能会处理本地化。
最后,数据库定期把录好的音频、字幕和文本打上对应的ID,推送到Perforce里——这些带ID的文件,没法直接在游戏里使用。
所以这一步最坑,策划必须在引擎里,手动把每条台词的ID,挂到对应的触发器上。我估计光这一项,就浪费了策划至少600个小时的纯苦力——还没算上修改迭代和系统性对话。


编剧那边也很痛苦。我们主编剧的原话是,感觉自己就是“把剧本隔着栅栏扔过去”。
因为他们在Google Docs里写完文本就交出去了,没办法在游戏里自己测试。想改点东西,哪怕只是调换两句台词的顺序,都得找策划帮忙操作,这就导致大家看似都很忙,但效率很差。
更要命的是,编剧长期不在引擎里工作,不知道引擎能实现什么,不能实现什么——只能祈祷自己写的东西能跑起来。
此外,Google Docs、台词数据库、Perforce这三个地方的由三组人维护,数据很容易脱节,来不及同步。
策划可能在Perforce里删了一句台词,但Google Docs和数据库没更新;编剧可能在文档里加了台词,但没进数据库……最坏的情况是,一些台词已经在游戏里删了,但其他人不知道,把这些废台词送去录音、本地化后才会发现,最后钱白花了。
而且我们的剧本、录音等环节,也不是一次就能完成的,所以这种数据同步的问题经常会发生。
最后,我们对这些外部工具的控制力很有限:在Google Docs没有发言权,台词数据库又是索尼内部的小团队负责,他们无法及时响应我们的定制化需求。
03
如何让编剧“写代码”
《对马岛之魂》做完的时候,我们决定彻底改掉这套管线。
方案上很简单:不用台词数据库,让编剧直接在游戏内的实现文件(Implementation)中工作。
理论上,这能一次性解决之前的所有问题:数据源统一了;不用手动挂台词了,因为编剧写台词的过程,本身就是在完成连接;编剧直接接触底层实现,对引擎的理解也会跟上来;而且我们甩掉了外部工具,控制权回到自己手里。

但具体执行前,需要先解决两个问题。
第一个比较简单:怎么把原先存在数据库里的元数据存到Perforce里?
我们做了一种自定义文本格式,直接作为文件存进Perforce,再写代码来读写和解析。下面这张图可以看到它大致长什么样。

第二个问题就大了:怎么让不懂代码的编剧,去编辑游戏的底层实现文件?
要回答这个问题,先得解释一下我们游戏的底层架构。
游戏叙事管线的核心组件叫“对话对象(Conversation Object)”。触发该组件后,系统会自动控制角色的动作,比如头部运动和口型同步,然后逐句播放台词。

上面两张截图分别是两段对话。第一段只有一句台词,第二段有六句。每句台词都有唯一的ID,图里用红色标出来了。
第一段对话挂在NPC角色Settler_Info_Tsuri身上。第二段里,四句来自同一个NPC,另外两句来自Hero——这是我们内部对主角Atsu的代称。绿色部分则是附带台词源文本的注释。
这些对话对象是“触发即弃”(Fire and Forget)的——代码只需要启动对话,系统会自动找到角色、按顺序播放、播完自动结束,不需要额外的管理。

再看另一个稍微复杂的例子。

上面的对话涉及分支(Branching)。
玩家第一次遇到这个NPC时,他会问:“你擅长骑马吗?我需要找回一对离家出走的马。”
但如果之前已经对话过,再来找他,台词会变成:“我仍需要帮助,把我的马找回来。这活应该能赚不少钱。”这就是Branch_If :Play_Count 0的意思——判断玩家是不是第一次来。
而玩家的选项直接写进了对话结构中。选择Refuse(拒绝),跳到后面的收尾台词;选择Accept(接受),则退出对话,触发对应的任务(Mission Rigging)。
此外,对话系统还支持特殊命令(Special Commands)。比如Set Emotion可以改变角色的面部表情、Delay可以在两句台词之间插入停顿……
我说这些,是为了说明:我们的对话不仅仅是一个台词列表,它还能做分支、选择、各种控制行为,需要的话甚至可以直接触发任意脚本(s)。
而在《对马岛之魂》的开发中,这些东西全需要策划手动创建和编辑。
了解之后,我们回到之前的问题——怎么让编剧来编辑这些内容?

显然不能让他们直接面对这堆代码,编剧需要的是直接写作。所以我们需要一个前端工具,提供更友好的编辑界面——最终,我们用Dear ImGui开发了这个工具,内部叫“Sucker Punch Writing Tool”。

这个工具的截图里有很多内容,但我们只需要关注中间的脚本编辑器部分( Editor)。
首先,脚本编辑器会把对话对象文件、数据库文件组合成一个脚本给编剧,编剧看到的不再是一堆/line ID和代码注释,而是实际的台词文本。
其次,我们还将编辑器界面做成了剧本格式(Screenplay Format)。这是影视和游戏行业的标准脚本格式:角色名在上方,有特定缩进;对话在下方,是另一种缩进;中间穿插动作描述——这种格式对编剧来说非常熟悉,同时也不影响游戏原本的对话结构。
第三,我们还专门模仿了业界标准剧本软件Final Draft的操作逻辑。编剧可以用快捷键在角色名、对话、动作描述之间快速切换。这种全键盘逻辑,能让编剧能保持连续的写作节奏,不用在各种下拉菜单里用鼠标点来点去。

最后,我们没有把底层指令完全藏起来。像Delay(停顿)、动画触发器这些元素,编剧在界面上仍然看得到、改得了。

这也是我们的设计思路:工具既要对编剧友好,也要对策划有用,对话对象里的所有内容都呈现在同一个视图里,不对任何人隐藏。
04
新的工作流
现在编剧的工作流变成了这样:
策划搭好任务框架,放上占位符对话。编剧打开工具,直接修改台词,添加动作描述和表演指导(Direction)。
改完之后,编剧可以在本地编译一次游戏,走到触发点去实际听一听。
我们引擎内置了一个叫Robo Voice的功能,没有录音的台词会用类似Microsoft Sam的合成语音(TTS)来播放。听着不太自然,但能帮编剧感受对话节奏,比什么声音都没有强。
调到满意,编剧能直接将其提交到Perforce,整个过程不需要策划介入,除非要加什么复杂功能。之后交给制作人安排录音,或者由主编剧、其他同事做脚本审查( Review)。
有时候流程也会反过来——编剧先写好脚本,策划再过来拆分成对话、连接任务逻辑。但不管哪个方向,双方之间都不再需要来来回回反复交接。
除了线性剧本,这个工具还支持编辑网格对话(Gridded Dialogue)和UI文本。
网格对话就是前面提到的系统性对话,比如一群角色走向玩家时的招呼,因此我们需要用大量变体,对应不同的状态和角色。这些内容设定好之后,就可以跨场景重复播放。

UI文本编辑器则覆盖了游戏里各种类型的文本需求,让不同习惯的编剧都能在这里干活。
这条管线大约用了两年部署到位,实现了我们想要的大部分功能。而且整个项目周期里,我们一直在给它加东西,因为会不断发现新的改进空间。

先说预期之内的收益:策划再也不用手动挂台词了;大家不用再三个地方手动同步数据了;Google Docs和台词数据库也退役了,编剧和策划能统一用自己的工具了,想加什么功能自己说了算。
更重要的是,编剧的工作方式被彻底打通了。
首先,他们可以自己在引擎里测试、在本地迭代、调节奏、加停顿、改表情、设分支,不需要事事找策划代劳。以前觉得太麻烦,不好意思开口请求的小调整,现在自己动手就行了。
其次,编剧摸清了引擎的技术边界。他们每天在引擎里工作,能看到策划是怎么连接任务的,能看到底层是怎么实现的,因此写出来的东西,也更贴合游戏的实际限制。
你可能会问,那本地化该怎么办?
这是新管线里唯一的例外——本地化团队还得用旧的台词数据库。但我们写了脚本,能自动从Perforce把数据同步给他们,至少内部不再有人手动维护台词数据库了。
上线之后我们发现,这条新管线带来的好处远超最初的设想。
第一,为制作人提供了诸多便利。
一开始我们其实不确定制作人会不会想用这个工具。最初的想法是给他们做个导出到Excel的功能,再加上一些基本的元数据编辑,应该就够了。但实际用起来之后我们很快发现,直接在工具里做功能方便得多。

我们做了一个自定义查询界面(Custom Query Interface),制作人可以在里面搜索、筛选、批量修改对话。这比之前导出到Excel再导回来的流程好太多。
制作人也因此被拉进了编剧和策划同一个脚本视图里,能看到完整的上下文、分支逻辑和所有标注,对对话的整体理解更完整。
另外,我们还为录音环节做了自定义导出功能。我们每次录音要准备很多版本的材料:演员一份、导演一份、录音棚各种角色各一份……以前这些全靠手工整理,现在制作人只要设定好查询条件,就能一键导出所有格式,可以省掉大量重复工作。

第二,所有人都在同一个工作空间(Shared Workspace)里工作了:
策划和程序能看到编剧写的动作描述和情感备注,更容易理解剧情意图;
编剧能看到策划写的底层逻辑和Bug备注;
主编剧开始直接在工具里做剧本审查( Review),直接批注修改,再也不用导成Word文档了;
音频团队也进驻了,直接在里面调参数。

大家共享同一套文件组织架构(Organization Scheme),互相利用对方留下的注释和标签,形成了一个良性循环。虽然这需要大家共同维护资产,有时也难免会有摩擦,但这比之前三个团队各自独立工作要好太多了。

第三,我们在工具里加了一个粉色钻石(Pink Diamond)图标,用来显示“这段对话到底有没有在游戏任务里被触发(Hooked up)”。

需要说清楚,这跟台词本身有没有被连接是两回事,台词的连接是自动的。粉色钻石只验证有没有东西触发这段对话。
说实话,这功能是我顺手加的,有几个人提了需求,我觉得有用就做了。没想到最后成了整个工具里最受欢迎的功能之一。
对策划来说,设置一个任务的工作量很大。一个大型任务可能要创建一百多段对话,过程中很容易漏配几段,有了粉色钻石,哪个没亮一眼就看到了——而且这个东西大家都能看到,可以相互提醒。
对编剧来说,没有粉色钻石,说明游戏里没有任何东西在调用它,放心删。有粉色钻石,那就得找策划聊聊再说。
有策划曾告诉我,在做《对马岛之魂》的时候,项目接近尾声时专门做了一次大规模排查,把游戏里所有没被引用的对话全找出来,一个个连上去;而到了《羊蹄山之魂》,这件事从来没发生过。大家在日常工作中看着粉色钻石,边做边就补了。
而且这个东西的技术实现简单粗暴,但十分有效:它不用编译游戏,就是打开工具时,全盘扫描所有文本文件,查找有没有包含CONV_开头的字符串。
这意味着它会有误报(False Positives)。可能某个文件里引用了一段对话,但那个文件根本没构建到游戏里,这种误报也是难免的,你要检查也根本不可能,所以大家也能理解;
而且它不会有漏报(False Negatives)。没有粉色钻石就是绝对没被引用,可以安全删除。

第四,我们还做了一个小功能,让UI团队在游戏运行时,记录每个文本框的极限长度。
工具读取这些数据后,会在编剧写UI文本时给出视觉提示(胶囊图标)。灰色代表字数安全,红色代表超长,翻译成其他语言可能会爆框——这既帮了编剧控制篇幅,也反过来帮UI团队排查了哪些文本框的限制设得过严。


当然,我也有必要说说这个过程中踩过的坑。
首先,复杂的逻辑会严重影响剧本的可读性。碰到复杂的网状分支,比如商人NPC的对话树,剧本界面里全是逻辑跳转,一句台词都看不见(如下图),这对配音演员和本地化人员来说简直是灾难。


如果时间允许,我们会把对话单独导出成Word文档,重新梳理分支结构方便演员理解角色。但实际情况是赶工居多,演员经常连基本的台词分支都来不及捋清楚。
其次,Perforce合并冲突(Merge Conflicts)。
现在所有人都在Perforce里改同一套文件,冲突是家常便饭。有半年时间几乎所有人都在密集修改内容,我天天帮大家解决冲突,非常痛苦。

05
结语
回顾一下这次管线重构的前后对比。
以前在《对马岛之魂》里,同一份脚本散落在三个地方,我们必须手动保持同步,策划必须手动挂每一条台词。大量时间耗在搬运和对接上,编剧觉得自己的修改总是不能快速落地,这整个流程一团乱。
现在,所有人在Perforce的同一套文件上工作。我们有一个自己开发的工具,简化了每个人的工作,也让我们能快速地往工作流里加各种功能。
粉色钻石、UI字数提示这些需求,都是因为团队自己掌控工具,发现痛点就能马上做——这些功能的代码未必漂亮,但能解决实际问题。
最重要的是,编剧的能力被释放了。他们可以自己做编剧润色,不需要把活交给策划,可以自己进游戏调行为、试效果。这是整件事里最有价值的变化。
编剧也因此,把这个工具列为了《羊蹄山之魂》开发过程中最好用的工具之一。

最后想说一句,希望大家都能改善自己的管线,别再从Google Docs里复制粘贴成千上万行台词了。
游戏葡萄招聘商务经理,