本章开始我们正式进入Java代码编写。
Forge提供了一套便利的注册表系统。Forge注册表用于注册和查询各种类型信息,常见的如物品类型、方块类型、实体类型、方块实体类型等。
1. Forge注册表的调用、ResourceLocation
Forge注册表的基类(接口)为IForgeRegistry
。Forge提供的注册表以静态常量的形式位于类ForgeRegistries
中,调用时使用:ForgeRegistries.ITEMS
即可获取物品注册表,另外ENTITY_TYPES
和BLOCKS
为实体类型和方块注册表。
Forge注册表在调用时可视为一个从ResourceLocation
到对象的映射。ResourceLocation
是Minecraft一种常见的键类型,由命名空间和路径两个字符串组成(仅允许小写字母、数字和下划线)。ResourceLocation
可以用于表示资源文件路径,但其本身并非必然具有实际含义,可以简单地视为两个字符串的组合。ResourceLocation
通常显示为namespace:path
的格式。其使用如下:
ResourceLocation key0 = new ResourceLocation("namespace", "path") // "namespace:path"
ResourceLocation key1 = new ResourceLocation("namespace:path") // "namespace:path"
ResourceLocation key2 = new ResourceLocation("path") // "minecraft:path".("minecraft"是默认命名空间)
key0.getNamespace(); // "namespace"
key0.getPath(); // "path"
通常在作为键时,其命名空间为模组ID。Forge注册表的查询类似于Java Map
,但请注意当试图查询一个不存在的键时,其会返回默认值而不是null
。例如:
EntityType<?> type = ForgeRegistries.ENTITY_TYPES.getValue(new ResourceLocation("something:unexisting"))
会返回猪的实体类型,而不是null
。这也是有时候缺失实体类型的刷怪类道具/方块刷出猪的原因。
2. 向注册表中注册内容
向Forge注册表中注册内容的最常用方法是使用延迟注册(DeferredRegister
)。新建类com.sodiumzh.tutorial.registries.ItemRegistry
,声明一个静态常量:
public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, ForgeTutorial.MODID);
这样就创建了一个用于物品的延迟注册器。create
的两个参数分别为目标注册表,以及其注册内容的键命名空间。
注册具体对象时,在DeferredRegister
的下方声明静态常量:
public static final RegistryObject<Item> TEST_ITEM = ITEMS.register("test_item", () -> new Item(new Item.Properties()));
这向ITEM
这个DeferredRegister
中注册了一个键为test_item
的默认物品。最终注册到注册表中时,这个物品的键是forge_tutorial:test_item
。
DeferredRegister#register
的第二个参数为Supplier
。这是为了在实际注册到注册表时再构建对象,而非声明时立即构建。这也是“延迟”一词的由来,因为DeferredRegister
并非立即将内容注册到注册表中,而是将自身注册到Mod事件总线(目前可以姑且理解为模组加载流程)中。当加载进行到注册表注册阶段时,所有的DeferredRegister
集中构建对象并注册。
由于注册的对象并非立即构建,register
方法不直接返回对象,而是返回一个该对象的RegistryObject
。在模组加载的注册阶段完成后,调用其get()
方法可以获取对象。要注意的是如果还没有运行完注册阶段,调用get()
会返回null
。
最终,回到主类的构造方法,加入如下代码:
IEventBus modEventBus = context.getModEventBus(); // 获取Mod事件总线
ItemRegistry.ITEMS.register(modEventBus); // 将DeferredRegister注册到Mod事件总线中
打开调试游戏,进入创造模式世界,输入命令:
/give Dev forge_tutorial:test_item
得到了一个缺失材质的物品。