我们玩过游戏的都有过这样的经历,一个游戏安装好之后,啥都不用管,每次点开游戏之后读个条,游戏内容就始终是最新的,可能有新的道具、新的活动,可能某个东西过些日子就找不到了。

当我们学过怎么做游戏之后,我们就知道,哦这玩意叫热更新。那么热更新到底是怎么更新的呢?

在传统的win32或者gnu linux中,我们要热更新一个软件或者游戏是非常方便的,因为它们本质上就是一堆文件堆在那儿,点两下就能运行,哪个有变化就更新哪个,完事。

但是在更多的平台上,我们是不能这么任性的,比如说在Android中,我们一个apk安装好一个App上去,这个App就是把屋顶都拆了也没法自己修改自己,你只能用一个新的apk文件来替代它。

而现代很多系统平台,什么uwp啊,iOS啊,xbox啊,都是采用了类似的软件包的设计形式。

那么就有问题了,照理说,这种机制下,我们的软件没法修改自己,那就没法实现热更新啊,怎么办呢,伟大的劳动人民总是心灵手巧的,人们发现:虽然我没法修改自己,但是在很多系统里面,我都可以申请一块存储空间来读写着玩。那,好像是不是可以曲线救国一下呢?

于是出于这种种原因,现代的很多App啊,游戏之类的,就演变出了这么一种热更新思路,首先,我们可以在概念上,把整个App拆成两个部分:

  • 基础部分:底层的、不会经常变动的部分。
  • 业务部分:基于基础部分之上的,变动频繁的部分。

通常,这个基础部分是无法热更新的,如果要修改这部分,就得重新制作安装包给应用商店。而业务部分,则是可以被热更新的,而通常负责业务部分热更新功能的,正是基础部分。


其实每次说到这个部分的时候,我就会想到网页浏览器。我也很喜欢用网页浏览器来作比喻:这个基础部分就是个浏览器,而业务部分就相当于是我们平时浏览器里的网页。这个浏览器在我们本地可能万年不更新,但是每次刷推特刷新闻都能立即看到最新的内容。

当然,其实这也不完全是比喻,比如PWA和某些“所谓的小程序”,就真的是浏览器和网页。


当我们理解了这个部分之后,我们就来进入正题了,在现在很多游戏领域有两个概念:“母包”和“补丁”。从玩家角度来看,大家可能都知道补丁是个什么东西,但是对于母包这个词就有点陌生了,那么母包和补丁包的关系到底是怎样的呢,我们来举个栗子:

比如说,我们在做一个游戏,做着做着,好像差不多了,欸我们发布给用户玩玩吧,怎么发布呢,就是正常的把游戏编译出一个安装包。就比如说是个apk包吧,我们把这种完整的安装包,就称为母包。为了方便描述,我们把这个母包称为“母包1”,这时候的客户端版本,记作1.0

比方说我们的母包1包含了这么些东西

然后,我们把这个1.0客户端给放在了应用商店,提供给用户下载使用。

但是,虽然我们发布了一个版本,但是开发并没有停止,我们还是不断的在往游戏里加新东西,那么到了第二天,我们改动了这么些东西:

我们在昨天的1.0版本的基础上,修改了一个文件,又增加了一个文件。这时候,我们希望我们的玩家的游戏,都同步到这个新版本来,怎么办呢?

最传统的方法就是我再编译一个安装包,扔给应用商店。但是这样做就有问题了,比如说啊,我一个安装包有10个G,但是我就修改了10kb的内容。你说你要是每天更新一次,每次都让玩家下载10个G的安装包,估计玩家四十米的大刀就收不住了,没过几天玩家全跑了没人玩了。那怎么办呢,这时候,就该补丁包出场了。

我们制作了一个补丁包,把我们今天变动的两个文件单独拧了出来,丢在我们的服务器上。然后玩家的客户端会自动下载这个补丁文件,把这两个改动的文件更新到原来的客户端中。

这样一来,玩家手里的客户端就是今天的最新版本了,为了方便说明,我们把这时候的客户端版本记作1.1

