第 5 章

第一份设计文档

杭州网易大厦B座十三层的灯光在2021年1月第二个周四的晚上亮到了凌晨一点十七分。监控录像显示,保洁员在零点四十分推着清洁车经过1308会议室门口时停了一下。门缝里传出争执声,一个女声说了句“你不能把附录当护身符”,然后门被从里面拉开,沈明远走出来,手里攥着一叠A4纸,径直走向走廊尽头的吸烟区。他没有点烟,在吸烟区站了十二分钟,然后折返会议室,重新把门关上。

那叠A4纸就是后来被团队成员称为“六十一页”的文档——编号P3-YANYUN-DOC-2020-0117,文件名《燕云十六州历史考据与世界观设定框架(v1.2)》。

但当晚真正的主角不是这份文档,而是一份比它薄得多的文件。代号“朔风”的可玩原型,版本号0.1.4,构建于2021年1月11日,文件大小3.7GB。它在1月14日下午三点的内部演示中跑完了自己的全部内容——四十三分钟的单人剧情流程,七处可探索的兴趣点,一场据点战斗。

演示结束时,观场安静了大约五秒钟。然后美术总监李想从前排座位上站起来,走到投影幕布前,用手指戳着画面一角那个积雪覆盖的城楼剪影,说了句:“这不是又一个《逆水寒》资料片。”

这句话在一周之内被重复了不下二十次。陆离在演示当晚给事业部副总裁发了条消息,措辞克制,只说“朔风切片反馈正面,申请按原计划推进八月评审”。但他在消息发出去之后,把手机翻过来扣在桌上,对坐在对面的方瑾说了一句话:“现在最难的部分来了。”

方瑾没接话。她在看投影幕布上静止的画面——朔州城南门外的雪地上,一行马蹄印延伸向灰色天际线。这张概念图她已经看了三个多月,但第一次在引擎里跑出实机画面时,她还是感到某种陌生的重量。

那不是好看。好看是意料之中的。陌生的东西是,这个画面让她产生了一种“在别处”的感觉——一个模拟信号,暗示这个虚构的蔚州可能真的存在过。

这种感觉只持续了不到二十四小时。1月15日,复盘会。1308会议室,下午两点到六点。没有午餐,没有茶歇,陆离提前在邮件里写了三个字:不设限。

会议的座位安排不是随机的。陆离坐在长桌短边,投影幕布在他身后。右手边依次是方瑾、沈明远和战斗系统负责人郑岩。左手边是技术负责人韩哲、角色美术组长和负责UI设计的外包协调员。这个座位序列意味着立场光谱:右边是世界观和叙事,左边是技术和实现。陆离坐在中间,需要同时面对两边的火力。会议从韩哲打开一份表格开始。表格分四列:测试机型、场景、帧率峰值、帧率最低值。

测试机型三款,覆盖了目标用户的最低配置、主流配置和最高配置。数据在三款机型上呈现出同一个趋势:进入蔚州城门外的主路区域后,帧率维持在可接受范围内;玩家视角转向台地方向时,帧率开始波动;进入战斗场景后,主流配置机型掉帧至每秒十八帧以下,最低配机型出现可感知的卡顿。“雪景是这个切片的视觉核心,”韩哲说,他没有抬头看屏幕,而是对着自己的笔记本电脑,“但雪的粒子密度、光照反射和脚印解算,每一项都在吃资源。我们现在的做法是把所有雪的渲染放在一个图层里,和地形一起加载。如果玩家只是在主路上走,没问题。但只要他转一下视角——”

他在键盘上敲了一下,投影幕布上切出一个技术示意图。图被几条线分成四个象限,分别标注着地形加载、粒子特效、光照计算和物理碰撞。每个象限里都有一根红色横线,标示着当前版本实际占用的算力预算。除了地形加载象限之外,其余三个象限的红线全部越过了预算标的黄线。“这不是优化能解决的问题,”韩哲把话说完,“这是技术选型的问题。弥赛亚引擎在处理大场景雪景渲染时没有现成的模块。我们在做的事情不是调参数,是写底层。”

