在本教程中,CoreMod是指对其他类进行修改的Mod,例如FML为了实现Mod加载功能需要对Minecraft进行修改,它也是一个CoreMod。
这里的其他类可以是Minecraft,也可以是其他Mod,甚至是自己Mod中的某个类。CoreMod在实际操作中,可以对各种来源的类进行修改,方法大同小异,本教程不会特别区别对待。
需要明确两点问题:
-
本教程仅讲解类的修改,虽然这并不是CoreMod的唯一用途,但是按照FML1.13对于CoreMod设计的思路,CoreMod只能受限制的使用JavaScript编写,且无法执行除了修改类以外的其他行为,意味着Forge团队并不支持CoreMod的其他用途,因此不进行讲解。
-
修改其他类不代表一定要使用ASM,Mixin、Javassist、修改二进制字节码、文件整体替换都是一种可行的方案,ASM只是一种工具,同样是因为FML1.13只能使用ASM进行CoreMod操作,因此教程以ASM为主。
- 可以对Minecraft、其他模组的类进行修改,这也是最主要的用途
- 可以在Minecraft启动前执行代码,这一特性被用于环境预处理等操作
CoreMod需要特别注意避免调用Minecraft、其他普通Mod,甚至自己的普通Mod部分,这样的行为会导致这些类在CoreMod全部修改完成前被过早的加载进ClassLoader
,以至于游戏崩溃,这样的崩溃甚至难以在crash-report中轻易的找出原因。
FML1.13限制了CoreMod的JavaScript可以使用的类,从根源上避免了这种行为的发生。
CoreMod可以通过修改其他类的行为是直接修改文件还是在运行时动态修改分为两种类型,在各ModLoader及其副产物(例如LaunchWrapper、ModLauncher)的帮助下,我们可以容易的运行时修改其他class而不用死板于使用MCP(Mod Coder Pack)等工具循环进行如下操作:
- 反混淆Minecraft
- 反编译Minecraft
- 修改Minecraft代码
- 编译Minecraft
- 提取并混淆发生变化的class文件
- 将混淆后的class文件进行游戏核心文件替换
抛开繁琐的流程不谈,更重要的是,如果两个CoreMod修改了同一个类,他们必然会发生冲突,此时我们为了使其兼容需要一行一行的合并对class文件的修改,这显然不是一种合理的解决方案。
面对这种致命的问题,这种由CoreMod自行完成的修改其他类的行为显得问题百出,就需要诸如FML的ModLoader的统一调度的帮助下完成。在合理的调度机制下,CoreMod之间可以通过动态修改确定修改的先后顺序,可以通过感知是否存在冲突来进行兼容操作,甚至可以无冲突地同时进行修改,这是几乎自顾自的原版CoreMod不具备的能力。