客户端1.1 = 母包1.0 + 补丁1

好的,我们的故事还在继续,第三天,我们又修改了一些内容,变成了这样:

然后我们现在又想把这个最新版本同步更新给玩家了。在刚刚第二天是时候,我们发现补丁包是个好东西,于是到了第三天这里,我们自然而然的就想到了:欸我们再打个补丁吧,就叫补丁2

思路没错,但是要注意的是,这里我们有两种方法来做这个补丁2

方法1:

我们把相对于1.0版本客户端的所有变动的内容,都放在补丁2中

这时候,比如说有个玩家,第一天下载了我们的游戏,版本是1.0,第二天这个玩家没玩,也就没更新成1.1,这时候当他第三天打开我们的游戏之后,游戏只需要直接下载补丁2,就可以把客户端变成最新版本了(记作1.2版本)

但是对于客户端版本是1.1的玩家,这时候就不爽了:“你这个补丁2里有三分之二的文件,我昨天都已经下载过一遍了,这又让我把整个文件下载一遍什么意思,我流量不要钱啊”

方法一中:版本1.2 = 母包1.0 + 始终最新版本的一个补丁

方法2:

我们在补丁1(版本1.1)的基础上,制作补丁2(版本1.2)

这时候,我们当前版本为1.1的玩家,只需要下载一个相对方法1中体积更小的补丁2,就可以把客户端变成最新的1.2版本了。

而版本在1.0的玩家,就得按照顺序,先下载补丁1,把自己变成1.1版本,再下载补丁2,把自己变成1.2版本。

至于说这两个方法哪个更好,其实没有明确答案。这两个方案各有优缺点,也都是被广泛使用的方法。

方法2中,版本1.2 = 母包1.0 + 补丁1 + 补丁2 (依次)

好的,到这一步,我们大概算是明白,母包和补丁之间的关系了,但是还没完,我们的例子继续进入下一步。

第四天,我们没有修改任何东西,但是我们重新编译了一个安装包,记作母包2

欸,我们发现了,这个母包2中的内容,和之前母包1加两补丁的1.2版本的内容是一模一样的。

如果这时候,我们把母包2放在应用商店中给新来的用户下载,那么下载了母包2的用户打开就直接能玩了,不需要再下载补丁来更新客户端。而与此同时,之前下载了我们母包1,并且通过补丁更新到1.2版本的玩家,也不需要重新去下载一个母包2,就可以获得一致的游戏内容。

也就是说:

  1. 母包、补丁包和客户端版本之间的关系并不是一一对应的。
  2. 补丁包是依托于某个特定的母包版本的。不能说我母包2去下载个母包1的补丁,那就乱套了。

(当然,也有那种补丁包不依赖于特定母包版本的骚操作存在,但那就是另一个故事了)


题外话,我们一开始把游戏分为基础部分和业务部分两个部分。对于很多游戏来说,会把javascript、lua、python这些语言代码文件放在业务部分,这样一来,游戏中的绝大部分业务内容就都可以实时更新了。

讲到这一步,对于我们大部分中小团队来说,就完全够用了,那么,看完之后要不要试试看活学活用,自己动手给自己的App/游戏实现一下热更新的功能呢。

转自https://www.yomunchan.moe/archives/367