方瑾在会议记录里标注了韩哲的判断。她的笔记在两个月后成为技术预研复盘的重要依据,但在当时,这句话的份量在于它直接触及了一个被回避了三个月的问题:团队选择蔚州作为第一个切片,理由之一是雪景可以“覆盖细节”——用视觉冲击力弥补内容密度的不足。但现在雪景本身就是最大的技术负债。

沈明远在韩哲说完之后做了第一次发言。他没有回应技术问题,而是把话题拉回了世界观层面。他在白板上画了一条横线,线上方写“朔风切片已完成的历史元素”,线下方写“未收录的历史元素”。上方有驿站制度、边关贸易、户籍分类——都是他在六十一页文档中详细论证过的核心机制。下方则列着他放进附录的那些内容:田赋税率、徭役折算、两属户土地分配、契丹盐铁禁运对边市价格的影响。

“这次切片的四十分钟流程里,”沈明远说,“玩家从头走到尾,接触到的是驿站和边关两个系统。但这两个系统运作起来的逻辑,在代码里靠的是数值表和触发器。田赋没有体现,户籍没有体现,盐铁禁运也没有体现。

一个玩家在蔚州雪地里打完这场战斗,不会知道这个村子里住的是因赋税逃亡的两属户,也不会知道他路过的那个废弃驿站之所以废弃,是因为两年前朝廷裁撤驿路、徭役折钱之后驿丁逃亡。”

陆离在这个节点打断了他。“你想说的结论是什么?”

“结论是,这份切片在历史还原上的刻度,比它看起来要浅。”沈明远停顿了一下,“但这不是切片的错。四十分钟装不下。”

郑岩从长桌另一侧接过了话头。他的声音在整个会议过程中始终保持在同一个音量和同一个语速,没有明显起伏。“容我说一句,”他说,“四十分钟装得下的,是战斗。战斗系统在蔚州切片里只有一场据点战,一场。我们在做战斗设计的时候,沈明远给过我一份据点守军的编制表——宋军步人甲十二人,弩手六人,什长一名。编制是准的,但打起来一点都不像历史。”

他打开自己的演示视频,拖到战斗部分。“玩家冲进据点之后,AI的反应模式是标准的索敌逻辑——进入视野范围,判定威胁等级,进入战斗状态。玩家砍倒前三个人之后,剩下的辽兵继续按既定逻辑战斗。他们没有逃跑的判定,没有投降的判定。一个宋辽对峙年代的据点战斗,打到最后要么是宋军全灭,要么是辽军全灭。这不像边关冲突,这像刷副本。”

沈明远在笔记本上写了几句。他的字迹很轻,铅笔划过纸面的声音几乎被空调出风口盖住。后来证实的会议记录显示,他写的是:“战斗AI的行为树需要加入溃散阈值——基于什长存活状态、伤亡比例和地形劣势的复合判定。”

但这个在会场上写下的方案,最终没有进入朔风切片的后续迭代。它的命运和附录里的田赋税率一样:被认为在当前的资源约束下不可实现,被搁置到“完整产品阶段再考虑”的清单里。

李想在下午三点四十分进入会议室。他之前一直在美术团队的工位上处理另一个项目的美术需求交接——听说是《逆水寒》新资料片的场景美术,但具体内容他没有在会上提。他带进来一台iPad,屏幕上是一组对比图。左边是蔚州切片的雪景材质截帧,右边是一个沙漠场景的材质测试。两边的格式完全一样:地表材质的分层结构、光照反射率、颗粒度参数、显存占用。表格很干,但他讲的方式让在场的每个人都听明白了。

“雪景材质的开发周期,从第一版到当前演示版本,是十一个工作日。但这不是全部工时。”李想用手指划过表格里的“资产复用率”一栏——0%。雪景专用的地形材质、建筑覆雪模型、角色脚印贴图,和团队已有的AAA级场景材质库之间没有共享通道。

而沙漠场景的测试数据来自另一个团队使用的通用地形模块,从草地、泥地到沙地的切换可以通过参数调整实现,工件复用率在百分之六十以上。“燕云十六州不会永远下雪,”李想说,“蔚州的雪是好看的,但蔚州只是十六个州中的一个。我们如果要在朔州城里做春天,或者在应州的山谷里做秋天,目前的雪景材质管线没有办法平移。到时我们要从零开始再做一遍。”

