User Tools

Site Tools


zh_cn:tutorial:registry

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
zh_cn:tutorial:registry [2022/12/15 23:48] – [注册类型] solidblockzh_cn:tutorial:registry [2024/08/27 05:07] (current) – [注册表键] solidblock
Line 1: Line 1:
-====== 注册表系统 ======+====== 注册表介绍 ======
  
-需要将添加到游戏的绝大多数内容注册进去,这有利于:+Minecraft 使用**注册表系统**处理游戏内的几乎一些,作为模组开发者,需要将添加到游戏的绝大多数内容注册进去,这有利于:
   * 让游戏知道你的内容存在   * 让游戏知道你的内容存在
   * 在客户端和服务器之间验证游戏内容   * 在客户端和服务器之间验证游戏内容
Line 9: Line 9:
   * 抽象化隐藏数字 ID   * 抽象化隐藏数字 ID
  
-注册任何类型内容时,你传入一个 ''%%Identifier%%'',也就是你需要加入的内容的标识符。标识符,简称 ID,通常拥有一个命名空间(namespace)和路径(path)。大多数情况下,命名空间是你的模组的ID,路径则是你要注册的内容的(英文)名称。如,标准的泥土方块的 ID 为 ''%%minecraft:dirt%%''+注册任何类型内容时,你传入一个 ''Identifier'' 对象,也就是你需要加入的内容的标识符。标识符,简称 ID,通常拥有一个命名空间(namespace)和路径(path)。大多数情况下,命名空间是你的模组的 ID(见 [[terms]]),路径则是你要注册的内容的(英文)名称。命名空间和路径不能包含大写字母或其他语言(包括中文)的字符。例如,原版的泥土方块的 ID 为 ''minecraft:dirt''
  
-不注册就使用自定义内容容易导致bug,比如缺失材质、世界保存问题和崩溃。游戏通常会让你知道你是否忘记注册了某个东西。+不注册就使用自定义内容容易导致 bug,比如缺失纹理、世界保存问题和崩溃。游戏通常会让你知道你是否忘记注册了某个东西。
  
-===== 注册类型 =====+===== 注册类型 =====
  
-注册内容时,你需要指定将内容加入哪个注册表。基本的游戏提供所有原版内容的注册表,可以在 ''Registries''(1.19.3 以上)或 ''Registry''(1.19.2 以下)中找到。例如,你很有可能会使用用于物品的 ''Registries.ITEM''(1.19.3 以上)/''Registry.ITEM''(1.19.2 以下)和用于方块的 ''Registries.BLOCK''(1.19.3 以上)/''Registry.BLOCK''(1.19.2 以下)+注册内容时,你需要指定将内容加入哪个注册表。基本的游戏提供所有原版内容的注册表,可以在 ''Registries''(1.19.3 以上)或 ''Registry''(1.19.2 以下)中找到。
  
-需详细了解所有可用的注册表,请阅读[[zh_cn:tutorial:registry_types|注册表类型]]页面+,你很有可能会使用于物品的 ''Registries.ITEM''(1.19.3 以上)/''Registry.ITEM''(1.19.2 以下)和用于方块的 ''Registries.BLOCK''(1.19.3 以上)/''Registry.BLOCK''(1.19.2 以下)
  
-===== 注册内容 =====+如需详细了解所有可用的注册表,请看 ''Registries'' 或 ''Registry''类。[[registry types]] 也有各注册表类型的简要描述。
  
-使用''%%Registry.register%%''将内容添加到注册表:+===== 基本用法  ===== 
 +==== 注册你的内容 ==== 
 +使用 ''<yarn class_2378>.<yarn method_10230>''你的内容注册到注册表。记住,每个内容不能注册超过 1 次。基本的语法是
  
 <code java> <code java>
-public static <T> T register(Registry<? super T> registry, Identifier id, T entry) { +    Registry.register(registry, id, content);
-    return ((MutableRegistry)registry).add(id, entry); +
-}+
 </code> </code>
-**registry** - 你需要将内容添加到的注册表的实例。位于''%%Registry%%''中的所有原版注册表的列表,可以在[[zh_cn:tutorial:registry_types|注册表类型]]页面中找到。 
  
-**id** - 注册表内,你的内容的一个标识符标准格式为''%%模组ID:名称%%'',就像''%%minecraft:dirt%%''这样+  * **registry** - 你需要添加内容进的注册表的实例。 
 +  * **id** - 你的内容在注册表内的 ID 
 +  * **content** - 你需要注册内容的实例
  
-**entry** - 你需要注册的内容的实+如: 
 +<code java> 
 +    Registry.register(Registries.ITEM, Identifier.of("tutorial", "example_item", EXAMPLE_ITEM)); 
 +</code>
  
-===== 注册表法 =====+> 记住:只能在模组初始化器中注册。否则,会因为注册表冻结而无注册。
  
-''%%get%%'' - 返回与注册表内ID关联的项(entry)。如果项不存在,''%%DefaultedRegistry%%''返回默认注册表值,''%%SimpleRegistry%%''返回null。+==== 通过 ID 获取对象 ====
  
-<code java> +''<yarn method_10223>'' 返回注册表内与 ID 关联的内容。如果内容不存在,''<yarn class_2348>'' 会返回默认的注册表值,而 ''<yarn class_2370>'' 就返回 null。可以使用 ''containsId'' 或 ''getOrEmpty'' 方法检测 ID 是否存在,例如:
-@Nullable +
-public abstract T get(@Nullable Identifier id); +
-</code>+
  
