User Tools

Site Tools


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
tutorial:registry [2022/12/09 04:52] – [Registry Types] solidblocktutorial:registry [2024/08/25 14:06] (current) solidblock
Line 1: Line 1:
--====== Registry System ======+====== Intro to Registries ======
  
-You will need to register most content you add to the game. This helps with:+Minecraft uses the **registry system** to handle almost everything in the game. When developing mods, you will need to register most content you add to the game. This helps with:
   * Letting the game know your content exists   * Letting the game know your content exists
   * Verifying game content between client & server   * Verifying game content between client & server
Line 9: Line 9:
   * Abstracting or hiding numerical IDs   * Abstracting or hiding numerical IDs
  
-When registering any type of content, you pass in an ''<yarn class_2960>'', which is a label for your addition<yarn class_2960>s– often abbreviated as IDs– have a namespace and path. In most cases, the namespace is the ID of your mod, and the path is the name of the content you’re registering. For example, the standard dirt block has the ID of ''%%minecraft:dirt%%''.+When registering any type of content, you pass in an ''<yarn class_2960>'' object, which speciied what things should be named for the gameIdentifiers, often abbreviated as IDshave a namespace and path. In most cases, the namespace is the ID of your mod (see [[terms]]), and the path is the name of the content you’re registering. The namespace and path cannot contain uppercases or characters in other languages. For example, the ID of vanilla dirt block has the ID of ''%%minecraft:dirt%%''.
  
 Using custom content without registering it can lead to buggy behavior, such as missing textures, world save issues, and crashes. The game will usually let you know if you forget to register something. Using custom content without registering it can lead to buggy behavior, such as missing textures, world save issues, and crashes. The game will usually let you know if you forget to register something.
Line 15: Line 15:
 ===== Registry Types ===== ===== Registry Types =====
  
-When registering content, you need to specify which registry you are adding content to. The base game provides registries for all vanilla content, which can be found in ''%%Registries%%'' (for 1.19.3 and above) or ''Registry'' (for below 1.19.3). Two examples of registries you may use include ''<yarn class_2378>.<yarn field_11142>'' for items and ''<yarn class_2378>.<yarn field_11146>'' for blocks.+When registering content, you need to specify which registry you are adding content to. The base game provides registries for all vanilla content, which can be found in ''%%Registries%%'' (for 1.19.3 and above) or ''Registry'' (for below 1.19.3).
  
-For a deeper overview and description of all available registries, read the [[tutorial:registry_types|registry types]] page.+Two examples of registries you may use include ''Registries.ITEM'' (for 1.19.3 above)/''Registry.ITEM'' (for 1.19.2 below) for items and ''Registries.BLOCK'' (for 1.19.3 above)/''Registry.BLOCK'' (for 1.19.2 below) for blocks.
  
-===== Registering Content =====+For a deeper overview and description of all available registries, read the ''Registries'' or ''Registry'' class. A brief description for the registry types can be found in [[registry types]] page.
  
-Use ''<yarn class_2378>.<yarn method_10230>'' for adding content to registries:+===== Basic usages ===== 
 +==== Registering your content ==== 
 +Use ''<yarn class_2378>.<yarn method_10230>'' to register your contents into registries. Remember, each content can be registered no more than once. The basic syntax is:
  
-<yarncode java> +<code java> 
-public static <T> T method_10230(class_2378<? super T> registry, class_2960 id, T entry) { +    Registry.register(registry, id, content); 
-    return ((class_2385)registry)method_10272(id, entry); +</code>
-} +
-</yarncode> +
-**registry** - an instance of the registry you want to add content to. A list of all vanilla registries, located in ''<yarn class_2378>'', can be found in the [[tutorial:registry_types|registry types]] page.+
  
-**id** - an identifying label for your content inside the registry. Standard convention is ''%%modid:name%%'', as seen with ''%%minecraft:dirt%%''.+  * **registry** - an instance of the registry you want to add content to. 
 +  * **id** - the identifier for your content inside the registry. 
 +  * **content** - an instance of the content you want to register.
  
-**entry** - an instance of the content you want to register.+For example: 
 +<code java> 
 +    Registry.register(Registries.ITEM, Identifier.of("tutorial", "example_item", EXAMPLE_ITEM)); 
 +</code>
  
-===== Registry Methods =====+> Remember: registration should happen in mod initializers. Otherwise, you cannot register as they may have been frozen.
  
-''<yarn method_10223>'' returns the entry associated with an ID inside a registry. If the entry doesn’t exist, ''<yarn class_2348>'' returns the default registry value, and ''<yarn class_2370>'' returns null.+==== Getting the object by ID ==== 
 + 
 +''<yarn method_10223>'' returns the content associated with an ID inside a registry. If the content doesn’t exist, ''<yarn class_2348>'' returns the default registry value, and ''<yarn class_2370>'' returns null. You can use ''containsId'' or ''getOrEmpty'' method to test whether the id exists. For example:
  
 <yarncode java> <yarncode java>