这不是一个美术问题。这是一个生产管线问题。如果每个州的美术资产都是独立的、不共享的,那么做完全部十六州的成本将是任何一个事业部都无法接受的数字。即使项目拿到了下一阶段的预算,这个管线结构也会在后来成为定时炸弹。陆离直到此刻才开口。“我们现在要做一个决定,”他说,“朔风切片要不要在八月评审之前做一次大幅调整——换掉蔚州,重新选一个州。”

会议室里的安静大约有十秒钟。这十秒钟里,每个人的反应方式都是不同的。方瑾把笔放下,沈明远翻回文档的第一页,韩哲摘下眼镜擦了擦,郑岩依旧用同样的语速说:“换不换,战斗AI的问题都在那里。”

最先打破沉默的是沈明远。“换州不能解决历史考据层面的问题,”他说,“蔚州暴露的不是蔚州的问题。是叙事框架的问题。我们至今没有在文档里写清楚过,单人剧情和多人生态之间的关系是什么。玩家在单人剧情里走完这四十分钟,他进到多人模式之后,这个世界到底怎么回应他?他是扮演这个世界的某个角色,还是这个世界帮他重新生成一个角色?如果他不做剧情直接进多人,他的世界是怎样的?”

他停顿了一拍。“这个问题不回答,换哪个州都一样。”

方瑾在这次会议上只说了三次话。第一句是在韩哲展示帧率数据时,她问了一个问题:帧率波动的节点是否和玩家视角转向台地的角度相关?第二句是在李想展示材质对比时,她问沙漠场景的通用模块是否可以直接嫁接到现有引擎分支上。第三个问题是在沈明远说完之后。“单人剧情和多人生态的衔接,这份文档里缺一张图。缺的不是世界观架构图,是一张逻辑流程。玩家从A状态到B状态,中间经过什么判断节点,失去什么获得什么保持什么。如果没有这张图,我们所有的原型都会是切片——好看的切片,但拼不成一张图。”

陆离在白板上用马克笔画了一个空白的方框。居中,大概手掌大小。“这张图,”他说,“在八月评审之前必须补上。不只是补上,要跑通。跑通的意思不是纸面逻辑说得通,是有可验证的原型可以跑。评审委员会不是来看世界观架构的,他们是来看产品化能力的。一个四十分钟的蔚州切片可以证明我们有能力做一个美丽的切片,但证明不了我们能做一款产品。如果八月份我们拿出的第二个切片仍然只有四十分钟,仍然只有单人流程,仍然没有多人生态的验证——”

他没说完。不需要说完。会议的第四个议题是本该在第一轮讨论中就被点燃的引信。但发言顺序调整了,这个问题被推到后半程才浮出水面:移动的代价。玩家在蔚州切片中的移动,绝大部分时间是马匹骑行。主路沿着桑干河河谷延伸,地形约束了行进方向,但马匹的体力消耗、骑行速度曲线和地形起伏之间的匹配关系,在当前的版本里是由两组独立的参数分别控制的。体力的衰减只看时间,不看坡度。骑速的变化只看玩家的按键力度,不看路面的摩擦系数。地面上的雪、冰面、碎石和泥地对移动速度的影响,全部没有被纳入计算模型。

方瑾在PrototypeReview_Snowstorm_0115的服务器日志里找到了移动测试的原始数据。四十三分钟的剧情流程中,玩家从朔州南门到据点战斗结束,马匹骑行的路段累计用时约二十一分钟。

在这二十一分钟里,移动速度曲线有三十四段明显波动,其中二十八段是玩家操作引起的加减速,只有六段来自不同地表材质对移动速度的被动影响——而这六段全部是手动触发器模拟出来的效果,不是物理引擎的自动计算。“这意味着现在版本里的移动,是视觉层面的移动,”方瑾说,“玩家看自己在雪地上骑马,看马蹄印在身后延伸,但马蹄陷进雪里的深度、转弯时的侧滑概率、上坡时的爬升阻力——这些影响移动手感的关键要素,我们全都没有做。现有的移动手感和在平地上骑马没有差别,雪景是背景布。”

