KiHan 热更双引擎详解
KiHan 热更双引擎详解
两套热更通道:Lua 脚本(xLua)+ C# 代码(ILRuntime),加上资源 bundle,构成完整更新体系。
“我这个改动能不能热更”看这一篇。
0. 三个破除谣言的澄清 ★(源码核验)
- 只有一个引擎:xLua。没有”V1=SLua / V2=xLua 双引擎”
- 全工程
using SLua命中 0 次;SLua 只是腾讯 Pandora 运营 SDK 残留
- 全工程
- Lua 框架核心不在
Assets/Scripts/,在Packages/khengine/Runtime/Lua/LuaVirtualMachine/LuaClass/RuntimeLuaProxy/LuaCodec全在 khengine 包内
- V1 与 V2 共享同一个 xLua VM
- 全工程
new LuaEnv()只出现一处(LuaVirtualMachine.cs:39);RuntimeLuaProxy是 V1↔V2 桥梁
- 全工程
1. 三语三层运行时
| 层 | 载体 | 能否热更 | 判定 |
|---|---|---|---|
| AOT C#(主工程) | Assembly-CSharp |
❌ 必须出包 | createMode == 0 |
| ILRuntime C# | Hotfix.dll(.bytes 下发) |
✅ | createMode == 1 |
| Lua 脚本 | .lua.txt |
✅ | createMode == 2 |
判定入口:KHPluginManager._pluginInfoDict[id].createMode
2. Lua 运行时:五层架构
1 | L5 业务脚本 LuaScript/(500+ .lua.txt,按模块分目录) |
三大机制:初始化(RuntimeLua.Instance 懒创建)→ 加载解密(CustomLoader + LuaCodec)→ 卸载防泄漏
3. ILRuntime:三段式 + 多域
| 层 | 落点 |
|---|---|
| 引擎本体 | Packages/com.ourpalm.ilruntime + Assets/ThirdParty/ILRuntime/ILRuntime/ |
| KH 接入层 | Assets/ThirdParty/ILRuntime/(AppDomain 生命周期 + KHILRuntime 适配器 + ILKexiu 热修) |
| 热更业务工程 | Others/ILRuntimeTools/ILAPPDomain/(11 个域,VS2022 打开 ILAppDomain.sln) |
11 个域:ILAppDomain(主)/ ILCommonDomain(公共,唯一由 C# 侧显式注册,其余域由它的 IL main 自行装配)/ ILKexiuDomain(热修)/ ILMonoDomain / ILTongLingDomain / ILTestDomain / PKNS / PVEGamePlay / SwapPlayerPvp / WanderingExploration / Lib
生命周期:AppDomainManager(多域单例)→ AppDomainMaker(单域构建:Dispose 旧域 → new AppDomain → LoadAssembly 从 MemoryStream 加载 dll+pdb)
4. 更新体系:两层心智模型 ★
VersionManager只负责把文件下载安装到本地磁盘,它不加载 IL/Lua!
加载生效发生在更晚的LoginDefaultPhase。
1 | 【传输安装层】VersionManager(AppCheckAndUpdate 出包 / ResCheckAndUpdate 周版本资源 |
四通道更新表
| 通道 | 载体 | 能否热更 | 生效时机 |
|---|---|---|---|
| 出包更新 | Assembly-CSharp |
❌ | 重装整包 |
| 资源热更 | AssetBundle(bundle.xml 清单) | ✅ | 下次进入使用点 |
| 代码热更 | Hotfix.dll |
✅ | 下次启动加载 DLL |
| 脚本热更 | .lua.txt |
✅ | 下次启动 / 脚本重载 |
关键洞察:
Hotfix.dll和.lua.txt物理上是随资源热更 bundle 一起下发的特殊文件——没有独立的 IL/Lua 下载器。
5. 必知重点与坑
- “热更不生效”二分法:先分传输(下载了吗)还是消费(加载了吗)——
VersionManager日志 vsLoginDefaultPhase时序 - Lua 热更生效时机是”下次启动”,改完 Lua 不会热生效(除非走
reload_lua,见skills/kihan-mcp-server) - IL 热修走
ILKexiuDomain:桥接字段名查表 / 新字段外挂 / 新方法内联自包含,SOP 见workflows/il-hotfix-authoring-workflow.md - 编辑器 PDB / 真机 bytes:编辑器走
EditorInitAppDomain(加载 PDB 可调试),运行时走SyncInitAppDomain
6. 排查速查
| 现象 | 先查 |
|---|---|
| 改动没生效 | 四通道判定:createMode 0/1/2;是 AOT 改动就必须出包 |
| 热更包下载了没生效 | 传输层 vs 消费层二分:LoginDefaultPhase 是否跑到对应步骤 |
| Lua 报找不到类 | Wrap 绑定层是否生成;GenConfig 是否声明导出 |
| IL 域初始化失败 | AppDomainConfig.AppDomainDic;dll/pdb bytes 是否落盘 |
| Lua 泄漏 | V1/V2 共享 VM,卸载走 LuaCodec/LuaScript 释放链 |
7. 记忆口诀
AOT 出包,IL 下 DLL,Lua 下脚本,资源下 Bundle;
下载归 VersionManager,生效归 LoginDefaultPhase;
一个 xLua 一个 VM,ILRuntime 十一个域。
相关笔记
- [[KiHan状态机架构详解]](LoginDefaultPhase 所在的 Boot 链路)
- [[KiHan 网络框架详解]](协议侧)
本文从 LearnByCompany 原始文档 自动同步。
