来源:游戏研究社
Silent是一位小有名气的游戏MOD作者,同时也是专攻逆向工程的游戏开发者。他平日里最大的乐趣便是为那些旧世代的经典游戏制作各种MOD和修复补丁,这一过程中,自然也包括帮助玩家们解决各类稀奇古怪的BUG。
比如最近,Silent就收到了一份令他颇感费解的BUG报告——有位使用了他制作的原版《GTA:圣安地列斯》修复补丁的玩家反映,在系统更新至Windows11 24H2版本后,游戏内的水上飞机Skimmer离奇消失。
早在去年Windows11推出了24H2版本过后,Silent时不时就会收到水上飞机消失的BUG报告。
他原本以为可能是自己的修复补丁与新的系统版本无法兼容,但在邀请了其他玩家测试过后,他发现未安装任何MOD的纯净版游戏在更新到了24H2版本后也可能遇到同样的问题。
为了验证类似的问题是否会在自己的电脑上复现,Silent搭建了Windows11 24H2 虚拟机,并使用脚本生成了水上飞机Skimmer。结果在他执行完命令的瞬间,主角CJ突然原地起飞至10.3千万亿米的高度,游戏画面直接卡死。
经过一番排查,Silent发现问题的根源在于水上飞机Skimmer模型的边界框Z轴坐标被设定为了一个极其不正常的数字,而这个错误源于游戏配置文件缺少了定义轮子尺寸的参数,导致在初始化悬挂系统时,错误地更新了Z轴的上限。
至于为何会出现这样的问题,Silent认为可能是在前作《侠盗猎车手:罪恶都市》里并不存在“飞机”这一类别,Skimmer是游戏中唯二能被玩家操控的飞机,因此在设计上并没有定义这些值。
到了《圣安地列斯》中,Skimmer的载具类型被改为飞机 ,但开发人员却忘记了添加额外的参数。
在旧版操作系统中,内存堆栈的分配和管理方式与新版系统不同。游戏代码在处理完一辆载具的轮子尺寸后,存储这些尺寸的栈内存并没有被立即覆盖。简单来说就是,水上飞机的数据缺少轮子尺寸信息,代码错误地沿用了上一辆载具的轮子尺寸,意外地让Skimmer得以勉强正常运行。
Windows 11 24H2 更新改变了内存堆栈使用方式,使用了更多的栈空间,从而覆盖了残留值,最终导致Skimmer的Z轴数值出错,并由此引发了后续的一系列 BUG。
当然,水上飞机消失的BUG与Windows 11的24H2版本更新无关,因为WinAPI 函数使用堆栈的方式之类的内容不受约束,随时可能修改。真正的问题在于游戏代码本身存在编写失误,以及官方对游戏后续更新的支持力度不足。
借此机会,Silent还检查了《GTA:圣安地列斯》其他版本的二进制文件。他发现,早在最初的Xbox版中,官方其实就已经修复了这个BUG,并且这一修复沿用到了后来发布的Android、Xbox 360、PS3乃至最终版等多个版本。
不过,在2005年发售的PC原版当中,官方始终没有推送修复补丁解决这一问题,这个BUG便也潜伏了近20年之久。
如果换做是别的游戏,这类离奇的BUG或许永远不会得到解决,并就此成为玩家们口口相传的都市传说。值得庆幸的是,哪怕是20年前的GTA,时至今日仍有大批MOD作者在尽力优化游戏体验,排查各种潜在的BUG。
这个案例对于那些喜欢钻研老游戏的玩家们来说,也算是又提了个醒:升级Windows系统,还是谨慎为妙。
0 条