郑岩在战斗设计的测试中印证了这个判断。据点战中,玩家下马进入步战,移动模式从骑行切换为行走。理论上,雪地行走应该比平地行走更慢、更耗费体力,但在当前版本中,切换后的移动速度曲线和平地场景完全一致。唯一的不同是视觉效果——雪地上多了行走时留下的脚印贴图。“如果雪只是画面,不是机制,”郑岩说,“那蔚州为什么非要是雪?”

这句话问到了根上。团队选择蔚州的初始逻辑是:雪景在视觉上足够震撼,在内容密度上可以做减法,在三个月内可以交出合格答卷。但如果雪只停留在视觉层面——如果它不是地形、不是移动阻力、不是战斗变量、不是生存要素——那它的存在就退化为一张高分辨率的壁纸。它好看,但和游戏本身的关系是浮在表面上的。

当这个判断在会场上被明确说出之后,沈明远在笔记本上又写了一句话。他写的是:“如果雪只是画面不是机制,那历史考据也只是一层皮肤。”这句话后来没有出现在任何一份正式文件里,但它出现在了方瑾那本周记的页脚——她引用这句话的时候没有标出处,只写了“有人在会上说了这么一句”。

会议的最后阶段是断裂的。不是争吵意义上的断裂,是议程意义上的断裂——时间到了六点,但还有三个议题没有展开:多人生态的验证方式、引擎中间件的授权费用、以及下一阶段的人员招聘计划。

陆离宣布散会,但这些没有展开的议题并没有消失,它们在随后的两周内各自演化为独立的子会议,消耗掉了团队本应用于迭代朔风切片的大量精力。方瑾在会议记录的最后一页写了四项“待决策事项”,每一项旁边都标注了期限:逻辑流程图(1月30日前)、移动系统技术方案(2月6日前)、美术管线复用性评估(2月6日前)、多人模式验证范围(2月13日前)。她在这页纸的顶端加了一行备注:“上述四项均需在八月评审前至少完成一轮内部验证,否则不满足产品化评审的基本门槛。”

这些期限和门槛,在当时的时间表上看起来足够充裕。八月评审还有将近七个月,七个月足够做完这些事——只要一切顺利。但“一切顺利”这个前提,本身就是一个奢侈的假设。

复盘会结束后的那个周末,陆离一个人回到会议室,把投影仪重新打开。幕布上是“朔风”原型的结束画面——蔚州山间的碉堡残骸上,一轮冷月悬在雪线之上,玩家的角色站在碉堡废墟中央,远处是契丹游骑退去的马蹄印记。四十分钟流程的最后一个镜头。陆离在这个画面前坐了近一个小时。他没有动手修改任何东西,也没有写邮件,没有打电话。他只是反复回放从碉堡战斗结束到这一幕定格中间大约两分钟的演出段落——一个在任务完成后站在废墟上回望来路的角色,身后是桑干河河谷里那片他们用三个月时间建造出来的十二平方公里的蔚州。

然后他把画面切换到项目总览图。那是一张巨大的表格,贴在白板上,用不同的颜色标记了十六个州的开发状态。蔚州是绿色的。绿色的格子里用马克笔写着一个词:已完成。但绿色之外,其余十五州的格子是灰色的。

不是计划中的灰,是空白的灰。没有概念图,没有白盒地形,没有据点设计,没有剧情大纲。朔州和应州有两行备注,写的是“考据数据初步到位”,其他州甚至连备注都没有。方瑾在复盘纪要的附录里贴了一张这张表格的照片。照片拍的不全,只拍到表格的左上角,蔚州那个绿色格子在画面最边缘。她在这张照片下面写的说明文字是:“原型切片展示的完成度,与产品整体进度的完成度,存在结构性落差。蔚州切片证明了团队有能力打造单州体验,但无法证明整套管线和架构足以覆盖十六州。”

韩哲在散会前做的最后一件事,是把那张技术示意图的源文件发给了陆离。邮件正文只有一行字:“这不是调参数的问题。”附件是一个用红框标出的引擎渲染管线节点图。红框圈在“全局光照-雪地反射”和“粒子系统-LOD”两个模块之间。在两个模块的连接线上,韩哲用鼠标画了一个手写的问号。

