跳到主要内容
版本:latest

构建和热更新

构建游戏

  • 运行HybridCLR/Generate/All
  • Build Settings中导出工程或者直接Build
  • 创建AOT快照,同时将AOT快照目录加入版本管理
  • 将AOT快照中的MetaVersions目录加入StreamingAssets目录,随包携带(可选,但强烈推荐)

创建AOT快照

危险

AOT快照中的dll必须精确地与构建出的主包中二进制代码一致,请务必在导出工程或者Build后再创建!

流程如下:

  • 创建AOT基础快照文件
  • 为基础AOT快照中的dhe dll生成meta version
  • 将最终的AOT快照目录加入版本管理

创建AOT基础快照文件

调用MetaVersionWorkflow.CreateAotSnapshot(BuildTarget target, string outputSnapshotDir)创建快照基础文件。

CreateAotSnapshot做了以下工作:

  • 复制所有AOT和DHE dll
  • 复制inject rule文件到InjectRules目录
  • 创建manifest.json,记录所有DHE程序集列表

基础快照目录结构如下:

  AotSnapshot
├── *.dll
├── InjectRules
├──rule1.xml
├──rule2.xml
└── manifest.json

为基础AOT快照中的dhe dll生成meta version文件

调用MetaVersionWorkflow.GenerateAotSnapshotMetaVersionFiles(string prevSnapshotDir, string curSnapshotDir)为快照中dhe dll生成对应的meta version文件。

MetaVersionWorkflow.GenerateAotSnapshotMetaVersionFilesprevSnapshotDir的参数规则:

  • 如果是第一个AotSnapshot,由于不存在更旧的AotSnapshot,prevSnapshotDir取null。
  • 如果项目使用单主包的模式,即同时只有一个有效主包,发布新主包后旧主包失效,则prevSnapshotDir取null。
  • 如果项目使用多主包模式,即发布新主包后旧主包仍然有效,则prevSnapshotDir参数取上一个发布的主包的AotSnapshot目录。

GenerateAotSnapshotMetaVersionFiles生成了以下文件:

  • meta version和spec文件。生成到MetaVersions目录下
  • signature-mapper.json文件

生成前目录结构如下:

  Snapshots
├── PrevAotSnapshotDir
├── *.dll
├── InjectRules
├── MetaVersions
├── *.mv.bytes
├── *.mv.spec
├── *.mv.diff.spec
├── signature-mapper.json
└── manifest.json
├── CurrentSnapshotDir
├── *.dll
├── InjectRules
└── manifest.json

生成后新增了MetaVersions目录和signature-mapper.json文件,最终目录结构如下:

  Snapshots
├── PrevAotSnapshotDir
├── *.dll
├── InjectRules
├── MetaVersions
├── *.mv.bytes
├── *.mv.spec
├── *.mv.diff.spec
├── signature-mapper.json
└── manifest.json
├── CurrentAotSnapshotDir
├── *.dll
├── InjectRules
├── MetaVersions (New)
├── *.mv.bytes
├── *.mv.spec
├── *.mv.diff.spec
├── signature-mapper.json (New)
└── manifest.json

随包携带AOT快照的meta version文件(可选,但强烈建议)

RuntimeApi::LoadDifferentialHybridAssemblyWithMetaVersion的参数originalMetaVersionFileBytes为DHE程序集的AOT快照中相应的meta version文件内容。 这个meta version文件每个主包都不一样,并且在构建主包时已经完全确定。此文件比较小,强烈建议随主包携带。

多平台

绝大多数游戏都会发布多个平台,由于不同平台之前的主包AOT dll差异较大,我们强烈建议为每个平台单独维护AotSnapshot树。目录结构类似这样:

  Snapshots
├── PreAotSnapshotDir-StandaloneWindows64
├── CurrentAotSnapshotDir-StandaloneWindows64
├── PreAotSnapshotDir-Android64
├── CurrentAotSnapshotDir-Android64
├── PreAotSnapshotDir-iOS
├── CurrentAotSnapshotDir-iOS

例如,计算新发布的Win64主包的meta version时,使用上一个发布的Win64主包的snapshot目录和新主包的snapshot计算该新主包的meta version。

Snapshot的版本管理

上一节多平台给出的目录结构实际上并不方便版本管理。一个适合版本管理的目录结构应该是这样的:

  Snapshots
