mdcdi1315的BML

mdcdi1315的BML

又一个支持我多平台项目的库!!!(也可能支持其他项目!)

mdcdi1315 的 Base Mods Library (BML)

重要提示:对于 Fabric,你还需要安装 Fabric API!!

这是提供我的基础模组库的项目,从今以后我的多平台模组将重度依赖于此。

该库受到了其他优秀模组的启发(例如 Balm 或 Architectury API,它们也都是很棒的库),但本库包含更多实用工具,并且比这些模组更加完整(还提供了对自定义注册表、数据包注册表等的支持!!)。

当然,如果仅安装此库而没有任何依赖它的模组,那么这个模组本身是无用的。

支持的平台

该库支持 1.21.1+ 版本的 Fabric、Forge 和 NeoForge(所有依赖此库的模组都应能正常运行)。

技术细节与背景

此库与其他抽象层库不同,旨在深入 Minecraft 内部,尽可能多地支持模组加载器的功能,同时在此过程中不破坏其他模组。此外,还需要向模组加载器指明模组本身如何加载。

该库的最终目标是让大型模组能够借此在所有可能的模组加载器上运行。像 Create 这样的大型模组,由于不同模组加载器提供的特性差异,很难在不同加载器上获得支持。

在跨模组加载器的场景下,Minecraft 模组开发中另一个难点是:开发者无法修改对许多 Minecraft 类的访问权限,因为这就像在原版 Minecraft 中进行模组开发一样。虽然 Mixin 项目覆盖了一些情况,但并不能解决所有问题。

为了解决这些问题,该库提供了轻量级的包装器(称为 Contract,合约),用于封装模组加载器和 Minecraft 类,从而实现平台无关性。这些合约在模组加载过程中会分配一个特定模组加载器实现的对象。然后,合约被提供给模组本身,以便模组可以自由地完成所需操作。

此外,该库将模组视为 Minecraft 实例中具有指定生命周期的真实实体——也就是说,模组拥有一些特性,使得围绕它们进行开发更加自然。同时,库中还定义了一些辅助方法用于常见任务(例如获取已知的模组实例)。因此,该库提供的所有组件本身就能作为一个非常优秀的模组加载器解决方案独立存在(不过出于显而易见的原因,它并没有这样做)。

现代模组面临的另一个问题是配置文件。目前仅为此目的就存在超过 5 个库(更不用说 Forge 和 NeoForge 也定义了它们自己的配置系统)。因此,该库提供了自己的一套非常完整的配置系统,具有高度灵活性,可以满足各种需求。在此基础上,该库还内置了对著名的屏幕配置库 Cloth Config API 的支持。更进一步,模组开发者也可以(为什么不呢?)注册他们自己制作的自定义配置屏幕。最后,对于仅限 Fabric 模组加载器的情况,该库还内置了对 ModMenu 模组的支持,这样模组开发者无需在开发环境中额外操作,即可挂接他们的配置屏幕。

由于其本质,Minecraft 中总是需要以某种形式加载或存储数据,无论是 JSON、NBT 还是其他可以通过 Mojang 序列化库支持的格式。然而,这种方式会占用可观的 CPU 和内存资源,并且不太好用,尤其是对于那些刚接触 Minecraft 庞大复杂性的模组开发者来说。为此,该库为许多应用场景提供了通用且易用的 Codec 实现,并且注重性能。

虽然所有这些功能都很不错,但还有一个因素被忽略了:Java 运行时本身。Java 饱受大量问题的困扰,而模组总是编写即时代码,这本身就非常脆弱且不安全。在开始我的模组开发体验时,我注意到很多次模组都在进行非常脆弱的操作。甚至 Minecraft 本身也有这个问题。作为一名 .NET 开发者,我很快意识到了类型安全的重要性。因此,该库提供了一小部分 .NET API,这些 API 拥抱类型安全,使代码更健壮、更不易出错。库中的大多数对象都强调类型安全,并通过这些 API 为已知的代码状态定义了异常。

然而,所有这些特性仍不足以让一个库变得完美。最重要的是,该库努力保持与之前版本的 ABI 兼容性。如果无法做到,相应的组件会被适当地弃用或修改。例如,我目前正在开发的一个模组是基于该库 1.0.11 版本构建的,而到了 1.0.15 版本,它仍然能正常工作!

不过,由于支持范围广泛,该库并非毫无错误,使用过程中可能会发现 Bug。如果发现任何 Bug,请及时报告!