哈啰,大家好
随着暗黑破坏神二:狱火重生 (Diablo II : Resurrected, D2R) 的 public beta 即将进入尾声,相信大家对于游戏仍有相当多的疑问,也让板上的讨论热闹了起来,但也发现了一些容易让人观念模糊或混淆的地方,因此产生了计划写这篇报告的想法。(原先只想解释测试阶段与bug的关系,但因为上周实在太忙,加上周末自己测试后有一些新发现,所以合并一起撰写)
身为一个闲暇时会做游戏自嗨的 QA 测试工程师,想在这边跟大家讨论两个面向:
- D2R 背后可能的技术细节
- Beta 测试到底是什么
不过毕竟我不是专业的游戏从业人员,也不是暴雪的员工,所以对于暴雪内部真正的方案或定义只能透过我对于游戏开发的知识、测试专业以及逆向工程来挖掘与分析,如果有说错的地方,还请相关专业的大大指正。
一、D2R 背后可能的技术细节
而大家都知道 D2R 是着重在画质和音效的重制,而在系统机制上,不管是官网的介绍,或是制作人的访谈,会提到 D2R 是基于 D2 的引擎所开发,所以能呈现原汁原味的游戏内容,也让许多人开始讨论起所谓的「画质重制」究竟是基于什么样的游戏引擎开发出来的。
在这边我要先让大家厘清一个观念,在游戏内的「画面渲染 (Render)」、「系统机制 (System)」、「物里运算 (Physic)」、「用户接口 (User Interface, UI)」、「事件 (Event)」等功能,其实是不同的,虽然上述这些功能可以建构一个完整的游戏,但各项功能其实是可以单独开发的,而游戏引擎就类似游戏开发的「工具集」,尽可能地将各种开发工具包含其中,如果有用过 Unreal Engine、Unity,亦或是 RPG maker 的大大应该就会知道,游戏引擎内会提供缺省的材质、模型、场景、物理参数、脚本设计和运行测试,也方便用户直接将游戏文件、代码、材质等加密打包,相反的,游戏制作是可以不需要用到游戏引擎的,例如网页游戏,或是独立开发的小游戏。
游戏制作是需要多种专业之间的协作才能完成,例如你会写程序,也许可以做出一个完美高效的游戏核心和机制,但因为没有画面的渲染,所以消费者依然无法玩到你所设计的游戏。(纯文本游戏除外);相反的,如果你的美工设计相当厉害,能画出精美的图形、制作精细的 3D 模型,可以渲染出以假乱真的场景或物体,但你不会写程序、不会拉骨架,这些作品就是单纯的作品,并无法变成游戏让人游玩。
为了方便大家能直观的理解,以下我会将游戏内容简化成「画面渲染」、「系统机制」和「用户接口」三个部分来讨论。
D2 是个 20 年前制作的老游戏,要进行画面的重制其实相当的简单(相对于整个重做来说),会对编程有涉略的大大应该知道,程序的运行方式是逐行运行,也就是说后面运行到的代码会叠在之前运行的代码之上,简单来说就像是:
第一行设置变量 a 等于 1,第二行设置变量 b 等于 3,第四行回传 a + b 的结果:
从右边的 console 也可以看到,程序运行的结果为 1 + 3 = 4。
但当我再添加一行告诉程序 a = a + b,接着才在第四行回传 a + b 的结果:
这时可以从右边的结果发现计算结果变成 7,虽然第一行声明了变量 a 等于 1,但程序第三行又在声明了 a = a + b,所以这时的变量 a 会变成 1 + 3 等于 4,接着第四行又再一次计算 a + b,而第四行的 a 因为已经变成了 4,所以计算的过程变成了 4 + 3 等于 7。
这个逻辑在变更游戏贴图材质也是通用的,有玩过上古卷轴 5 mod的玩家应该也非常清楚,这也是为什么上古卷轴加载 mod 时,会非常重视 mod 的加载顺序,因为先加载的贴图资源会被后加载的贴图资源覆盖,适合的高画质贴图 mod,搭配喜欢的光线渲染参数 ENB,再加上正确的加载顺序,可以让原本的游戏被改成几乎不同的游戏。
根据个人的分析,D2R 也是利用同样的方法来进行画面贴图的重置,如下图可以知道:
上半是怀旧模式的画面,下半是狱火重生模式,左右两边分别是在两个地点拍摄的,其中可以发现
,当原版画面中出现这种石笋的贴图时,在重制画面中会被加载为简易帐篷。
像暗黑破坏神这种随机生成的场景,并不像大多游戏的场景一样是全手工绘制而成,而是开发者会制作大量构成场景的一些要素(墙壁、障碍物、树木、石块、尸体、骨骸、房屋等地图对象),再由程序运行时随机拼凑生成(当然也可以限制一张地图最多只会加载多少张地图区块,从而让每次产生的地图大小大致相同),因此只要让程序能知道玩家的角色进入邪恶洞穴时,程序要抓取数据库中的哪些区块拼凑成地图,就能顺利加载重制过的高画质贴图。
而技能特效也是一样的方式,所以德鲁伊的裂地之火才会有破图的状况,因为原本 D2 的裂地之火效果不包含深度,只是单纯在地面绘制技能动画,但不知道为啥 D2R 的技能设计要把这个技能添加一个深度…但地板本身又没有厚度,所以这个技能在地图的边缘就会产生破图。
而要让程序加载高画质贴图的方法有三种:
1. 针对数据库修改,把产生地图相关的代码要加载的资源对应到新版的文件。
2. 将重制后的文件替换掉相同路径下的相同文件名,程序抓数据时就只会看到唯一的新版文件,然后读取进去处理。
3. 利用程序逐行运行的特性,用后面加载的高画质贴图覆盖掉原先加载的原版贴图(这也是 mod 的运作原理)。
这时我自己就产生疑问,一方面官方说是基于原本的引擎所重制的游戏,另一方面有常听到有大大说 D2 的原代码已经遗失,所以无法动到太多核心机制。但游戏代码是游戏公司的命脉,暴雪这么大一间公司有可能在代码管理上出现这么大的纰漏吗?另一方面, D2R 究竟是用哪种方式做重制呢?
这就是我测试时发现的一个重点,虽然我的电脑配备并不算太差(CPU: i5-8600, GPU: RTX 2060 6GB, RAM: 16G),但当我快速切换多重复杂场景时(例如从死亡之殿 1F 往 2F 楼梯的旁边,开发送门回鲁 高因,然后立刻进入发送门返回死亡之殿 1F,接着迅速点楼梯到 2F,目的是为了让显卡渲染画面时产生延迟),这时会发现 D2R 会先加载旧版的游戏画面,然后在大约 0.1~0.3 秒左右的时间恢复成重制版画面。这时我所担忧的事情就浮现了:
D2R 难道真的只是在原本封装好的 D2 外再套一层新壳吗?
从上面游戏开发的技术可以知道,开发者可以利用加载顺序覆盖变量或是资源,那 D2R 就极有可能是先运行 D2,然后利用后续的程序替代掉原先加载的资源,这样就能达到画质重制的效果。(其实就跟 mod 一样)
如此一来就能做到资源覆盖的效果,按下G件进入怀旧模式,也只要让后面 D2R 的负责画面处理的代码不运行,就能切换回旧版画面,这种运作方式,等于让程序读取了两次文件,运行了两次的画面渲染,因此在显示性能上会有一定程度的影响,但这种方法也可以在不修改游戏本体的情况下做到扩充和修改的效果。
而添加的 7.1 声道音效,只要将原先的效果音、背景音、音乐重新录制,再放入文件中,将 D2 的音效删除,让 D2R 的代码读取新版的音效文件就行。(上面三种方法的第二种)
用户接口的部分,这次使用这接口是完全重制,因为就如一开始所说,系统机制跟用户接口其实是可以分开开发的,开发者可以在 D2R 程序的部分加入新版的 UI,然后让显卡渲染画面时,将新渲染的画面「完全覆盖」旧版画面,就一样能显示新旧 UI 切换的功能。
D2R 画面渲染不透明度 0%:D2 画面(怀旧模式):
D2R 画面渲染不透明度 50%
D2R 画面渲染不透明度 100%(狱火重生模式)
这样也能解释为什么会有大大遇到游戏地图显示不完全的问题(我自己也有遇到),而遇到这问题,有时候只要重新进出该地图、放大画面,或是移动一下就能解决。(显卡要重新渲染最新的画面,所以原先因为 bug 被跳过的对象加载也会再度被运行,从而恢复正常)
而穿模(两个对象互相穿透的问题)也是时常发生,如下图,我的角色在重制画面看起来已经跨越石头,可以往下走,但实际上却不能,切回原版画面后会发现,原来我的角色碰撞区根本没有跨过这颗石头的碰撞区。
在这边要在帮大家补充一个细节,玩游戏时常看到两个物体相互碰撞,然后被阻挡或是弹开,但其实在 3D 建模中,物体的外观跟碰撞区是完全不同的东西,因为画面渲染需要计算画面内所有场景跟物体的面,以及每个面之间的光线变化,动画或电影可以用好几天去渲染一个画面、仿真最真实的碰撞效果,但对于每秒要渲染 60 帧的画面、每秒要计算 60 次碰撞结果的游戏来说,逼近真实的计算是不切实际的,因为会让玩家像在玩投影片一样,所以即使在精细的贴图和建模,有时候碰撞区会是用球形、立方体,甚至是凸壳的形状来表示,也就造就「爬墙壁」、「摸不到物体」、「子弹打在空气上」等奇妙事件……。
剩下的添加功能,例如自动捡钱,则可以在 D2R 的程序中增加检测掉落金币座标与角色所在座标的关系,当角色座标接近金币座标时,角色身上存有金钱数量增加地上金币的数量,删除地上金币显示且删除掉落状态:(粗略示范,真正游戏的判定没这么简单)
if (player.x === coin123.x) && (player.y === coin123.y) {
player.coin += coin123.number;
display coin123 = false;
delete coin123
}
而加大的仓库、共享仓库因为会牵涉到数据库数组(例如 json )的内容,所以这部分应该是连同 UI 重制一起重新设计。(希望是 D2 的 UI 部分代码没有遗失,这样未来在用户接口调整上才有比较大的弹性空间)
而我担忧的地方就在于,如果原版 D2 的代码真的遗失,现在的 D2 就是加密封装后数据,那么 D2R 能重制调整的地方真的就会受到很大的限制,包含原本 D2 就有的 bug。
以上是我目前测试出来的结果,说实话我目前的想法是趋向 D2 代码真的已经部分遗失,所以制作团队只能用覆盖的方式重制游戏,对于这点是有点小失望;但如果问我在知晓这些问题的前提下会不会买游戏?我会说:「等正式版推出后看看他们的 debug 和优化能力。」
谢谢大家的观看,第二点的何谓测试,我留到二楼再说明~