怎么理解游戏热更新中的“母包”和“补丁”相关推荐

  1. 【热更新】游戏热更新方案

    游戏热更新方案 热更新演化 热更新方案 [1] 进程切换 1.1 利用fork.exec切换 1.2 利用网关切换 1.3 微服务 - 进程切换注意要点 [2] 动态库替换 [3] 脚本语言热更新 热 ...

  2. 游戏热更新(XLua)专题一(知识点)

    课程学习笔记:https://ke.qq.com/course/337826 ps:建议搭配课程学习,吃透知识点,解决疑惑:什么是xlua,热更新和xlua什么关系,xlua和lua又是什么关系?等等 ...

  3. Unity游戏开发-游戏热更新以及登录流程

    本篇主要分享基于热更新的游戏初始化方案. 整体初始化的流程大致为:检查是否需要解压资需要则解压,之后再检查是否存在需要热更新的资源文件需要则更新,更新完成后则初始化结束可进入登录界面. 关于登录这块的 ...

  4. Xlua文件在热更新中调用方法

    Xlua文件在热更新中调用方法 public class news : MonoBehaviour { LuaEnv luaEnv;//定义Lua初始变量 void Awake() { luaEnv ...

  5. siki学院 游戏热更新实战案例(基于xLua) 捕鱼达人 完整素材

    xlua 游戏热更新实战案例(基于xLua)课程视频 哔哩哔哩上就能看 课程素材,工程,源码 下载地址 http://ese2a8b8c9d5wv.pri.qiqiuyun.net/course-ac ...

  6. 【Spring Boot官方文档原文理解翻译-持续更新中】

    [Spring Boot官方文档原文理解翻译-持续更新中] 文章目录 [Spring Boot官方文档原文理解翻译-持续更新中] Chapter 4. Getting Started 4.1. Int ...

  7. Android APP热更新中的插件化(Hook技术:反射或动态代理),Demo (2)

    修改AAPT,资源分区,用于Android插件化- https://github.com/BaoBaoJianqiang/AAPT -- Android下的挂钩(hook)和代码注入(inject) ...

  8. CocosCreator游戏热更新完整教程,超简单,超详细

    使用cocos已经是第7个年头了,也算是老司机了,今天就介绍下使用cocos creator开发游戏如何热更新. 预备知识 首先,科普下基础知识,热更新的基础原理是,不同版本的游戏资源对应不同的man ...

  9. 【Webpack】1047- 轻松理解webpack热更新原理

    一.前言 - webpack热更新 Hot Module Replacement,简称HMR,无需完全刷新整个页面的同时,更新模块.HMR的好处,在日常开发工作中体会颇深:节省宝贵的开发时间.提升开发 ...

最新文章

  1. Sleep()和wait()方法的区别
  2. java 面向对象的特性 抽象_java面向对象的四个特性
  3. 三十七、细说Scrapy中的settings设置
  4. Linux学习:shell命令(查找和索引)
  5. python验证身份证号码大全_身份证号码处理技巧大全
  6. [剑指offer]面试题第[2]题[JAVA][替换空格][函数][字符串]
  7. Java 9 关注度不断上升!2018 编程语言流行度大调查
  8. 通过python程序调取摄像头画面
  9. win10 卸载mysql5.7
  10. linux机顶盒怎么破解wifi,折腾一下数字电视的机顶盒
  11. 应聘高校教师的试讲技巧
  12. Delphi Inputbox,InputQuery用法
  13. MATLAB彩色图片的处理
  14. TPT又一次重量级更新——TPT16使嵌入式测试变得更加轻松
  15. 计算机表格 求差,教大家Excel2013中表格求差函数公式怎么使用
  16. vue中reject与provide使用
  17. ElasticSearch~received plaintext http traffic on an https channel, closing connection Netty4HttpChan
  18. 【前端之旅】Webpack模块打包工具
  19. Mysql数据库快速插入亿级数据
  20. 苹果致力于手势再生研发,无须使用控制器即可与 ARKit 交互?

热门文章

  1. 订票助手 12306
  2. 安卓Camera2悬浮窗录像
  3. 泪点太低,什么煽情的陷阱都会掉进去
  4. 永恩上线服务器维护,云顶之弈维护到几天今天 2021年3月18日维护公告详情一览...
  5. 扎心!妹子一个rm -rf把公司服务器数据删没了,这该怎么办?
  6. 加法运算替代 牛客网 程序员面试金典 C++ Python
  7. 专为云原生、微服务架构而设计的链路追踪工具 【SkyWalking介绍及搭建】
  8. 牛客OI周赛7-普及组(A 救救喵咪)
  9. 华为 微信视频 连接到服务器,华为EMUI10里这个新功能,想要干掉微信视频?
  10. KV260 FPGA工程开发流程及源码