最佳實踐

创建一个插件有很多种方法,然而如果一个开发者刚刚接触插件开发,那很难保证他不会踩到坑里去。在这里,我们描述了如何充分利用 Sponge API 进行插件开发,在兼容性和可用性之间找到一个平衡点。该部分可能会随着 Sponge 项目的成熟而改变和扩充。

开发 Sponge 插件需注意

下面的开发指南针对于 Sponge 插件开发者。这并不是一个明确或全面的列表,因此它存在的意义仅仅是试图说明一些在开发过程中可能出现的问题,以及它们的比较好的解决方案。

備註

我们保留使用 Sponge 用于描述官方 SpongePowered 项目的权利。请不要使用 Sponge 作为您的插件名称的一部分,除非:(1)您的插件主要涉及到 Minecraft 方块“海绵(Sponge)”,(2)您的插件也有依赖其他 API 的版本(在这种情况下, 可以在标题中加入诸如“For Sponge”等字样)。

经济 API

经济 API 用于把希望使用经济系统的插件(如商店插件)与提供经济 API 的插件联系起来。你可以在 这里 读到关于经济 API 的内容,该部分包含了所有你想要知道的关于经济 API 的部分。

数据包

与拦截数据包、引入自定义物品、方块、实体等相关的任何事情都 不会 计划作为 Sponge API 的一部分。请注意,如果你使用了数据包,那么你很有可能在使用错误的方式考虑问题,因为可能存在现有 Sponge API 完全可以解决的解决方案。在某些情况下,可以添加 Sponge API 所需的任何东西,否则,替代方案往往是使用 Forge API 并创建一个 Mod 来解决问题。

使用 Forge 或者 NMS 的类

我们不建议使用 Forge 或 Minecraft 基类,除非开发者想要制作一个与 Sponge API 兼容的 Mod。大多数使用 NMS(net.minecraft.server)的代码的插件不会轻易地出错,因此这使故障排除非常困难。维护因 NMS 修改而带来的修改也比使用 Sponge API 更困难。想要加入 Sponge API 的 Mod 必须专门编写一个不依赖于底层的 Minecraft 代码的 API 并且可以被 Sponge 插件使用。然而,插件要分别创建并加载用于“兼容”的模块与底层实现(SpongeForge 或 SpongeVanilla)进行交互。

依赖于特定 Minecraft 实现的插件的代码很容易在版本更新后无法正常工作。插件开发者应该标记清楚任何出现不兼容代码的地方。正因如此,这些插件会看起来更像是 「Mod」 。

Mixins

Mixin 是专门用于在其他 Mod 或插件启动前操纵类字节码的工具。FML 将其称为 Coremod,SpongeForge 本身也是一个 Coremod,并且在 Minecraft 启动时使用 Mixin。插件在使用 Mixin 时,需要额外注意可能带来的更高的维护成本。

与 Mod 的界线

有着一些 Mixin 代码的 Sponge 插件实际上也可以被称为 Coremod。

  • 如果想要在 FML 中使用 Mixin,那么相应的代码必须在一个 Coremod 中。当然相应的 JAR 也可能包含一个 Sponge 插件,所以说实际上插件和 Mod 的界线其实很模糊。

  • 如果想要在 SpongeVanilla 中使用 Mixin,那么相关的声明必须出现在 Manifest 文件中。SpongeVanilla 从而可以执行 Mixin 中的代码。

  • 单个 JAR 完全可以在不同的服务端扮演不同的角色(事实上,一个 JAR 可能会包含一个 Tweaker,一个 FML Mod,一个 Bukkit 插件,一个 Sponge 插件,以及/或者一个 LiteMod)。

这里我们给出一些有助于理解的定义。

Tweak Mod(又名 Tweaker)

Tweaker Mod 属于一个子系统级别的 Mod,将会在游戏启动前被 LaunchWrapper 调用从而直接修改游戏代码。Tweaker Mod常常用于 Mod 加载器(如 LiteLoader 或 Forge),或者单独的 Mod(如 Optifine)。在任何情况下,Tweaker Mod 都将会被直接暴露在游戏环境下。Tweaker Mod 一般没有办法保证不同 Minecraft 版本的兼容性。

Coremod

Coremod 一般有着和 Tweaker Mod 一样的能力修改游戏代码,不过它的加载过程一般被 Mod 加载器包装起来了。Coremod 在任何情况下都会被直接暴露在游戏环境下。Coremod 一般没有办法保证不同 Minecraft 版本的兼容性。

Mod

一般模组只能通过 Mod 加载器和游戏交互。一般模组通常可以直接操作游戏中的对象,然而大部分情况下它们只能通过 Mod 加载器提供的代码修改游戏内容。一般模组通常没有办法在不同的 Minecraft 版本间保持兼容性(具体和模组的性质有关)。广义的 Mod 通常指所有拥有修改游戏行为的代码,不过这里以防混淆我们暂且使用这样的定义。

插件

插件一般通过 API 和游戏交互,因此并不直接和游戏对象交互,而只是操作 API 提供的对象。因此插件一般只会在 API 发生不向前兼容的变动时不再兼容(一些插件甚至可以在 API 发生变动时仍然保持兼容性)。

区分这些概念也是很重要的。因为一些 JAR 包含有 Mod,所以它们往往会被归入到 Mod 的类别,因而带来术语上的混淆不清。一些并没有完全和 API 解耦的插件也会被归入 Mod 的类别。这种“插件”在相应的插件 API 还没有完全成熟的时候很常见。

优势

如果一个插件不仅仅局限在调用 API,同时担任一个 Mod ,甚至 Coremod 的工作,那么除了显而易见的缺点(难以保证跨版本兼容性)之外,它也可以同时利用 Mod 的优点(可与游戏代码直接交互)以及插件的优势(对游戏机制的高度抽象,及与其他插件的协作)。

一个主要的优势包括在迁移到更高版本的 Minecraft 时需要的维护成本的降低,因为基于相应的 API 的特性往往会更稳定些。

这些 Mod 的存在可以用于实现插件 API 没有提供的游戏特性(尤其是为了某些特性而不得不使用 Mixin 的时候)。此外,这些 Mod 还可以帮助 Mod 和 Sponge 插件服务交互(如一些想要直接支持权限和消息通道的 Mod)。

和一些 NMS “插件”不同,这种 Mod 和插件的组合让一切都明朗起来。

插件之间的交互

解释如何与其他插件交互, 未完待续