IMC 集成 API

基本信息

属性 值
IMC 消息键 addMineTweakerScript(大小写不敏感比较,MineTweakerMod.java:119)
接收端 MineTweakerMod.onIMCEvent,@Mod.EventHandler(MineTweakerMod.java:116-130)
载荷类型 String 消息或 NBT 消息({name, content} 两字段)
脚本容器 ScriptProviderCustom("intermod")(MineTweakerMod.java:107)
组名 intermod
本仓发送方 无 —— 纯对外接口,供其他模组推送脚本

这是本模组对外暴露的唯一正式集成接口:其他模组通过 Forge 的 InterModComms 在自己的初始化阶段推送 ZenScript 片段,MineTweaker 会把它们编入同一批脚本执行。

消息格式

onIMCEvent 遍历 event.getMessages(),只处理键等于 addMineTweakerScript(equalsIgnoreCase)的消息,其余静默忽略(MineTweakerMod.java:118-119)。

字符串载荷

if (imcMessage.isStringMessage()) {
    scriptsIMC.add(imcMessage.getSender() + "::imc", imcMessage.getStringValue());
}

(MineTweakerMod.java:120-121)组名为 "<发送方 modid>::imc"。

NBT 载荷

} else if (imcMessage.isNBTMessage()) {
    NBTTagCompound message = imcMessage.getNBTValue();
    scriptsIMC.add(
            imcMessage.getSender() + "::" + message.getString("name"),
            message.getString("content"));
}

(MineTweakerMod.java:122-127)组名为 "<发送方 modid>::<name>",name 字段允许推送方自定义分组。

ScriptProviderMemory.collect / ScriptProviderCustom 由此成为第三级脚本来源,参与三级级联(顺序最末,优先级最低)。

Java 侧扩展点

MineTweakerAPI 提供 4 个供其他模组调用的注册方法(均无 ZenScript 注解,仅 Java 可见):

方法 作用 源码行
registerClass(annotatedClass) 注册一个带 @ZenClass / @ZenExpansion / @BracketHandler 的类 MineTweakerAPI.java:304-326
registerBracketHandler(handler) 直接注册括号处理器实例 MineTweakerAPI.java:353
registerRemover(remover) 注册配方删除器 MineTweakerAPI.java:343-345
registerGlobalSymbol(name, symbol) 注册自定义全局符号 MineTweakerAPI.java:334-336

registerClass 是模组间共享脚本类型的主要途径:其他模组只要提供带注解的类并调用它,脚本里就能用。推荐做法是走 IMC 推脚本而非直接调这些方法。

已失效的 5 个 ClassRegistry 常量

MineTweakerMod.java:59-63 声明了 5 个「按模组拆分」的类注册表字符串:

private static final String[] REGISTRIES = { "minetweaker.mods.ic2.ClassRegistry",
        "minetweaker.mods.nei.ClassRegistry", "minetweaker.mods.mfr.ClassRegistry",
        "minetweaker.mods.gregtech.ClassRegistry", "minetweaker.mods.buildcraft.ClassRegistry" };
private static final String[] REGISTRY_DESCRIPTIONS = { "IC2 mod support", "NEI mod support", "MFR mod support",
        "GregTech mod support", "Buildcraft mod support" };

这 5 个类在本仓全部不存在。 逐个检查 src/main/java/minetweaker/mods/<pkg>/ClassRegistry.java 均为 MISSING;git ls-files | grep -i ClassRegistry 全仓只命中 minetweaker/ClassRegistry.java(其 getClasses 还是空壳)。mods/ 下只有 ic2/ 与 nei/ 两个子目录,没有 mfr/、gregtech/、buildcraft/。

registerClassRegistry(String, String) 吞掉 ClassNotFoundException 返回 false(MineTweakerAPI.java:289-296),调用方 MineTweakerMod.java:144-146 不看返回值,于是:

  • 5 次循环每次静默失败,无异常、无日志。
  • Loaded class registry: <description> 一条都不会打印。
  • MFR / GregTech / Buildcraft 集成在本仓没有任何代码,其 REGISTRY_DESCRIPTIONS 描述字符串是纯死数据。

实际生效的 IC2 / NEI 支持改由 MineTweakerRegistry 构建期自动扫描(见类注册机制)。

@ModOnly 门控机制

模组专属脚本类的门控靠 @ModOnly(定义在 minetweaker/annotations/ModOnly.java):

@ZenClass("mods.ic2.Macerator")
@ModOnly("IC2")
public class Macerator { ... }

registerClassRegistry 在注册每个类前检查(MineTweakerAPI.java:245-256):

for (Annotation annotation : cls.getAnnotations()) {
    if (annotation instanceof ModOnly) {
        String[] value = ((ModOnly) annotation).value();
        String version = ((ModOnly) annotation).version();
        for (String mod : value) {
            if (!loadedMods.contains(mod)) continue outer;
            if (!loadedMods.get(mod).getVersion().startsWith(version)) continue outer;
        }
    }
}

语义:

  • 注解值是 AND 关系:列出的每个 mod 都必须已加载,任一缺失即跳过该类。
  • version() 默认为空串,startsWith("") 恒为 true,因此默认不做版本检查。
  • 未通过门控的类不会打印任何提示。

全仓 @ModOnly 共 23 处,全部在 mods/ 下,api/ 与 mc1710/ 一处都没有:

区域 数量 明细
mods/ic2/ 22 14 台机器 + 4 个作物类 + 2 个扩展 + IC2BracketHandler + IC2ExplosionWhitelist
mods/nei/ 1 NEI.java

即只有模组专属支持层做门控,核心 API 不做 —— 这符合设计:核心 API 必须在任何模组环境下都可用。门控依赖 ILoadedMods.contains,即 @ZenOperator(CONTAINS),见Minecraft 层 API。

相关条目