-----+<yarncode java> 
 +    Registries.ITEM.containsId(Identifier.ofVanilla("diamond")); // 返回 true 
 +     
 +    Registries.ITEM.containsId(Identifier.ofVanilla("invalid_name")); // 返回 false 
 +     
 +    Registries.ITEM.get(Identifier.ofVanilla("diamond")); // 返回 Items.DIAMOND 
 +     
 +    Registries.ITEM.get(Identifier.ofVanilla("invalid_name")); // 返回 Items.AIR 
 +     
 +    Registries.ITEM.getOrEmpty(Identifier.ofVanilla("diamond")); // 返回 Optional.of(Items.DIAMOND) 
 +     
 +    Registries.ITEM.getOrEmpty(Identifier.ofVanilla("invalid_name")); // 返回 Optional.empty() 
 +</yarncode>
  
-''%%getId%%'' 返回注册表内与关联的''%%Identifier%%''如果项不存在,''%%DefaultedRegistry%%''返回默认注册表标识符,''%%SimpleRegistry%%''返回null。+==== 获取对象的 ID ==== 
 + 
 +''<yarn method_10221>'' 返回注册表内与对象关联的 ''<yarn class_2960>''如果这个项不存在, ''<yarn class_2348>'' 返回默认注册表 ID,''<yarn class_2370>'' 返回 null。例如:
  
 <code java> <code java>
-@Nullable +    Registries.BLOCK.getId(Blocks.STONE);  // 返回 Identifier.ofVanilla("stone"))
-public abstract Identifier getId(T entry);+
 </code> </code>
  
-----+===== 相关概念 =====
  
-''%%getRawId%%'' - 返回注册表内与项关联内部整ID。如果项在,''%%DefaultedRegistry%%''返回默认注册表原始ID,''%%SimpleRegistry%%''返回-1+==== 注册表键 ===== 
 +有些类型的注册表不是静态存储在 ''Registries'' 类中的。例如,你无法在 ''Registries'' 类中找到生物群系的注册表或战利品表注册表。但是这些注册表在 Minecraft 中确实存在,这是因为这些注册表是//动态//的:在不同世界之间加载,因为是由据包定义相比之下,//静态//的注册表,例如 ''Registries.ITEM'' 和 ''Regitries.BLOCK'',还是由数据包定义的,所以不管哪个世界都保持不变。 
 + 
 +但是每个注册表都有个**注册表键**(''RegistryKey''),可以在 ''RegistrKeys'' 类中找到。可以通过 ''RegistryWrapper.WrapperLookup''(如果有 ''World'' 对象,通常是 ''world.getRegistryManager'',注册[[commands|命令]]时则通常是 ''CommandRegistryAccess'')对象根据注册表键找到注册表。参见下面例子假设你有 ''World'' 对象
  
 <code java> <code java>
-public abstract int getRawId(@Nullable T entry);+    final DynamicRegistryManager registryManager = world.getRegistryManager(); 
 +     
 +    // 下面两个语句都返回当前世界的沙漠的 ''Biome'' 对象 
 +    registryManager.get(RegistryKeys.BIOME).get(Identifier.ofVanilla("desert")); 
 +    registryManager.getWrapperOrThrow(RegistryKeys.BIOME).getOrThrow(RegistryKey.of(RegistryKeys.BIOME, Identifier.ofVanilla("desert"))).value();
 </code> </code>
  
 +不仅注册表有注册表键。所有的注册表内容都有注册表键(因为注册表本身也属于 ''Registries.REGISTRIES'' 的注册表内容)。注册表内容在不同世界之间可能改变,但是注册表键是不会改变的。
 +
 +==== 注册表项 =====
 +
 +**注册表项**(''RegistryEntry'')是属于有注册表的类型的内容。有两种类型:
 +  * ''RegistryEntry.Reference'':在注册表内注册的东西,因此有 ID。
 +  * ''RegistryEntry.Direct'':不在注册表内注册的东西,可能是通过某种方式匿名指定的。
 +
 +看看下面两个命令,以清晰地展示出了两者的区别:
 +  * ''/loot give @s loot minecraft:blocks/stone''
 +  * ''%%/loot give @s loot {pools:[{rolls:1, entries:[{type:"item", name:"minecraft:stone"}]}]}%%''
 +
 +两个命令都会给你一个石头。前者会从世界的战利品表注册表中获取战利品表 ''minecraft:blocks/stone'',所以是 ''RegistryEntry.Reference''。后者会从 SNBT 中解码一个战利品表. 没有 ID,所以是 ''RegistryEntry.Direct''。两种类型的注册表项都可以通过调用 ''value()'' 方法来获取其实际的内容。
 +
 +==== 注册表项列表====
 +
 +和注册表项类似,**注册表项列表**(''RegistryEntryList'')用得很多,也有两种类型:
 +  * ''RegistryEntryList.Named'':通过由数据包定义的[[tags|标签]]定义的列表。
 +  * ''RegistryEntryList.Direct'':直接通过列举出所有内容定义的列表。
zh_cn/tutorial/registry.1671148139.txt.gz · Last modified: 2022/12/15 23:48 by solidblock