Skip to main content
Version: 1.21.4

资源位置(Resource Locations)

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

命名空间用于标识这个位置属于哪个模组(mod)、资源包(resource pack)或数据包(datapack)。例如,一个模组的 mod id 是 examplemod,那么它就会使用 examplemod 作为命名空间。Minecraft 本体使用 minecraft 作为命名空间。你可以随时定义额外的命名空间,只需要创建对应的数据文件夹即可,这通常由数据包完成,以便将它们的逻辑与原版集成点分离。

路径(path)则是在你的命名空间内部对某个对象的引用。例如,minecraft:cow 表示 minecraft 命名空间下名为 cow 的对象——通常这个位置会用来从实体注册表获取牛(cow)实体。再比如,examplemod:example_item 可能用于从物品注册表获取你的模组的 example_item

ResourceLocation 只允许包含小写字母、数字、下划线、点和连字符。路径还可以包含正斜杠。请注意,由于 Java 模块的限制,mod id 不能包含连字符,这也意味着 mod 命名空间同样不能包含连字符(但路径中仍然允许)。

info

单独一个 ResourceLocation 并不能说明它用于哪种对象。比如,名为 minecraft:dirt 的对象在多个地方都存在。需要由接收这个 ResourceLocation 的代码来决定它实际关联的是哪个对象。

你可以通过调用 ResourceLocation.fromNamespaceAndPath("examplemod", "example_item")ResourceLocation.parse("examplemod:example_item") 来创建一个新的 ResourceLocation。如果使用 withDefaultNamespace,则字符串会被当作路径,而命名空间默认为 minecraft。例如,ResourceLocation.withDefaultNamespace("example_item") 会得到 minecraft:example_item

你可以通过 ResourceLocation#getNamespace()#getPath() 方法分别获取 ResourceLocation 的命名空间和路径,合并后的完整形式可以通过 ResourceLocation#toString 获取。

ResourceLocation 是不可变(immutable)的。所有 ResourceLocation 上的工具方法,比如 withPrefixwithSuffix,都会返回一个新的 ResourceLocation

解析 ResourceLocation(Resolving ResourceLocations)

有些地方,比如注册表(registries),会直接使用 ResourceLocation。但在其他地方,ResourceLocation 会根据需要被解析。例如:

  • ResourceLocation(资源位置)用于作为 GUI 背景的标识符。例如,熔炉 GUI 使用的资源位置是 minecraft:textures/gui/container/furnace.png。它对应磁盘上的文件路径为 assets/minecraft/textures/gui/container/furnace.png。请注意,在这个资源位置中,.png 后缀是必须的。
  • ResourceLocation 也用于作为方块模型的标识符。例如,泥土方块的模型使用的资源位置是 minecraft:block/dirt。它对应磁盘上的文件路径为 assets/minecraft/models/block/dirt.json。请注意,这里不需要 .json 后缀。同时,这个资源位置会自动映射到 models 子文件夹下。
  • ResourceLocation 还用于作为客户端物品的标识符。例如,苹果的客户端物品使用的资源位置是 minecraft:apple(由 DataComponents#ITEM_MODEL 定义)。它对应磁盘上的文件路径为 assets/minecraft/items/apple.json。同样,这里不需要 .json 后缀,并且该资源位置会自动映射到 items 子文件夹下。
  • ResourceLocation 也用于作为配方(recipe)的标识符。例如,铁块的合成配方使用的资源位置是 minecraft:iron_block。它对应磁盘上的文件路径为 data/minecraft/recipe/iron_block.json。这里同样不需要 .json 后缀,并且资源位置会自动映射到 recipe 子文件夹下。

至于 ResourceLocation 是否需要文件后缀,以及资源位置实际解析到哪里的具体规则,这些都取决于具体的使用场景。

ModelResourceLocation(模型资源位置)

ModelResourceLocation 是一种专门用于方块状态(block states)的资源位置,它包含第三部分,称为 variant(变体)。Minecraft 主要用它来区分模型的不同变体。variant 是由属性-值对组成的、用逗号分隔的字符串(例如 facing=north,waterlogged=false,如果方块没有状态属性则为空),并以 # 附加在常规资源位置后面。

ModelResourceLocation 是一个 仅限客户端 的类。这意味着如果服务器端引用此类,会因 NoClassDefFoundError 报错而崩溃。

ResourceKey(资源键)

ResourceKey 将注册表 ID(registry id)与注册表名称(registry name)结合在一起。例如,一个注册表键可以由注册表 ID minecraft:item 和注册表名称 minecraft:diamond_sword 组成。与 ResourceLocation 不同,ResourceKey 实际上指向某个唯一元素,因此可以明确标识一个元素。它们通常用于多个不同注册表需要互相交互的场景。数据包(datapack),尤其是世界生成(worldgen)相关内容,是一个常见的使用场景。 可以通过静态方法 ResourceKey#create(ResourceKey<? extends Registry<T>>, ResourceLocation) 创建一个新的 ResourceKey(资源键)。这里的第二个参数是注册表名称(registry name),而第一个参数被称为注册表键(registry key)。注册表键是一种特殊类型的 ResourceKey,其注册表是根注册表(root registry),也就是所有其他注册表的注册表。可以使用 ResourceKey#createRegistryKey(ResourceLocation) 方法,通过指定所需注册表的 id 来创建注册表键。

ResourceKey(资源键)在创建时会进行驻留(interned)处理。这意味着可以通过引用相等(==)进行比较,并且推荐这么做,但创建过程相对较为昂贵。