├── AotSnapshotDir-StandaloneWindows64
├── AotSnapshotDir-Android64
├── AotSnapshotDir-iOS

Snapshot更新流程如下:

  • 创建一个最新主包的CurrentAotSnapshotDir-{buildTarget}目录。
  • CurrentAotSnapshotDir-{buildTarget}AotSnapshotDir-{buildTarget}对比计算出CurrentAotSnapshotDir-{buildTarget}的meta version文件。
  • CurrentAotSnapshotDir-{buildTarget}替换AotSnapshotDir-{buildTarget}
  • 提交AotSnapshotDir-{buildTarget}到仓库。

发布热更新

旗舰版本是专业版本和社区版本的超集,即支持社区版本的纯解释程序集,也支持DHE程序集,两者可以并存。

由于DHE程序集会编译到AOT中,因此DHE程序集不能依赖普通的纯解释热更新程序集,否则会构建主包时就会因编译错误而失败,但普通的热更新程序集可以依赖DHE程序集。 DHE程序集也可以依赖DHE程序集。

普通的热更新程序集的配置和发布流程与社区版本完全相同,这儿不再赘述,只介绍DHE程序集的热更流程。

  • 使用 HybridCLR/CompileDll/ActivedBuildTarget 生成热更新dll。
  • 生成热更新程序集的meta version文件。
  • 将最新的热更新dll和meta version文件加入热更新资源管理系统。

生成热更新程序集的meta version文件

调用MetaVersionWorkflow.GenerateHotUpdateMetaVersionFiles(string aotSnapshotDir, string hotUpdateSnapshotDir)生成热更新程序集的meta version文件。 其中aotSnapshotDir为最新的AotSnapshot-{buildTarget}目录,hotUpdateSnapshotDir为最新的热更新程序集目录。

调用完该函数后,将在{hotUpdateSnapshotDir}/MetaVersions目录下生成DHE程序集对应的meta version文件。目录结构类似:

  HotUpdateSnapshot
├── *.dll
├── MetaVersions
├── *.mv.bytes
├── *.mv.spec
├── *.mv.diff.spec

示例代码如下:

        public static void GenerateHotUpdateMetaVersionFiles(BuildTarget target)
{
var latestSnapshotSolutionDir = GetAOTAssemblySnapshotDir(target);
var newHotUpdateSolutionDir = SettingsUtil.GetHotUpdateDllsOutputDirByTarget(target);
MetaVersionWorkflow.GenerateHotUpdateMetaVersionFiles(latestSnapshotSolutionDir, newHotUpdateSolutionDir);
}

*.mv.spec*.mv.bytes的可阅读版本,而*.mv.diff.spec记录了*.mv.spec中发生版本变化的元数据。这两类文件只用于方便追踪问题,运行过程中用不到它们。 建议将它们加入到仓库,但不要加入到热更新资源,因为没有任何用途!

其他

UserEditorSettings.development选项

发布主包时的development选项和发布热更新的development选项必须一致,即创建AotSnapshot和编译热更新dll时的UserEditorSettings.development选项必须一致。因为development会对最终编译出的dll有巨大影响, 如果development参数不一致会导致计算出meta version有巨大变化!

HybridCLRSettings.differentialHybridAssemblies 列表变化

MetaVersionWorkflow.GenerateAotSnapshotMetaVersionFiles(string prevSnapshotDir, string curSnapshotDir)要求prevSnapshotDir和curSnapshotDir快照的DHE程序集列表相同。

如果从某个主包起,新增或者删除了DHE程序集,都会导致生成meta version失败。解决办法为自这个主包起,创建一个全新的AotSnapshot-{buildTarget}-v2版本树。目录类似如下:

```txt
Snapshots
├── AotSnapshotDir-StandaloneWindows64-v1
├── AotSnapshotDir-StandaloneWindows64-v2
  • 使用v1版本的DHE列表配置,生成v1版本的AotSnapshot和HotUpdateSnapshot的meta version文件。
  • 使用v2版本的DHE列表配置,生成v2版本的AotSnapshot和HotUpdateSnapshot的meta version文件。

发布热更新时,v1的主包只能加载v1版本的HotUpdateSnapshot的dll和meta version文件。v2版本的主包只能加载v2版本的HotUpdateSnapshot的dll和meta version文件。