介绍
重要许可声明
以任何形式使用本项目,即表示你在此对本项目许可条款(见许可协议)作出“明确同意”,并确认我(本项目作者)已履行许可协议中“在具体情况下尽合理努力,取得接收者对本许可条款明确同意”的义务。
TooManyRecipeViewers
TooManyRecipeViewers(简称 TMRV)是一个兼容层,可在无需安装JEI物品管理器的情况下,让JEI物品管理器插件与EMI配合运行,由 Nolij 编写。
使用此模组需要安装 EMI。
为什么选择 TMRV,而不是 EMI+JEI(又称 JEMI)?
JEMI 是 EMI 内置的兼容层,旨在让 JEI 插件大部分能够在 EMI 中运行,其实现高度依赖 JEI 的内部机制。它的设计尽可能简单,并依赖 JEI 先处理配方数据,再将数据导入 EMI。
TMRV 与 JEMI 不同——它的目标是彻底替代 JEI API(注意:TMRV 确实包含一些未经修改的 JEI 内部代码,详见JEI 代码复用)。在可行的情况下,TMRV 会用直接映射到 EMI API 的方式替代 JEI API,而不是加载整个 JEI 注册表,再事后查询。这样做有若干优点,包括更高效地利用系统资源;但也有取舍,因为与 JEMI 相比,TMRV 的维护工作要复杂得多。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 加载世界也总是比使用 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 有自己的隐藏物品配置,请改用该配置。TMRV 会完全忽略其他所有 JEI 配置文件,也没有计划支持它们。
配方管理器插件
JEI API 支持“配方管理器插件”。这些插件允许模组控制自己的配方注册表,并在运行时自行处理配方查询。
TMRV 会尝试从这些插件中提取配方,但对大多数插件都不起作用,也绝不代表它已妥善支持此功能。目前没有进一步支持的计划。配方管理器插件是一个过时的概念,如今仍在使用它们的插件寥寥无几;若要妥善支持此功能,就必须使用会对 EMI 造成重大侵入的 mixin,而我无意在本项目中使用这种做法。
运行时注册表变更
JEI API 支持在运行时(即插件注册完成后)修改配方和原料注册表。这一概念与 EMI 不兼容,也不是我想要支持的做法。因此,在调用 IModPlugin.onRuntimeAvailable 之后,所有用于运行时注册表修改的 API 若被调用都将抛出 IllegalStateException,以避免潜在的混淆。
JEI 代码复用
计划是在未来的更新中替换更多 JEI 的内部实现。然而,由于各种原因,JEI 的某些部分根本不值得重新实现。无论如何,TMRV 中已经替换了足够多的 JEI 内容,因此我可以自信地说:
- 通过 mixins 实现对 JEMI 的同等改进是不可行的(至少在不疯狂的前提下),并且
- JEI 的内部实现已被替换或移除得足够多,我不认为这对 JEI 不公平,尤其是考虑到 JEI 的许可证明确允许这样做。
许可证
本项目采用 OSL-3.0 许可证。更多信息请参见 LICENSE。
部分代码在遵守其版权许可证的前提下复制自 EMI 和 JEI。本项目中的所有修改均与本项目其余部分采用相同的许可证,即 OSL-3.0。
常见问题
TooManyRecipeViewers (TMRV) 支持哪些 Minecraft 版本?
TooManyRecipeViewers (TMRV) 支持 Minecraft Java 版 1.20.1–1.21.1,共 2 个版本,可用的加载器:Forge / NeoForge。下载时注意选择和你游戏版本一致的文件。
TooManyRecipeViewers (TMRV) 怎么安装?
先用 PCL2 或 HMCL 启动器安装对应版本的 Forge / NeoForge,再把下载的 .jar 文件放进游戏目录的 mods 文件夹,重新启动游戏即可。开启了版本隔离的,mods 文件夹在 versions/版本名 下面。
评论
登录后评论和评分