1.介绍

   使用脚本开发游戏业务逻辑其中一个好处就是代码可线上热更,不停机修复bug。而热更代码的写法与需要被热更的文件的代码又有着密切的关系,本文介绍一种热更方法。

2.热更原理

  Lua提供一个叫require的函数,实现文件的加载,require的作用可查看云风大大的参考手册说明  http://cloudwu.github.io/lua53doc/manual.html#pdf-require
要热更一个已经被加载(require)过的模块,要做两件事件.

1. 将package.loaded[filename] = nil, 将模块置空.

2. 重新调用require,require(filename).

如果要热更的模块里面所用到的都是全局变量,那么只需要这样写:

global_var = global_var

ok,新的模块内容就会重新被加载进内存了,而且全局变量也成功保留了热更前的值。

然而每个文件里面只定义全局变量,会破坏模块的可读性,试想一下,定义了一个类,但它并没有成员变量,用到的变量全是全局变量,这是一种怎样的感受。
所以我们要换一种写法,模块既可以有自己的变量,又可以被热更。

3. 实现

  形如一个类既有成员变量,又有成员函数,要实现热更一个模块同时又保留其原有变量,我们可以把模块的变量定义和函数定义分开,分别写在两个文件。
目录如下:

  data目录: modA.lua; modB.lua; modC.lua

logic目录: modA.lua; modB.lua; modC.lua

把模块的变量定义放在data文件夹,把模块函数的实现放在logic目录。

下面是实现:

 -- data.modA
local mod = {}
-- 这里定义模块变量
mod.players = {}
mod.total_online = -- 最后记得return这个表
return mod
 -- logic.lua
local mod = require("data.modA") -- 定义函数
function mod.login()
-- xxxxxx
end function mod.load_data()
-- xxxxxxx
end

这里只是一个例子,logic.modA想要执行 `require("data.modA")` 成功,还要修改package.path,这个是Lua虚拟机启动时自己去定义了,这里不做讨论。
这里把模块的变量和函数的定义分离了,我们只热更function目录下的文件,data目录下的则不管。
热更文件的实现如下:

 -- require_ex.lua
function require_ex(filename)
local old_content
if package.loaded[filename] then
-- 把旧的模块保存起来
old = package.loaded[filename]
-- 然后package.loaded[filename]赋空
package.loaded[filename] = nil
end -- xpcall下执行require
local ok,err = pcall(require, filename)
if not ok then
--热更失败,将旧值赋回去
print("hotfix fail, err msg ",err)
package.loaded[filename] = old_content
return false
end return true
end

切记: 重新require模块的时候,必须在pcall下执行,万一模块有语法错误,require挂掉的话,package.loaded[filename]就会一直为nil。当有其他文件需要执行 require(filename)的时候,则会报错,后面的逻辑无法执行。

Lua热更系统的更多相关文章

  1. lua热更框架之XLua

    框架介绍 xLua是当下最流行的unity热更方案之一,作者是腾讯的车雄生前辈,自2016年初推出以来,已经在腾讯的多款游戏项目上应用,目前xLua已经开源到了GitHub.xLua最大的特色是不仅支 ...

  2. 热更新-----为何使用lua进行热更

    事实上我们在安卓端是可以使用c#jit的,但是我们在ios上的代码是AOT(预先编译,静态编译)的,不能用c# jit(实时编译,即时编译). ios不能用c#热更是因为启动了CPU的No eXecu ...

  3. 客户端热更新框架之UI热更框架设计(上)

    什么是热更新,为什么需要热更新?          热更新是目前各大手游等众多App常用的更新方式.简单来说就是在用户通过App Store下载App之后,打开App时遇到的即时更新.对于手游客户端来 ...

  4. Unity3D热更新之LuaFramework篇[08]--热更新原理及热更服务器搭建

    前言 前面铺垫了这么久,终于要开始写热更新了. Unity游戏热更新包含两个方面,一个是资源的更新,一个是脚本的更新. 资源更新是Unity本来就支持的,在各大平台也都能用.而脚本的热更新在iOS平台 ...

  5. 实现iOS图片等资源文件的热更新化(三):动态的资源文件夹

    简介 此文,将尝试动态从某个不确定的文件夹中加载资源文件.文章,会继续完善自定义的 imageNamed 函数,并为下一篇文章铺垫. 这么做的意义 正如我们经常所说的那样,大多数情景知道做事的意义往往 ...

  6. 实现iOS图片等资源文件的热更新化(零): 序

    必要的序 以后在写系列文章,准备把基本的规划和动机等,单独作为一个小的序言部分给独立出来.序言部分,可以较为完整地交待系列文章的写作动机,所展示的编码技术可能的应用场景等.个人,我还是比较看重文章或者 ...

  7. lua热重载

    热重载,就是不重新开unity让代码的变化直接看出来,一般在开发时候使用 lua中通过require导入的文件,最终都存在package.loaded这个table中.require会判断是否文件已经 ...

  8. Unity热更方案汇总

    http://www.manew.com/thread-114496-1-1.html   谈到目前的代码热更方案:没什么特别的要求   <ignore_js_op>    toLua(效 ...

  9. 客户端热更新框架之UI热更框架设计(下)

    上一篇笔者介绍了关于什么是热更新,为什么需要热更新的技术文章.本篇就专门针对UI框架的热更新功能实现部分展开讨论,讨论的重点是热更新如何与UI框架进行结合? 现在笔者把设计“UI热更新框架”的整体设计 ...

随机推荐

  1. form上传文件2种方式

    示例1: 表单里有图片/文件的上传 <form enctype="multipart/form-data" method="post"> <i ...

  2. Mac终端用Sublime打开指定文件或文件夹

    首先你先把的sublime放到Application中,再确认您的Sublime的路径是否正确 1 创建别名: sudo ln -s "/Applications/Sublime\ Text ...

  3. Html5特性及简介

  4. 所有的cursor图标

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. HDU-1257 导弹拦截系统 http://acm.hdu.edu.cn/showproblem.php?pid=1257

    Problem Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高 ...

  6. 夺命雷公狗-----React_native---3---react-native-cli的安装

    我们用npm安装下react-native-cli,并用-g来全局安装,我们用命令 npm install -g react-native-cli 如果和下图一样即表示已安装成功:

  7. 从oracle数据库中导出excel问题导致乱码的问题

    使用plsqldev工具将oracle的查询结果导出为excel,结果可以成功导出,但是使用libreoffice进行查看时,有好多记录都是空的. 使用python进行导出(openpyxl模块进行e ...

  8. Ubuntu/linux 有关权限修改的命令

    chmod更改文件权限命令 最常用的基础命令chmod chmod 777  目录名(路径名) 777 三位数字分别代表 user.group.others 的权限,可读(r).可写(w).可执行(x ...

  9. ecplise常用快捷键

    常用 Ctrl+1 快速修复(最经典的快捷键,就不用多说了)Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加)Ctrl+Alt+↑ 复制当前行到上一行(复制增加)Alt+ ...

  10. RobotFramework中加载自定义python包中的library(一个py文件中有多个类)

    结构如下: appsdk\ appsdk.py(这里面有多个类,包括appsdk,appsdksync等类) __init__.py ... ① 有个appsdk的文件夹(符合python包的定义) ...