这个问号的意义,技术团队之外的人要到三个月之后才完全理解——弥赛亚引擎在处理大规模动态粒子与复杂光照模型的交互时,没有自动化的细节层级管理系统(LOD)。在其他AAA项目中,雪景要么是静态的,要么是小范围的。但蔚州切片里的雪是动态的,覆盖十二平方公里的地形,玩家走到哪里雪下到哪里。这意味着引擎必须同时 在每一帧判断每一片雪花的LOD层级。

没有现成的算法,韩哲团队只能手写一个简化模型。而手写的简化模型,在技术评审中被认为“在高负载场景下不可靠”。这句话翻译成非技术语言就是:如果未来把蔚州切片的雪景逻辑原样搬到多人在线环境下,服务器和客户端的算力会同时崩盘。

沈明远提出的“单人多人生态衔接”问题,在复盘会后第三天演化成了一场小型工作坊。方瑾在白板上列出了至少五种可能的衔接模式:单人剧情作为多人模式的序章,完成后玩家继承角色状态进入共享世界;单人剧情和多人模式完全 分离,玩家分别创建角色;单人剧情嵌入多人模式,作为某类任务线存在;多人模式是单人剧情的“后日谈”,时间线在剧情结束之后;以有第五种,被方瑾称为“折叠模式”——单人和多人共享同一个世界状态,但玩家的行动在不同 层级上产生不同的叙事反馈。

每一种模式对应套不同的技术架构、一套不同的角色数据结构和一套不同的叙事设计逻辑。方瑾在白板前站了四十分钟,把这五条路径各自的利弊逐条拆解,最后在白板最下方写了一行字:“无论选 哪条路径,都需要在八月评审前至少完成策一轮多人原型验证。当前进度:零。”这个“零”字写得比别的字都大,力透纸背。

美术管线的复用性问题,在李想展示的那组对比图中有一条隐藏的数据后来被单独提取出来做了分析。雪景材质在蔚州切片中的开发工时为十一个工作日,但这是“从零开始”的十一天。所谓“从零开始”,是指团队没有可复用的基础材质库,每张贴图、每个着色器参数、每个光照反射配置都是为蔚州的特定雪景条件单独创建的。对比组的数据来自《逆水寒》项目组提供的一组沙漠场景资产。这组资产开发 utilized 一套通化地形着色器,从基础泥地到沙化地、从草地到碎石 地面的切换,在不超过三个参数的调整

这句话就是整场复盘会的真正结论。“朔风”原型是一次成功的演示。它成功到让观者看见了一个令人兴奋的可能性——一个不必活在《逆水寒》阴影下的、属于燕云十六州自己的美学气质。

但它同时也是一次清晰的暴露。它暴露了技术选型上的雪景负债,暴露了叙事框架中单人剧情与多人生态之间的真空地带,暴露了美术管线的复用性瓶颈,暴露了移动系统在机制层面的空洞,也暴露了团队在将一片美丽切片转化为可持续产品的路径上,缺乏一张每个人都看得懂的逻辑流程图。所有这些问题,没有一条是在复盘会上被解决的。它们被记录下来,被分类,被标注了期限和责任人。但记录不是解决,期限不是方案。

那份“朔风”原型的技术文档,在复盘会后被归档到了项目共享文件夹里。文档的第五十七页是蔚州切片已实现功能的清单,每一项后面都有状态标记。除了移动系统的摩擦系数和战斗AI的溃散逻辑之外,所有条目都被标记为“已完成”。在页面的右下角,版本号下方的签章栏里,压着一个日期戳印。2021年1月15日。

同一日期之下,方瑾在项目总览表上做了更新。她把蔚州的状态改成详尽的备注——那些在会上暴露的问题被一条一条填进了绿色格子里,密密麻麻的铅笔字占据了格子一半的面积。但墨绿色的底色没有变。蔚州在总览表上依然是已完成。十五个灰色的格子并排展开。桑干河继续向东流,流过蔚州边界之后进入的是一片空白。