使用 Project Launcher 打包项目时遇到 ZenStore 的报错

我们已经通过引擎源码了解到这个问题的原因,以下是原因分析:

首先是在 ProjectLauncherModel.cpp,SetProfileContentScheme 方法这里,对于 Content Scheme 不使用散文件和 On the fly 的情况,都会将 Profile 的 bUseZenStore 属性设置为 true

然后根据 LauncherWorker.cpp,CreateUATCommand 方法的实现,Profile 启动时,因为 bUseZenStore 属性为 true,所以强制给 UAT 命令添加了 -zenstore 参数,从而在 Cook 步骤生成 zenfs.manifest 文件。

最后执行 Archive 步骤时,根据 CopyBuildToStagingDirectory.Automation.cs,ApplyStagingManifest 方法的实现,对于使用 Pak 且不使用 IoStore 的情况,要求不能出现 zenfs.manifest 文件

我们也了解过引擎源码的版本,以上处理是在 5.6.0 版本新增的,在最新的 5.7.3 版本里仍然存在,而且与平台无关,无论打包哪个平台,只要使用 Pak,不使用 IoStore,并且执行 Archive 步骤,就必然会出现这个错误。

我们想了解引擎做此番设计的目的,为什么在 Pak 模式下会强制添加 -zenstore 参数,以及为什么不允许在存在 zenfs.manifest 文件的情况下进行 Archive。另外我们也注意到在 ProjectLauncherModel.cpp,SetProfileContentScheme 方法里有一行注释,这是否意味着当前的功能还在完善当中

Steps to Reproduce
这个问题只出现在使用 Project Launcher 打包项目的情况,如果是使用 Package Project 功能打包项目则不会出现问题。

以下是可以稳定复现问题的步骤:​

  1. 打开 Project Launcher
  2. 新建一个 Launch Profile​
  3. Platform 选择 Android​/Android (ASTC)
  4. Content Scheme 选择 Pak Files
  5. 不勾选 Use Io Store
  6. ​勾选 Cook Content
  7. 勾选 Build the game
  8. 勾选 Archive Build​
  9. 填写 Archive Directory,例如​ Saved/StagedBuilds
  10. 不勾选 Deploy To Device​
  11. 不勾选 Run​
  12. 启动 Profile

​按照以上步骤,Profile 在执行到 Archive 这一步时,就会出现报错,提示出现了预期之外的 zenfs.manifest 文件。而如果在第5步中,勾选 Use Io Store,就可以解决这个问题,不过我们暂时不打算启用 IoStore。

您好,这里应该是有一些逻辑处理不正确,iostore是zenstore的前提,所以使用zenstore的话要求iostore必须打开

因此在第一张代码截图的地方就应该加上iostore的判断

抱歉,由于这个功能推出其实比较久了…我搜索了一下,内部的一些资料找不到了​…暂时没有这类数据

我试了一下,最简单的改法应该是 ​

	virtual bool IsUsingZenStore() const override
	{
		return bUseZenStore && bUseIoStore;
	}

按照您的改法,确实可以解决问题🌹 。

除了这个 ZenStore 的报错之外,其实我们对于 IoStore 和 ZenStore 这两个概念还存在一些疑惑。我们在最新的官方文档里搜索这两个关键字,只搜到了 ZenLoaderZenServer 两个概念,其中 ZenLoader 是一种经过优化的运行时资源加载方案,使用 .utoc 和 .ucas 容器文件代替 .pak 文件,ZenServer 则是一种存储方案,用于提高 cook,stage 和 deploy 操作的效率。

可否请您介绍 IoStore 和 ZenStore,ZenLoader 和 ZenServer 这几个概念以及它们之间的关系呢?另外,如果我们不启用 IoStore 和 ZenStore,继续使用 .pak 文件作为资源容器,会有什么问题?

IoStore — 核心容器格式,是一切的基础

  • 这是最底层的概念,定义了新的资源打包格式:.utoc(目录)+ .ucas(内容)
  • 取代传统单一 .pak 文件,所有资源通过 FIoChunkId(Hash)寻址
  • 是 ZenStore / ZenLoader 能正常工作的前提条件

ZenStore — Cook 阶段的存储后端

  • 在 Cook/Stage/Deploy 流程中,把 cooked 资源存入本地 ZenServer,实现增量 cook 和快速分发
  • 相当于 Cook 端的"智能缓存层",你的日志里也能看到 ZenStore Establishing oplog 这样的输出

ZenServer — 本地存储服务进程

  • 就是跑在后台的那个服务,ZenStore 写入、ZenLoader 读取都依赖它

ZenLoader — 运行时资源加载器

  • 基于 IoStore 容器格式的优化运行时加载器,替代传统的 PakFile 加载路径
  • 使用 .utoc/.ucas 而非 .pak,加载效率更高

禁用 IoStore 继续用 .pak 会有什么问题:

  • 加载性能明显下降,尤其是大型项目;
  • ZenStore/ZenLoader完全失效,无法使用

感谢您的详细回答。请问启用 IoStore 后对于运行时资源加载性能的提升,有没有一些具体数据可以提供给我们参考呢?例如一个项目,加载同一个资源,启用 IoStore 后的加载效率大概能有多少提升?

好的,那我们就自行做些测试吧。感谢您的回复,这个问题可以关闭了。