热更新:真的有必要更新framework_precompiled.zip吗?

最近要做游戏的热更新,拜读了论坛几位大牛的文章,很好很强大,但有个疑问是几个解决方案中都提到framework_precompile.zip的热更新机制,我总觉得似乎并无必要。

在我的理解中quick分为C++和Lua两部分,C++实现核心功能然后暴露Lua给调用,而framework_precompiled.zip是Lua的部分的打包,这两者需要配合在一起使用,光是热升级这个zip包,比如从2.2.4到2.2.5,但C++的部分仍还是2.2.4,一旦API有变动会有很大的隐患吧。在我看来这个zip包应该放在app store的大版本更新中才是安全的。

大牛的方案中为了处理这个zip增加了不少复杂度,乎先要延迟加载这个zip以便于可以之后加载下载得到的新版zip,其次是为了做出热更新的界面,要么是放在C++中做,要么是提取出framework中的基本功能放到一个Lua文件中(比如init.lua),然后在更新界面之前加载用来做界面。如果不考虑framework_precompiled.zip的热更新的话,方案可以简化不少。

quick新人,怕是自己有遗漏的地方,请指正。

强迫症而已!

是的,可以不更新。其实zip中的函数,如果需要修改的话,完全可以另外写一个文件,定义同名的函数来覆盖更新的。
其实在我较早前写的更新策略文章中,我就已经提出了上述"强制覆盖式调用"的更新处理方式,在我看来是能够简单处理这一问题的。但还是有人会觉得这样形式上不完美,呵呵。
http://my.oschina.net/SunLightJuly/blog/180657

原来如此。
我决定还是把framework跟着C++代码一起更新吧。

关于强制覆盖的事情,我之前在其它项目里做过Lua的hotswap,这个倒是很好处理,把旧的_G视为一棵树,新的_G也视为一棵树,那么只要自底向上遍历旧的_G树,然后跟新_G树做diff判断(可以参考git之类代码版本控制工具的算法),该覆盖的覆盖,该新增的新增,该删除的删除,(自底向上遍历的目的是防止某些值被绑定到local里,比如closure,先覆盖父结点的话就找不回旧的引用了)。这样可以实现完美的真正意义上的code级别的hotswap。

但这个hotswap只在code级别有意义,真正的游戏中充满了各种state,想象code是在一个game world上进行各种操作,code被swap成了新的版本,但state还是旧的数据结构,这必须有问题……也就是说正确的hotswap实现必须要考虑数据结构的hot upgrade,这在现实中几乎不可能有人做出正确的实现。所以我认为hotswap只在web server这种无状态的应用中有意义,在游戏这种围绕着“状态”的应用来说,hotswap一点意义也没有。完全可以先更新,再加载,这样代码也比较简单。事实上如果程序里大量用了closure的话,closure从某种意义上来讲也属于state,这部分是swap不到的,也就是说上面提出的hotswap算法在stateful的程序中,不论如何都会有问题。

最后,如果quick framework真的跟C++代码绑定紧密的话,那么热升级framework已经不是有没有必要的问题,而是对与错的问题。在我看来完全就不应该对framework进行热升级,逻辑上就有问题。

这个看个人习惯,当你的ui 式样有新的变更时,旧的framework 不满足你的需求时,你就得修改framework。 不过你也可以走强制覆盖。

关于hotswap,你说得很对,我也是赞成先更新再加载,不赞成所谓的“即时热更新”。
最后一点,确实,framework真正需要升级往往与C++代码有关。不过偶尔也有小的lua层面修改的情况,但lua层面的修改通常都是可以通过加一个新文件重载变量与函数的方式来完成,这种修改可以看作是增量修改,实际上不需要对原来的famework进行修改。从这个意义上来讲,本质上就是“完全不对framework进行热升级”。

以上的方案我觉得都做的太过于细致,
我最近实现了一个方案(还没在实际项目用过)

在旧版本里面 将新版的资源都下载到本地后
做一次类似 F5的操作 那么启动后就可以从新代码启动了

简单来说 就是将整个lua虚拟机给干掉 重新创建虚拟机
这时候启动的 一定是百分百最新代码

嗯,版主也给了我相同的回复,就是有些bugfix只会修改framework而不动C++,这种情况下确实可以只更新framework。
我再调研一下,看看framework单独改动的机会有多少,值不值得为它增加复杂度吧。

这个方法听起来不错啊,有搞头。
快糙猛,我喜欢。
学习学习。

恩 我采用这个方法后 发现原来论坛的方案碰到的问题
在这里都完美解决了
本来很纠结的热更新变得非常简单

请教 如何吧 lua 虚拟机干掉 重现创建虚拟机