如果你注册了全新 ArgumentTypeInfo,你需要知道的事

考虑到 TeaCon 2023 出现了两次同类问题,特撰写此教程以供不时之需:

在 Minecraft 1.20 和 1.20.1 的 Forge 下,你要注册两遍 ArgumentTypeInfo:

  1. 第一遍是给 ForgeRegistry<ArgumengType<?>> 的,你可以用 DeferredRegister,也可以考虑直接走事件

  2. 第二遍是给 ArgumentTypeInfos 的。你需要调用这个类下的 registerByClass 方法。注意这个方法是 Forge 自己加的。在别的地方(NeoForge 除外)是没有的。

两次注册缺一不可。若缺失一次注册,可能会引发各种难以调试的问题。

参考代码(来自 AreaControl):

@Mod.EventBusSubscriber(modid = "area_control", bus = Mod.EventBusSubscriber.Bus.MOD)
public class AreaControlPreSetup {

    // 这个记得要注册进 Mod 的事件总线,也就是 FMLJavaModLoadingContext.get().getModEventBus() 那个。
    static final DeferredRegister<ArgumentTypeInfo<?, ?>> ARG_TYPES = DeferredRegister.create(ForgeRegistries.COMMAND_ARGUMENT_TYPES, "area_control");

    static final RegistryObject<ArgumentTypeInfo<AreaPropertyArgument, ?>> AREA_PROPERTY_ARG_TYPE = ARG_TYPES.register("area_property", () -> SingletonArgumentInfo.contextFree(AreaPropertyArgument::areaProperty));
    static final RegistryObject<ArgumentTypeInfo<DirectionArgument, ?>> DIRECTION_ARG_TYPE = ARG_TYPES.register("direction", () -> SingletonArgumentInfo.contextFree(DirectionArgument::direction));

    static final RegistryObject<ArgumentTypeInfo<GroupArgument, ?>> GROUP_ARG_TYPE = ARG_TYPES.register("group", () -> SingletonArgumentInfo.contextFree(GroupArgument::group));

    @SubscribeEvent
    public static void setup(FMLCommonSetupEvent event) {
        ArgumentTypeInfos.registerByClass(AreaPropertyArgument.class, AREA_PROPERTY_ARG_TYPE.get());
        ArgumentTypeInfos.registerByClass(DirectionArgument.class, DIRECTION_ARG_TYPE.get());
        ArgumentTypeInfos.registerByClass(GroupArgument.class, GROUP_ARG_TYPE.get());

        AreaSelectorOption.register();
    }
}