游戏中的补丁程序如何工作?


37

控制台和PC游戏有时会修复一些补丁,以解决开发人员错过/没有时间修复的错误。

我的问题是这些如何工作?

有时,补丁文件的大小为几兆字节。我不了解小文件如何更改已编译的程序。


您想更改使用小补丁制作的编译游戏吗?
wolfdawn 2012年

不,我只是对背后的理论感兴趣。我的游戏很小,可以重新编译并重新分发整个游戏:)
MulletDevil

4
这是一个有趣的问题。它不是基于您在游戏设计中遇到的问题。还有许多方法可以以最幼稚的方式处理补丁,将所有修改后的文件替换为最复杂的文件,并获得有关更改现有文件中特定内容的说明。我不确定这个问题是否适合本网站。
wolfdawn 2012年

3
几兆字节并不小。假设我们有一个3兆字节的文件,它是压缩后的6兆字节的可执行代码。假设指令平均长度为六个字节,那么大约是一百万条指令。(让我们忽略诸如字符串文字之类的静态数据之类的东西。)如果C行对应于大约十条机器指令,那么这就是100,000行代码。对于游戏的核心引擎而言,这似乎已经足够。大多数安装尺寸将是诸如纹理贴图,屏幕,视频序列之类的东西。

2
几兆字节可能很小,这全部取决于其中的内容以及占总代码库的百分比。如果说由于选择的文件格式等原因需要替换整个3D级别地图,包括所有的纹理等等,那么实际上只有几兆字节。
jwenting 2012年

Answers:


30

有多种方法可以执行此操作,最简单的方法是对两个文件进行XOR并压缩它们(GZIP等)。这背后的理论是希望您可以得到大的零序列(相同值的长序列压缩得很好)。

您可以进一步了解该概念,并尝试查找两个文件中数据相同的区域,并完全忽略它们。

最后,您可以利用每种类型的文件的结构来发挥自己的优势。例如,在EXE中,您可以将每个方法单独打包(仅对已更改的方法进行打包),然后在补丁应用程序中自行重新构造EXE。但是请记住,这很可能在过度杀伤的领域中,并且不值得付出努力(简单bdiff的获得可能并不能证明可能在野外打破的额外复杂性)。作为另一个示例,您可以将diff文件用于脚本。

但是,大多数修补系统采用的是最简单的方法:它们只是打包已更改的文件-他们不会尝试仅将这些文件中的更改打包(可能有充分的理由,大多数游戏内容已被压缩并针对高熵或压缩数据根本不起作用)。


您是指将每个方法分别打包在exe中是什么意思。那可行吗?
wolfdawn 2012年

@ArthurWulfWhite是的。对于独立屋来说,可能不值得花时间,因为这将花费大量的时间和精力(您基本上需要编写自己的链接器)-作为一家专门处理“修补技术”的公司,这是非常值得的。这完全取决于可执行代码的大小-我快速浏览了Sacred 2,它的大小为26mb(主EXE为8mb)。二进制diff也许可以接近它-仍然值得一提(我知道CAB在EXE上得到了很好的压缩,因为它们利用了结构)。
乔纳森·迪金森

那很有趣。我想在当今带宽如此的情况下,最小化游戏补丁的大小并不是主要问题。+1一个有趣且经过深思熟虑的答案。
wolfdawn 2012年

在大多数游戏中修补单个方法并不可行。即使简单的代码更改,编译器的输出也可能大不相同。自动内联决策可以更改,符号表布局可以更改等。代码更改还经常更改内部API结构。与您在代码编辑器中看到的相比,优化已经模糊了函数边界之间的界限。DRM系统还会使水变得很浑浊。修补程序系统使用批量替换或二进制差异进行压缩,然后对其进行压缩。imo,您提出的任何建议都太脆弱了,无法在现实世界中发布。
肖恩·米德迪奇

2
@SeanMiddleditch我要这样做只是为了证明它是可能的:)。
乔纳森·迪金森

15

游戏的可执行代码并不总是驻留在可执行文件中,而是经常分为几个动态库(例如游戏,图形和声音引擎),实际可执行文件,以及可能出于各种目的的许多脚本。

补丁程序可以解决这些部分中的任何一个问题,而无需保证所有部分都进行更改。

与替换所有更改的文件不同,可以采用一种简单的方法是对它们进行二进制比较,然后仅打包要重新分发的实际差异。

(这当然只适用于您可以保证不会被用户更改的文件。)


2
您可以举一个例子:daemonology.net/bsdiff
wolfdawn

2
很好的实用答案。+1
wolfdawn,2012年

2

通常,他们使用第三方二进制diff系统将补丁分发到游戏数据。可执行文件通常很小,足以被完全分发。

大多数现代游戏都有数百兆的游戏数据(主要是纹理,模型,关卡数据等)。这些要求经常打补丁。据我所知,出版商通常有一种标准的专有方式来做到这一点。

不用说,有开源示例。一些Linux发行版(Fedora?)使用二进制差异作为其补丁。您可以调查这些内容并阅读其源代码或文档。


-1

现代diff算法可以有效地找到两个二进制文件之间共有的字节序列。考虑一下就不足为奇了。文件压缩也依赖于找到相同的字节序列。

一旦获得了相同字节序列的列表,您只需要发送旧的和新的偏移量,长度,当然还有所有全新的偏移量即可。在接收方,这是一个简单的组装。复制旧文件中需要保留的位,然后填写新位。

如果您的链接器可以吐出一个MAP文件,该文件列出了文件中每个功能的偏移量,则创建补丁变得更加容易。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.