-@Nullable +    Registries.ITEM.containsId(Identifier.ofVanilla("diamond")); // returns true 
-public abstract T method_10223(@Nullable class_2960 id);+     
 +    Registries.ITEM.containsId(Identifier.ofVanilla("invalid_name")); // returns false 
 +     
 +    Registries.ITEM.get(Identifier.ofVanilla("diamond")); // returns Items.DIAMOND 
 +     
 +    Registries.ITEM.get(Identifier.ofVanilla("invalid_name")); // returns Items.AIR 
 +     
 +    Registries.ITEM.getOrEmpty(Identifier.ofVanilla("diamond")); // returns Optional.of(Items.DIAMOND) 
 +     
 +    Registries.ITEM.getOrEmpty(Identifier.ofVanilla("invalid_name")); // returns Optional.empty()
 </yarncode> </yarncode>
  
-----+==== Getting the id of an object ====
  
-''<yarn method_10221>'' returns the ''<yarn class_2960>'' associated with an entry inside a registry. If the entry doesn’t exist, ''<yarn class_2348>'' returns the default registry ID, and ''<yarn class_2370>'' returns null.+''<yarn method_10221>'' returns the ''<yarn class_2960>'' associated with an entry inside a registry. If the entry doesn’t exist, ''<yarn class_2348>'' returns the default registry ID, and ''<yarn class_2370>'' returns null. For example:
  
-<yarncode java> +<code java> 
-@Nullable +    Registries.BLOCK.getId(Blocks.STONE);  // returns Identifier.ofVanilla("stone")) 
-public abstract class_2960 method_10221(T entry); +</code>
-</yarncode>+
  
-----+===== Related concepts =====
  
-''<yarn method_10206>'' - returns the internal integer ID associated with an entry inside a registryIf the entry doesn’t exist, ''<yarn class_2348>'' returns the raw ID of the default registry value, and ''<yarn class_2370>'' returns -1.+==== Registry keys ===== 
 +Some type of registries are not staticly stored in ''Registries'' classFor exampleyou cannot find biome registries or loot table registries in ''Registries'' class. But the registries do exist in Minecraft. That's because those registries are //dynamic//: they are loaded between different worlds as they are defined in data packs. In contrary//static// registries, such as ''Registries.ITEM'' and ''Registries.BLOCK'', are not defined in data packs yet, so they keep unchanged no matter which worlds you are in.
  
-<yarncode java> +However, each registry has a **registry key**, which can be found in ''RegistryKeys''. You can get dynamic registries through registry keys with ''RegistryWrapper.WrapperLookup'' objects (usually ''world.getRegistryManager()'' when you have a ''World'' object, or ''CommandRegistryAccess'' when registering [[commands]]). See the example below, assume that you have a ''World'' object: 
-public abstract int method_10206(@Nullable T entry); + 
-</yarncode>+<code java> 
 +    final DynamicRegistryManager registryManager = world.getRegistryManager(); 
 +     
 +    // both of the following two statements return the ''Biome'' object for desert in the world 
 +    registryManager.get(RegistryKeys.BIOME).get(Identifier.ofVanilla("desert")); 
 +    registryManager.getWrapperOrThrow(RegistryKeys.BIOME).getOrThrow(RegistryKey.of(RegistryKeys.BIOME, Identifier.ofVanilla("desert"))).value(); 
 +</code> 
 + 
 +Not only registries have registry keys. All registry contents have registry keys (as registries themselves also belong to registry contents of ''Registries.REGISTRIES''). Registry contents may change between worlds, but registry keys always keep unchanged. 
 + 
 +==== Registry entry ===== 
 + 
 +A **registry entry** (''RegistryEntry'') is a wrapper of contents that belong to types that have registry. They have two types: 
 +  * ''RegistryEntry.Reference'': things that are registered in the registry, and therefore have their IDs. 
 +  * ''RegistryEntry.Direct'': things not registered in the register. They may be anonymously specified in some ways. 
 + 
 +To explicitly show the differences between two, see the following two commands: 
 +  * ''/loot give @s loot minecraft:blocks/stone'' 
 +  * ''%%/loot give @s loot {pools:[{rolls:1, entries:[{type:"item", name:"minecraft:stone"}]}]}%%'' 
 + 
 +Both the two commands give you a stone. The former one will get the loot table ''minecraft:blocks/stone'' from the loot table registry of the world, so it is ''RegistryEntry.Reference''. The latter one will decode a loot table from a SNBT, which does not have an ID, so it is ''RegistryEntry.Direct''. Both the two type of registry entries can be fetched the actual content by calling ''value()'' method. 
 + 
 +==== Registry entry list ====
  
 +Similar to registry entries, **registry entry lists** (''RegistryEntryList'') are used in many cases and also have two types:
 +  * ''RegistryEntryList.Named'': The list defined by [[tags]], which are defined in data packs.
 +  * ''RegistryEntryList.Direct'': The list defirectly defined by listing all contents.
tutorial/registry.1670561534.txt.gz · Last modified: 2022/12/09 04:52 by solidblock