标识符

标识符

Identifier 是 Minecraft 中最重要的概念之一。它用作注册表中的键、数据或资源文件的标识符、代码中对模型的引用,以及许多其他用途。一个 Identifier 由命名空间和路径两部分组成,以 : 分隔。

命名空间表示该位置所属的 Mod、资源包或数据包。例如,Mod ID 为 examplemod 的 Mod 使用 examplemod 命名空间;Minecraft 使用 minecraft 命名空间。只需创建相应的数据文件夹,就可以按需定义额外命名空间。数据包通常会以此将自身逻辑与接入原版内容的部分分开。

路径是在命名空间中指向目标对象的引用。例如,minecraft:cow 指向 minecraft 命名空间中名为 cow 的对象,通常用于从实体注册表获取牛实体。examplemod:example_item 则可能用于从物品注册表获取 Mod 的 example_item。

Identifier 只能包含小写字母、数字、下划线、点和连字符。路径还可以包含正斜杠。受 Java 模块限制,Mod ID 不能包含连字符,因此 Mod 命名空间也不能包含连字符(路径中仍可使用)。

说明 Identifier 本身并不表示对象的类型。例如,minecraft:dirt 可以在多个位置表示不同对象。由接收 Identifier 的代码决定它对应哪种对象。

可以调用 Identifier.fromNamespaceAndPath("examplemod", "example_item") 或 Identifier.parse("examplemod:example_item") 创建新的 Identifier。如果使用 withDefaultNamespace,字符串会被视为路径,并以 minecraft 作为命名空间。例如,Identifier.withDefaultNamespace("example_item") 会得到 minecraft:example_item。

可以分别通过 Identifier#getNamespace() 和 #getPath() 获取命名空间与路径,也可以通过 Identifier#toString 获取完整字符串。

Identifier 是不可变对象。它的所有工具方法(例如 withPrefix 和 withSuffix)都会返回新的 Identifier。

解析 Identifier

有些位置(例如注册表)会直接使用 Identifier,其他位置则会按需解析它。例如:

  • GUI 背景使用 Identifier。熔炉 GUI 使用 minecraft:textures/gui/container/furnace.png,对应磁盘上的 assets/minecraft/textures/gui/container/furnace.png 文件。此处必须包含 .png 后缀。
  • 方块模型使用 Identifier。泥土模型使用 minecraft:block/dirt,对应 assets/minecraft/models/block/dirt.json。此处无需 .json 后缀,而且会自动映射到 models 子文件夹。
  • 客户端物品使用 Identifier。苹果的客户端物品使用 minecraft:apple(由 DataComponents#ITEM_MODEL 定义),对应 assets/minecraft/items/apple.json。此处无需 .json 后缀,而且会自动映射到 items 子文件夹。
  • 配方使用 Identifier。铁块合成配方使用 minecraft:iron_block,对应 data/minecraft/recipe/iron_block.json。此处无需 .json 后缀,而且会自动映射到 recipe 子文件夹。

是否需要文件后缀,以及标识符具体解析到什么内容,取决于使用场景。

ResourceKey

ResourceKey 将注册表 ID 与注册表名称组合起来。例如,注册表 ID 为 minecraft:item、注册表名称为 minecraft:diamond_sword 的注册表键。与 Identifier 不同,ResourceKey 指向唯一元素,因此可以明确标识某个元素。它常用于多个不同注册表相互作用的场景;数据包(尤其是世界生成)是常见用途。

可以通过静态方法 ResourceKey#create(ResourceKey<? extends Registry<T>>, Identifier) 创建新的 ResourceKey。第二个参数是注册表名称,第一个参数称为注册表键。注册表键是一种特殊的 ResourceKey,其注册表为根注册表(所有其他注册表的注册表)。可以使用目标注册表的 ID,通过 ResourceKey#createRegistryKey(Identifier) 创建注册表键。

创建 ResourceKey 时会进行驻留(interning)。因此,可以并且建议使用引用相等比较(==),但创建开销相对较高。


来源: NeoForged/Documentation(26.1)。中文翻译依据提交 4a680cdd4d15。