
TooManyRecipeViewers
由Nolij编写的用于在EMI中运行JEI插件的兼容层
重要许可声明
以任何形式使用本项目,即表示您对本项目许可条款(见许可)给予“明确同意”,并确认我(本项目作者)已履行许可中“在合理情况下努力获得接收者对许可条款的明确同意”的义务。
TooManyRecipeViewers
TooManyRecipeViewers(简称 TMRV)是一个兼容层,用于在不安装 JEI 的情况下,运行 JEI 插件搭配 EMI。由 Nolij 编写。
使用本模组需要安装 EMI。
为什么使用 TMRV 而不是 EMI+JEI(又称 JEMI)?
JEMI 是 EMI 内置的兼容层,通过大量依赖 JEI 内部实现,使 JEI 插件_基本_能在 EMI 上运行。它设计得尽可能简单,依赖 JEI 先处理配方数据,然后导入 EMI。
TMRV 与 JEMI 不同——它旨在完全替代 JEI API(注意:TMRV 确实包含一些未经修改的 JEI 内部代码——见 JEI 代码复用)。TMRV(在可行的情况下)将 JEI API 替换为 EMI API 的直接映射器,而不是加载整个 JEI 注册表然后事后查询。这有几个优点,包括更有效地利用系统资源,但这也是一种权衡,因为 TMRV 的方法使维护工作比 JEMI 复杂得多。JEMI 是故意这样设计的,让 EMI 的开发可以专注于改进 EMI 本身,我完全支持这种做法。
简而言之:TMRV 比 JEMI 高效得多,但代价是维护起来比 JEMI 费力得多,而且没有人应该期望 EMI 投入这么多精力去支持一个在设计时故意未被参考的 API。要庆幸 EMI 开箱就能加载 JEI 插件——这本身就付出了不少努力。
话虽如此,TMRV 相比 JEMI 有两个主要优势:
1. 插件兼容性
TMRV 对 JEI API 的覆盖比 JEMI 更好(有一个例外——见已知 API 限制)。截至撰写本文时,这包括:
- 更好地转换内置配方类型(JEMI 仅支持合成和信息配方类型;TMRV 支持所有内置的 JEI 配方类型)
- 物品/搜索别名支持
createRecipeExtras支持
2. 效率
使用 TMRV,你进入世界总是比 JEMI 更快。这是因为 JEI 插件初始化会阻塞世界加载——在初始化所有 JEI 插件之前,你无法开始游戏。而 EMI 是在世界加载_之后_异步加载插件的。
这意味着即使 TMRV 加载 JEI 插件比 JEI 本身_更慢_(事实并非如此,TMRV 加载速度明显更快——见基准测试),使用 TMRV 的世界加载总是比 JEMI 更快。
如前所述,TMRV 将大部分 JEI API 替换为对应 EMI API 的映射器——这意味着 JEI 内部实现的很大一部分可以完全移除。无需初始化和存储整个 JEI 配方注册表——TMRV 只需将 JEI API 调用转换为 EMI 调用,并将响应转换回 JEI 格式。可以把 TMRV 想象成 Wine 或 Proton,而 JEMI 是虚拟机。JEMI 使用真实的 JEI,因此在某些场景下 TMRV 会出错而 JEMI 不会(注意这不一定意味着 JEMI 真正支持某种场景,只是看起来像支持),但 TMRV 总体上比 JEMI 更高效。
基准测试
完整结果和获取步骤记录在 BENCHMARKS.md 中。这些结果不是挑选出来的。测试步骤完全按照该文件中的文档执行。我鼓励社区进行验证。
加载时间
| TMRV | JEMI | 对比项 | |
|---|---|---|---|
| Craftoria | 1582ms(世界加载前 5ms,世界加载后 1577ms) | 11036ms(世界加载前 10000ms,世界加载后 1036ms) | -9454ms(世界加载前 -9995ms,世界加载后 +541ms) |
| ATM10 | 4951ms(世界加载前 3ms,世界加载后 4948ms) | 20132ms(世界加载前 15550ms,世界加载后 4582ms) | -15181ms(世界加载前 -15547ms,世界加载后 +366ms) |
| Finality: Omnia | 3010ms(世界加载前 6ms,世界加载后 3004ms) | 6354ms(世界加载前 4425ms,世界加载后 1929ms) | -3344ms(世界加载前 -4419ms,世界加载后 +1075ms) |
内存使用
| TMRV | JEMI | 对比项 | |
|---|---|---|---|
| Craftoria | 4.278 GiB | 4.386 GiB | -110.6 MiB(约) |
| ATM10 | 4.401 GiB | 5.273 GiB | -892.9 MiB(约) |
| Finality: Omnia | 1.947 GiB | 2.065 GiB | -120.8 MiB(约) |
已知 API 限制
JEI 配置文件
.minecraft/config/jei/blacklist.json 是 TMRV 唯一读取的 JEI 配置文件。该文件对于原版物品类型以及由 JEI 插件添加的模组物品类型应该_可以_正常工作(这不包括原生支持 JEI 和 EMI 的模组,如 Mekanism)。这是为从 JEI 迁移过来的整合包提供的过渡方案。JEMI 也有类似的缺陷。EMI 有自己的隐藏物品配置——请使用该配置。所有其他 JEI 配置文件都被 TMRV 完全忽略,并且没有计划支持它们。
配方管理器插件
JEI API 支持“配方管理器插件”。这些插件允许模组控制自己的配方注册表,并在运行时自行处理配方查找。
TMRV 将尝试从这些插件中提取配方,但这对大多数插件无效,并且绝不是对该功能的适当支持。超出此范围的支持没有计划。配方管理器插件是一个过时的概念,很少有插件仍在使用,并且如果没有非常侵入性的 EMI mixin,就无法正确支持——这是我在这项目中不打算使用的。
运行时注册表更改
JEI API 支持在运行时(即插件注册完成后)修改配方和物品注册表。这个概念与 EMI 不兼容,我也不想支持这种做法。因此,在 IModPlugin.onRuntimeAvailable 被调用后,所有用于运行时注册表修改的 API 在被调用时都会抛出 IllegalStateException,以避免潜在的混淆。
JEI 代码复用
计划在未来更新中替换更多 JEI 内部实现。然而,由于各种原因,JEI 的某些部分根本不值得重新实现。无论如何,TMRV 中已经替换了足够多的 JEI 代码,我可以自信地说:
- 使用 mixin 实现与 JEMI 相同的改进是不可行的(至少不能理智地实现),并且
- 已经有足够多的 JEI 内部实现被替换或移除,我认为这对 JEI 并不不公平,尤其是考虑到 JEI 的许可证明确允许这样做。
许可
本项目根据 OSL-3.0 许可。更多信息,请参阅 LICENSE。
部分代码复制自 EMI 和 JEI,并遵守其版权许可。本项目中的所有修改均与本项目其他部分使用相同的许可,即 OSL-3.0。
正在加载版本记录…
正在加载评论…
评论在新手盒子客户端中发表,这里同步展示。