<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://forge.gemwire.uk/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=ChampionAsh5357</id>
	<title>Forge Community Wiki - User contributions [en-gb]</title>
	<link rel="self" type="application/atom+xml" href="https://forge.gemwire.uk/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=ChampionAsh5357"/>
	<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/wiki/Special:Contributions/ChampionAsh5357"/>
	<updated>2026-06-02T04:21:51Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.0</generator>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Codecs&amp;diff=3416</id>
		<title>Codecs</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Codecs&amp;diff=3416"/>
		<updated>2024-01-10T12:57:27Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Reverted edits by Blabliblubpaul (talk) to last revision by Commoble&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Codecs are a serialization tool from mojang's DataFixerUpper library. Codecs are used alongside [[DynamicOps|DynamicOps]] to allow objects to be serialized to different formats and back, such as JSON or [[Using_NBT|NBT]]. While the DynamicOps describes the format the object is to be serialized to, the Codec describes the manner in which the object is to be serialized; a single Codec can be used to serialize an object to any format for which a DynamicOps exists. Codecs and DynamicOps jointly form an abstraction layer over data serialization, simplifying the effort needed to serialize or deserialize data.&lt;br /&gt;
&lt;br /&gt;
= Using Codecs =&lt;br /&gt;
&lt;br /&gt;
== Serialization and Deserialization ==&lt;br /&gt;
&lt;br /&gt;
The primary use for Codecs is to serialize java objects to some serialized type, such as a JsonElement or a Tag, and to deserialize an serialized object back to its proper java type. This is accomplished with &amp;lt;code&amp;gt;Codec#encodeStart&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Codec#parse&amp;lt;/code&amp;gt;, respectively. Given a Codec&amp;lt;SomeJavaType&amp;gt; and a DynamicOps&amp;lt;SomeSerializedType&amp;gt;, we can convert instances of SomeJavaType to instances of SomeSerializedType and back.&lt;br /&gt;
&lt;br /&gt;
Each of these methods take a [[DynamicOps]] instance and an instance of the object we are serializing or deserializing, and returns a DataResult:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// let someCodec be a Codec&amp;lt;SomeJavaType&amp;gt;&lt;br /&gt;
// let someJavaObject be an instance of SomeJavaType&lt;br /&gt;
// let someTag and someJsonElement be instances of Tag and JsonElement, respectively&lt;br /&gt;
&lt;br /&gt;
// serialize some java object to Tag&lt;br /&gt;
DataResult&amp;lt;Tag&amp;gt; result = someCodec.encodeStart(NBTOps.INSTANCE, someJavaObject);&lt;br /&gt;
&lt;br /&gt;
// deserialize some Tag instance back to a proper java object&lt;br /&gt;
DataResult&amp;lt;SomeJavaType&amp;gt; result = someCodec.parse(NBTOps.INSTANCE, someTag );&lt;br /&gt;
&lt;br /&gt;
// serialize some java object to a JsonElement&lt;br /&gt;
DataResult&amp;lt;JsonElement&amp;gt; result = someCodec.encodeStart(JsonOps.INSTANCE, someJavaObject);&lt;br /&gt;
&lt;br /&gt;
// deserialize a JsonElement back to a proper java object&lt;br /&gt;
DataResult&amp;lt;SomeJavaType&amp;gt; result = someCodec.parse(JsonOps.INSTANCE, someJsonElement);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A DataResult either holds the converted instance, or it holds some error data, depending on whether the conversion was successful or not, respectively. There are several things we can do with this DataResult; &amp;lt;code&amp;gt;DataResult#result&amp;lt;/code&amp;gt; simply returns an Optional containing the converted object if the conversion was successful, while &amp;lt;code&amp;gt;DataResult#resultOrPartial&amp;lt;/code&amp;gt; also runs a given function if the conversion was unsuccessful (in addition to returning the Optional). #resultOrPartial is particularly useful for logging errors during datapack deserialization:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// deserialize something from json&lt;br /&gt;
someCodec.parse(JsonOps.INSTANCE, someJsonElement)&lt;br /&gt;
	.resultOrPartial(errorMessage -&amp;gt; doSomethingIfBadData(errorMessage))&lt;br /&gt;
	.ifPresent(someJavaObject -&amp;gt; doSomethingIfGoodData(someJavaObject))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Builtin Codecs ==&lt;br /&gt;
=== Primitive Codecs ===&lt;br /&gt;
The Codec class itself contains static instances of codecs for all supported primitive types, e.g. &amp;lt;code&amp;gt;Codec.STRING&amp;lt;/code&amp;gt; is the canonical &amp;lt;code&amp;gt;Codec&amp;lt;String&amp;gt;&amp;lt;/code&amp;gt; implementation. Primitive codecs include:&lt;br /&gt;
* BOOL, which serializes to a boolean value&lt;br /&gt;
* BYTE, SHORT, INT, LONG, FLOAT, and DOUBLE, which serialize to numeric values&lt;br /&gt;
* STRING, which serializes to a string&lt;br /&gt;
* BYTE_BUFFER, INT_STREAM, and LONG_STREAM, which serialize to lists of numbers&lt;br /&gt;
* EMPTY, which represents null objects&lt;br /&gt;
&lt;br /&gt;
=== Other Builtin Codecs ===&lt;br /&gt;
Vanilla minecraft has many builtin codecs for objects that it frequently serializes. These codecs are typically static instances in the class the codec is serializing; e.g. &amp;lt;code&amp;gt;ResourceLocation.CODEC&amp;lt;/code&amp;gt; is the canonical &amp;lt;code&amp;gt;Codec&amp;lt;ResourceLocation&amp;gt;&amp;lt;/code&amp;gt;, while &amp;lt;code&amp;gt;BlockPos.CODEC&amp;lt;/code&amp;gt; is the codec used for serializing a BlockPos.&lt;br /&gt;
&lt;br /&gt;
Each vanilla &amp;lt;code&amp;gt;Registry&amp;lt;/code&amp;gt; acts as the Codec for the type of object the registry contains; e.g. &amp;lt;code&amp;gt;Registry.BLOCK&amp;lt;/code&amp;gt; is itself a &amp;lt;code&amp;gt;Codec&amp;lt;Block&amp;gt;&amp;lt;/code&amp;gt;. Forge Registries, however, do not currently implement Codec and cannot yet be used in this way; custom codecs must be created for forge-specific registries that are not tied to specific vanilla registries.&lt;br /&gt;
&lt;br /&gt;
Of particular note here is the CompoundTag.CODEC, which can be used to e.g. serialize a CompoundTag into a json file. This has a notable limitation in that CompoundTag.CODEC *cannot* safely deserialize lists of numbers from json, due to the strong typing of ListTag and the way that the NBTOps deserializer reads numeric values.&lt;br /&gt;
&lt;br /&gt;
= Creating Codecs =&lt;br /&gt;
&lt;br /&gt;
Suppose we have the following class, and we want to deserialize json files to instances of this class:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class ExampleCodecClass {&lt;br /&gt;
&lt;br /&gt;
    private final int someInt;&lt;br /&gt;
    private final Item item;&lt;br /&gt;
    private final List&amp;lt;BlockPos&amp;gt; blockPositions;&lt;br /&gt;
&lt;br /&gt;
    public ExampleCodecClass(int someInt, Item item, List&amp;lt;BlockPos&amp;gt; blockPositions) {...}&lt;br /&gt;
&lt;br /&gt;
    public int getSomeInt() { return this.someInt; }&lt;br /&gt;
    public Item getItem() { return this.item; }&lt;br /&gt;
    public List&amp;lt;BlockPos&amp;gt; getBlockPositions() { return this.blockPositions; }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where a json file for an instance of this class might look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;some_int&amp;quot;: 42,&lt;br /&gt;
	&amp;quot;item&amp;quot;: &amp;quot;minecraft:gold_ingot&amp;quot;,&lt;br /&gt;
	&amp;quot;block_positions&amp;quot;:&lt;br /&gt;
	[&lt;br /&gt;
		[0,0,0],&lt;br /&gt;
		[10,20,-100]&lt;br /&gt;
	]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can assemble a codec for this class by building a new codec out of smaller codecs. We'll need a codec for each of these fields:&lt;br /&gt;
* a &amp;lt;code&amp;gt;Codec&amp;lt;Integer&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* a &amp;lt;code&amp;gt;Codec&amp;lt;Item&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* a &amp;lt;code&amp;gt;Codec&amp;lt;List&amp;lt;BlockPos&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
And then we'll need to assemble these into a &amp;lt;code&amp;gt;Codec&amp;lt;ExampleCodecClass&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
As previously mentioned, we can use &amp;lt;code&amp;gt;Codec.INT&amp;lt;/code&amp;gt; for the integer codec, and &amp;lt;code&amp;gt;Registry.ITEM&amp;lt;/code&amp;gt; for the Item codec. We don't have a builtin codec for list-of-blockpos, but we can use BlockPos.CODEC to create one.&lt;br /&gt;
&lt;br /&gt;
== Lists ==&lt;br /&gt;
The &amp;lt;code&amp;gt;Codec#listOf&amp;lt;/code&amp;gt; instance method can be used to generate a codec for a List from an existing codec:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// BlockPos.CODEC is a Codec&amp;lt;BlockPos&amp;gt;&lt;br /&gt;
Codec&amp;lt;List&amp;lt;BlockPos&amp;gt;&amp;gt; = BlockPos.CODEC.listOf();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Codecs created via listOf() serialize things to listlike objects, such as [] json arrays or ListTags.&lt;br /&gt;
&lt;br /&gt;
Deserializing a list in this manner produces an ''immutable'' list. If a mutable list is needed, [[Codecs#Equivalent_Types_and_xmap|xmap]] can be used to convert the list after deserializing.&lt;br /&gt;
&lt;br /&gt;
== Records ==&lt;br /&gt;
RecordCodecBuilder is used to generate codecs that serialize instances of classes with explicitly named fields, like our example above. Codecs created via RecordCodecBuilder serialize things to maplike objects, such as {} json objects or CompoundTags.&lt;br /&gt;
&lt;br /&gt;
RecordCodecBuilder can be used in several ways, but the simplest form is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static final Codec&amp;lt;SomeJavaClass&amp;gt; = RecordCodecBuilder.create(instance -&amp;gt; instance.group(&lt;br /&gt;
		someFieldCodecA.fieldOf(&amp;quot;field_name_a&amp;quot;).forGetter(SomeJavaClass::getFieldA),&lt;br /&gt;
		someFieldCodecB.fieldOf(&amp;quot;field_name_b&amp;quot;).forGetter(SomeJavaClass::getFieldB),&lt;br /&gt;
		someFieldCodecC.fieldOf(&amp;quot;field_name_c&amp;quot;).forGetter(SomeJavaClass::getFieldC),&lt;br /&gt;
		// up to 16 fields can be declared here&lt;br /&gt;
	).apply(instance, SomeJavaClass::new));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where each line in the group specifies a codec instance for the type of that field, the field name in the serialized object, and the corresponding getter function in the java class. The builder is concluded by specifying a constructor or factory for the java class whose arguments are the previously defined fields in the same order.&lt;br /&gt;
&lt;br /&gt;
For example, using RecordCodecBuilder to create a codec for our example class above:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static final Codec&amp;lt;ExampleCodecClass&amp;gt; = RecordCodecBuilder.create(instance -&amp;gt; instance.group(&lt;br /&gt;
		Codec.INT.fieldOf(&amp;quot;some_int&amp;quot;).forGetter(ExampleCodecClass::getSomeInt),&lt;br /&gt;
		Registry.ITEM.fieldOf(&amp;quot;item&amp;quot;).forGetter(ExampleCodecClass::getItem),&lt;br /&gt;
		BlockPos.CODEC.listOf().fieldOf(&amp;quot;block_positions&amp;quot;).forGetter(ExampleCodecClass::getBlockPositions)&lt;br /&gt;
	).apply(instance, ExampleCodecClass::new));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Optional and Default Values in Record Fields===&lt;br /&gt;
When RecordCodecBuilder is used as shown above, all of the fields are *required* to be in the serialized object (the JsonObject/CompoundTag/etc), or the entire thing will fail to parse when the codec tries to deserialize it. If we wish to have optional or default values, we have several alternatives of fieldOf() we can use.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;someCodec.optionalFieldOf(&amp;quot;field_name&amp;quot;)&amp;lt;/code&amp;gt; creates a field for an Optional. If the field in the json/nbt is not present or invalid, it will deserialize as an empty optional. Empty optionals will not be serialized; the field will be omitted from the json or nbt.&lt;br /&gt;
* &amp;lt;code&amp;gt;someCodec.optionalFieldOf(&amp;quot;field_name&amp;quot;, someDefaultValue)&amp;lt;/code&amp;gt; creates an optional field that deserializes as the given default value if the field is not present in the json/nbt. When serializing, if the field in the java object equals the default value, the value will not be serialized and the field will be omitted from the json or nbt.&lt;br /&gt;
&lt;br /&gt;
When using optional fields, be wary that if the field contains bad data or otherwise fails to serialize, the error will be silently caught, and the field will serialize as the default value instead!&lt;br /&gt;
&lt;br /&gt;
===Boxing values as objects===&lt;br /&gt;
In some situations, we may need to serialize a single value as a single-field object. We can use fieldOf to box a single value in this way without needing the entire RecordCodecBuilder process:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static final Codec&amp;lt;Integer&amp;gt; BOXED_INT_CODEC = Codec.INT.fieldOf(&amp;quot;value&amp;quot;).codec();&lt;br /&gt;
&lt;br /&gt;
JsonElement value = BOXED_INT_CODEC.encodeStart(JsonOps.INSTANCE, 5).result().get();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which serializes the following output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&amp;quot;value&amp;quot;:5}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Unit==&lt;br /&gt;
The &amp;lt;code&amp;gt;Codec.unit(defaultValue)&amp;lt;/code&amp;gt; codec creates a Codec that always deserializes a specified default value, regardless of input. When serializing, it serializes nothing.&lt;br /&gt;
&lt;br /&gt;
==Pair==&lt;br /&gt;
The &amp;lt;code&amp;gt;Codec.pair(codecA, codecB)&amp;lt;/code&amp;gt; static method takes two codecs and generates a Codec&amp;lt;Pair&amp;lt;A,B&amp;gt;&amp;gt; from them.&lt;br /&gt;
&lt;br /&gt;
The only valid arguments for this method are codecs that serialize to objects with explicit fields, such as codecs created using [[Codecs#Records|RecordCodecBuilder]] or [[Codecs#Boxing_values_as_objects|fieldOf]]. Codecs that serialize nothing (such as [[Codecs#Unit|unit codecs]]) are also valid as they act as objects-with-no-fields.&lt;br /&gt;
&lt;br /&gt;
The resulting Pair codec will serialize a single object that has all of the fields of the two original codecs. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static final Codec&amp;lt;Pair&amp;lt;Integer,String&amp;gt;&amp;gt; PAIR_CODEC = Codec.pair(&lt;br /&gt;
	Codec.INT.fieldOf(&amp;quot;value&amp;quot;).codec(),&lt;br /&gt;
	Codec.STRING.fieldOf(&amp;quot;name&amp;quot;).codec());&lt;br /&gt;
&lt;br /&gt;
JsonElement encodedPair = PAIR_CODEC.encodeStart(JsonOps.INSTANCE, Pair.of(5, &amp;quot;cheese&amp;quot;).result().get();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This codec serializes the above value to:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;value&amp;quot;: 5,&lt;br /&gt;
	&amp;quot;name&amp;quot;: &amp;quot;cheese&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Codecs that serialize to objects with undefined fields such as [[Codecs#Maps|unboundedMap]] may cause strange and unpredictable behaviour when used here; these objects should be boxed via fieldOf when used in a pair codec.&lt;br /&gt;
&lt;br /&gt;
==Either==&lt;br /&gt;
The &amp;lt;code&amp;gt;Codec.either(codecA, codecB)&amp;lt;/code&amp;gt; static method takes two codecs and generates a Codec&amp;lt;Either&amp;lt;A,B&amp;gt;&amp;gt; from them.&lt;br /&gt;
&lt;br /&gt;
When this codec is used to de/serialize an object, it first attempts to use the first codec; if and only if that conversion fails, it then attempts to use the second codec. If that conversion also fails, then the returned DataResult will contain the error data from the *second* codec's conversion attempt.&lt;br /&gt;
&lt;br /&gt;
==Numeric Ranges==&lt;br /&gt;
The &amp;lt;code&amp;gt;Codec.intRange(min,max)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Codec.floatRange(min,max)&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;Codec.doubleRange(min,max)&amp;lt;/code&amp;gt; static methods generate Codecs for Integers, Floats, or Doubles, respectively, for which only a specified inclusive range is valid, and values outside that range will fail to de/serialize.&lt;br /&gt;
&lt;br /&gt;
==Maps==&lt;br /&gt;
Suppose we want to serialize a HashMap or other Map type, where we could have indefinitely many key-value pairs and we don't know what the keys are ahead of time.&lt;br /&gt;
&lt;br /&gt;
We can create a &amp;lt;code&amp;gt;Codec&amp;lt;Map&amp;lt;KEY,VALUE&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; using the &amp;lt;code&amp;gt;Codec.unboundedMap&amp;lt;/code&amp;gt; static method, which takes a key codec and a value codec and creates a codec for a map type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static final Codec&amp;lt;Map&amp;lt;String, BlockPos&amp;gt;&amp;gt; = Codec.unboundedMap(Codec.STRING, BlockPos.CODEC);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The serialized form of maps serialized by this codec will be a JsonObject or CompoundTag, whose fields are the key-value pairs in the map; the map's keys will be used as the field names, and the map's values will be the values of those fields&lt;br /&gt;
&lt;br /&gt;
A limitation of using unboundedMap is that it only supports key codecs that serialize to Strings (including codecs for things like ResourceLocation that aren't Strings themselves but still serialize to strings). To create a codec for a Map whose keys are not fundamentally strings, the Map must be serialized as a list of key-value pairs instead of using unboundedMap.&lt;br /&gt;
&lt;br /&gt;
==Equivalent Types and xmap==&lt;br /&gt;
Suppose we have two java classes, Amalgam and Box; any Amalgam instance can be converted to a Box, and vice-versa. Now suppose we have a Codec&amp;lt;Amalgam&amp;gt;, but we'd also like to have a Codec&amp;lt;Box&amp;gt;. Rather than creating an entirely new codec for Box from scratch, we can simply xmap our Amalgam codec instead.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;Codec#xmap&amp;lt;/code&amp;gt; instance method is used to generate a second codec for a fundamentally equivalent type to the first codec's type. The method takes two function objects as arguments, which are used to convert the first type to the second when deserializing, and converting the second type to the first when serializing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static final Codec&amp;lt;Box&amp;gt; = Amalgam.CODEC.xmap(Amalgam::toBox, Box::toAmalgam);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Codecs created in this manner will serialize objects in the same format as the starting codec.&lt;br /&gt;
&lt;br /&gt;
==Partially Equivalent Types, flatComapMap, comapFlatMap, and flatXMap==&lt;br /&gt;
Consider the ResourceLocation: Any ResourceLocation can be converted to a String, but not all Strings can be converted to a ResourceLocation; ResourceLocations have strict limits on their format and allowed characters.&lt;br /&gt;
&lt;br /&gt;
While we *could* use xmap to convert the Codec.STRING to a codec for ResourceLocations, this would cause attempts to parse an invalid string like &amp;lt;code&amp;gt;SHOUTY:MOD:Invalid$Characters&amp;lt;/code&amp;gt; to throw a runtime exception, when we really should be returning a failed DataResult to the parser instead -- which indeed is what the vanilla ResourceLocation codec does.&lt;br /&gt;
&lt;br /&gt;
Codecs have three additional instance methods for creating equivalent codecs for when we can *potentially* convert one type to another, but are not guaranteed to be able to do so. These take conversion function arguments that return DataResults, allowing validation to be performed during serialization and deserialization.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Codec Conversion Methods&lt;br /&gt;
|-&lt;br /&gt;
! Can A always be converted to B? !! Can B always be converted to A? !! Which method of codecA should be used to create codecB?&lt;br /&gt;
|-&lt;br /&gt;
| yes || yes || codecA.xmap&lt;br /&gt;
|-&lt;br /&gt;
| yes || no || codecA.flatComapMap&lt;br /&gt;
|-&lt;br /&gt;
| no || yes || codecA.comapFlatMap&lt;br /&gt;
|-&lt;br /&gt;
| no || no || codecA.flatXmap&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Registry Dispatch ==&lt;br /&gt;
Registry Dispatch Codecs allow us to define a registry of codecs and delegate to a specific codec to deserialize a particular json based on a type field in that json. Dispatch codecs are used extensively when deserializing worldgen data.&lt;br /&gt;
&lt;br /&gt;
To create a dispatch codec for a Thing class, the following steps can be performed:&lt;br /&gt;
# Create a Thing abstract class class and ThingType interface. The ThingType interface should have a method that supplies a Codec&amp;lt;Thing&amp;gt;, while Thing subclasses must define a method that supplies a ThingType.&lt;br /&gt;
# Create a map or registry of ThingTypes, and register a ThingType for each sub-codec we want to have.&lt;br /&gt;
# Create a Codec&amp;lt;ThingType&amp;gt;, or have the ThingType registry implement Codec.&lt;br /&gt;
# Create our Codec&amp;lt;Thing&amp;gt; master codec by invoking &amp;lt;code&amp;gt;Codec#dispatch&amp;lt;/code&amp;gt; on our ThingType codec. This method's arguments are:&lt;br /&gt;
## A field name for the ID of the sub-codec (the example json below is using &amp;quot;type&amp;quot;)&lt;br /&gt;
## A function to retrieve a ThingType from a Thing&lt;br /&gt;
## A function to retrieve a Codec&amp;lt;Thing&amp;gt; from a ThingType&lt;br /&gt;
&lt;br /&gt;
We can then use our Codec&amp;lt;Thing&amp;gt; to create Thing fields in other codecs whose serialized format depends on the specific sub-codec used by a Thing instance.&lt;br /&gt;
&lt;br /&gt;
As an example of this, consider the ExampleCodecClass earlier. Suppose we make this class extend Thing and register our codec for it to a codec dispatch registry with the id &amp;quot;ourmod:exampleclass&amp;quot;. If we were to define an instance of this class in a Thing field in some json, it would look like&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;some_thing&amp;quot;:&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;type&amp;quot;: &amp;quot;ourmod:exampleclass&amp;quot;,&lt;br /&gt;
	&amp;quot;some_int&amp;quot;: 42,&lt;br /&gt;
	&amp;quot;item&amp;quot;: &amp;quot;minecraft:gold_ingot&amp;quot;,&lt;br /&gt;
	&amp;quot;block_positions&amp;quot;:&lt;br /&gt;
	[&lt;br /&gt;
		[0,0,0],&lt;br /&gt;
		[10,20,-100]&lt;br /&gt;
	]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other ThingTypes we register would have different fields in this json object, but would still be valid for the &amp;quot;some_thing&amp;quot; field.&lt;br /&gt;
&lt;br /&gt;
Several examples of vanilla classes that use dispatch codecs:&lt;br /&gt;
* RuleTest and RuleTestType&lt;br /&gt;
* BlockPlacer and BlockPlacerType&lt;br /&gt;
* ConfiguredDecorator and FeatureDecorator&lt;br /&gt;
&lt;br /&gt;
=== Registering MapCodecCodecs for Dispatch Subcodecs ===&lt;br /&gt;
&lt;br /&gt;
When registering a subcodec to any dispatch codec registry, the registered subcodec should be an instance of MapCodecCodec, or the subcodec will be nested in its own object when serialized.&lt;br /&gt;
&lt;br /&gt;
For example, suppose we register a single-field subcodec, where we use fieldOf-and-xmap to convert an int to our int-holding Thing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public record Thing(int n){}&lt;br /&gt;
public static Codec&amp;lt;Thing&amp;gt; CODEC = Codec.INT.fieldOf(&amp;quot;n&amp;quot;).codec().xmap(Thing::new, Thing::n);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This results in this json when serialized:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;some_thing&amp;quot;:&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;type&amp;quot;: &amp;quot;ourmod:thing&amp;quot;,&lt;br /&gt;
	&amp;quot;value&amp;quot;: {&lt;br /&gt;
		&amp;quot;n&amp;quot;: 5&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This occurs because xmap does not produce a MapCodecCodec, and if this nested object is not desired, then our registered subcodec must be a MapCodecCodec.&lt;br /&gt;
&lt;br /&gt;
However, fieldOf() produces a MapCodec, which has a codec() method, which does produce a MapCodecCodec. We can rearrange our codec builder, which then produces a cleaner json:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static Codec&amp;lt;Thing&amp;gt; CODEC = Codec.INT // Primitive codec&lt;br /&gt;
	.fieldOf(&amp;quot;n&amp;quot;) // MapCodec&lt;br /&gt;
	.xmap(Thing::new, Thing::n) // MapCodec&lt;br /&gt;
	.codec(); // MapCodecCodec! That's what we want.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;some_thing&amp;quot;:&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;type&amp;quot;: &amp;quot;ourmod:thing&amp;quot;,&lt;br /&gt;
	&amp;quot;n&amp;quot;: 5&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
RecordCodecBuilder also produces MapCodecCodecs.&lt;br /&gt;
&lt;br /&gt;
=External Links=&lt;br /&gt;
* [https://github.com/Mojang/DataFixerUpper/blob/master/src/main/java/com/mojang/serialization/Codec.java Codecs in Mojang's official public DataFixerUpper repository]&lt;br /&gt;
* [https://kvverti.github.io/Documented-DataFixerUpper/snapshot/com/mojang/serialization/Codec.html#flatXmap-java.util.function.Function-java.util.function.Function- Unofficial Codec Javadocs]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Jar-in-Jar&amp;diff=3404</id>
		<title>Jar-in-Jar</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Jar-in-Jar&amp;diff=3404"/>
		<updated>2023-06-06T19:45:31Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Fix grammar&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Jar-in-Jar is a way to handle the dependencies of your mod.&lt;br /&gt;
Sometimes these are libraries pulled from a central maven repository, sometimes these are libraries specially designed for Minecraft and sometimes these are completely other mods.&lt;br /&gt;
Whatever the reason for using a library during the development of your mods, you will need to ensure that the end user has them available when someone runs your mod in their environment.&lt;br /&gt;
&lt;br /&gt;
Although there are several options available to achieve this, including for example the Shading plugin, this does not work all the time and can even cause problems along the way when for example two mods need the same dependency.&lt;br /&gt;
Introducing the all-new, all-shiny: Jar-In-Jar.&lt;br /&gt;
&lt;br /&gt;
====Central function====&lt;br /&gt;
Jar-In-Jar is first and foremost a way to load dependencies for mods, from the jars of the mods.&lt;br /&gt;
To achieve this it looks for a file called: ''META-INF/jarjar/metadata.json''. If you are interested in the format of this file, see the following section of the JarJar library which we expose: [https://github.com/MinecraftForge/JarJar/tree/main/metadata/src/main/java/net/minecraftforge/jarjar/metadata JarJar Library - Metadata Source] &lt;br /&gt;
&lt;br /&gt;
In short, this metadata file lists a set of dependencies to include, what their maven coordinate is, the accepted version range that your mod supports, the version of the dependency that is included in your mods jar as well as a path to the jar in your mods jar file.&lt;br /&gt;
&lt;br /&gt;
During the startup of the game, FML will first collect all mods and then collect all their dependencies to load. Jar-In-Jar hooks into this second phase and reads all the dependency files (recursively) and then determines what versions of the dependencies to load. &lt;br /&gt;
====Dependency negotiation====&lt;br /&gt;
Because different mods might need different versions of the same dependency (and have those included) Jar-In-Jar is first and foremost a negotiation system (hence you having to supply a version range your mod supports). From all dependencies that need to be loaded their supported version range is narrowed down to the agreeable range that all mods support. Then there are in principle three outcomes that can occur:&lt;br /&gt;
# No agreeable version range is found: Loading can not continue and the user will see an error message that mods require different dependency versions which are not compatible.&lt;br /&gt;
# An agreeable version range is found, but no jar was included in any of the dependencies which have a version that fits in the agreed range: Loading can not continue and the user will see an error message that the mods have agreed upon a supported range, but no file was found with the required version.&lt;br /&gt;
# An agreeable version range is found, and a matching jar could be located: That dependency will be loaded.&lt;br /&gt;
&lt;br /&gt;
====Dependency loading====&lt;br /&gt;
Once negotiation ends, the selected jars are loaded into the game.&lt;br /&gt;
The class loading layer is determined in two ways:&lt;br /&gt;
# The default way: If a mod, plugin, or language loader is detected then it is loaded in the appropriate layer and processed as such.&lt;br /&gt;
# The override way: If a library is supposed to be loaded which is not aware of Minecraft (for example JGraphT) then it will be loaded as a game library only. Meaning that your mod has access to it, but not plugins or language loaders. Those as such can only use libraries that are Minecraft aware or Shaded instead of Jar-In-Jarred into their respective jar.&lt;br /&gt;
&lt;br /&gt;
=== Using ForgeGradle to generate a Jar-In-Jar ===&lt;br /&gt;
Jar-In-Jar is a completely optional system.&lt;br /&gt;
To enable it, you need to call `jarJar.enable()` anywhere in your buildscript.&lt;br /&gt;
By default, this will include all the dependencies in the `jarjar` configuration into the task output of the `jarJar` task.&lt;br /&gt;
''Note: The task jarJar is not accessible via the `jarJar` statement, since this references the project extension to manage Jar-In-Jar. If you need to modify the task use: `tasks.jarJar.configure { ... } `''&lt;br /&gt;
&lt;br /&gt;
==== Using the runtime dependencies ====&lt;br /&gt;
To include the runtime dependencies as well, you can invoke `jarJar.fromRuntimeConfiguration()` which will include the dependencies which are found at the runtime. If you use this, it is highly suggested to include a dependency filter, since else every single dependency, including Minecraft, forge, and their dependencies are included as well.&lt;br /&gt;
&lt;br /&gt;
==== Using dependency filters ====&lt;br /&gt;
While you can filter the dependencies by including them in the `jarJar` configuration or not, this is not always as flexible as you need it to be. To achieve fine grain filtering the dependency configuration endpoint has been added to the `jarJar` extension as well as to the `jarJar` task. &lt;br /&gt;
Using this endpoint you can configure dependency patterns (including using regular expressions) which you can include and exclude from the configuration:&lt;br /&gt;
&lt;br /&gt;
===== Exclude gson example =====&lt;br /&gt;
 dependencies {&lt;br /&gt;
     exclude(dependency('com.google.gson.*')) &lt;br /&gt;
 }&lt;br /&gt;
This example excludes any dependency which has `com.google.gson.` as a prefix of the group name of that artifact.&lt;br /&gt;
&lt;br /&gt;
===== Include filters with runtime configuration usage =====&lt;br /&gt;
It is generally recommended to set at least one `include` filter when using the `fromRuntimeConfiguration` option.&lt;br /&gt;
&lt;br /&gt;
==== Dependency version pinning ====&lt;br /&gt;
Since Jar-In-Jar is first and foremost a negotiation system it is required that you provide a way to supply it with a supported range, by default this is done via the version property of your dependency:&lt;br /&gt;
 dependencies {&lt;br /&gt;
    jarJar(group: 'com.google.code.gson', name: 'gson', version: '[2.0,3.0)')&lt;br /&gt;
 }&lt;br /&gt;
However, this might not produce the required result or even the required artifact you wish to include (by default the highest supported version is included based on Gradle dependency resolution rules).&lt;br /&gt;
Using dependency version pinning you can specify which version of the dependency Jar-In-Jar should include when the jar is made. To achieve this configure the dependency and invoke: `jarJar.pin(&amp;lt;dependency instance&amp;gt;, &amp;quot;version_string&amp;quot;)` as follows:&lt;br /&gt;
 dependencies {&lt;br /&gt;
    implementation(group: 'com.google.code.gson', name: 'gson', version: '[2.0,3.0)') {&lt;br /&gt;
        jarJar.pin(it, &amp;quot;2.8.0&amp;quot;)&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
The example above will include version 2.8.0 of the GSON library into the Jar-In-Jar jar built by the `jarJar` task.&lt;br /&gt;
&lt;br /&gt;
==== Dependency range pinning ====&lt;br /&gt;
Next to dependency version pinning Jar-In-Jar also supports pinning the version range which your mod supports, outside of the compile dependency range that you specify in the dependency statement:&lt;br /&gt;
 dependencies {&lt;br /&gt;
    implementation(group: 'com.google.code.gson', name: 'gson', version: '2.8.0') {&lt;br /&gt;
        jarJar.ranged(it, &amp;quot;[2.0,3.0)&amp;quot;)&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
As you can see this function is very useful when you combine it with runtime configuration-based dependency selection since it allows you to use a single statement to add the dependency to your project, as well as include it with a properly supported version range within your Jar-In-Jar jar.&lt;br /&gt;
&lt;br /&gt;
==== Publishing a Jar-in-Jar jar to maven ====&lt;br /&gt;
Although in practice this is not really useful to do, for archival reasons FG supports publishing Jar-In-Jar artifacts to a maven of choice. The setup is similar to how the Shadow plugin handles this:&lt;br /&gt;
 publications {&lt;br /&gt;
     mavenJava(MavenPublication) {&lt;br /&gt;
         from components.java&lt;br /&gt;
         jarJar.component(it)&lt;br /&gt;
  &lt;br /&gt;
         //Other statements related to configuring the POM go here&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Using this technique will add all Jar-In-Jar you build in the project to the publication at once and publish them with the other artifacts.&lt;br /&gt;
If you want to only publish a specific Jar-In-Jar artifact to this publication use the following statement, which accepts a task instance to achieve this:&lt;br /&gt;
 publications {&lt;br /&gt;
     mavenJava(MavenPublication) {&lt;br /&gt;
         from components.java&lt;br /&gt;
         jarJar.component(it, tasks.jarJarOther)&lt;br /&gt;
  &lt;br /&gt;
         //Other statements related to configuring the POM go here&lt;br /&gt;
     }&lt;br /&gt;
 }&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Sending_Packets&amp;diff=3402</id>
		<title>Sending Packets</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Sending_Packets&amp;diff=3402"/>
		<updated>2023-05-27T16:11:10Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Move distributor list into a table&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Once a packet has been added to the network, it can be called to send a message to the side it refers to. Usually there are four different directions a packet can be sent:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; border=1&lt;br /&gt;
!Direction !!Description &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;PLAY_TO_CLIENT&amp;lt;/code&amp;gt;   ||  A packet is sent from the server to the client during gameplay. &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;PLAY_TO_SERVER&amp;lt;/code&amp;gt;   ||  A packet is sent from the client to the server during gameplay. &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;LOGIN_TO_CLIENT&amp;lt;/code&amp;gt;   ||  A packet is sent to the client on initial login. &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;LOGIN_TO_SERVER&amp;lt;/code&amp;gt;   ||  A packet is sent to the server on initial login. &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The two login packets are handled internally by forge itself. However, the other two need to be sent using &amp;lt;code&amp;gt;SimpleChannel#send&amp;lt;/code&amp;gt; for &amp;lt;code&amp;gt;SimpleChannel#sendToServer&amp;lt;/code&amp;gt;. Each method takes a new instance of the message to send.&lt;br /&gt;
&lt;br /&gt;
==Client Packet Locations==&lt;br /&gt;
&lt;br /&gt;
* It might not always be necessary to update every single client with a packet if they are not viewing the entity or are not affected by it. To specify which clients to send a packet from the server to, a &amp;lt;code&amp;gt;PacketDistributor$PacketTarget&amp;lt;/code&amp;gt; must also be passed in as a parameter. There are many helpful fields that hold simple implementations of where to send which packet within &amp;lt;code&amp;gt;PacketDistributor&amp;lt;/code&amp;gt;. However, they must be supplied with the required input either via &amp;lt;code&amp;gt;PacketDistributor#with&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;PacketDistributor#noArg&amp;lt;/code&amp;gt; if it is going to all players.&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
Here is a list of Forge provided &amp;lt;code&amp;gt;PacketDistributor&amp;lt;/code&amp;gt;s:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; border=1&lt;br /&gt;
!&amp;lt;code&amp;gt;PacketDistributor&amp;lt;/code&amp;gt; !!Supplied Value !!Description &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;PLAYER&amp;lt;/code&amp;gt;                     || &amp;lt;code&amp;gt;ServerPlayer&amp;lt;/code&amp;gt;       || Send to the specified player .&lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;DIMENSION&amp;lt;/code&amp;gt;                  || &amp;lt;code&amp;gt;ResourceKey&amp;lt;Level&amp;gt;&amp;lt;/code&amp;gt; || Send to all players within the specified dimension.&lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;NEAR&amp;lt;/code&amp;gt;                       || &amp;lt;code&amp;gt;TargetPoint&amp;lt;/code&amp;gt;        || Send to all players within the range of the target point.&lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;ALL&amp;lt;/code&amp;gt;                        || None                            || Send to all currently logged in players.&lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;SERVER&amp;lt;/code&amp;gt;                     || None                            || Send from the player client to the server. This is the only distributor that should be used for client -&amp;gt; server communication.&lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;TRACKING_ENTITY&amp;lt;/code&amp;gt;            || &amp;lt;code&amp;gt;Entity&amp;lt;/code&amp;gt;             || Send to all players currently tracking the specified entity.&lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;TRACKING_ENTITY_AND_SELF&amp;lt;/code&amp;gt;   || &amp;lt;code&amp;gt;Entity&amp;lt;/code&amp;gt;             || Send to all players currently tracking the specified entity and the entity itself, if it is a player.&lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;TRACKING_CHUNK&amp;lt;/code&amp;gt;             || &amp;lt;code&amp;gt;LevelChunk&amp;lt;/code&amp;gt;         || Send to all players tracking the specified chunk.&lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;NMLIST&amp;lt;/code&amp;gt;                     || &amp;lt;code&amp;gt;List&amp;lt;Connection&amp;gt;&amp;lt;/code&amp;gt;   || Send to the listed connections. Each connection is typically an individual player.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Tags&amp;diff=3369</id>
		<title>Tags</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Tags&amp;diff=3369"/>
		<updated>2022-12-17T05:56:35Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Undo revision 3368 by Xan (talk), not an actual standard but was rather introducing a new one&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tags are generalized sets of objects in the game, used for grouping related things together and providing fast membership checks.&lt;br /&gt;
&lt;br /&gt;
== Declaring Your Own Groupings ==&lt;br /&gt;
Tags are declared in your mod’s [https://mcforge.readthedocs.io/en/latest/utilities/tags/datapacks.md datapack]. For example, a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;TagKey&amp;lt;Block&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with a given identifier of  &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;modid:foo/tagname&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; will reference a tag at &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;/data/&amp;lt;modid&amp;gt;/tags/blocks/foo/tagname.json&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Tags for &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Item&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;EntityType&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Fluid&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;GameEvent&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s use the plural forms for their folder location while all other registries use the singular version (&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;EntityType&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; uses the folder &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;entity_types&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; while &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Potion&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; would use the folder &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;potion&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;). Similarly, you may append to or override tags declared in other domains, such as Vanilla, by declaring your own JSONs. For example, to add your own mod’s saplings to the Vanilla sapling tag, you would specify it in &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;/data/minecraft/tags/blocks/saplings.json&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, and Vanilla will merge everything into one tag at reload, if the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;replace&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; option is false. If &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;replace&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; is true, then all entries before the json specifying &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;replace&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; will be removed.&lt;br /&gt;
&lt;br /&gt;
Values listed that are not present will cause the tag to error unless the value is listed using an &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;id&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; string and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;required&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; boolean set to false, as in the following example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;replace&amp;quot;: false,&lt;br /&gt;
  &amp;quot;values&amp;quot;: [&lt;br /&gt;
    &amp;quot;minecraft:gold_ingot&amp;quot;,&lt;br /&gt;
    &amp;quot;mymod:my_ingot&amp;quot;,&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;othermod:ingot_other&amp;quot;,&lt;br /&gt;
      &amp;quot;required&amp;quot;: false&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See the [https://minecraft.gamepedia.com/Tag#JSON_format Vanilla wiki] for a description of the base syntax.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There is also a Forge extension on the Vanilla syntax.&lt;br /&gt;
You may declare a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;remove&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; array of the same format as the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;values&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; array. Any values listed here will be removed from the tag. This acts as a finer grained version of the Vanilla &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;replace&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
==Using Tags In Code==&lt;br /&gt;
Tags for all registries are automatically sent from the server to any remote clients on login and reload. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Item&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;EntityType&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Fluid&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;GameEvent&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s are special cased as they have &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Holder&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s allowing for available tags to be accessible through the object itself.&lt;br /&gt;
&lt;br /&gt;
Tags wrappers can be created using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;TagKey#create&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; where the registry the tag should belong to and the tag name are supplied. Some vanilla defined helpers are also available to create wrappers via &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;*Tags#create&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; where &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; refers to the name of the registry object. Forge wrapped registries can create a tag using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ITagManager&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; via &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;IForgeRegistry#tags&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;TagKey&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s can then be obtained via &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ITagManager#createTagKey&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Forge wrapped registry objects can grab their associated holder using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;IForgeRegistry#getHolder&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Additionally, other streamlined operations can be performed using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ITagManager&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Non-Forge registry objects use either &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Registry#getHolder&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Registry#getHolderOrThrow&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; to get the current holder.&lt;br /&gt;
&lt;br /&gt;
They then can compare if the registry object has a tag using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Holder#is&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Tag-holding registry objects contain a method called &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;#is&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; in either their registry object or state-aware class to check whether the object belongs to a certain tag.&lt;br /&gt;
&lt;br /&gt;
As an example: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static final TagKey&amp;lt;Item&amp;gt; myItemTag = ItemTags.create(new ResourceLocation(&amp;quot;mymod&amp;quot;, &amp;quot;myitemgroup&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
public static final TagKey&amp;lt;Potion&amp;gt; myPotionTag = ForgeRegistries.POTIONS.tags().createTagKey(new ResourceLocation(&amp;quot;mymod&amp;quot;, &amp;quot;mypotiongroup&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
public static final TagKey&amp;lt;VillagerType&amp;gt; myVillagerTypeTag = TagKey.create(Registry.VILLAGER_TYPE, new ResourceLocation(&amp;quot;mymod&amp;quot;, &amp;quot;myvillagertypegroup&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
// In some method where stack is an ItemStack&lt;br /&gt;
boolean isInItemGroup = stack.is(myItemTag);&lt;br /&gt;
&lt;br /&gt;
// In some method where potion is a Potion&lt;br /&gt;
boolean isInPotionGroup = ForgeRegistries.POTIONS.tags().getTag(myPotionTag).contains(potion);&lt;br /&gt;
&lt;br /&gt;
// In some method where villagerTypeKey is a ResourceKey&amp;lt;VillagerType&amp;gt;&lt;br /&gt;
boolean isInVillagerTypeGroup = Registry.VILLAGER_TYPE.getHolder(villagerTypeKey).map(holder -&amp;gt; holder.is(myVillagerTypeTag)).orElse(false);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Migration from OreDictionary ==&lt;br /&gt;
* For recipes, tags can be used directly in the vanilla recipe format (see below)&lt;br /&gt;
* For matching items in code, see the section above.&lt;br /&gt;
* If you are declaring a new type of item grouping, follow a couple naming conventions:&lt;br /&gt;
** Use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;domain:type/material&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. When the name is a common one that all modders should adopt, use the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;forge&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; domain.&lt;br /&gt;
** For example, brass ingots should be registered under the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;forge:ingots/brass&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; tag, and cobalt nuggets under the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;forge:nuggets/cobalt&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; tag.&lt;br /&gt;
&lt;br /&gt;
== Using Tags in Recipes and Advancements  ==&lt;br /&gt;
Tags are directly supported by Vanilla, see the respective Vanilla wiki pages for [https://minecraft.gamepedia.com/Recipe#JSON_format recipes] and [https://minecraft.gamepedia.com/Advancements advancements] for usage details.&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
&lt;br /&gt;
There are several conventions that will help facilitate compatibility in the ecosystem: &lt;br /&gt;
   * If there is a Vanilla tag that fits your block or item, add it to that tag. See the [https://minecraft.gamepedia.com/Tag#List_of_tags list of Vanilla tags]. &lt;br /&gt;
   * If there is a Forge tag that fits your block or item, add it to that tag. The list of tags declared by Forge can be seen on [https://github.com/MinecraftForge/MinecraftForge/tree/1.18.x/src/generated/resources/data/forge/tags GitHub]. &lt;br /&gt;
   * If there is a group of something you feel should be shared by the community, consider PR-ing it to Forge instead of making your own tag &lt;br /&gt;
   * Tag naming conventions should follow Vanilla conventions. In particular, item and block groupings are plural instead of singular. E.g. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;minecraft:logs&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;minecraft:saplings&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. &lt;br /&gt;
   * Item tags should be sorted into subdirectories according to the type of item, e.g. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;forge:ingots/iron&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;forge:nuggets/brass&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
=== Forge Tags ===&lt;br /&gt;
&lt;br /&gt;
This is a list of all [https://github.com/MinecraftForge/MinecraftForge/tree/1.18.x/src/generated/resources/data/forge/tags tags] using the &amp;lt;code&amp;gt;forge&amp;lt;/code&amp;gt; namespace that are currently defined by Forge along those that are commonly used by other mods. These can all be found within the [https://github.com/MinecraftForge/MinecraftForge/blob/1.18.x/src/main/java/net/minecraftforge/common/Tags.java &amp;lt;code&amp;gt;Tags&amp;lt;/code&amp;gt;] class.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|Tags that are not officially defined within the Forge codebase will have &amp;lt;code&amp;gt;*&amp;lt;/code&amp;gt; as a suffix. To use those outside the Forge codebase, an &amp;lt;code&amp;gt;IOptionalNamedTag&amp;lt;/code&amp;gt; must be created using &amp;lt;code&amp;gt;*Tags#createOptional&amp;lt;/code&amp;gt; where the asterisk can be replaced by its associated class name.}}&lt;br /&gt;
&lt;br /&gt;
==== Blocks ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Super Tag(s) !! Contains&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:barrels&amp;lt;/code&amp;gt; || None || Barrels&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:barrels/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:barrels&amp;lt;/code&amp;gt; || Wooden barrels&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || None || Chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests/ender&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || Ender chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests/trapped&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || Trapped chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || Wooden chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || None || Cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/normal&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Normal cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/infested&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Infested cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/mossy&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Mossy cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/deepslate&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Deepslate cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:end_stones&amp;lt;/code&amp;gt; || None || End stones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:enderman_place_on_blacklist&amp;lt;/code&amp;gt; || None || Blocks that an enderman cannot place its held block on&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fence_gates&amp;lt;/code&amp;gt; || None || Fence gates&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fence_gates/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:fence_gates&amp;lt;/code&amp;gt; || Wooden fence gates&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fences&amp;lt;/code&amp;gt; || None || Fences&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fences/nether_brick&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:fences&amp;lt;/code&amp;gt; || Nether brick fences&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fences/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:fences&amp;lt;/code&amp;gt; || Wooden fences&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || None || Glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/black&amp;lt;/code&amp;gt; || None || Black glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/blue&amp;lt;/code&amp;gt; || None || Blue glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/brown&amp;lt;/code&amp;gt; || None || Brown glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/colorless&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || Normal glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/cyan&amp;lt;/code&amp;gt; || None || Cyan glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/gray&amp;lt;/code&amp;gt; || None || Gray glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/green&amp;lt;/code&amp;gt; || None || Green glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/light_blue&amp;lt;/code&amp;gt; || None || Light blue glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/light_gray&amp;lt;/code&amp;gt; || None || Light gray glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/lime&amp;lt;/code&amp;gt; || None || Lime glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/magenta&amp;lt;/code&amp;gt; || None || Magenta glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/orange&amp;lt;/code&amp;gt; || None || Orange glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/pink&amp;lt;/code&amp;gt; || None || Pink glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/purple&amp;lt;/code&amp;gt; || None || Purple glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/red&amp;lt;/code&amp;gt; || None || Red glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/silica&amp;lt;/code&amp;gt; || None || Sand-based glass with minor ingredient variation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/tinted&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || Tinted glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/white&amp;lt;/code&amp;gt; || None || White glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/yellow&amp;lt;/code&amp;gt; || None || Yellow glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes&amp;lt;/code&amp;gt; || None || Glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/black&amp;lt;/code&amp;gt; || None || Black glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/blue&amp;lt;/code&amp;gt; || None || Blue glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/brown&amp;lt;/code&amp;gt; || None || Brown glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/colorless&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass_panes&amp;lt;/code&amp;gt; || Normal glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/cyan&amp;lt;/code&amp;gt; || None || Cyan glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/gray&amp;lt;/code&amp;gt; || None || Gray glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/green&amp;lt;/code&amp;gt; || None || Green glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/light_blue&amp;lt;/code&amp;gt; || None || Light blue glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/light_gray&amp;lt;/code&amp;gt; || None || Light gray glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/lime&amp;lt;/code&amp;gt; || None || Lime glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/magenta&amp;lt;/code&amp;gt; || None || Magenta glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/orange&amp;lt;/code&amp;gt; || None || Orange glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/pink&amp;lt;/code&amp;gt; || None || Pink glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/purple&amp;lt;/code&amp;gt; || None || Purple glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/red&amp;lt;/code&amp;gt; || None || Red glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/white&amp;lt;/code&amp;gt; || None || White glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/yellow&amp;lt;/code&amp;gt; || None || Yellow glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gravel&amp;lt;/code&amp;gt; || None || Gravel&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:netherrack&amp;lt;/code&amp;gt; || None || Netherrack&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:obsidian&amp;lt;/code&amp;gt; || None || Obsidian&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_bearing_ground/deepslate&amp;lt;/code&amp;gt; || None || Blocks replaced by deepslate ores during world generation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_bearing_ground/netherrack&amp;lt;/code&amp;gt; || None || Blocks replaced by netherrack ores during world generation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_bearing_ground/stone&amp;lt;/code&amp;gt; || None || Blocks replaced by stone ores during world generation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_rates/dense&amp;lt;/code&amp;gt; || None || Ores which produce numerous resources on average&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_rates/singular&amp;lt;/code&amp;gt; || None || Ores which produce a single resource on average&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_rates/sparse&amp;lt;/code&amp;gt; || None || Ores which produce less than a single resource on average&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || None || Ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/coal&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Coal ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Copper ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/diamond&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Diamond ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/emerald&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Emerald ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Gold ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/lapis&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Lapis ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/netherite_scrap&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Netherite scrap ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/quartz&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Quartz ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/redstone&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Redstone ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores_in_ground/deepslate&amp;lt;/code&amp;gt; || None || Ores which can be found in deepslate&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores_in_ground/netherrack&amp;lt;/code&amp;gt; || None || Ores which can be found in netherrack&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores_in_ground/stone&amp;lt;/code&amp;gt; || None || Ores which can be found in stone&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sand&amp;lt;/code&amp;gt; || None || Sand&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sand/colorless&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:sand&amp;lt;/code&amp;gt; || Normal sand&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sand/red&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:sand&amp;lt;/code&amp;gt; || Red sand&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sandstone&amp;lt;/code&amp;gt; || None || Sandstone&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:stained_glass&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || Stained glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:stained_glass_panes&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass_panes&amp;lt;/code&amp;gt; || Stained glass planes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:stone&amp;lt;/code&amp;gt; || None || Stones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || None || Storage blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/amethyst&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Amethyst blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/coal&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Coal blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Copper blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/diamond&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Diamond blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/emerald&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Emerald blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Gold blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Iron blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/lapis&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Lapis blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/netherite&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Netherite blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/quartz&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Quartz blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/raw_copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Raw copper blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/raw_gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Raw gold blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/raw_iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Raw iron blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/redstone&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Redstone blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:needs_wood_tool&amp;lt;/code&amp;gt; || None || Blocks which need a wooden tool to be mined efficiently&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:needs_gold_tool&amp;lt;/code&amp;gt; || None || Blocks which need a gold tool to be mined efficiently&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:needs_netherite_tool&amp;lt;/code&amp;gt; || None || Blocks which need a netherite tool to be mined efficiently&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Items ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Super Tag(s) !! Contains&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:barrels&amp;lt;/code&amp;gt; || None || Barrels&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:barrels/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:barrels&amp;lt;/code&amp;gt; || Wooden barrels&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:bones&amp;lt;/code&amp;gt; || None || Bones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:bookshelves&amp;lt;/code&amp;gt; || None || Bookshelves&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || None || Chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests/ender&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || Ender chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests/trapped&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || Trapped chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || Wooden chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || None || Cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/normal&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Normal cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/infested&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Infested cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/mossy&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Mossy cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/deepslate&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Deepslate cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:crops&amp;lt;/code&amp;gt; || None || Crops&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:crops/beetroot&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:crops&amp;lt;/code&amp;gt; || Beetroot crops&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:crops/carrot&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:crops&amp;lt;/code&amp;gt; || Carrot crops&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:crops/nether_wart&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:crops&amp;lt;/code&amp;gt; || Nether wart crops&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:crops/potato&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:crops&amp;lt;/code&amp;gt;  || Potato crops&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:crops/wheat&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:crops&amp;lt;/code&amp;gt; || Wheat crops&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dusts&amp;lt;/code&amp;gt; || None || Dusts&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dusts/prismarine&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dusts&amp;lt;/code&amp;gt; || Prismarine dusts&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dusts/redstone&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dusts&amp;lt;/code&amp;gt; || Redstone dusts&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dusts/glowstone&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dusts&amp;lt;/code&amp;gt; || Glowstone dusts&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || None || Dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/black&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Black dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/blue&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Blue dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/brown&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Brown dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/cyan&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Cyan dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/gray&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Gray dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/green&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Green dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/light_blue&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt;  || Light blue dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/light_gray&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Light green dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/lime&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt;  || Lime dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/magenta&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Magenta dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/orange&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Orange dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/pink&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Pink dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/purple&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Purple dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/red&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Red dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/white&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || White dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/yellow&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Yellow dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:eggs&amp;lt;/code&amp;gt; || None || Eggs&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:enchanting_fuels&amp;lt;/code&amp;gt; || None || Enchantment table fuels&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:end_stones&amp;lt;/code&amp;gt; || None || End stones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ender_pearls&amp;lt;/code&amp;gt; || None || Ender pearls&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:feathers&amp;lt;/code&amp;gt; || None || Feathers&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fence_gates&amp;lt;/code&amp;gt; || None || Fence gates&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fence_gates/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:fence_gates&amp;lt;/code&amp;gt; || Wooden fence gates&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fences&amp;lt;/code&amp;gt; || None || Fences&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fences/nether_brick&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:fences&amp;lt;/code&amp;gt; || Nether brick fences&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fences/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:fences&amp;lt;/code&amp;gt; || Wooden fences&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; || None || Gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems/amethyst&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; || Amethyst gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems/diamond&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; || Diamond gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems/emerald&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; || Emerald gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems/lapis&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;forge:enchanting_fuels&amp;lt;/code&amp;gt; || Lapis gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems/prismarine&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; || Prismarine gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems/quartz&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; || Quartz gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || None || Glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/black&amp;lt;/code&amp;gt; || None || Black glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/blue&amp;lt;/code&amp;gt; || None || Blue glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/brown&amp;lt;/code&amp;gt; || None || Brown glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/colorless&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || Normal glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/cyan&amp;lt;/code&amp;gt; || None || Cyan glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/gray&amp;lt;/code&amp;gt; || None || Gray glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/green&amp;lt;/code&amp;gt; || None || Green glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/light_blue&amp;lt;/code&amp;gt; || None || Light blue glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/light_gray&amp;lt;/code&amp;gt; || None || Light gray glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/lime&amp;lt;/code&amp;gt; || None || Lime glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/magenta&amp;lt;/code&amp;gt; || None || Magenta glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/orange&amp;lt;/code&amp;gt; || None || Orange glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/pink&amp;lt;/code&amp;gt; || None || Pink glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/purple&amp;lt;/code&amp;gt; || None || Purple glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/red&amp;lt;/code&amp;gt; || None || Red glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/silica&amp;lt;/code&amp;gt; || None || Sand-based glass with minor ingredient variation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/tinted&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || Tinted glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/white&amp;lt;/code&amp;gt; || None || White glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/yellow&amp;lt;/code&amp;gt; || None || Yellow glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes&amp;lt;/code&amp;gt; || None || Glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/black&amp;lt;/code&amp;gt; || None || Black glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/blue&amp;lt;/code&amp;gt; || None || Blue glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/brown&amp;lt;/code&amp;gt; || None || Brown glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/colorless&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass_panes&amp;lt;/code&amp;gt; || Normal glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/cyan&amp;lt;/code&amp;gt; || None || Cyan glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/gray&amp;lt;/code&amp;gt; || None || Gray glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/green&amp;lt;/code&amp;gt; || None || Green glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/light_blue&amp;lt;/code&amp;gt; || None || Light blue glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/light_gray&amp;lt;/code&amp;gt; || None || Light gray glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/lime&amp;lt;/code&amp;gt; || None || Lime glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/magenta&amp;lt;/code&amp;gt; || None || Magenta glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/orange&amp;lt;/code&amp;gt; || None || Orange glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/pink&amp;lt;/code&amp;gt; || None || Pink glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/purple&amp;lt;/code&amp;gt; || None || Purple glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/red&amp;lt;/code&amp;gt; || None || Red glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/white&amp;lt;/code&amp;gt; || None || White glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/yellow&amp;lt;/code&amp;gt; || None || Yellow glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gravel&amp;lt;/code&amp;gt; || None || Gravel&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gunpowder&amp;lt;/code&amp;gt; || None || Gunpowder&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:heads&amp;lt;/code&amp;gt; || None || Heads&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || None || Ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots/brick&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || Brick ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots/copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || Copper ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || Gold ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots/iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || Iron ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots/netherite&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || Netherite ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots/nether_brick&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || Nether brick ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:leather&amp;lt;/code&amp;gt; || None || Leather&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:mushrooms&amp;lt;/code&amp;gt; || None || Mushrooms&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:nether_stars&amp;lt;/code&amp;gt; || None || Nether stars&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:netherrack&amp;lt;/code&amp;gt; || None || Netherrack&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:nuggets&amp;lt;/code&amp;gt; || None || Nuggets&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:nuggets/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:nuggets&amp;lt;/code&amp;gt; || Gold nuggets&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:nuggets/iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:nuggets&amp;lt;/code&amp;gt; || Iron nuggets&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:obsidian&amp;lt;/code&amp;gt; || None || Obsidian&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_bearing_ground/deepslate&amp;lt;/code&amp;gt; || None || Blocks replaced by deepslate ores during world generation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_bearing_ground/netherrack&amp;lt;/code&amp;gt; || None || Blocks replaced by netherrack ores during world generation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_bearing_ground/stone&amp;lt;/code&amp;gt; || None || Blocks replaced by stone ores during world generation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_rates/dense&amp;lt;/code&amp;gt; || None || Ores which produce numerous resources on average&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_rates/singular&amp;lt;/code&amp;gt; || None || Ores which produce a single resource on average&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_rates/sparse&amp;lt;/code&amp;gt; || None || Ores which produce less than a single resource on average&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || None || Ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/coal&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Coal ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Copper ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/diamond&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Diamond ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/emerald&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Emerald ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Gold ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/lapis&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Lapis ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/netherite_scrap&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Netherite scrap ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/quartz&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Quartz ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/redstone&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Redstone ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores_in_ground/deepslate&amp;lt;/code&amp;gt; || None || Ores which can be found in deepslate&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores_in_ground/netherrack&amp;lt;/code&amp;gt; || None || Ores which can be found in netherrack&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores_in_ground/stone&amp;lt;/code&amp;gt; || None || Ores which can be found in stone&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:raw_materials&amp;lt;/code&amp;gt; || None || Raw materials&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:raw_materials/copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:raw_materials&amp;lt;/code&amp;gt; || Copper raw materials&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:raw_materials/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:raw_materials&amp;lt;/code&amp;gt; || Gold raw materials&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:raw_materials/iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:raw_materials&amp;lt;/code&amp;gt; || Iron raw materials&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:rods&amp;lt;/code&amp;gt; || None || Rods&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:rods/blaze&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:rods&amp;lt;/code&amp;gt; || Blaze rods&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:rods/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:rods&amp;lt;/code&amp;gt; || Wooden rods&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sand&amp;lt;/code&amp;gt; || None || Sand&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sand/colorless&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:sand&amp;lt;/code&amp;gt; || Normal sand&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sand/red&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:sand&amp;lt;/code&amp;gt; || Red sand&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sandstone&amp;lt;/code&amp;gt; || None || Sandstone&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:seeds&amp;lt;/code&amp;gt; || None || Seeds&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:seeds/beetroot&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:seeds&amp;lt;/code&amp;gt; || Beetroot seeds&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:seeds/melon&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:seeds&amp;lt;/code&amp;gt; || Melon seeds&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:seeds/pumpkin&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:seeds&amp;lt;/code&amp;gt; || Pumpkin seeds&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:seeds/wheat&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:seeds&amp;lt;/code&amp;gt; || Wheat seeds&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:shears&amp;lt;/code&amp;gt; || None || Shears&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:slimeballs&amp;lt;/code&amp;gt; || None || Slimeballs&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:stained_glass&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || Stained glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:stained_glass_panes&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass_panes&amp;lt;/code&amp;gt; || Stained glass planes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:stone&amp;lt;/code&amp;gt; || None || Stones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || None || Storage blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/amethyst&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Amethyst blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/coal&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Coal blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Copper blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/diamond&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Diamond blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/emerald&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Emerald blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Gold blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Iron blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/lapis&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Lapis blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/netherite&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Netherite blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/quartz&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Quartz blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/raw_copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Raw copper blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/raw_gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Raw gold blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/raw_iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Raw iron blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/redstone&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Redstone blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:string&amp;lt;/code&amp;gt; || None || String&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Fluids ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Super Tag(s) !! Contains&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:milk&amp;lt;/code&amp;gt; || None || Milk&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Entity Types ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Super Tag(s) !! Contains&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:bosses&amp;lt;/code&amp;gt; || None || Mobs that are designed as bosses (boss bar appears and difficult to fight)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:Resources and Data]]&lt;br /&gt;
&lt;br /&gt;
=== Community Tags ===&lt;br /&gt;
&lt;br /&gt;
This is a list of all tags in the Forge namespace that are not part of Forge but agreed on by the modding community as the standard.&lt;br /&gt;
&lt;br /&gt;
==== Blocks ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Super Tag(s) !! Contains&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/honeycombs&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Honeycomb blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/wax&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Wax blocks&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Items ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Super Tag(s) !! Contains&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:buckets/honey&amp;lt;/code&amp;gt; || None || Buckets holding honey fluids&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:concrete&amp;lt;/code&amp;gt; || None || Concrete&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:concrete_powder&amp;lt;/code&amp;gt; || None || Concrete Powder&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:honeycombs&amp;lt;/code&amp;gt; || None || Honeycombs&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:honey_bottles&amp;lt;/code&amp;gt; || None || Honey bottles&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glazed_terracotta&amp;lt;/code&amp;gt; || None || Glazed Terracotta&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:pollen&amp;lt;/code&amp;gt; || None || Pollen&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:shulker_boxes&amp;lt;/code&amp;gt; || None || Shulker Boxes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/honeycombs&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Honeycomb blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/wax&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Wax blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:wax&amp;lt;/code&amp;gt; || None || Wax&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Fluids ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Super Tag(s) !! Contains&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:honey&amp;lt;/code&amp;gt; || None || Honey&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Entity Types ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Super Tag(s) !! Contains&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:slimes&amp;lt;/code&amp;gt; || None || Slime-like mobs&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Game_Tests&amp;diff=3360</id>
		<title>Game Tests</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Game_Tests&amp;diff=3360"/>
		<updated>2022-11-20T15:01:25Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Fixing gameTestServer: reminder from a month ago&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Game Tests are a way to run in-game unit tests. The system was designed to be scalable and in parallel to run large numbers of different tests efficiently. Testing object interactions and behaviors are simply a few of the many applications of this framework.&lt;br /&gt;
&lt;br /&gt;
== Creating a Game Test ==&lt;br /&gt;
&lt;br /&gt;
A standard Game Test follows three basic steps:&lt;br /&gt;
&lt;br /&gt;
# A structure, or template, is loaded holding the scene on which the interaction or behavior is tested.&lt;br /&gt;
# A method conducts the logic to perform on the scene.&lt;br /&gt;
# The method logic executes. If a successful state is reached, then the test succeeds. Otherwise, the test fails and the result is stored within a lectern adjacent to the scene.&lt;br /&gt;
&lt;br /&gt;
As such, to create a Game Test, there must be an existing template holding the initial start state of the scene and a method which provides the logic of execution.&lt;br /&gt;
&lt;br /&gt;
=== The Test Method ===&lt;br /&gt;
&lt;br /&gt;
A Game Test method is a &amp;lt;code&amp;gt;Consumer&amp;lt;GameTestHelper&amp;gt;&amp;lt;/code&amp;gt; reference, meaning it takes in a &amp;lt;code&amp;gt;GameTestHelper&amp;lt;/code&amp;gt; and returns nothing. For a Game Test method to be recognized, it must have a &amp;lt;code&amp;gt;@GameTest&amp;lt;/code&amp;gt; annotation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class ExampleGameTests {&lt;br /&gt;
  @GameTest&lt;br /&gt;
  public static void exampleTest(GameTestHelper helper) {&lt;br /&gt;
    // Do stuff&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;@GameTest&amp;lt;/code&amp;gt; annotation also contains members which configure how the game test should run.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// In some class&lt;br /&gt;
@GameTest(&lt;br /&gt;
  setupTicks = 20L, // The test spends 20 ticks to set up for execution&lt;br /&gt;
  required = false // The failure is logged but does not affect the execution of the batch&lt;br /&gt;
)&lt;br /&gt;
public static void exampleConfiguredTest(GameTestHelper helper) {&lt;br /&gt;
  // Do stuff&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Relative Positioning ====&lt;br /&gt;
&lt;br /&gt;
All &amp;lt;code&amp;gt;GameTestHelper&amp;lt;/code&amp;gt; methods translate relative coordinates within the structure template scene to its absolute coordinates using the structure block's current location. To allow for easy conversion between relative and absolute positioning, &amp;lt;code&amp;gt;GameTestHelper#absolutePos&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;GameTestHelper#relativePos&amp;lt;/code&amp;gt; can be used respectively.&lt;br /&gt;
&lt;br /&gt;
The relative position of a structure template can be obtained in-game by loading the structure via the [[#Running_Game_Tests|test command]], placing the player at the wanted location, and finally running the &amp;lt;code&amp;gt;/test pos&amp;lt;/code&amp;gt; command. This will grab the coordinates of the player relative to the closest structure within 200 blocks of the player. The command will export the relative position as a copyable text component in the chat to be used as a final local variable.&lt;br /&gt;
&lt;br /&gt;
{{Tip|The local variable generated by &amp;lt;code&amp;gt;/test pos&amp;lt;/code&amp;gt; can specify its reference name by appending it to the end of the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
/test pos &amp;lt;var&amp;gt; # Exports 'final BlockPos &amp;lt;var&amp;gt; = new BlockPos(...);'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Successful Completion ====&lt;br /&gt;
&lt;br /&gt;
A Game Test method is responsible for one thing: marking the test was successful on a valid completion. If no success state was achieved before the timeout is reached (as defined by &amp;lt;code&amp;gt;GameTest#timeoutTicks&amp;lt;/code&amp;gt;), then the test automatically fails.&lt;br /&gt;
&lt;br /&gt;
There are many abstracted methods within &amp;lt;code&amp;gt;GameTestHelper&amp;lt;/code&amp;gt; which can be used to define a successful state; however, four are extremely important to be aware of.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Method !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#succeed&amp;lt;/code&amp;gt; || The test is marked as successful.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#succeedIf&amp;lt;/code&amp;gt; || The supplied &amp;lt;code&amp;gt;Runnable&amp;lt;/code&amp;gt; is tested immediately and succeeds if no &amp;lt;code&amp;gt;GameTestAssertException&amp;lt;/code&amp;gt; is thrown. If the test does not succeed on the immediate tick, then it is marked as a failure.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#succeedWhen&amp;lt;/code&amp;gt; || The supplied &amp;lt;code&amp;gt;Runnable&amp;lt;/code&amp;gt; is tested every tick until timeout and succeeds if the check on one of the ticks does not throw a &amp;lt;code&amp;gt;GameTestAssertException&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#succeedOnTickWhen&amp;lt;/code&amp;gt; || The supplied &amp;lt;code&amp;gt;Runnable&amp;lt;/code&amp;gt; is tested on the specified tick and will succeed if no &amp;lt;code&amp;gt;GameTestAssertException&amp;lt;/code&amp;gt; is thrown. If the &amp;lt;code&amp;gt;Runnable&amp;lt;/code&amp;gt; succeeds on any other tick, then it is marked as a failure.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|Game Tests are executed every tick until the test is marked as a success. As such, methods which schedule success on a given tick must be careful to always fail on any previous tick.}}&lt;br /&gt;
&lt;br /&gt;
==== Scheduling Actions ====&lt;br /&gt;
&lt;br /&gt;
Not all actions will occur when a test begins. Actions can be scheduled to occur at specific times or intervals:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Method !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#runAtTickTime&amp;lt;/code&amp;gt; || The action is ran on the specified tick.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#runAfterDelay&amp;lt;/code&amp;gt; || The action is ran &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; ticks after the current tick.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#onEachTick&amp;lt;/code&amp;gt; || The action is ran every tick.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Assertions ====&lt;br /&gt;
&lt;br /&gt;
At any time during a Game Test, an assertion can be made to check if a given condition is true. There are numerous assertion methods within &amp;lt;code&amp;gt;GameTestHelper&amp;lt;/code&amp;gt;; however, it simplifies to throwing a &amp;lt;code&amp;gt;GameTestAssertException&amp;lt;/code&amp;gt; whenever the appropriate state is not met.&lt;br /&gt;
&lt;br /&gt;
=== Generated Test Methods ===&lt;br /&gt;
&lt;br /&gt;
If Game Test methods need to be generated dynamically, a test method generator can be created. These methods take in no parameters and return a collection of &amp;lt;code&amp;gt;TestFunction&amp;lt;/code&amp;gt;s. For a test method generator to be recognized, it must have a &amp;lt;code&amp;gt;@GameTestGenerator&amp;lt;/code&amp;gt; annotation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class ExampleGameTests {&lt;br /&gt;
  @GameTestGenerator&lt;br /&gt;
  public static Collection&amp;lt;TestFunction&amp;gt; exampleTests() {&lt;br /&gt;
    // Return a collection of TestFunctions&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== TestFunction ====&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;TestFunction&amp;lt;/code&amp;gt; is the boxed information held by the &amp;lt;code&amp;gt;@GameTest&amp;lt;/code&amp;gt; annotation and the method running the test.&lt;br /&gt;
&lt;br /&gt;
{{Tip|Any methods annotated using &amp;lt;code&amp;gt;@GameTest&amp;lt;/code&amp;gt; are translated into a &amp;lt;code&amp;gt;TestFunction&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;GameTestRegistry#turnMethodIntoTestFunction&amp;lt;/code&amp;gt;. That method can be used as a reference for creating &amp;lt;code&amp;gt;TestFunction&amp;lt;/code&amp;gt;s without the use of the annotation.}}&lt;br /&gt;
&lt;br /&gt;
=== Batching ===&lt;br /&gt;
&lt;br /&gt;
Game Tests can be executed in batches instead of registration order. A test can be added to a batch by having the same supplied &amp;lt;code&amp;gt;GameTest#batch&amp;lt;/code&amp;gt; string.&lt;br /&gt;
&lt;br /&gt;
On its own, batching does not provide anything useful. However, batching can be used to perform setup and teardown states on the current level the tests are running in. This is done by annotating a method with either &amp;lt;code&amp;gt;@BeforeBatch&amp;lt;/code&amp;gt; for setup or &amp;lt;code&amp;gt;@AfterBatch&amp;lt;/code&amp;gt; for takedown. The `#batch` methods must match the string supplied to the game test.&lt;br /&gt;
&lt;br /&gt;
Batch methods are &amp;lt;code&amp;gt;Consumer&amp;lt;ServerLevel&amp;gt;&amp;lt;/code&amp;gt; references, meaning they take in a &amp;lt;code&amp;gt;ServerLevel&amp;lt;/code&amp;gt; and return nothing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class ExampleGameTests {&lt;br /&gt;
  @BeforeBatch(batch = &amp;quot;firstBatch&amp;quot;)&lt;br /&gt;
  public static void beforeTest(ServerLevel level) {&lt;br /&gt;
    // Perform setup&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  @GameTest(batch = &amp;quot;firstBatch&amp;quot;)&lt;br /&gt;
  public static void exampleTest2(GameTestHelper helper) {&lt;br /&gt;
    // Do stuff&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Registering a Game Test ==&lt;br /&gt;
&lt;br /&gt;
A Game Test must be registered to be ran in-game. There are two methods of doing so: via the &amp;lt;code&amp;gt;@GameTestHolder&amp;lt;/code&amp;gt; annotation or &amp;lt;code&amp;gt;RegisterGameTestsEvent&amp;lt;/code&amp;gt;. Both registration methods still require the test methods to be annotated with either &amp;lt;code&amp;gt;@GameTest&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;@GameTestGenerator&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;@BeforeBatch&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;@AfterBatch&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== GameTestHolder ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;@GameTestHolder&amp;lt;/code&amp;gt; annotation registers any test methods within the type (class, interface, enum, or record). &amp;lt;code&amp;gt;@GameTestHolder&amp;lt;/code&amp;gt; contains a single method which has multiple uses. In this instance, the supplied &amp;lt;code&amp;gt;#value&amp;lt;/code&amp;gt; must be the mod id of the mod; otherwise, the test will not run under default configurations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
@GameTestHolder(MODID)&lt;br /&gt;
public class ExampleGameTests {&lt;br /&gt;
  // ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== RegisterGameTestsEvent ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;RegisterGameTestEvent&amp;lt;/code&amp;gt; can also register either classes or methods using &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt;. The event listener must be [[Events#Event_Listeners|added]] to the mod event bus. Test methods registered this way must supply their mod id to &amp;lt;code&amp;gt;GameTest#templateNamespace&amp;lt;/code&amp;gt; on every method annotated with &amp;lt;code&amp;gt;@GameTest&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// In some class&lt;br /&gt;
public void registerTests(RegisterGameTestsEvent event) {&lt;br /&gt;
  event.register(ExampleGameTests.class);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// In ExampleGameTests&lt;br /&gt;
@GameTest(templateNamespace = MODID)&lt;br /&gt;
public static void exampleTest3(GameTestHelper helper) {&lt;br /&gt;
  // Perform setup&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Tip|The value supplied to &amp;lt;code&amp;gt;GameTestHolder#value&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;GameTest#templateNamespace&amp;lt;/code&amp;gt; can be different from the current mod id. The configuration within the [[#Enabling_Other_Namespaces|buildscript]] would need to be changed.}}&lt;br /&gt;
&lt;br /&gt;
== Structure Templates ==&lt;br /&gt;
&lt;br /&gt;
Game Tests are performed within scenes loaded by structures, or templates. All templates define the dimensions of the scene and the initial data (blocks and entities) that will be loaded. The template must be stored as an &amp;lt;code&amp;gt;.nbt&amp;lt;/code&amp;gt; file within &amp;lt;code&amp;gt;data/&amp;lt;namespace&amp;gt;/structures&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Tip|A structure template can be created and saved using a structure block.}}&lt;br /&gt;
&lt;br /&gt;
The location of the template is specified by a few factors:&lt;br /&gt;
&lt;br /&gt;
* If the namespace of the template is specified.&lt;br /&gt;
* If the class should be prepended to the name of the template.&lt;br /&gt;
* If the name of the template is specified.&lt;br /&gt;
&lt;br /&gt;
The namespace of the template is determined by &amp;lt;code&amp;gt;GameTest#templateNamespace&amp;lt;/code&amp;gt;, then &amp;lt;code&amp;gt;GameTestHolder#value&amp;lt;/code&amp;gt; if not specified, then &amp;lt;code&amp;gt;minecraft&amp;lt;/code&amp;gt; if neither is specified.&lt;br /&gt;
&lt;br /&gt;
The simple class name is not prepended to the name of the template if the &amp;lt;code&amp;gt;@PrefixGameTestTemplate&amp;lt;/code&amp;gt; is applied to a class or method with the test annotations and set to &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;. Otherwise, the simple class name is made lowercase and prepended and followed by a dot before the template name.&lt;br /&gt;
&lt;br /&gt;
The name of the template is determined by &amp;lt;code&amp;gt;GameTest#template&amp;lt;/code&amp;gt;. If not specified, then the lowercase name of the method is used instead.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Modid for all structures will be MODID&lt;br /&gt;
@GameTestHolder(MODID)&lt;br /&gt;
public class ExampleGameTests {&lt;br /&gt;
&lt;br /&gt;
  // Class name is prepended, template name is not specified&lt;br /&gt;
  // Template Location at 'modid:examplegametests.exampletest'&lt;br /&gt;
  @GameTest&lt;br /&gt;
  public static void exampleTest(GameTestHelper helper) { /*...*/ }&lt;br /&gt;
&lt;br /&gt;
  // Class name is not prepended, template name is not specified&lt;br /&gt;
  // Template Location at 'modid:exampletest2'&lt;br /&gt;
  @PrefixGameTestTemplate(false)&lt;br /&gt;
  @GameTest&lt;br /&gt;
  public static void exampleTest2(GameTestHelper helper) { /*...*/ }&lt;br /&gt;
&lt;br /&gt;
  // Class name is prepended, template name is specified&lt;br /&gt;
  // Template Location at 'modid:examplegametests.test_template'&lt;br /&gt;
  @GameTest(template = &amp;quot;test_template&amp;quot;)&lt;br /&gt;
  public static void exampleTest3(GameTestHelper helper) { /*...*/ }&lt;br /&gt;
&lt;br /&gt;
  // Class name is not prepended, template name is specified&lt;br /&gt;
  // Template Location at 'modid:test_template2'&lt;br /&gt;
  @PrefixGameTestTemplate(false)&lt;br /&gt;
  @GameTest(template = &amp;quot;test_template2&amp;quot;)&lt;br /&gt;
  public static void exampleTest4(GameTestHelper helper) { /*...*/ }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Running Game Tests ==&lt;br /&gt;
&lt;br /&gt;
Game Tests can be run using the &amp;lt;code&amp;gt;/test&amp;lt;/code&amp;gt; command. The &amp;lt;code&amp;gt;test&amp;lt;/code&amp;gt; command is highly configurable; however, only a few are of importance to running tests:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;run&amp;lt;/code&amp;gt; || Runs the specified test: &amp;lt;code&amp;gt;run &amp;lt;test_name&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;runall&amp;lt;/code&amp;gt; || Runs all available tests.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;runthis&amp;lt;/code&amp;gt; || Runs the nearest test to the player within 15 blocks.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;runthese&amp;lt;/code&amp;gt; || Runs tests within 200 blocks of the player.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;runfailed&amp;lt;/code&amp;gt; || Runs all tests that failed in the previous run.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Tip|Subcommands follow the test command: &amp;lt;code&amp;gt;/test &amp;lt;subcommand&amp;gt;&amp;lt;/code&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
== Buildscript Configurations ==&lt;br /&gt;
&lt;br /&gt;
Game Tests provide additional configuration settings within a buildscript (the &amp;lt;code&amp;gt;build.gradle&amp;lt;/code&amp;gt; file) to run and integrate into different settings.&lt;br /&gt;
&lt;br /&gt;
=== Enabling Other Namespaces ===&lt;br /&gt;
&lt;br /&gt;
If the buildscript was [[Getting_Started#Customizing_the_MDK|setup as recommended]], then only Game Tests under the current mod id would be enabled. To enable other namespaces to load Game Tests from, a run configuration must set the property &amp;lt;code&amp;gt;forge.enabledGameTestNamespaces&amp;lt;/code&amp;gt; to a string specifying each namespace separated by a comma. If the property is empty or not set, then all namespaces will be loaded.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;gradle&amp;quot;&amp;gt;&lt;br /&gt;
// Inside a run configuration&lt;br /&gt;
property 'forge.enabledGameTestNamespaces', 'modid1,modid2,modid3'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|There must be no spaces in-between namespaces; otherwise, the namespace will not be loaded correctly.}}&lt;br /&gt;
&lt;br /&gt;
=== Game Test Server Run Configuration ===&lt;br /&gt;
&lt;br /&gt;
The Game Test Server is a special configuration which runs a build server. The build server returns an exit code of the number of required, failed Game Tests. All failed tests, whether required or optional, are logged. This server can be run using &amp;lt;code&amp;gt;gradlew runGameTestServer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Failure on Successful Test Execution ====&lt;br /&gt;
&lt;br /&gt;
Due to a quirk in how Gradle works, by default, if a task forces a system exit before it has finished executing, even in a zero code exit, the task will be marked as the failure. ForgeGradle sets by default a force exit on run tasks such that any subprojects are not executed in sequence. However, as such, the Game Test Server will always fail.&lt;br /&gt;
&lt;br /&gt;
This can be fixed by disabling the force exit on the run configuration using the &amp;lt;code&amp;gt;#setForceExit&amp;lt;/code&amp;gt; method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;gradle&amp;quot;&amp;gt;&lt;br /&gt;
// For the Game Test Server run configuration&lt;br /&gt;
gameTestServer {&lt;br /&gt;
    // ...&lt;br /&gt;
    setForceExit false&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enabling Game Tests in Other Run Configurations ===&lt;br /&gt;
&lt;br /&gt;
By default, only the &amp;lt;code&amp;gt;client&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;server&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;gameTestServer&amp;lt;/code&amp;gt; run configurations have Game Tests enabled. If another run configuration should run Game Tests, then the &amp;lt;code&amp;gt;forge.enableGameTest&amp;lt;/code&amp;gt; property must be set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;gradle&amp;quot;&amp;gt;&lt;br /&gt;
// Inside a run configuration&lt;br /&gt;
property 'forge.enableGameTest', 'true'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Block_Entity_Renderer&amp;diff=3358</id>
		<title>Block Entity Renderer</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Block_Entity_Renderer&amp;diff=3358"/>
		<updated>2022-10-12T19:04:17Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Missed one&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A &amp;lt;code&amp;gt;BlockEntityRenderer&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;BER&amp;lt;/code&amp;gt; is used to render blocks in a way that cannot be represented with a static baked model (JSON, OBJ, B3D, etc.). A block entity renderer requires the block to have a &amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Creating a BER ==&lt;br /&gt;
To create a BER, create a class that inherits from &amp;lt;code&amp;gt;BlockEntityRenderer&amp;lt;/code&amp;gt;. It takes a generic argument specifying the block's &amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt; class. The generic argument is used in the BER's &amp;lt;code&amp;gt;render&amp;lt;/code&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
Only one BER exists for a given &amp;lt;code&amp;gt;BlockEntityType&amp;lt;/code&amp;gt;. Therefore, values that are specific to a single instance in the world should be stored in the block entity being passed to the renderer rather than in the BER itself. For example, an integer that increments every frame, if stored in the BER, will increment every frame for every block entity of this type in the world.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;render&amp;lt;/code&amp;gt; ===&lt;br /&gt;
This method is called every frame in order to render the block entity.&lt;br /&gt;
&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;blockEntity&amp;lt;/code&amp;gt;: This is the instance of the block entity being rendered.&lt;br /&gt;
* &amp;lt;code&amp;gt;partialTick&amp;lt;/code&amp;gt;: The amount of time, in a fraction of a tick, that has passed since the last full tick.&lt;br /&gt;
* &amp;lt;code&amp;gt;poseStack&amp;lt;/code&amp;gt;: A stack holding four-dimensional matrix entries offset to the current position of the block entity.&lt;br /&gt;
* &amp;lt;code&amp;gt;bufferSource&amp;lt;/code&amp;gt;: A rendering buffer able to access a vertex consumer.&lt;br /&gt;
* &amp;lt;code&amp;gt;combinedLight&amp;lt;/code&amp;gt;: An integer of the current light value on the block entity.&lt;br /&gt;
* &amp;lt;code&amp;gt;combinedOverlay&amp;lt;/code&amp;gt;: An integer set to the current overlay of the block entity, usually &amp;lt;code&amp;gt;OverlayTexture#NO_OVERLAY&amp;lt;/code&amp;gt; or 655,360.&lt;br /&gt;
&lt;br /&gt;
== Registering a BER ==&lt;br /&gt;
In order to register a BER, you must subscribe to the &amp;lt;code&amp;gt;EntityRenderersEvent$RegisterRenderers&amp;lt;/code&amp;gt; event on the mod event bus and call &amp;lt;code&amp;gt;#registerBlockEntityRenderer&amp;lt;/code&amp;gt;.&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Block_Entity_Renderer&amp;diff=3357</id>
		<title>Block Entity Renderer</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Block_Entity_Renderer&amp;diff=3357"/>
		<updated>2022-10-12T19:04:05Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Somehow deleted spaces without knowing, readding&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A &amp;lt;code&amp;gt;BlockEntityRenderer&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;BER&amp;lt;/code&amp;gt; is used to render blocks in a way that cannot be represented with a static baked model (JSON, OBJ, B3D, etc.). A block entity renderer requires the block to have a &amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Creating a BER ==&lt;br /&gt;
To create a BER, create a class that inherits from &amp;lt;code&amp;gt;BlockEntityRenderer&amp;lt;/code&amp;gt;. It takes a generic argument specifying the block's &amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt; class. The generic argument is used in the BER's &amp;lt;code&amp;gt;render&amp;lt;/code&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
Only one BER exists for a given &amp;lt;code&amp;gt;BlockEntityType&amp;lt;/code&amp;gt;. Therefore, values that are specific to a single instance in the world should be stored in the block entity being passed to the renderer rather than in the BER itself. For example, an integer that increments every frame, if stored in the BER, will increment every frame for every block entity of this type in the world.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;render&amp;lt;/code&amp;gt; ===&lt;br /&gt;
This method is called every frame in order to render the block entity.&lt;br /&gt;
&lt;br /&gt;
=== Parameters ===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;blockEntity&amp;lt;/code&amp;gt;: This is the instance of the block entity being rendered.&lt;br /&gt;
* &amp;lt;code&amp;gt;partialTick&amp;lt;/code&amp;gt;: The amount of time, in a fraction of a tick, that has passed since the last full tick.&lt;br /&gt;
* &amp;lt;code&amp;gt;poseStack&amp;lt;/code&amp;gt;: A stack holding four-dimensional matrix entries offset to the current position of the block entity.&lt;br /&gt;
* &amp;lt;code&amp;gt;bufferSource&amp;lt;/code&amp;gt;: A rendering buffer able to access a vertex consumer.&lt;br /&gt;
* &amp;lt;code&amp;gt;combinedLight&amp;lt;/code&amp;gt;: An integer of the current light value on the block entity.&lt;br /&gt;
* &amp;lt;code&amp;gt;combinedOverlay&amp;lt;/code&amp;gt;: An integer set to the current overlay of the block entity, usually &amp;lt;code&amp;gt;OverlayTexture#NO_OVERLAY&amp;lt;/code&amp;gt; or 655,360.&lt;br /&gt;
&lt;br /&gt;
==Registering a BER==&lt;br /&gt;
In order to register a BER, you must subscribe to the &amp;lt;code&amp;gt;EntityRenderersEvent$RegisterRenderers&amp;lt;/code&amp;gt; event on the mod event bus and call &amp;lt;code&amp;gt;#registerBlockEntityRenderer&amp;lt;/code&amp;gt;.&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Block_Entity_Renderer&amp;diff=3356</id>
		<title>Block Entity Renderer</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Block_Entity_Renderer&amp;diff=3356"/>
		<updated>2022-10-12T16:56:08Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Grammar&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A &amp;lt;code&amp;gt;BlockEntityRenderer&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;BER&amp;lt;/code&amp;gt; is used to render blocks in a way that cannot be represented with a static baked model (JSON, OBJ, B3D, etc.). A block entity renderer requires the block to have a &amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Creating a BER==&lt;br /&gt;
To create a BER, create a class that inherits from &amp;lt;code&amp;gt;BlockEntityRenderer&amp;lt;/code&amp;gt;. It takes a generic argument specifying the block's &amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt; class. The generic argument is used in the BER's &amp;lt;code&amp;gt;render&amp;lt;/code&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
Only one BER exists for a given &amp;lt;code&amp;gt;BlockEntityType&amp;lt;/code&amp;gt;. Therefore, values that are specific to a single instance in the world should be stored in the block entity being passed to the renderer rather than in the BER itself. For example, an integer that increments every frame, if stored in the BER, will increment every frame for every block entity of this type in the world.&lt;br /&gt;
&lt;br /&gt;
===&amp;lt;code&amp;gt; render &amp;lt;/code&amp;gt;===&lt;br /&gt;
This method is called every frame in order to render the block entity.&lt;br /&gt;
&lt;br /&gt;
===Parameters===&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;blockEntity&amp;lt;/code&amp;gt;: This is the instance of the block entity being rendered.&lt;br /&gt;
* &amp;lt;code&amp;gt;partialTick&amp;lt;/code&amp;gt;: The amount of time, in a fraction of a tick, that has passed since the last full tick.&lt;br /&gt;
* &amp;lt;code&amp;gt;poseStack&amp;lt;/code&amp;gt;: A stack holding four-dimensional matrix entries offset to the current position of the block entity.&lt;br /&gt;
* &amp;lt;code&amp;gt;bufferSource&amp;lt;/code&amp;gt;: A rendering buffer able to access a vertex consumer.&lt;br /&gt;
* &amp;lt;code&amp;gt;combinedLight&amp;lt;/code&amp;gt;: An integer of the current light value on the block entity.&lt;br /&gt;
* &amp;lt;code&amp;gt;combinedOverlay&amp;lt;/code&amp;gt;: An integer set to the current overlay of the block entity, usually &amp;lt;code&amp;gt;OverlayTexture#NO_OVERLAY&amp;lt;/code&amp;gt; or 655,360.&lt;br /&gt;
&lt;br /&gt;
==Registering a BER==&lt;br /&gt;
In order to register a BER, you must subscribe to the &amp;lt;code&amp;gt;EntityRenderersEvent$RegisterRenderers&amp;lt;/code&amp;gt; event on the mod event bus and call &amp;lt;code&amp;gt;#registerBlockEntityRenderer&amp;lt;/code&amp;gt;.&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Datageneration/Tags&amp;diff=3353</id>
		<title>Datageneration/Tags</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Datageneration/Tags&amp;diff=3353"/>
		<updated>2022-10-06T22:12:59Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Finish tag providers&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tags can be generated for a mod by subclassing &amp;lt;code&amp;gt;TagsProvider&amp;lt;/code&amp;gt; and implementing &amp;lt;code&amp;gt;#addTags&amp;lt;/code&amp;gt;. After implementation, the provider must be added to the &amp;lt;code&amp;gt;DataGenerator&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= TagsProvider =&lt;br /&gt;
&lt;br /&gt;
The tags provider typically generates tags via &amp;lt;code&amp;gt;#tag&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Tip|There is another method called &amp;lt;code&amp;gt;#getOrCreateRawBuilder&amp;lt;/code&amp;gt;, but this is typically used only in cases when two registries represent the same object but in different forms (block and items).}}&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;code&amp;gt;#tag&amp;lt;/code&amp;gt; is called, a builder is created to which the following methods can be chained:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Method !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#add&amp;lt;/code&amp;gt; || Adds an object to a tag.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#addOptional&amp;lt;/code&amp;gt; || Adds an object to a tag through its name. If the object is not present, then the object will be skipped when loading.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#addTag&amp;lt;/code&amp;gt; || Adds a tag to a tag. All elements within the inner tag are now a part of the outer tag.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#addOptionalTag&amp;lt;/code&amp;gt; || Adds a tag to a tag through its name. If the tag is not present, then the tag will be skipped when loading.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#replace&amp;lt;/code&amp;gt; || When &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, all previously loaded entries added to this tag from other datapacks will be discarded. If a datapack is loaded after this one, then it will still append the entries to the tag.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#remove&amp;lt;/code&amp;gt; || Removes an object or all objects within a tag from a tag. If the object is not present in the tag, nothing happens.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Tabs/Code Snippets|&lt;br /&gt;
java=// In some TagProvider#addTags&lt;br /&gt;
this.tag(EXAMPLE_TAG)&lt;br /&gt;
  .add(EXAMPLE_OBJECT) // Adds an object to the tag&lt;br /&gt;
  .addOptional(new ResourceLocation(&amp;quot;othermod&amp;quot;, &amp;quot;other_object&amp;quot;)); // Adds an object from another mod to the tag&lt;br /&gt;
&lt;br /&gt;
this.tag(EXAMPLE_TAG_2)&lt;br /&gt;
  .addTag(EXAMPLE_TAG) // Adds a tag to the tag&lt;br /&gt;
  .remove(EXAMPLE_OBJECT); // Removes an object from this tag&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|If the mod's tags softly depends on another mod's tags (the other mod may or may not be present at runtime), the other mods' tags should be referenced using the optional methods.}}&lt;br /&gt;
&lt;br /&gt;
== Using Existing Tag Providers ==&lt;br /&gt;
&lt;br /&gt;
Vanilla contains a few tag providers for certain registries that can be subclassed for ease of implementation.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
! Registry Object Type !! Tag Provider&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;BlockTagsProvider&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;ItemTagsProvider&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;EntityType&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;EntityTypeTagsProvider&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Fluid&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;FluidTagsProvider&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;GameEvent&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;GameEventTagsProvider&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Biome&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;BiomeTagsProvider&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;FlatLevelGeneratorPreset&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;FlatLevelGeneratorPresetTagsProvider&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;WorldPreset&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;WorldPresetTagsProvider&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Structure&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;StructureTagsProvider&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;PoiType&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;PoiTypeTagsProvider&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;BannerPattern&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;BannerPatternTagsProvider&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;CatVariant&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;CatVariantTagsProvider&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;PaintingVariant&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;PaintingVariantTagsProvider&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Instrument&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;InstrumentTagsProvider&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Tabs/Code Snippets|&lt;br /&gt;
java=public class ExampleBlockTagsProvider extends BlockTagsProvider {&lt;br /&gt;
    &lt;br /&gt;
    public ExampleBlockTagsProvider(DataGenerator gen, String modId, ExistingFileHelper efh) {&lt;br /&gt;
        // ...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public void addTags() {&lt;br /&gt;
        // Add block tags here&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== ItemTagsProvider#copy ===&lt;br /&gt;
&lt;br /&gt;
Blocks have item representations such that they can be obtained within an inventory. As such, a number of block tags can also be applied to a similar item tag. To easily generate an item tag with the same entries as a block tag, the &amp;lt;code&amp;gt;#copy&amp;lt;/code&amp;gt; method can be used.&lt;br /&gt;
&lt;br /&gt;
{{Tabs/Code Snippets|&lt;br /&gt;
java=// In #addTags within a ItemTagsProvider subclass&lt;br /&gt;
this.copy(EXAMPLE_BLOCK_TAG, EXAMPLE_ITEM_TAG);&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Custom Tag Providers ==&lt;br /&gt;
&lt;br /&gt;
A custom tag provider can be created via a &amp;lt;code&amp;gt;TagsProvider&amp;lt;/code&amp;gt; subclass which takes in the &amp;lt;code&amp;gt;Registry&amp;lt;/code&amp;gt; to generate tags for.&lt;br /&gt;
&lt;br /&gt;
{{Tabs/Code Snippets|&lt;br /&gt;
java=public RecipeTypeTagsProvider(DataGenerator gen, String modId, ExistingFileHelper efh) {&lt;br /&gt;
  super(gen, Registry.RECIPE_TYPE, modId, efh);&lt;br /&gt;
}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Forge Registry Tag Providers ===&lt;br /&gt;
&lt;br /&gt;
If a registry is wrapped by Forge or created by a mod, a provider can be created via a &amp;lt;code&amp;gt;ForgeRegistryTagsProvider&amp;lt;/code&amp;gt; subclass instead:&lt;br /&gt;
&lt;br /&gt;
{{Tabs/Code Snippets|&lt;br /&gt;
java=public AttributeTagsProvider(DataGenerator gen, String modId, ExistingFileHelper efh) {&lt;br /&gt;
  super(gen, ForgeRegistries.ATTRIBUTES, modId, efh);&lt;br /&gt;
}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Data Generation]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Making_Entities&amp;diff=3352</id>
		<title>Making Entities</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Making_Entities&amp;diff=3352"/>
		<updated>2022-10-06T21:49:38Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Correct mistakes in entity attributes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Under construction}}&lt;br /&gt;
&lt;br /&gt;
Entities are core to the Minecraft world and make up all movable objects that do not fall under [[Making Blocks|Blocks]] or [[Block Entities]]. Entities can tick and be controlled by AI or player input. This article serves as a guide for setting up a basic entity. It does not involve setting up the rendering for an entity, which is a required step to be able to see an entity in-game without crashing. See [[Entity Renderer]] for more information on entity rendering and setup.&lt;br /&gt;
&lt;br /&gt;
== Entity Type ==&lt;br /&gt;
Much of the identity of an entity is determined by its '''entity type'''. This contains information universal to an entity. An entity type must exist and be [[Registration|registered]] for the corresponding entity to be summonable. &lt;br /&gt;
&lt;br /&gt;
=== Creating the Builder ===&lt;br /&gt;
The primary way to make an &amp;lt;code&amp;gt;EntityType&amp;lt;/code&amp;gt; is to create and configure an &amp;lt;code&amp;gt;EntityType$Builder&amp;lt;/code&amp;gt;. Creating an entity type builder is done using the static factory &amp;lt;code&amp;gt;EntityType.Builder#of&amp;lt;/code&amp;gt;. It requires two parameters: an &amp;lt;code&amp;gt;EntityType.EntityFactory&amp;lt;/code&amp;gt; and a &amp;lt;code&amp;gt;MobCategory&amp;lt;/code&amp;gt;.&lt;br /&gt;
The entity factory is usually an entity class with a constructor taking its own &amp;lt;code&amp;gt;EntityType&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Level&amp;lt;/code&amp;gt; of the form &amp;lt;code&amp;gt;MyEntity::new&amp;lt;/code&amp;gt;. This requires a class of the name &amp;lt;code&amp;gt;MyEntity&amp;lt;/code&amp;gt; to actually exist (see [[#Entity Class|the entity class section]] for more info).&lt;br /&gt;
The mob category is an enum describing mostly spawning properties about a category of mobs. This includes:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;How many entities in a given mob category can spawn per chunk&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Whether the entity is friendly (and therefore will spawn in peaceful difficulty)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Whether the entity is persistent (and therefore will save to disk and be reloaded)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;How many blocks away a player must be for an entity in a given mob category to despawn&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuring the Builder ===&lt;br /&gt;
An entity type builder by itself is not very useful. It must be configured to match the desired properties of the entity.&lt;br /&gt;
The possible properties that can be configured are listed below:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=1&lt;br /&gt;
! Method !! Default Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;sized&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; || 0.6 meters wide by 1.8 meters tall (player dimensions) || Sets the default pose dimensions of the entity in order of square base width then height in meters/blocks. A value of 1.0 would be equivalent to the length of 1 full block. The base cannot be configured with a separate width and length.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;noSummon&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; || Can summon || Calling this prevents spawning the entity through &amp;lt;code&amp;gt;/summon&amp;lt;/code&amp;gt;; intended for internal entities that a user should not be able to create. This also prevents summoning through natural spawning in biomes, if it is configured.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;noSave&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; || Can save || Calling this prevents the entity from ever saving to disk. Unloading a chunk with a &amp;lt;code&amp;gt;noSave&amp;lt;/code&amp;gt; entity will effectively delete the entity.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;fireImmune&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; || Vulnerable to fire || Calling this prevents the entity from taking any fire/lava damage.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;clientTrackingRange&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; || 5 chunks || Sets the maximum range in chunks in which players should be sent update packet information about the entity. Sending update information about an entity to a player is known as the player ''tracking'' that entity. If the player is outside this chunk range, they will not know of the entity's existence.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;immuneTo&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; || Empty set of blocks || Effectively useless for modding purposes.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;canSpawnFarFromPlayer&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; || True for &amp;lt;code&amp;gt;MobCategory.CREATURE&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;MobCategory.MISC&amp;lt;/code&amp;gt;, false otherwise. || Calling this allows an entity to spawn outside of the despawn distance of its mob category.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;updateInterval&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; || 3 ticks || How often, in ticks, update packets should be sent to all client players tracking this entity (see &amp;lt;code&amp;gt;clientTrackingRange&amp;lt;/code&amp;gt;). The update packets contain information like position, rotation, and velocity. They may be sent more quickly than this interval during specific actions.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;setShouldReceiveVelocityUpdates&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; || true || Sets whether tracking client players should receive velocity information in update interval packets. If false, velocity information will not be sent to clients unless necessary.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Building the Builder ===&lt;br /&gt;
After creating and configuring the entity type builder, it must be built. This requires the modid and name of the entity type. For an entity type with the name &amp;quot;example_monster&amp;quot; in the mod &amp;quot;examplemod&amp;quot;, this would look like &amp;lt;code&amp;gt;builder.build(&amp;quot;examplemod:example_monster&amp;quot;)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Tying It Together ===&lt;br /&gt;
Given the above information, a basic EntityType might look like the following:&lt;br /&gt;
{{Tabs/Code Snippets&lt;br /&gt;
|java=EntityType.Builder.of(ExampleMonsterEntity::new, MobCategory.MONSTER)&lt;br /&gt;
    .sized(1.0F, 2.0F)&lt;br /&gt;
    .fireImmune()&lt;br /&gt;
    .updateInterval(1)&lt;br /&gt;
    .build(&amp;quot;examplemod:example_monster&amp;quot;)&lt;br /&gt;
}}&lt;br /&gt;
To function, this example requires that an entity class of the name &amp;lt;code&amp;gt;ExampleMonsterEntity&amp;lt;/code&amp;gt; exist along with the entity type being [[Registration|registered]].&lt;br /&gt;
&lt;br /&gt;
== Entity Class ==&lt;br /&gt;
Alongside an entity type, an entity requires a class outlining its behavior and any information that may change from one instance to another. All entities must extend from the base class &amp;lt;code&amp;gt;Entity&amp;lt;/code&amp;gt;. However, some entities should extend from specific subclasses instead. For a completely generic entity, use &amp;lt;code&amp;gt;Entity&amp;lt;/code&amp;gt;. For a living entity with health, potion effects, and an inventory, use &amp;lt;code&amp;gt;LivingEntity&amp;lt;/code&amp;gt;. For a living entity with movement AI and AI goals, use &amp;lt;code&amp;gt;Mob&amp;lt;/code&amp;gt;. There are also many other entity subclasses which can be found through your IDE and picked depending on the scenario.&lt;br /&gt;
&lt;br /&gt;
Once picking a target superclass to extend, an entity class should be created and the constructor should be setup. It should look something like this:&lt;br /&gt;
{{Tabs/Code Snippets|&lt;br /&gt;
java=public class ExampleMonsterEntity extends Mob {&lt;br /&gt;
    public ExampleMonsterEntity(EntityType&amp;lt;? extends Mob&amp;gt; entityType, Level level) {&lt;br /&gt;
        super(entityType, level);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
To define custom behavior, methods must be overriden. Your IDE should have a feature to list all possible methods to override, although some common ones might be: &amp;lt;code&amp;gt;customServerAiStep&amp;lt;/code&amp;gt; for server AI, &amp;lt;code&amp;gt;tick&amp;lt;/code&amp;gt; for code to execute each tick on client/server, and &amp;lt;code&amp;gt;registerGoals&amp;lt;/code&amp;gt; to setup AI goals.&lt;br /&gt;
&lt;br /&gt;
== Entity Attributes ==&lt;br /&gt;
All &amp;lt;code&amp;gt;LivingEntity&amp;lt;/code&amp;gt;s must have an associated &amp;lt;code&amp;gt;AttributeSupplier&amp;lt;/code&amp;gt;, which, as named, supplies the default settings for all the attributes an entity has. An &amp;lt;code&amp;gt;Attribute&amp;lt;/code&amp;gt; represents a syncable piece of data representing a characteristic, quality, or feature of an entity. Vanilla and Forge both define attributes that an entity can use within &amp;lt;code&amp;gt;Attributes&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ForgeMod&amp;lt;/code&amp;gt;, respectively. &lt;br /&gt;
&lt;br /&gt;
To attach an attribute to a new entity, you must create an event listener for the &amp;lt;code&amp;gt;EntityAttributeCreationEvent&amp;lt;/code&amp;gt; on the '''mod''' event bus and call &amp;lt;code&amp;gt;#put&amp;lt;/code&amp;gt;, providing the &amp;lt;code&amp;gt;EntityType&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; and the attribute supplier.&lt;br /&gt;
&lt;br /&gt;
{{Tabs/Code Snippets&lt;br /&gt;
|java=// On the mod event bus&lt;br /&gt;
public void newEntityAttributes(EntityAttributeCreationEvent event) {&lt;br /&gt;
    event.put(EXAMPLE_ENTITY_TYPE.get(),&lt;br /&gt;
        AttributeSupplier.builder()&lt;br /&gt;
            .add(Attributes.MAX_HEALTH) // Sets max health to default value 20&lt;br /&gt;
            .add(Attributes.KNOCKBACK_RESISTANCE, 4.0D) // Sets knockback resistance to 4&lt;br /&gt;
            // ...&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
You can similarly append new attributes or modify existing attributes for existing entities by listening to &amp;lt;code&amp;gt;EntityAttributeModificationEvent&amp;lt;/code&amp;gt; on the '''mod''' event bus and call &amp;lt;code&amp;gt;#add&amp;lt;/code&amp;gt;, supplying the &amp;lt;code&amp;gt;EntityType&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt;, the &amp;lt;code&amp;gt;Attribute&amp;lt;/code&amp;gt;, and optionally the value if you do not want the default.&lt;br /&gt;
&lt;br /&gt;
{{Tabs/Code Snippets&lt;br /&gt;
|java=// On the mod event bus&lt;br /&gt;
public void existingEntityAttributes(EntityAttributeModificationEvent event) {&lt;br /&gt;
    if (!event.has(EntityType.CREEPER, EXAMPLE_ATTRIBUTE.get())) {&lt;br /&gt;
        event.add(EntityType.CREEPER,&lt;br /&gt;
            EXAMPLE_ATTRIBUTE.get() // Applies new attribute to creeper&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Reusable Attribute Suppliers ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;LivingEntity&amp;lt;/code&amp;gt; and its subclasses require specific attributes to be defined on the entity (&amp;lt;code&amp;gt;LivingEntity&amp;lt;/code&amp;gt; requires max health, knockback resistance, movement speed, armor, armor toughness, swim speed, nametag distance, entity gravity, and step height addition). To make it such that subclasses can use the previously defined attribute suppliers while still being able to add or override the specified super value, a static method is used to hold the builder, which is then referenced in a later subclass. The resulting method can then be passed into the &amp;lt;code&amp;gt;EntityAttributeCreationEvent&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Tabs/Code Snippets&lt;br /&gt;
|java=&lt;br /&gt;
// In your LivingEntity subclass&lt;br /&gt;
public static AttributeSupplier.Builder createExampleAttributes() {&lt;br /&gt;
    return LivingEntity.createLivingAttributes().add(Attributes.KNOCKBACK_RESISTANCE, 4.0D);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// In some separate class on the mod event bus&lt;br /&gt;
public void newEntityAttributes(EntityAttributeCreationEvent event) {&lt;br /&gt;
    event.put(EXAMPLE_ENTITY_TYPE.get(), ExampleEntity.createExampleAttributes().build());&lt;br /&gt;
}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Tip|Most mobs use this static method attribute builder, so if you are subclassing a different entity class (e.g., &amp;lt;code&amp;gt;Mob&amp;lt;/code&amp;gt;), you should look in the superclasses for the associated static method to build the attributes from (e.g., &amp;lt;code&amp;gt;Mob#createMobAttributes&amp;lt;/code&amp;gt;).}}&lt;br /&gt;
&lt;br /&gt;
== Natural Spawning ==&lt;br /&gt;
To make entities naturally spawn, they must be added to the spawn list for each biome that the entity should spawn in. This can be achieved with a [[Biome Modifiers#Add Spawns|&amp;lt;code&amp;gt;forge:add_spawns&amp;lt;/code&amp;gt; biome modifier]].&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Dynamic_Loot_Modification&amp;diff=3329</id>
		<title>Dynamic Loot Modification</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Dynamic_Loot_Modification&amp;diff=3329"/>
		<updated>2022-09-20T18:30:03Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Fix the explanation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Global Loot Modifiers are a data-driven method of handling modification of harvested drops without the need to overwrite dozens to hundreds of vanilla loot tables or to handle effects that would require interactions with another mod's loot tables without knowing what mods may be loaded. Global Loot Modifiers are also stacking, rather than last-load-wins as modifications to loot tables would be.&lt;br /&gt;
&lt;br /&gt;
== Registering a Global Loot Modifier ==&lt;br /&gt;
&lt;br /&gt;
You will need 3 things:&lt;br /&gt;
# Create a &amp;lt;code&amp;gt;global_loot_modifiers.json&amp;lt;/code&amp;gt; file at &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;/data/forge/loot_modifiers/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
#* This will tell Forge about your modifiers and works similar to [[Tags|tags]].&lt;br /&gt;
# A serialized json representing your modifier at &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;/data/&amp;lt;modID&amp;gt;/loot_modifiers/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
#* This will contain all of the data about your modification and allows data packs to tweak your effect.&lt;br /&gt;
# A class that extends &amp;lt;code&amp;gt;LootModifier&amp;lt;/code&amp;gt;&lt;br /&gt;
#* The operational code that makes your modifier work and associated codec.&lt;br /&gt;
&lt;br /&gt;
Finally, the codec for your operational class is [[Registration|registered]] as any other registry object.&lt;br /&gt;
&lt;br /&gt;
==The global_loot_modifiers.json==&lt;br /&gt;
All you need to add here are the file names of your loot modifiers.&lt;br /&gt;
These are the names of the json files you have made in the loot_modifiers folder, in ResourceLocation format.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;replace&amp;quot;: false,&lt;br /&gt;
  &amp;quot;entries&amp;quot;: [&lt;br /&gt;
    &amp;quot;global_loot_test:silk_touch_bamboo&amp;quot;,&lt;br /&gt;
    &amp;quot;global_loot_test:smelting&amp;quot;,&lt;br /&gt;
    &amp;quot;global_loot_test:wheat_harvest&amp;quot;&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;replace&amp;lt;/code&amp;gt; causes the cache of modifiers to be cleared fully when this asset loads (mods are loaded in an order that may be specified by a data pack). For modders you will want to use &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; while data pack makers may want to specify their overrides with &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;entries&amp;lt;/code&amp;gt; is an ''ordered list'' of the modifiers that will be loaded. Any modifier that is not listed will not be loaded and the ones listed are called in the order listed. This is primarily relevant to data pack makers for resolving conflicts between modifiers from separate mods.&lt;br /&gt;
&lt;br /&gt;
== The serialized json ==&lt;br /&gt;
&lt;br /&gt;
This file contains all of the potential variables related to your modifier, including the conditions that must be met prior to modifying any loot as well as any other parameters your modifier might have. Avoid hard-coded values where ever possible so that data pack makers can adjust balance if they wish to.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;conditions&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;condition&amp;quot;: &amp;quot;minecraft:match_tool&amp;quot;,&lt;br /&gt;
      &amp;quot;predicate&amp;quot;: {&lt;br /&gt;
        &amp;quot;item&amp;quot;: &amp;quot;minecraft:shears&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;condition&amp;quot;: &amp;quot;minecraft:block_state_property&amp;quot;,&lt;br /&gt;
      &amp;quot;block&amp;quot;: &amp;quot;minecraft:wheat&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;seedItem&amp;quot;: &amp;quot;minecraft:wheat_seeds&amp;quot;,&lt;br /&gt;
  &amp;quot;numSeeds&amp;quot;: 3,&lt;br /&gt;
  &amp;quot;replacement&amp;quot;: &amp;quot;minecraft:wheat&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, the modification only happens if the player harvests wheat when using shears (specified by the two &amp;lt;code&amp;gt;conditions&amp;lt;/code&amp;gt; which are automatically &amp;lt;code&amp;gt;AND&amp;lt;/code&amp;gt;ed together). The &amp;lt;code&amp;gt;seedsItem&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;numSeeds&amp;lt;/code&amp;gt; values are then used to count how many seeds were generated by the vanilla loot table, and if matched, are substituted for an additional &amp;lt;code&amp;gt;replacement&amp;lt;/code&amp;gt; item instead. The operation code will be shown below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Tip|&amp;lt;code&amp;gt;conditions&amp;lt;/code&amp;gt; is the only object needed by the system specification, everything else is the mod maker's data. &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code&amp;gt;seedItem&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;numSeeds&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;replacement&amp;lt;/code&amp;gt; are NOT standard elements of Global Loot Modifiers.  &lt;br /&gt;
&lt;br /&gt;
They are deserialized manually in the next section.}}&lt;br /&gt;
&lt;br /&gt;
== The LootModifier Subclass ==&lt;br /&gt;
&lt;br /&gt;
You will also need a &amp;lt;code&amp;gt;Codec&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; where &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; is your LootModifier subclass in order to deserialize your json data file into operational code. The codec must be [[Registration|registered]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
     * When harvesting wheat with shears, this modifier is invoked via the wheat_harvest loot_modifier json&amp;lt;br/&amp;gt;&lt;br /&gt;
     * This modifier checks how many seeds were harvested and turns X seeds into Y wheat (3:1)&lt;br /&gt;
     *&lt;br /&gt;
     */&lt;br /&gt;
// Assume there exists a &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;Codec&amp;lt;T extends LootModifier&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; LOOT_MODIFIER_REGISTRAR added by a mod&lt;br /&gt;
private static class WheatSeedsConverterModifier extends LootModifier&lt;br /&gt;
{&lt;br /&gt;
        public static final RegistryObject&amp;lt;Codec&amp;lt;WheatSeedsConverterModifier&amp;gt;&amp;gt; CODEC = LOOT_MODIFIER_REGISTRAR.register(&amp;quot;wheat_seeds_converter&amp;quot;, () -&amp;gt; &lt;br /&gt;
        RecordCodecBuilder.create(inst -&amp;gt; codecStart(inst).and(&lt;br /&gt;
                inst.group(&lt;br /&gt;
                        Codec.INT.fieldOf(&amp;quot;numSeeds&amp;quot;).forGetter(m -&amp;gt; m.numSeedsToConvert),&lt;br /&gt;
                        ForgeRegistries.ITEMS.getCodec().fieldOf(&amp;quot;seedItem&amp;quot;).forGetter(m -&amp;gt; m.itemToCheck),&lt;br /&gt;
                        ForgeRegistries.ITEMS.getCodec().fieldOf(&amp;quot;replacement&amp;quot;).forGetter(m -&amp;gt; m.itemReward)&lt;br /&gt;
                )).apply(inst, WheatSeedsConverterModifier::new)&lt;br /&gt;
        ));&lt;br /&gt;
&lt;br /&gt;
        private final int numSeedsToConvert;&lt;br /&gt;
        private final Item itemToCheck;&lt;br /&gt;
        private final Item itemReward;&lt;br /&gt;
        public WheatSeedsConverterModifier(LootItemCondition[] conditionsIn, int numSeeds, Item itemCheck, &lt;br /&gt;
             Item reward)&lt;br /&gt;
        {&lt;br /&gt;
            super(conditionsIn);&lt;br /&gt;
            numSeedsToConvert = numSeeds;&lt;br /&gt;
            itemToCheck = itemCheck;&lt;br /&gt;
            itemReward = reward;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        @NotNull&lt;br /&gt;
        @Override&lt;br /&gt;
        public ObjectArrayList&amp;lt;ItemStack&amp;gt; doApply(ObjectArrayList&amp;lt;ItemStack&amp;gt; generatedLoot, LootContext context) {&lt;br /&gt;
            //&lt;br /&gt;
            // Additional conditions can be checked, though as much as possible should be parameterized via JSON data.&lt;br /&gt;
            // It is better to write a new ILootCondition implementation than to do things here.&lt;br /&gt;
            //&lt;br /&gt;
            int numSeeds = 0;&lt;br /&gt;
            generatedLoot.stream().filter(stack -&amp;gt; stack.getItem() == itemToCheck)&lt;br /&gt;
                   .forEach(stack -&amp;gt; numSeeds+=stack.getCount())&lt;br /&gt;
            if(numSeeds &amp;gt;= numSeedsToConvert) {&lt;br /&gt;
                generatedLoot.removeIf(x -&amp;gt; x.getItem() == itemToCheck);&lt;br /&gt;
                generatedLoot.add(new ItemStack(itemReward, (numSeeds/numSeedsToConvert)));&lt;br /&gt;
                numSeeds = numSeeds%numSeedsToConvert;&lt;br /&gt;
                if(numSeeds &amp;gt; 0)&lt;br /&gt;
                    generatedLoot.add(new ItemStack(itemToCheck, numSeeds));&lt;br /&gt;
            }&lt;br /&gt;
            return generatedLoot;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        @Override&lt;br /&gt;
        public Codec&amp;lt;? extends IGlobalLootModifier&amp;gt; codec() {&lt;br /&gt;
            return CODEC.get();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The critical portion is the &amp;lt;code&amp;gt;doApply&amp;lt;/code&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
This method is only called if the &amp;lt;code&amp;gt;conditions&amp;lt;/code&amp;gt; specified return &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; and the modder is now able to make the modifications they desire. In this case we can see that the number of &amp;lt;code&amp;gt;itemToCheck&amp;lt;/code&amp;gt; meets or exceeds the &amp;lt;code&amp;gt;numSeedsToConvert&amp;lt;/code&amp;gt; before modifying the list by adding an &amp;lt;code&amp;gt;itemReward&amp;lt;/code&amp;gt; and removing any excess &amp;lt;code&amp;gt;itemToCheck&amp;lt;/code&amp;gt; stacks, matching the previously mentioned effects: ''When a wheat block is harvested with shears, if enough seeds are generated as loot, they are converted to additional wheat instead''.&lt;br /&gt;
&lt;br /&gt;
The codec can also be used for [[datageneration|data generation]] with a &amp;lt;code&amp;gt;GlobalLootModifierProvider&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Additional [https://github.com/MinecraftForge/MinecraftForge/blob/1.19.x/src/test/java/net/minecraftforge/debug/gameplay/loot/GlobalLootModifiersTest.java examples] can be found on the Forge Git repository, including silk touch and smelting effects.&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Registration&amp;diff=3293</id>
		<title>Registration</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Registration&amp;diff=3293"/>
		<updated>2022-06-27T21:32:22Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Fix lazy in multilingual examples&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Registration is the process of making an object (such as an item or block) known to the game during runtime. If some objects are not registered, this could cause crashes even before the game is fully loaded or arbitrary behaviors such as bottlenecking mod compatibility for world generation.&lt;br /&gt;
&lt;br /&gt;
Most objects that are known within the game are handled by a &amp;lt;code&amp;gt;Registry&amp;lt;/code&amp;gt;. Each registry uniquely defines each object through a &amp;quot;registry name&amp;quot; via a [[Using Resources#ResourceLocation|ResourceLocation]].&lt;br /&gt;
&lt;br /&gt;
{{Tip|In a global context, each object is universally unique through its &amp;lt;code&amp;gt;ResourceKey&amp;lt;/code&amp;gt;: a concatenation of its registry's id and the object's registry name.}}&lt;br /&gt;
&lt;br /&gt;
Due to the inconsistent ordering and registration process vanilla uses, Forge wraps most vanilla registries using &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt;. This guarantees that the loading order for these wrapped registries will be &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt;, and then the rest of the wrapped registries in alphabetical order. All registries supported by Forge can be found within the &amp;lt;code&amp;gt;ForgeRegistries&amp;lt;/code&amp;gt; class. Since all registry names are unique to a specific registry, different registry objects within different registries can have the same name (e.g. a &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt; and an &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; each hold a registry object named &amp;lt;code&amp;gt;examplemod:object&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|If two registry objects within the same registry have the same name, the second object will override the first. The only registry that will throw an &amp;lt;code&amp;gt;IllegalArgumentException&amp;lt;/code&amp;gt; is the &amp;lt;code&amp;gt;DataSerializerEntry&amp;lt;/code&amp;gt; registry.}}&lt;br /&gt;
&lt;br /&gt;
== Methods for Registering ==&lt;br /&gt;
&lt;br /&gt;
There are two proper ways to register objects within an associated wrapped Forge registry: the &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; class, and the &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; lifecycle event.&lt;br /&gt;
&lt;br /&gt;
=== DeferredRegister ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; is an abstraction layer over the registry event used to register objects. It maintains a map of &amp;quot;registry name&amp;quot; to their associated suppliers and resolves those suppliers during &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; for the associated registry. This method is the currently recommended, and documented, way to handle these objects as it provides convenience and safety for those who want to statically initialize objects while avoiding some issues associated with it.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|When using &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt;s with non-vanilla registries, the registry key or the registry name should be supplied to the &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt; method. These include the custom Forge registries for entity data serializers, global loot modifier serializers, world presets, and biome modifier serializers. Calling &amp;lt;code&amp;gt;Supplier#get&amp;lt;/code&amp;gt; on a &amp;lt;code&amp;gt;Supplier&amp;lt;IForgeRegistry&amp;lt;?&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; when making a DeferredRegister will return null because the registry does not exist yet.}}&lt;br /&gt;
&lt;br /&gt;
An example of a mod registering a custom block:&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=private static final DeferredRegister&amp;lt;Block&amp;gt; BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;Block&amp;gt; EXAMPLE_BLOCK = BLOCKS.register(&amp;quot;example_block&amp;quot;, () -&amp;gt; new Block(BlockBehaviour.Properties.of(Material.STONE)));&lt;br /&gt;
&lt;br /&gt;
public ExampleMod() {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get().getModEventBus());&lt;br /&gt;
}&lt;br /&gt;
|kotlin=private val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID)&lt;br /&gt;
&lt;br /&gt;
val EXAMPLE_BLOCK: RegistryObject&amp;lt;Block&amp;gt; = BLOCKS.register(&amp;quot;example_block&amp;quot;) { Block(BlockBehaviour.Properties.of(Material.ROCK)) }&lt;br /&gt;
&lt;br /&gt;
internal class ExampleMod {&lt;br /&gt;
    init {&lt;br /&gt;
        BLOCKS.register(FMLJavaModLoadingContext.get().modEventBus)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
|scala=object ExampleMod {&lt;br /&gt;
    private final val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID)&lt;br /&gt;
&lt;br /&gt;
    final val EXAMPLE_BLOCK = registerBlock(&amp;quot;example_block&amp;quot;, () =&amp;gt; new Block(BlockBehaviour.Properties.of(Material.ROCK)))&lt;br /&gt;
}&lt;br /&gt;
class ExampleMod {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get.getModEventBus)&lt;br /&gt;
}&lt;br /&gt;
|groovy=private static final DeferredRegister&amp;lt;Block&amp;gt; BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;Block&amp;gt; EXAMPLE_BLOCK = BLOCKS.register(&amp;quot;example_block&amp;quot;, () -&amp;gt; new Block(BlockBehaviour.Properties.of(Material.STONE)));&lt;br /&gt;
&lt;br /&gt;
ExampleMod() {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get().modEventBus);&lt;br /&gt;
}&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip|When using a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; to register any object, the name inputted will be automatically prefixed with the mod id passed in, giving the above object a &amp;quot;registry name&amp;quot; of &amp;lt;code&amp;gt;examplemod:example_block&amp;lt;/code&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
=== RegisterEvent ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is the second way register objects. This [[Events|event]] is fired for each registry synchronously in vanilla registry order after &amp;lt;code&amp;gt;FMLConstructModEvent&amp;lt;/code&amp;gt; and before the configs are loaded. Objects are registered using &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; by passing in the registry key, the name of the registry object, and the object itself. There is an additional &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; overload which takes in a consumed helper to register an object with a given name. It is recommended to use this method to avoid unnecessary object creation.&lt;br /&gt;
&lt;br /&gt;
Here is an example: (the event handler is registered on the '''mod event bus''')&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=@SubscribeEvent&lt;br /&gt;
public void register(RegisterEvent event) {&lt;br /&gt;
    event.register(ForgeRegistries.Keys.BLOCKS,&lt;br /&gt;
        helper -&amp;gt; helper.register(new ResourceLocation(MODID, &amp;quot;example_block&amp;quot;), new Block(...))&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
|kotlin=@JvmStatic&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
private fun register(event: RegisterEvent) =&lt;br /&gt;
    event.register(ForgeRegistries.Keys.BLOCKS) {&lt;br /&gt;
        helper -&amp;gt; helper.register(ResourceLocation(MODID, &amp;quot;example_block&amp;quot;), Block(...))&lt;br /&gt;
    }&lt;br /&gt;
|scala=@SubscribeEvent&lt;br /&gt;
def register(event: RegisterEvent): Unit =&lt;br /&gt;
    event.register(ForgeRegistries.Keys.BLOCKS,&lt;br /&gt;
        helper =&amp;gt; helper.register(new ResourceLocation(MODID, &amp;quot;example_block&amp;quot;), new Block(...))&lt;br /&gt;
    )&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|Since all objects registered must be singleton, some classes cannot by themselves be registered. Instead, &amp;lt;code&amp;gt;*Type&amp;lt;/code&amp;gt; classes are registered and used in the formers' constructors to wrap the flyweight objects. For example, a [[Basics_of_Block_Entities|&amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt;]] is wrapped via &amp;lt;code&amp;gt;BlockEntityType&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;Entity&amp;lt;/code&amp;gt; is wrapped via &amp;lt;code&amp;gt;EntityType&amp;lt;/code&amp;gt;. These &amp;lt;code&amp;gt;*Type&amp;lt;/code&amp;gt; classes hold factories that simply create the containing type on demand.&lt;br /&gt;
&lt;br /&gt;
These factory holders are created through the use of their &amp;lt;code&amp;gt;*Type$Builder&amp;lt;/code&amp;gt; classes. An example: (&amp;lt;code&amp;gt;REGISTER&amp;lt;/code&amp;gt; here refers to a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;BlockEntityType&amp;lt;?&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final RegistryObject&amp;lt;BlockEntityType&amp;lt;ExampleBlockEntity&amp;gt;&amp;gt; EXAMPLE_BLOCK_ENTITY = REGISTER.register(&lt;br /&gt;
    &amp;quot;example_block_entity&amp;quot;, () -&amp;gt; BlockEntityType.Builder.of(ExampleBlockEntity::new, EXAMPLE_BLOCK.get()).build(null)&lt;br /&gt;
);&lt;br /&gt;
|kotlin=val EXAMPLE_BLOCK_ENTITY: RegistryObject&amp;lt;BlockEntityType&amp;lt;ExampleBlockEntity&amp;gt;&amp;gt; = REGISTER.register(&amp;quot;example_block_entity&amp;quot;) { BlockEntityType.Builder.of(::ExampleBlockEntity, EXAMPLE_BLOCK.get()).build(null)) }&lt;br /&gt;
|scala=final val EXAMPLE_BLOCK_ENTITY = REGISTER.register(&amp;quot;example_block_entity&amp;quot;, () =&amp;gt; BlockEntityType.Builder.of(() =&amp;gt; new ExampleBlockEntity(), GeneralRegistrar.EXAMPLE_BLOCK.get).build(null))&lt;br /&gt;
|}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Non-Forge Registries ===&lt;br /&gt;
&lt;br /&gt;
Not all vanilla registries are wrapped as a Forge registry. To register objects to any one of these registries, create a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; via the &amp;lt;code&amp;gt;#create&amp;lt;/code&amp;gt; overload which takes in a resource key of the registry and the mod id to register the entries for. Then simply call &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; like any other &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=private static final DeferredRegister&amp;lt;LootItemConditionType&amp;gt; REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;LootItemConditionType&amp;gt; EXAMPLE_LOOT_ITEM_CONDITION_TYPE = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;, () -&amp;gt; new LootItemConditionType(...));&lt;br /&gt;
|kotlin=private val REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID)&lt;br /&gt;
&lt;br /&gt;
val EXAMPLE_LOOT_ITEM_CONDITION_TYPE : RegistryObject&amp;lt;LootItemConditionType&amp;gt; = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;) {&lt;br /&gt;
    LootItemConditionType(...)&lt;br /&gt;
}&lt;br /&gt;
|scala=private final val REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID)&lt;br /&gt;
&lt;br /&gt;
final val EXAMPLE_LOOT_ITEM_CONDITION_TYPE = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;, () =&amp;gt; new LootItemConditionType(...))&lt;br /&gt;
|groovy=private static final DeferredRegister&amp;lt;LootItemConditionType&amp;gt; REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;LootItemConditionType&amp;gt; EXAMPLE_LOOT_ITEM_CONDITION_TYPE = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;, () -&amp;gt; new LootItemConditionType(...));&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
If you attempt to make one of these instances require an instance of another registry object, you should use the lazy initialization method mentioned above to register the object in the correct order.&lt;br /&gt;
&lt;br /&gt;
=== Data Driven Entries ===&lt;br /&gt;
&lt;br /&gt;
Registries are considered to be data driven if they are located within &amp;lt;code&amp;gt;RegistryAccess&amp;lt;/code&amp;gt; with the exception of &amp;lt;code&amp;gt;LevelStem&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Level&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
These registry objects only need to be registered within code if they are to be used within a pre-existing registry object (e.g. a &amp;lt;code&amp;gt;PlacedFeature&amp;lt;/code&amp;gt; for ore generation within an overworld &amp;lt;code&amp;gt;Biome&amp;lt;/code&amp;gt;). Otherwise, their instance can be purely registered using a JSON file.&lt;br /&gt;
&lt;br /&gt;
If a data driven registry object has to be registered within code, a dummy object should be supplied to hold a &amp;quot;registry name&amp;quot; and then constructed within a JSON file.&lt;br /&gt;
&lt;br /&gt;
== Referencing Registered Objects ==&lt;br /&gt;
&lt;br /&gt;
Each forge registered object should not be statically initialized nor reference another instance being registered. They must always be a new, singleton instance that is resolved during when &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is called for their registry. This is to maintain a sane loading order for registries and their objects along with dynamic loading/unloading of mods.&lt;br /&gt;
&lt;br /&gt;
Forge registered objects must always be referenced through a &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; or a field with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Using RegistryObjects===&lt;br /&gt;
&amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;s can be used to retrieve references to registered objects once they become available. Their references are updated along with all &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; annotations after the registry that &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is called for is dispatched and frozen.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; can be retrieved as a result of using &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; or calling the static factory &amp;lt;code&amp;gt;RegistryObject#create&amp;lt;/code&amp;gt;. Each static factory takes in the &amp;quot;registry name&amp;quot; of the object being referenced and one of the following: a &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt;, a registry name of the type &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt;, or a registry key of the type &amp;lt;code&amp;gt;ResourceKey&amp;lt;? extends Registry&amp;lt;?&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; can be stored within some field and retrieve the registered object using &amp;lt;code&amp;gt;#get&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
An example using &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;:&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final RegistryObject&amp;lt;Item&amp;gt; EXAMPLE_ITEM = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_item&amp;quot;), ForgeRegistries.ITEMS);&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
public static final RegistryObject&amp;lt;ExampleRegistry&amp;gt; EXAMPLE_OBJECT = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;); &lt;br /&gt;
|kotlin=val EXAMPLE_ITEM: RegistryObject&amp;lt;Item&amp;gt; = RegistryObject.create(ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_item&amp;quot;), ForgeRegistries.ITEMS)&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
val EXAMPLE_OBJECT: RegistryObject&amp;lt;ExampleRegistry&amp;gt; = RegistryObject.create(ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;)&lt;br /&gt;
|scala=final val EXAMPLE_ITEM = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_item&amp;quot;), ForgeRegistries.ITEMS)&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
final val EXAMPLE_OBJECT = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;); &lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|All vanilla objects are bootstrapped and registered before mods are loaded. As such, they can be referenced as is without any issues.}}&lt;br /&gt;
&lt;br /&gt;
=== Using @ObjectHolder ===&lt;br /&gt;
&lt;br /&gt;
Forge registry objects can also be injected into &amp;lt;code&amp;gt;public static&amp;lt;/code&amp;gt; fields with either their class or that field annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;. There must be enough information to construct a &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; to identify a single object within a specific registry.&lt;br /&gt;
&lt;br /&gt;
The rules for &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; are as follows:&lt;br /&gt;
&lt;br /&gt;
* If the class is annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;, its value will be the default namespace for all fields within if not explicitly defined&lt;br /&gt;
* If the class is annotated with &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt;, the modid will be the default namespace for all annotated fields within if not explicitly defined &lt;br /&gt;
* A field is considered for injection if:&lt;br /&gt;
** it has at least the modifiers &amp;lt;code&amp;gt;public static&amp;lt;/code&amp;gt;; and&lt;br /&gt;
** the '''field''' is annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;, and:&lt;br /&gt;
*** the name value is explicitly defined; and&lt;br /&gt;
*** the registry name value is explicitly defined&lt;br /&gt;
** ''An exception is thrown if a field does not have a corresponding registry.''&lt;br /&gt;
* ''An exception is thrown if the resulting &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; is incomplete or invalid (non-valid characters in path)''&lt;br /&gt;
* If no other errors or exceptions occur, the field will be injected&lt;br /&gt;
* If all of the above rules do not apply, no action will be taken (and a message may be logged)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; annotated fields are injected with their associated object values after &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is fired for their registry, along with &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;s.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|If the object does not exist in the registry when it is to be injected, a debug message will be logged, and no value will be injected. If the object is found, but the field cannot be set, a warning message will be logged instead.}}&lt;br /&gt;
&lt;br /&gt;
As these rules are rather complicated, here are some examples:&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; style=&amp;quot;border: solid 2px; padding: 2px 5px; margin-top: 3px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-weight:bold;line-height:1.6;&amp;quot;&amp;gt;Example uses of &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot; style=&amp;quot;overflow: auto; white-space: nowrap;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
class Holder {&lt;br /&gt;
    @ObjectHolder(registryName = &amp;quot;enchantment&amp;quot;, value = &amp;quot;minecraft:flame&amp;quot;)&lt;br /&gt;
    public static final Enchantment flame = null;     // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // Registry name is explicitly defined: &amp;quot;minecraft:enchantment&amp;quot;&lt;br /&gt;
                                                      // Resource location is explicitly defined: &amp;quot;minecraft:flame&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:flame&amp;quot; from the [Enchantment] registry&lt;br /&gt;
&lt;br /&gt;
    public static final Biome ice_flat = null;        // No annotation on the field.&lt;br /&gt;
                                                      // Therefore, the field is ignored.&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(&amp;quot;minecraft:creeper&amp;quot;)&lt;br /&gt;
    public static Entity creeper = null;              // Annotation present. [public static] is required.&lt;br /&gt;
                                                      // The registry has not been specified on the field.&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(registryName = &amp;quot;potion&amp;quot;)&lt;br /&gt;
    public static final Potion levitation = null;     // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // Registry name is explicitly defined: &amp;quot;minecraft:potion&amp;quot;&lt;br /&gt;
                                                      // Resource location is not specified on the field&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Creating Custom Registries ==&lt;br /&gt;
&lt;br /&gt;
Creating custom registries for your mod might be useful if you want other mods to add new things to your system. For example, you might have magic spells and want to allow other mods to add new spells. For this you will want to make a registry (eg. &amp;quot;mymagicmod:spells&amp;quot;). This way, other mods will be able to register things to that list, and you won't have to do anything else.&lt;br /&gt;
&lt;br /&gt;
Just like with registering a new item or block you have two ways of making a new registry. Each method takes in a &amp;lt;code&amp;gt;RegistryBuilder&amp;lt;/code&amp;gt; which is used to build an &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt;. Each builder should have its name set via &amp;lt;code&amp;gt;#setName&amp;lt;/code&amp;gt; before being created.&lt;br /&gt;
&lt;br /&gt;
=== With DeferredRegister ===&lt;br /&gt;
&lt;br /&gt;
The first method involves the second static constructor: &amp;lt;code&amp;gt;DeferredRegister#create(ResourceLocation, String)&amp;lt;/code&amp;gt;. From there, we can construct the registry using &amp;lt;code&amp;gt;#makeRegistry&amp;lt;/code&amp;gt;. This will already populate &amp;lt;code&amp;gt;#setName&amp;lt;/code&amp;gt; for us. This method also returns a supplier of the registry which we can use after the &amp;lt;code&amp;gt;NewRegistryEvent&amp;lt;/code&amp;gt; is called.&lt;br /&gt;
&lt;br /&gt;
Here is an example:&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final DeferredRegister&amp;lt;ExampleRegistry&amp;gt; EXAMPLE = DeferredRegister.create(new ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;), MODID);&lt;br /&gt;
&lt;br /&gt;
public static final Supplier&amp;lt;IForgeRegistry&amp;lt;ExampleRegistry&amp;gt;&amp;gt; REGISTRY = EXAMPLE.makeRegistry(RegistryBuilder::new);&lt;br /&gt;
|kotlin=val EXAMPLE: DeferredRegister&amp;lt;ExampleRegistry&amp;gt; = DeferredRegister.create(ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;), MODID)&lt;br /&gt;
&lt;br /&gt;
val REGISTRY: IForgeRegistry&amp;lt;ExampleRegistry&amp;gt; by EXAMPLE.makeRegistry(::RegistryBuilder).let {&lt;br /&gt;
    lazy {&lt;br /&gt;
        it.get()&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
|scala=final val EXAMPLE = DeferredRegister.create(new ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;), MODID)&lt;br /&gt;
&lt;br /&gt;
private final val PRIVATE_REGISTRY = EXAMPLE.makeRegistry(() =&amp;gt; new RegistryBuilder)&lt;br /&gt;
final lazy val REGISTRY = PRIVATE_REGISTRY.get&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
=== Using &amp;lt;code&amp;gt;NewRegistryEvent&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The second method can be done during the &amp;lt;code&amp;gt;NewRegistryEvent&amp;lt;/code&amp;gt; event. Using &amp;lt;code&amp;gt;NewRegistryEvent#create&amp;lt;/code&amp;gt;, you can pass in a &amp;lt;code&amp;gt;RegistryBuilder&amp;lt;/code&amp;gt; directly. This method will return a &amp;lt;code&amp;gt;Supplier&amp;lt;IForgeRegistry&amp;lt;V&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; that can be stored and queried after the event is fired to gain access to your &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt; instance.&lt;br /&gt;
&lt;br /&gt;
Here is an example: (the event handler is registered on the '''mod event bus''')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public static Supplier&amp;lt;IForgeRegistry&amp;lt;ExampleRegistry&amp;gt;&amp;gt; registrySupplier = null;&lt;br /&gt;
&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void onNewRegistry(NewRegistryEvent event){&lt;br /&gt;
    RegistryBuilder&amp;lt;ExampleRegistry&amp;gt; registryBuilder = new RegistryBuilder&amp;lt;&amp;gt;();&lt;br /&gt;
    registryBuilder.setName(new ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;);&lt;br /&gt;
    registrySupplier = event.create(registryBuilder);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Handling Missing Entries ==&lt;br /&gt;
&lt;br /&gt;
When loading a pre-existing world after removing mods or updating versions, there are cases where certain registry objects will cease to exist. In these cases, it is possible to specify actions to remove a mapping, prevent the world from loading, or remap the name as needed. This can be done through the third of the registry events: &amp;lt;code&amp;gt;MissingMappingsEvent&amp;lt;/code&amp;gt;. Within the event, you can grab an immutable list of missing mappings associated with a mod id for a given registry via &amp;lt;code&amp;gt;#getMappings&amp;lt;/code&amp;gt; or a list of all mappings via &amp;lt;code&amp;gt;#getAllMappings&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For each &amp;lt;code&amp;gt;Mapping&amp;lt;/code&amp;gt;, you can either execute one of the following methods:&lt;br /&gt;
* &amp;lt;code&amp;gt;#ignore&amp;lt;/code&amp;gt; which abandons the entry when loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#warn&amp;lt;/code&amp;gt; which warns the user about the missing entry but continues loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#fail&amp;lt;/code&amp;gt; which prevents the world from loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#remap&amp;lt;/code&amp;gt; which remaps the entry to the specified non-null object in the same registry&lt;br /&gt;
&lt;br /&gt;
If none of the above are specified, then the default action of notifying the user about the missing mappings occur.&lt;br /&gt;
&lt;br /&gt;
Here is an example:  (the event handler is registered on the '''forge event bus''')&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=// This will ignore any missing test items from the specified world&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void onMissing(final MissingMappingsEvent event) {&lt;br /&gt;
    event.getMappings(ForgeRegistries.Keys.ITEMS, MODID).stream()&lt;br /&gt;
        .filter(mapping -&amp;gt; mapping.key.getPath().contains(&amp;quot;test&amp;quot;))&lt;br /&gt;
            .forEach(Mapping::ignore);&lt;br /&gt;
}&lt;br /&gt;
|groovy=// This will ignore any missing test items from the specified world&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
void onMissing(final MissingMappingsEvent event) {&lt;br /&gt;
    event.getMappings(ForgeRegistries.Keys.ITEMS, MODID).stream()&lt;br /&gt;
        .filter(mapping -&amp;gt; mapping.key.path.contains(&amp;quot;test&amp;quot;))&lt;br /&gt;
            .forEach(Mapping::ignore);&lt;br /&gt;
}&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Common Concepts]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Components&amp;diff=3292</id>
		<title>Components</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Components&amp;diff=3292"/>
		<updated>2022-06-18T16:16:52Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update to 1.19&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Components''' (base interface &amp;lt;code&amp;gt;Component&amp;lt;/code&amp;gt;) are forms of text used by Minecraft and Forge to concisely hold data relating to text. They form the basis of the chat system used in Minecraft. They are used for serializing and sending text data over network to players, displaying on clients, and styling for how the text appears with modifiers like bold and coloration.&lt;br /&gt;
&lt;br /&gt;
There are two main types of content a component can hold: &amp;lt;code&amp;gt;LiteralContents&amp;lt;/code&amp;gt;s and &amp;lt;code&amp;gt;TranslatableContents&amp;lt;/code&amp;gt;s. Both serve different purposes, although you should prefer the latter one for most general mod development.&lt;br /&gt;
&lt;br /&gt;
== MutableComponent ==&lt;br /&gt;
Components at their most basic level hold a &amp;lt;code&amp;gt;Style&amp;lt;/code&amp;gt; object and a list of &amp;quot;sibling&amp;quot; components named &amp;lt;code&amp;gt;siblings&amp;lt;/code&amp;gt;. In reality, these &amp;quot;siblings&amp;quot; are actually children of the main component, and are treated as such when formatting with the &amp;lt;code&amp;gt;Style&amp;lt;/code&amp;gt; object. A style can be applied to a component by calling &amp;lt;code&amp;gt;withStyle&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;setStyle&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;withStyle&amp;lt;/code&amp;gt; modifies the existing &amp;lt;code&amp;gt;Style&amp;lt;/code&amp;gt; object with the given property, while &amp;lt;code&amp;gt;setStyle&amp;lt;/code&amp;gt; replaces the current &amp;lt;code&amp;gt;Style&amp;lt;/code&amp;gt; object. By default, components use a style of &amp;lt;code&amp;gt;Style.EMPTY&amp;lt;/code&amp;gt;, with an empty color representing white and empty properties meaning no special chat formatting. To add a light blue color for example, one could simple call &amp;lt;code&amp;gt;theMutableComponent.withStyle(ChatFormatting.BLUE)&amp;lt;/code&amp;gt;. This will merge the &amp;lt;code&amp;gt;BLUE&amp;lt;/code&amp;gt; color with the existing &amp;lt;code&amp;gt;Style&amp;lt;/code&amp;gt; object. When applying a parent component's &amp;lt;code&amp;gt;Style&amp;lt;/code&amp;gt; to its children components, a non-null property of a child &amp;lt;code&amp;gt;Style&amp;lt;/code&amp;gt; will take precedence over its parent &amp;lt;code&amp;gt;Style&amp;lt;/code&amp;gt;. This means that if the color is set for both a child and parent component, the child's color will be displayed. Otherwise, non-null properties from a parent component's &amp;lt;code&amp;gt;Style&amp;lt;/code&amp;gt; override properties from the child &amp;lt;code&amp;gt;Style&amp;lt;/code&amp;gt; if they are null.&lt;br /&gt;
&lt;br /&gt;
=== Appending siblings ===&lt;br /&gt;
Siblings can be appended to components similar to the plus (+) operator with Strings via &amp;lt;code&amp;gt;MutableComponent#append(Component)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== LiteralContents ==&lt;br /&gt;
Literal contents are the most basic form of component contents. They are raw contents that contain a single String object. These are not preferred for general mod development as they cannot be translated into other languages.&lt;br /&gt;
&lt;br /&gt;
=== Creating ===&lt;br /&gt;
Literal contents are instantiated in the form &amp;lt;code&amp;gt;new LiteralContents(&amp;quot;Hello, world!&amp;quot;)&amp;lt;/code&amp;gt;. A component can be created with the contents using &amp;lt;code&amp;gt;Component#literal&amp;lt;/code&amp;gt;. In practice, when sent to a player, this would simply be displayed as declared: &amp;lt;code&amp;gt;Hello, world!&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Usage ===&lt;br /&gt;
Literal contents are most commonly used to create empty or space-filling components, which can then be used to link multiple components together.&lt;br /&gt;
&lt;br /&gt;
== TranslatableContents ==&lt;br /&gt;
Translatable contents are a more advanced form that support String formatting and translation into multiple languages. Translatable contents hold a '''translation key''', which is integral to translation into other languages. Translation keys are then mapped with a language file (commonly know as a lang file) to their appropriate entry for each translated language. It is important to note that the translation key is translated by the client, not the server. The server sends the translation key to the player, and the player's client converts the translation key into its fully expanded form when rendering depending on the player's selected language. If a player selects a specific language for which a translation key is not mapped, it will default to English.&lt;br /&gt;
&lt;br /&gt;
=== Format modifiers ===&lt;br /&gt;
Translatable contents also support format modifiers like used in &amp;lt;code&amp;gt;String#format&amp;lt;/code&amp;gt;. These format modifiers are declared by using the string &amp;lt;code&amp;gt;%s&amp;lt;/code&amp;gt; when creating a translation entry for a given translation key. This format modifier will then be expanded and replaced with the provided object when rendered by the client. Any other format modifiers like &amp;lt;code&amp;gt;%d&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;%n&amp;lt;/code&amp;gt; are ''not supported'' and will throw a formatting error. To get a normal percentage, a double percentage sign must be used (&amp;lt;code&amp;gt;%%&amp;lt;/code&amp;gt;). A number can also be inserted, and it will be used as a 1-based index to select the argument. This is useful for choosing a specific argument out of order, or using the same argument twice. This looks like &amp;lt;code&amp;gt;%1$s&amp;lt;/code&amp;gt;. The list of arguments to expand these format modifiers are passed to the constructor of the &amp;lt;code&amp;gt;TranslatableContents&amp;lt;/code&amp;gt; using an Object varargs parameter, similar to &amp;lt;code&amp;gt;String#format&amp;lt;/code&amp;gt;. The arguments passed in the constructor of a &amp;lt;code&amp;gt;TranslatableContents&amp;lt;/code&amp;gt; can be either an Object or another &amp;lt;code&amp;gt;Component&amp;lt;/code&amp;gt;. Any &amp;lt;code&amp;gt;Component&amp;lt;/code&amp;gt;s will be expanded and have any declared &amp;lt;code&amp;gt;Style&amp;lt;/code&amp;gt;s properties preserved in the final output. Any objects that are not an instance of &amp;lt;code&amp;gt;Component&amp;lt;/code&amp;gt; will have &amp;lt;code&amp;gt;Object#toString&amp;lt;/code&amp;gt; called during expansion.&lt;br /&gt;
&lt;br /&gt;
=== Creating ===&lt;br /&gt;
Translatable contents are instantiated in the form &amp;lt;code&amp;gt;new TranslatableContents(&amp;quot;your.translation_key.here&amp;quot;, new Component.literal(&amp;quot;thing1&amp;quot;).withStyle(ChatFormatting.RED), new Component.literal(&amp;quot;thing2&amp;quot;).withStyle(ChatFormatting.BLUE))&amp;lt;/code&amp;gt;. A component can be created with the contents using &amp;lt;code&amp;gt;Component#translatable&amp;lt;/code&amp;gt;. In your lang file, the entry would look something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;your.translation_key.here&amp;quot;: &amp;quot;I like using %1$s and %2$s!&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In practice, when sent to a player, this would be displayed as &amp;lt;code&amp;gt;I like using thing1 and thing2!&amp;lt;/code&amp;gt;, where &amp;lt;code&amp;gt;thing1&amp;lt;/code&amp;gt; would be colored as red and &amp;lt;code&amp;gt;thing2&amp;lt;/code&amp;gt; would be colored as blue. Normal &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt;s can also be passed in, and they will inherit the &amp;lt;code&amp;gt;Style&amp;lt;/code&amp;gt; object of the main component. Note that any more values in the language file must be declared as comma-separated key-value pairs as required by the JSON specification, with the last key-value pair not ending with a comment.&lt;br /&gt;
&lt;br /&gt;
=== Usage ===&lt;br /&gt;
Translatable contents are used for sending anything visual to the player. Using them provides a benefit of format modifiers and the ability to be translated into different languages. This means that, given a translator, one could translate the English translation file (by default, &amp;lt;code&amp;gt;en_us.json&amp;lt;/code&amp;gt;) into another language for a given mod. This system is also used by Minecraft itself and has been used to translate the game into hundreds of languages. Translation keys are also required for declaring the names of items, blocks, and entities in the game.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Translations]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Key_Mappings&amp;diff=3291</id>
		<title>Key Mappings</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Key_Mappings&amp;diff=3291"/>
		<updated>2022-06-18T15:03:56Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update to 1.19&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A '''key mapping''' or '''keybinding''' is the relation of an action to an input, such as a mouse click or a combination of key presses. The action for the keymapping is defined in the code, while the triggering input is configurable by the user through the [[:mc:Options#Controls|Controls menu]]. In the code, these key mappings are declared and represented by &amp;lt;code&amp;gt;KeyMapping&amp;lt;/code&amp;gt; instances&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;KeyMapping&amp;lt;/code&amp;gt; can be declared with the following parameters:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Parameter !! Description&lt;br /&gt;
|-&lt;br /&gt;
| name || A translation key used to set the name of this key mapping (e.g. &amp;lt;code&amp;gt;key.modid.key_name&amp;lt;/code&amp;gt;).&lt;br /&gt;
|-&lt;br /&gt;
| keyConflictContext || Determines when the key mapping should conflict with another defined key mapping. By default, there are three values within &amp;lt;code&amp;gt;KeyConflictContext&amp;lt;/code&amp;gt;: &amp;lt;code&amp;gt;UNIVERSAL&amp;lt;/code&amp;gt; which are used in every context, &amp;lt;code&amp;gt;GUI&amp;lt;/code&amp;gt; which are used whenever a screen is open, and &amp;lt;code&amp;gt;IN_GAME&amp;lt;/code&amp;gt; whenever a screen is not open. Custom contexts can be created by implementing &amp;lt;code&amp;gt;IKeyConflictContext&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| key || Determines the input context this mapping will declare by default. This is a combination of the input type, input code, and any additional modifiers. There are three possible values for the input type: &amp;lt;code&amp;gt;KEYSYM&amp;lt;/code&amp;gt; which represents a mapped key, &amp;lt;code&amp;gt;SCANCODE&amp;lt;/code&amp;gt; which represents the value emitted by the keyboard itself, and &amp;lt;code&amp;gt;MOUSE&amp;lt;/code&amp;gt; which represents a mouse click. The associated input codes and modifiers are based on the specified input type as mapped by &amp;lt;code&amp;gt;GLFW&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| category || A translation key representing the category this key is located in (e.g. &amp;lt;code&amp;gt;key.modid.categories.category_name&amp;lt;/code&amp;gt;).&lt;br /&gt;
|}&lt;br /&gt;
{{Tip|If you would like there to be no mapping by default, use a constructor that contains &amp;lt;code&amp;gt;InputConstants$Key&amp;lt;/code&amp;gt; instead and supply &amp;lt;code&amp;gt;InputConstants#UNKNOWN&amp;lt;/code&amp;gt; as the argument.}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;KeyMapping&amp;lt;/code&amp;gt; can then be registered using &amp;lt;code&amp;gt;ClientRegistry::registerKeyBinding&amp;lt;/code&amp;gt; within &amp;lt;code&amp;gt;FMLClientSetupEvent&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Using Registered Mappings ==&lt;br /&gt;
&lt;br /&gt;
There are two contexts in which a key mapping can be used normally: in or not in a screen. As such, there are two ways to handle these mappings. When not in a screen, &amp;lt;code&amp;gt;ClientTickEvent&amp;lt;/code&amp;gt; should be used to determine whether the key is down using &amp;lt;code&amp;gt;KeyMapping#isDown&amp;lt;/code&amp;gt;. If within a screen, the following logic can be applied using &amp;lt;code&amp;gt;IForgeKeyMapping#isActiveAndMatches&amp;lt;/code&amp;gt; within &amp;lt;code&amp;gt;GuiEventListener#keyPressed&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;GuiEventListener#mouseClicked&amp;lt;/code&amp;gt; for mouse input. Note that the necessary &amp;lt;code&amp;gt;InputConstants$Key&amp;lt;/code&amp;gt; can be constructed using &amp;lt;code&amp;gt;InputConstants::getKey&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;InputConstants$Type::getOrCreate&amp;lt;/code&amp;gt; respectively.&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Dynamic_Loot_Modification&amp;diff=3290</id>
		<title>Dynamic Loot Modification</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Dynamic_Loot_Modification&amp;diff=3290"/>
		<updated>2022-06-18T15:00:52Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update to 1.19&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Global Loot Modifiers are a data-driven method of handling modification of harvested drops without the need to overwrite dozens to hundreds of vanilla loot tables or to handle effects that would require interactions with another mod's loot tables without knowing what mods may be loaded. Global Loot Modifiers are also stacking, rather than last-load-wins as modifications to loot tables would be.&lt;br /&gt;
&lt;br /&gt;
== Registering a Global Loot Modifier ==&lt;br /&gt;
&lt;br /&gt;
You will need 3 things:&lt;br /&gt;
# Create a &amp;lt;code&amp;gt;global_loot_modifiers.json&amp;lt;/code&amp;gt; file at &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;/data/forge/loot_modifiers/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
#* This will tell Forge about your modifiers and works similar to [[Tags|tags]].&lt;br /&gt;
# A serialized json representing your modifier at &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;/data/&amp;lt;modID&amp;gt;/loot_modifiers/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
#* This will contain all of the data about your modification and allows data packs to tweak your effect.&lt;br /&gt;
# A class that extends &amp;lt;code&amp;gt;LootModifier&amp;lt;/code&amp;gt;&lt;br /&gt;
#* The operational code that makes your modifier work and associated serializer.&lt;br /&gt;
&lt;br /&gt;
Finally, the serializer for your operational class is [[Registration|registered]] as any other &amp;lt;code&amp;gt;ForgeRegistryEntry&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==The global_loot_modifiers.json==&lt;br /&gt;
All you need to add here are the file names of your loot modifiers.&lt;br /&gt;
These are the names of the json files you have made in the loot_modifiers folder, in ResourceLocation format.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;replace&amp;quot;: false,&lt;br /&gt;
  &amp;quot;entries&amp;quot;: [&lt;br /&gt;
    &amp;quot;global_loot_test:silk_touch_bamboo&amp;quot;,&lt;br /&gt;
    &amp;quot;global_loot_test:smelting&amp;quot;,&lt;br /&gt;
    &amp;quot;global_loot_test:wheat_harvest&amp;quot;&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;replace&amp;lt;/code&amp;gt; causes the cache of modifiers to be cleared fully when this asset loads (mods are loaded in an order that may be specified by a data pack). For modders you will want to use &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; while data pack makers may want to specify their overrides with &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;entries&amp;lt;/code&amp;gt; is an ''ordered list'' of the modifiers that will be loaded. Any modifier that is not listed will not be loaded and the ones listed are called in the order listed. This is primarily relevant to data pack makers for resolving conflicts between modifiers from separate mods.&lt;br /&gt;
&lt;br /&gt;
== The serialized json ==&lt;br /&gt;
&lt;br /&gt;
This file contains all of the potential variables related to your modifier, including the conditions that must be met prior to modifying any loot as well as any other parameters your modifier might have. Avoid hard-coded values where ever possible so that data pack makers can adjust balance if they wish to.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;conditions&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;condition&amp;quot;: &amp;quot;minecraft:match_tool&amp;quot;,&lt;br /&gt;
      &amp;quot;predicate&amp;quot;: {&lt;br /&gt;
        &amp;quot;item&amp;quot;: &amp;quot;minecraft:shears&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;condition&amp;quot;: &amp;quot;minecraft:block_state_property&amp;quot;,&lt;br /&gt;
      &amp;quot;block&amp;quot;: &amp;quot;minecraft:wheat&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;seedItem&amp;quot;: &amp;quot;minecraft:wheat_seeds&amp;quot;,&lt;br /&gt;
  &amp;quot;numSeeds&amp;quot;: 3,&lt;br /&gt;
  &amp;quot;replacement&amp;quot;: &amp;quot;minecraft:wheat&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, the modification only happens if the player harvests wheat when using shears (specified by the two &amp;lt;code&amp;gt;conditions&amp;lt;/code&amp;gt; which are automatically &amp;lt;code&amp;gt;AND&amp;lt;/code&amp;gt;ed together). The &amp;lt;code&amp;gt;seedsItem&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;numSeeds&amp;lt;/code&amp;gt; values are then used to count how many seeds were generated by the vanilla loot table, and if matched, are substituted for an additional &amp;lt;code&amp;gt;replacement&amp;lt;/code&amp;gt; item instead. The operation code will be shown below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Tip|&amp;lt;code&amp;gt;conditions&amp;lt;/code&amp;gt; is the only object needed by the system specification, everything else is the mod maker's data. &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;code&amp;gt;seedItem&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;numSeeds&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;replacement&amp;lt;/code&amp;gt; are NOT standard elements of Global Loot Modifiers.  &lt;br /&gt;
&lt;br /&gt;
They are deserialized manually in the next section.}}&lt;br /&gt;
&lt;br /&gt;
== The LootModifier Subclass ==&lt;br /&gt;
&lt;br /&gt;
You will also need a static child class that extends &amp;lt;code&amp;gt;GlobalLootModifierSerializer&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; where &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; is your LootModifier subclass in order to deserialize your json data file into operational code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
private static class WheatSeedsConverterModifier extends LootModifier {&lt;br /&gt;
  private final int numSeedsToConvert;&lt;br /&gt;
  private final Item itemToCheck;&lt;br /&gt;
  private final Item itemReward;&lt;br /&gt;
  public WheatSeedsConverterModifier(LootItemCondition[] conditions, int numSeeds, Item itemCheck, Item reward) {&lt;br /&gt;
    super(conditions);&lt;br /&gt;
    numSeedsToConvert = numSeeds;&lt;br /&gt;
    itemToCheck = itemCheck;&lt;br /&gt;
    itemReward = reward;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  @Nonnull&lt;br /&gt;
  @Override&lt;br /&gt;
  public List&amp;lt;ItemStack&amp;gt; doApply(List&amp;lt;ItemStack&amp;gt; generatedLoot, LootContext context) {&lt;br /&gt;
    /*&lt;br /&gt;
     * Additional conditions can be checked, though as much as possible should be parameterized via JSON data.&lt;br /&gt;
     * It is better to write a new LootItemCondition implementation than to do things here.&lt;br /&gt;
     */&lt;br /&gt;
    int numSeeds = 0;&lt;br /&gt;
    for(ItemStack stack : generatedLoot) {&lt;br /&gt;
      if(stack.getItem() == itemToCheck)&lt;br /&gt;
        numSeeds += stack.getCount();&lt;br /&gt;
    }&lt;br /&gt;
    if(numSeeds &amp;gt;= numSeedsToConvert) {&lt;br /&gt;
      generatedLoot.removeIf(x -&amp;gt; x.getItem() == itemToCheck);&lt;br /&gt;
      generatedLoot.add(new ItemStack(itemReward, (numSeeds/numSeedsToConvert)));&lt;br /&gt;
      numSeeds = numSeeds % numSeedsToConvert;&lt;br /&gt;
      if(numSeeds &amp;gt; 0)&lt;br /&gt;
        generatedLoot.add(new ItemStack(itemToCheck, numSeeds));&lt;br /&gt;
    }&lt;br /&gt;
    return generatedLoot;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  private static class Serializer extends GlobalLootModifierSerializer&amp;lt;WheatSeedsConverterModifier&amp;gt; {&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public WheatSeedsConverterModifier read(ResourceLocation name, JsonObject object, LootItemCondition[] conditions) {&lt;br /&gt;
      int numSeeds = GsonHelper.getAsInt(object, &amp;quot;numSeeds&amp;quot;);&lt;br /&gt;
      Item seed = ForgeRegistries.ITEMS.getValue(new ResourceLocation((GsonHelper.getAsString(object, &amp;quot;seedItem&amp;quot;))));&lt;br /&gt;
      Item wheat = ForgeRegistries.ITEMS.getValue(new ResourceLocation(GsonHelper.getAsString(object, &amp;quot;replacement&amp;quot;)));&lt;br /&gt;
      return new WheatSeedsConverterModifier(conditions, numSeeds, seed, wheat);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    @Override&lt;br /&gt;
    public JsonObject write(WheatSeedsConverterModifier instance) {&lt;br /&gt;
      JsonObject json = makeConditions(instance.conditions);&lt;br /&gt;
      json.addProperty(&amp;quot;numSeeds&amp;quot;, instance.numSeedsToConvert);&lt;br /&gt;
      json.addProperty(&amp;quot;seedItem&amp;quot;, ForgeRegistries.ITEMS.getKey(instance.itemToCheck).toString());&lt;br /&gt;
      json.addProperty(&amp;quot;replacement&amp;quot;, ForgeRegistries.ITEMS.getKey(instance.itemReward).toString());&lt;br /&gt;
      return json;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The critical portion is the &amp;lt;code&amp;gt;doApply&amp;lt;/code&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
This method is only called if the &amp;lt;code&amp;gt;conditions&amp;lt;/code&amp;gt; specified return &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; and the modder is now able to make the modifications they desire. In this case we can see that the number of &amp;lt;code&amp;gt;itemToCheck&amp;lt;/code&amp;gt; meets or exceeds the &amp;lt;code&amp;gt;numSeedsToConvert&amp;lt;/code&amp;gt; before modifying the list by adding an &amp;lt;code&amp;gt;itemReward&amp;lt;/code&amp;gt; and removing any excess &amp;lt;code&amp;gt;itemToCheck&amp;lt;/code&amp;gt; stacks, matching the previously mentioned effects: ''When a wheat block is harvested with shears, if enough seeds are generated as loot, they are converted to additional wheat instead''.&lt;br /&gt;
&lt;br /&gt;
Also take note of the &amp;lt;code&amp;gt;read&amp;lt;/code&amp;gt; method in the serializer. The conditions are already deserialized for you and if you have no other data, simply &amp;lt;code&amp;gt;return new MyModifier(conditions)&amp;lt;/code&amp;gt;. However, the full &amp;lt;code&amp;gt;JsonObject&amp;lt;/code&amp;gt; is available if needed. The &amp;lt;code&amp;gt;write&amp;lt;/code&amp;gt; method, on the other hand, is used for if you want to utilize &amp;lt;code&amp;gt;GlobalLootModifierProvider&amp;lt;/code&amp;gt; for [[datageneration|data generation]].&lt;br /&gt;
&lt;br /&gt;
Additional [https://github.com/MinecraftForge/MinecraftForge/blob/1.19.x/src/test/java/net/minecraftforge/debug/gameplay/loot/GlobalLootModifiersTest.java examples] can be found on the Forge Git repository, including silk touch and smelting effects.&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=BlockState_JSONs&amp;diff=3289</id>
		<title>BlockState JSONs</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=BlockState_JSONs&amp;diff=3289"/>
		<updated>2022-06-18T14:44:16Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update to 1.19&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Blockstate JSONs are Minecraft’s way to map “variant strings” to models. A variant string can be absolutely anything, from “inventory” to “power=5” to “I am your father.” They represent an actual model, where the blockstate is just a container for them. In code, a variant string within a blockstate JSON is represented by a &amp;lt;code&amp;gt;ModelResourceLocation&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
When the game searches for a model corresponding to a block in the world, it takes the [[BlockState JSONs|blockstate]] for that position, and then it uses a map within &amp;lt;code&amp;gt;ModelManager&amp;lt;/code&amp;gt; to find the corresponding &amp;lt;code&amp;gt;ModelResourceLocation&amp;lt;/code&amp;gt; for it, which then refers to the actual model. &amp;lt;code&amp;gt;BlockModelShaper&amp;lt;/code&amp;gt; uses the block's registry name as the location of the blockstate JSON. (E.g. block &amp;lt;code&amp;gt;examplemod:testblock&amp;lt;/code&amp;gt; goes to the &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;examplemod:testblock&amp;lt;/code&amp;gt;.) The variant string is pieced together from the &amp;lt;code&amp;gt;BlockState&amp;lt;/code&amp;gt;'s properties.&lt;br /&gt;
&lt;br /&gt;
As an example, let’s take a look at the vanilla &amp;lt;code&amp;gt;oak_log.json&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;variants&amp;quot;: {&lt;br /&gt;
    &amp;quot;axis=x&amp;quot;: {&lt;br /&gt;
      &amp;quot;model&amp;quot;: &amp;quot;minecraft:block/oak_log_horizontal&amp;quot;,&lt;br /&gt;
      &amp;quot;x&amp;quot;: 90,&lt;br /&gt;
      &amp;quot;y&amp;quot;: 90&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;axis=y&amp;quot;: {&lt;br /&gt;
      &amp;quot;model&amp;quot;: &amp;quot;minecraft:block/oak_log&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;axis=z&amp;quot;: {&lt;br /&gt;
      &amp;quot;model&amp;quot;: &amp;quot;minecraft:block/oak_log_horizontal&amp;quot;,&lt;br /&gt;
      &amp;quot;x&amp;quot;: 90&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Here we define three variant strings, and for each we use a certain model: the upright log and the sideways log (rotated about the y-axis or not). These variants will define the look of a log depending on the property axis.&lt;br /&gt;
&lt;br /&gt;
A variant should be defined for every property that invokes a change in the model displayed. Any property not specified in the JSON will not have any bearing to determine the current model (e.g. '''waterlogged''' has no effect on how a model might look).&lt;br /&gt;
&lt;br /&gt;
Each blockstate can be specified using one of two methods: '''variants''' and '''multiparts'''. A variant defines an associated array of states which point to the associated model to render. Note that every single property that changes the model must be defined (e.g. If 4 boolean properties defines how the model looks, then 2 ^ 4 = 16 variants must be defined). Multiparts, on the other hand, use conditions to display a certain model when true (e.g. If a model is only shown when north was true, then when that case occurs, the model will display along with any other models whose conditions are met).&lt;br /&gt;
&lt;br /&gt;
For a better understanding of multiparts, let's look at a variant built fence connection:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;east=true,north=false,south=false,west=false&amp;quot;: { &amp;quot;model&amp;quot;: &amp;quot;oak_fence_n&amp;quot;, &amp;quot;y&amp;quot;: 90, &amp;quot;uvlock&amp;quot;: true }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This represents one variant out of 16 possible states. Even worse, there must be models that can uniquely define unique states (a state that can be rotated to become another state is not unique for this purpose). For fences, there are 6 models: one for no connections, one connection, two connections in a straight line, two perpendicular connections, three connections, and one for all four connections.&lt;br /&gt;
&lt;br /&gt;
Now let's view a modern day multipart built fence connection:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{ &lt;br /&gt;
  &amp;quot;when&amp;quot;:  { &amp;quot;east&amp;quot;: &amp;quot;true&amp;quot; },&lt;br /&gt;
  &amp;quot;apply&amp;quot;: { &amp;quot;model&amp;quot;: &amp;quot;minecraft:block/oak_fence_side&amp;quot;, &amp;quot;y&amp;quot;: 90, &amp;quot;uvlock&amp;quot;: true }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In this case, the JSON defines that if the east connector is true, then show the model &amp;lt;code&amp;gt;minecraft:block/oak_fence_side&amp;lt;/code&amp;gt; rotated 90 degrees. This allows the model to be broken up in only two files: the base post and the connection. It can also be represented as 5 statements, one that checks if each of the sides is connected and one that applies the base post unconditionally.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Models]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Access_Transformers&amp;diff=3288</id>
		<title>Access Transformers</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Access_Transformers&amp;diff=3288"/>
		<updated>2022-06-18T14:39:55Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update to 1.19&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Access transformers''' (abbreviated as ''ATs'') are declarations for modifying or transforming the access visibility or finality of a class member (classes, fields, methods). These declarations are parsed by a transformer and applied to classes using the ASM library, either modifying the class files on-disk or modifying the class bytes during runtime.&lt;br /&gt;
&lt;br /&gt;
The [https://github.com/MinecraftForge/AccessTransformers AccessTransformers] library provides a pluggable ModLauncher transformation service and a command-line application for applying access transformers on class bytes during runtime and on class files on-disk.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
Java provides the mechanism of '''access level modifiers''' (or ''access modifiers''), to modify the ''visibility'' of a member with the modifier to other classes. This is commonly used to hide fields and methods from other classes, such as instance fields for [[:wikipedia:Encapsulation (computer programming)|encapsulation]] or private methods which are part of the implementation of the class and not normally exposed to callers.&lt;br /&gt;
&lt;br /&gt;
A member can be declared with any of the modifier keywords &amp;lt;code&amp;gt;public&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;private&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;protected&amp;lt;/code&amp;gt; to set the access level of the member, or none of the keywords, which defaults to a ''package-private'' access level.&lt;br /&gt;
&lt;br /&gt;
The following table shows the different access levels and their modifiers, and what classes may access members with that access level:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
|+ Access levels&lt;br /&gt;
! Access modifier&lt;br /&gt;
! Within the same class&lt;br /&gt;
! Classes in the same package&lt;br /&gt;
! Subclasses&lt;br /&gt;
! All other classes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;public&amp;lt;/code&amp;gt;&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;protected&amp;lt;/code&amp;gt;&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
| style=&amp;quot;color:indianred&amp;quot; | '''No'''&lt;br /&gt;
|-&lt;br /&gt;
| ''no modifier''&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
| style=&amp;quot;color:indianred&amp;quot; | '''No'''&lt;br /&gt;
| style=&amp;quot;color:indianred&amp;quot; | '''No'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;private&amp;lt;/code&amp;gt;&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
| style=&amp;quot;color:indianred&amp;quot; | '''No'''&lt;br /&gt;
| style=&amp;quot;color:indianred&amp;quot; | '''No'''&lt;br /&gt;
| style=&amp;quot;color:indianred&amp;quot; | '''No'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, a field marked &amp;lt;code&amp;gt;protected&amp;lt;/code&amp;gt; cannot be accessed by a class in another package, but can be accessed by: any class within the same package, any subclass of the class (even if the subclass belongs to another package), and within the same class where the field is declared.&lt;br /&gt;
&lt;br /&gt;
Additionally to the access modifiers, there exists the &amp;lt;code&amp;gt;final&amp;lt;/code&amp;gt; keyword, which:&lt;br /&gt;
* on classes, prevents any subclassing of the class;&lt;br /&gt;
* on fields, marks it as being assignable only once during construction; and&lt;br /&gt;
* on methods, prevents any subclasses from overriding the method with their own implementation.&lt;br /&gt;
&lt;br /&gt;
Normally, Java programmers restrict access levels to be as restrictive as they need to be, controlling what is the effective publicly-available surface for the application. For example, a field may be declared as &amp;lt;code&amp;gt;private&amp;lt;/code&amp;gt; while providing setter and getter methods to access the field (a technique known as encapsulation).&lt;br /&gt;
&lt;br /&gt;
However, this convention of restricting access levels and marking members as &amp;lt;code&amp;gt;final&amp;lt;/code&amp;gt; where approriate presents a problem with modding Minecraft, because they restrict what parts of the game that modders can access or modify, usually without other means to access or modify them (such as setters and getters for fields).&lt;br /&gt;
&lt;br /&gt;
One solution is to use Java [[:wikipedia:reflection|reflection]] to reflectively access these fields and methods during runtime, but they suffer from some problems:&lt;br /&gt;
* Reflection is slower than regular method calls or field accesses, as certain optimizations done by the JVM cannot be applied.&amp;lt;ref&amp;gt;[https://docs.oracle.com/javase/tutorial/reflect/index.html The Java™ Tutorials: The Reflection API]: ''&amp;quot;Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.&amp;quot;''&amp;lt;/ref&amp;gt; This makes reflection unsuitable for performance-critical code, such as during rendering.&lt;br /&gt;
* Reflection cannot allow the modification of &amp;lt;code&amp;gt;final&amp;lt;/code&amp;gt; fields which are either marked &amp;lt;code&amp;gt;static&amp;lt;/code&amp;gt; or belong to a record class.&amp;lt;ref&amp;gt;[https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/reflect/AccessibleObject.html#setAccessible(boolean) Java 17 javadocs] for &amp;lt;code&amp;gt;java.lang.reflect.AccessibleObject.setAccessible(boolean)&amp;lt;/code&amp;gt;&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Runtime reflection loses the benefit of compile-time type checks, which allows dangerous operations such as trying to set a field's value to an incompatible type.&lt;br /&gt;
* The use of reflection does not allow a class to extend a non-visible class.&lt;br /&gt;
&lt;br /&gt;
These problems are solved with the use of access transformers, which allow modification of the access modifiers of members such that they can be applied on class files on-disk to allow compiling against them, and applying the same transformer declarations on class bytes during runtime to allow classes which compiled against those transformed classes to work correctly.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
&lt;br /&gt;
To use access transformers in the development environment, ForgeGradle must be configured with the location of the access transformer configuration file (or files). Because FML is hardwired to look for the configuration file at &amp;lt;code&amp;gt;META-INF/accesstransformer.cfg&amp;lt;/code&amp;gt; within JAR files, it is recommended that the AT configuration file for the project be placed at the same location: within the resources folder of the main source set, or &amp;lt;code&amp;gt;src/main/resources/META-INF/accesstransformer.cfg&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To configure the location of the access transformer configuration file with ForgeGradle:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;gradle&amp;quot;&amp;gt;&lt;br /&gt;
minecraft { // Within the minecraft block&lt;br /&gt;
    // Configures FG to look at the given file path for the AT configuration file&lt;br /&gt;
    accessTransformer = file(&amp;quot;src/main/resources/META-INF/accesstransformer.cfg&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Access-transformers-uncomment-this-line-in-build-gradle.png|thumb|300px]]&lt;br /&gt;
&lt;br /&gt;
The Forge-provided mod development environment's buildscript contains the above line but commented out, as the MDK does not ship with an access transformer file. Users of the MDK can therefore uncomment out the above line and create the AT configuration file at the same location. &lt;br /&gt;
&lt;br /&gt;
Once the configuration file(s) has been added and everytime the contents or location of the file(s) changes, the developer should then refresh the Gradle nature/project in their IDE of choice for ForgeGradle to apply the access transformers to the compiled source. Each change to the access transformer configuration will trigger a full decompilation of the game.&lt;br /&gt;
&lt;br /&gt;
== Declarations ==&lt;br /&gt;
&lt;br /&gt;
Access transformers are declared line-by-line in configuration files, which are then parsed by ForgeGradle in the development environment and by FML in the production or end-user environment.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt; character and any content after that up to the end of the line is considered a comment, and will be ignored by the parser. Any lines which are either empty or consist of only whitespace or comments are ignored.&lt;br /&gt;
&lt;br /&gt;
An access transformer declaration has three different variations, depending on the target to be transformed:&lt;br /&gt;
&lt;br /&gt;
* for '''classes''': &amp;lt;code&amp;gt;''&amp;lt;modifier&amp;gt;'' ''&amp;lt;class name&amp;gt;''&amp;lt;/code&amp;gt;&lt;br /&gt;
* for '''methods''': &amp;lt;code&amp;gt;''&amp;lt;modifier&amp;gt;'' ''&amp;lt;class name&amp;gt;'' ''&amp;lt;method name&amp;gt;'''''('''''[parameter descriptors]''''')'''''&amp;amp;lt;return descriptor&amp;gt;''&amp;lt;/code&amp;gt;&lt;br /&gt;
* for '''fields''': &amp;lt;code&amp;gt;''&amp;lt;modifier&amp;gt;'' ''&amp;lt;class name&amp;gt;'' ''&amp;lt;field name&amp;gt;''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The modifier consists of one of the following words:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;public&amp;lt;/code&amp;gt; for the ''public'' access level (denoted by the modifier keyword of the same name)&lt;br /&gt;
* &amp;lt;code&amp;gt;protected&amp;lt;/code&amp;gt; for the ''protected'' access level (denoted by the modifier keyword of the same name)&lt;br /&gt;
* &amp;lt;code&amp;gt;default&amp;lt;/code&amp;gt; for the ''package-private'' access level (denoted by the absence of an access modifier keyword)&lt;br /&gt;
* &amp;lt;code&amp;gt;private&amp;lt;/code&amp;gt; for the ''private'' access level (denoted by the modifier keyword of the same name)&lt;br /&gt;
* For any of the preceding words, the &amp;lt;code&amp;gt;-f&amp;lt;/code&amp;gt; suffix removes the &amp;lt;code&amp;gt;final&amp;lt;/code&amp;gt; modifier, while the &amp;lt;code&amp;gt;+f&amp;lt;/code&amp;gt; suffix adds the modifier.&lt;br /&gt;
&lt;br /&gt;
The class name is the fully qualified name of the class, using &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt; (dots) to separate between (sub)packages and classes (for example, &amp;lt;code&amp;gt;java.lang.Object&amp;lt;/code&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
For methods, the method descriptor&amp;lt;ref&amp;gt;''[https://docs.oracle.com/javase/specs/jvms/se17/html/jvms-4.html#jvms-4.3.3 Java Virtual Machine Specification, Java SE 17 Edition]'', 4.3.3. Method Descriptors &amp;lt;/ref&amp;gt; of the method is included, which consists of the descriptors for each of the method's parameters and the method's return type. The method parameters descriptors can be absent if there are no parameters in the method, but the return type descriptor must be present.&lt;br /&gt;
&lt;br /&gt;
The following are the matching descriptors for each type as seen in the method declaration:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Matching type descriptors&lt;br /&gt;
! Descriptor&lt;br /&gt;
! Source form&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Z&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;boolean&amp;lt;/code&amp;gt; || a &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; value&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;B&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;byte&amp;lt;/code&amp;gt; || a 8-bit signed number&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;S&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt; || a 16-bit signed number&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;C&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;char&amp;lt;/code&amp;gt; || a Unicode character code point in UTF-16&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; || a 32-bit signed number&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;F&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt; || a single-precision floating-point value&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;J&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; || a 64-bit signed number&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;D&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;double&amp;lt;/code&amp;gt; || a double-precision floating-point value&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[''I''&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;''int''[]&amp;lt;/code&amp;gt; || one dimension of an array; this can be repeated, and must end with another descriptor other than an array&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;L''java/lang/Object'';&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;java.lang.Object&amp;lt;/code&amp;gt; || a reference type; the internal form of the class' binary name must be present (in the given example, the class referenced is &amp;lt;code&amp;gt;java.lang.Object&amp;lt;/code&amp;gt;). &lt;br /&gt;
Note that inner classes are separated using the &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; (dollar sign) character, such as &amp;lt;code&amp;gt;java/lang/System$Logger&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;V&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;void&amp;lt;/code&amp;gt; || a void or no-value return type; only available for the return type of a method descriptor&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Danger&lt;br /&gt;
|title=Wildcard access transformers&lt;br /&gt;
|A special type of access transformers called '''wildcard ATs''' (oftentimes referred to as '''shotgun ATs''' allows transforming the access modifier and finality of ''all'' fields or methods within a class.&lt;br /&gt;
&lt;br /&gt;
To use wildcard access transformers:&lt;br /&gt;
* for all methods within a class: &amp;lt;code&amp;gt;''&amp;lt;modifier&amp;gt;'' ''&amp;lt;class name&amp;gt;'' '''*()'''&amp;lt;/code&amp;gt;&lt;br /&gt;
* for all fields within a class: &amp;lt;code&amp;gt;''&amp;lt;modifier&amp;gt;'' ''&amp;lt;class name&amp;gt;'' '''*'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Modders should avoid using this in live code.''' Access transformers should always have the fewest and narrowest targets possible, and wildcard ATs violate this convention. Use of wildcard ATs may cause problems with both the ForgeGradle setup process. Wildcard ATs may be removed in a future update of the access transformer specification.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
The following are some examples of access transformer declarations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
# Makes public the ScreenConstructor class in MenuScreens&lt;br /&gt;
public net.minecraft.client.gui.screens.MenuScreens$ScreenConstructor&lt;br /&gt;
&lt;br /&gt;
# Makes protected the 'COLOR_WHITE' field in Gui&lt;br /&gt;
protected net.minecraft.client.gui.Gui f_168667_ # COLOR_WHITE&lt;br /&gt;
&lt;br /&gt;
# Makes protected and removes the final modifier from 'random' field in MinecraftServer&lt;br /&gt;
protected-f net.minecraft.server.MinecraftServer f_129758_ # random&lt;br /&gt;
&lt;br /&gt;
# Makes public the 'makeExecutor' method in Util,&lt;br /&gt;
# which accepts a String and returns an ExecutorService&lt;br /&gt;
public net.minecraft.Util m_137477_(Ljava/lang/String;)Ljava/util/concurrent/ExecutorService; # makeExecutor&lt;br /&gt;
&lt;br /&gt;
# Makes public the 'leastMostToIntArray' method in UUIDUtil,&lt;br /&gt;
# which accepts two longs and returns an int[]&lt;br /&gt;
public net.minecraft.core.UUIDUtil m_235872_(JJ)[I # leastMostToIntArray&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Access_Transformers&amp;diff=3287</id>
		<title>Access Transformers</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Access_Transformers&amp;diff=3287"/>
		<updated>2022-06-18T14:39:10Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update to 1.19&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Access transformers''' (abbreviated as ''ATs'') are declarations for modifying or transforming the access visibility or finality of a class member (classes, fields, methods). These declarations are parsed by a transformer and applied to classes using the ASM library, either modifying the class files on-disk or modifying the class bytes during runtime.&lt;br /&gt;
&lt;br /&gt;
The [https://github.com/MinecraftForge/AccessTransformers AccessTransformers] library provides a pluggable ModLauncher transformation service and a command-line application for applying access transformers on class bytes during runtime and on class files on-disk.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
Java provides the mechanism of '''access level modifiers''' (or ''access modifiers''), to modify the ''visibility'' of a member with the modifier to other classes. This is commonly used to hide fields and methods from other classes, such as instance fields for [[:wikipedia:Encapsulation (computer programming)|encapsulation]] or private methods which are part of the implementation of the class and not normally exposed to callers.&lt;br /&gt;
&lt;br /&gt;
A member can be declared with any of the modifier keywords &amp;lt;code&amp;gt;public&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;private&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;protected&amp;lt;/code&amp;gt; to set the access level of the member, or none of the keywords, which defaults to a ''package-private'' access level.&lt;br /&gt;
&lt;br /&gt;
The following table shows the different access levels and their modifiers, and what classes may access members with that access level:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
|+ Access levels&lt;br /&gt;
! Access modifier&lt;br /&gt;
! Within the same class&lt;br /&gt;
! Classes in the same package&lt;br /&gt;
! Subclasses&lt;br /&gt;
! All other classes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;public&amp;lt;/code&amp;gt;&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;protected&amp;lt;/code&amp;gt;&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
| style=&amp;quot;color:indianred&amp;quot; | '''No'''&lt;br /&gt;
|-&lt;br /&gt;
| ''no modifier''&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
| style=&amp;quot;color:indianred&amp;quot; | '''No'''&lt;br /&gt;
| style=&amp;quot;color:indianred&amp;quot; | '''No'''&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;private&amp;lt;/code&amp;gt;&lt;br /&gt;
| style=&amp;quot;color:limegreen&amp;quot; | '''Yes'''&lt;br /&gt;
| style=&amp;quot;color:indianred&amp;quot; | '''No'''&lt;br /&gt;
| style=&amp;quot;color:indianred&amp;quot; | '''No'''&lt;br /&gt;
| style=&amp;quot;color:indianred&amp;quot; | '''No'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, a field marked &amp;lt;code&amp;gt;protected&amp;lt;/code&amp;gt; cannot be accessed by a class in another package, but can be accessed by: any class within the same package, any subclass of the class (even if the subclass belongs to another package), and within the same class where the field is declared.&lt;br /&gt;
&lt;br /&gt;
Additionally to the access modifiers, there exists the &amp;lt;code&amp;gt;final&amp;lt;/code&amp;gt; keyword, which:&lt;br /&gt;
* on classes, prevents any subclassing of the class;&lt;br /&gt;
* on fields, marks it as being assignable only once during construction; and&lt;br /&gt;
* on methods, prevents any subclasses from overriding the method with their own implementation.&lt;br /&gt;
&lt;br /&gt;
Normally, Java programmers restrict access levels to be as restrictive as they need to be, controlling what is the effective publicly-available surface for the application. For example, a field may be declared as &amp;lt;code&amp;gt;private&amp;lt;/code&amp;gt; while providing setter and getter methods to access the field (a technique known as encapsulation).&lt;br /&gt;
&lt;br /&gt;
However, this convention of restricting access levels and marking members as &amp;lt;code&amp;gt;final&amp;lt;/code&amp;gt; where approriate presents a problem with modding Minecraft, because they restrict what parts of the game that modders can access or modify, usually without other means to access or modify them (such as setters and getters for fields).&lt;br /&gt;
&lt;br /&gt;
One solution is to use Java [[:wikipedia:reflection|reflection]] to reflectively access these fields and methods during runtime, but they suffer from some problems:&lt;br /&gt;
* Reflection is slower than regular method calls or field accesses, as certain optimizations done by the JVM cannot be applied.&amp;lt;ref&amp;gt;[https://docs.oracle.com/javase/tutorial/reflect/index.html The Java™ Tutorials: The Reflection API]: ''&amp;quot;Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.&amp;quot;''&amp;lt;/ref&amp;gt; This makes reflection unsuitable for performance-critical code, such as during rendering.&lt;br /&gt;
* Reflection cannot allow the modification of &amp;lt;code&amp;gt;final&amp;lt;/code&amp;gt; fields which are either marked &amp;lt;code&amp;gt;static&amp;lt;/code&amp;gt; or belong to a record class.&amp;lt;ref&amp;gt;[https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/lang/reflect/AccessibleObject.html#setAccessible(boolean) Java 16 javadocs] for &amp;lt;code&amp;gt;java.lang.reflect.AccessibleObject.setAccessible(boolean)&amp;lt;/code&amp;gt;&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Runtime reflection loses the benefit of compile-time type checks, which allows dangerous operations such as trying to set a field's value to an incompatible type.&lt;br /&gt;
* The use of reflection does not allow a class to extend a non-visible class.&lt;br /&gt;
&lt;br /&gt;
These problems are solved with the use of access transformers, which allow modification of the access modifiers of members such that they can be applied on class files on-disk to allow compiling against them, and applying the same transformer declarations on class bytes during runtime to allow classes which compiled against those transformed classes to work correctly.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
&lt;br /&gt;
To use access transformers in the development environment, ForgeGradle must be configured with the location of the access transformer configuration file (or files). Because FML is hardwired to look for the configuration file at &amp;lt;code&amp;gt;META-INF/accesstransformer.cfg&amp;lt;/code&amp;gt; within JAR files, it is recommended that the AT configuration file for the project be placed at the same location: within the resources folder of the main source set, or &amp;lt;code&amp;gt;src/main/resources/META-INF/accesstransformer.cfg&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To configure the location of the access transformer configuration file with ForgeGradle:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;gradle&amp;quot;&amp;gt;&lt;br /&gt;
minecraft { // Within the minecraft block&lt;br /&gt;
    // Configures FG to look at the given file path for the AT configuration file&lt;br /&gt;
    accessTransformer = file(&amp;quot;src/main/resources/META-INF/accesstransformer.cfg&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Access-transformers-uncomment-this-line-in-build-gradle.png|thumb|300px]]&lt;br /&gt;
&lt;br /&gt;
The Forge-provided mod development environment's buildscript contains the above line but commented out, as the MDK does not ship with an access transformer file. Users of the MDK can therefore uncomment out the above line and create the AT configuration file at the same location. &lt;br /&gt;
&lt;br /&gt;
Once the configuration file(s) has been added and everytime the contents or location of the file(s) changes, the developer should then refresh the Gradle nature/project in their IDE of choice for ForgeGradle to apply the access transformers to the compiled source. Each change to the access transformer configuration will trigger a full decompilation of the game.&lt;br /&gt;
&lt;br /&gt;
== Declarations ==&lt;br /&gt;
&lt;br /&gt;
Access transformers are declared line-by-line in configuration files, which are then parsed by ForgeGradle in the development environment and by FML in the production or end-user environment.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt; character and any content after that up to the end of the line is considered a comment, and will be ignored by the parser. Any lines which are either empty or consist of only whitespace or comments are ignored.&lt;br /&gt;
&lt;br /&gt;
An access transformer declaration has three different variations, depending on the target to be transformed:&lt;br /&gt;
&lt;br /&gt;
* for '''classes''': &amp;lt;code&amp;gt;''&amp;lt;modifier&amp;gt;'' ''&amp;lt;class name&amp;gt;''&amp;lt;/code&amp;gt;&lt;br /&gt;
* for '''methods''': &amp;lt;code&amp;gt;''&amp;lt;modifier&amp;gt;'' ''&amp;lt;class name&amp;gt;'' ''&amp;lt;method name&amp;gt;'''''('''''[parameter descriptors]''''')'''''&amp;amp;lt;return descriptor&amp;gt;''&amp;lt;/code&amp;gt;&lt;br /&gt;
* for '''fields''': &amp;lt;code&amp;gt;''&amp;lt;modifier&amp;gt;'' ''&amp;lt;class name&amp;gt;'' ''&amp;lt;field name&amp;gt;''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The modifier consists of one of the following words:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;public&amp;lt;/code&amp;gt; for the ''public'' access level (denoted by the modifier keyword of the same name)&lt;br /&gt;
* &amp;lt;code&amp;gt;protected&amp;lt;/code&amp;gt; for the ''protected'' access level (denoted by the modifier keyword of the same name)&lt;br /&gt;
* &amp;lt;code&amp;gt;default&amp;lt;/code&amp;gt; for the ''package-private'' access level (denoted by the absence of an access modifier keyword)&lt;br /&gt;
* &amp;lt;code&amp;gt;private&amp;lt;/code&amp;gt; for the ''private'' access level (denoted by the modifier keyword of the same name)&lt;br /&gt;
* For any of the preceding words, the &amp;lt;code&amp;gt;-f&amp;lt;/code&amp;gt; suffix removes the &amp;lt;code&amp;gt;final&amp;lt;/code&amp;gt; modifier, while the &amp;lt;code&amp;gt;+f&amp;lt;/code&amp;gt; suffix adds the modifier.&lt;br /&gt;
&lt;br /&gt;
The class name is the fully qualified name of the class, using &amp;lt;code&amp;gt;.&amp;lt;/code&amp;gt; (dots) to separate between (sub)packages and classes (for example, &amp;lt;code&amp;gt;java.lang.Object&amp;lt;/code&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
For methods, the method descriptor&amp;lt;ref&amp;gt;''[https://docs.oracle.com/javase/specs/jvms/se16/html/jvms-4.html#jvms-4.3.3 Java Virtual Machine Specification, Java SE 16 Edition]'', 4.3.3. Method Descriptors &amp;lt;/ref&amp;gt; of the method is included, which consists of the descriptors for each of the method's parameters and the method's return type. The method parameters descriptors can be absent if there are no parameters in the method, but the return type descriptor must be present.&lt;br /&gt;
&lt;br /&gt;
The following are the matching descriptors for each type as seen in the method declaration:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Matching type descriptors&lt;br /&gt;
! Descriptor&lt;br /&gt;
! Source form&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Z&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;boolean&amp;lt;/code&amp;gt; || a &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; value&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;B&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;byte&amp;lt;/code&amp;gt; || a 8-bit signed number&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;S&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;short&amp;lt;/code&amp;gt; || a 16-bit signed number&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;C&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;char&amp;lt;/code&amp;gt; || a Unicode character code point in UTF-16&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;I&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt; || a 32-bit signed number&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;F&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;float&amp;lt;/code&amp;gt; || a single-precision floating-point value&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;J&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; || a 64-bit signed number&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;D&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;double&amp;lt;/code&amp;gt; || a double-precision floating-point value&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;[''I''&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;''int''[]&amp;lt;/code&amp;gt; || one dimension of an array; this can be repeated, and must end with another descriptor other than an array&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;L''java/lang/Object'';&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;java.lang.Object&amp;lt;/code&amp;gt; || a reference type; the internal form of the class' binary name must be present (in the given example, the class referenced is &amp;lt;code&amp;gt;java.lang.Object&amp;lt;/code&amp;gt;). &lt;br /&gt;
Note that inner classes are separated using the &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; (dollar sign) character, such as &amp;lt;code&amp;gt;java/lang/System$Logger&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;V&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;void&amp;lt;/code&amp;gt; || a void or no-value return type; only available for the return type of a method descriptor&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Danger&lt;br /&gt;
|title=Wildcard access transformers&lt;br /&gt;
|A special type of access transformers called '''wildcard ATs''' (oftentimes referred to as '''shotgun ATs''' allows transforming the access modifier and finality of ''all'' fields or methods within a class.&lt;br /&gt;
&lt;br /&gt;
To use wildcard access transformers:&lt;br /&gt;
* for all methods within a class: &amp;lt;code&amp;gt;''&amp;lt;modifier&amp;gt;'' ''&amp;lt;class name&amp;gt;'' '''*()'''&amp;lt;/code&amp;gt;&lt;br /&gt;
* for all fields within a class: &amp;lt;code&amp;gt;''&amp;lt;modifier&amp;gt;'' ''&amp;lt;class name&amp;gt;'' '''*'''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Modders should avoid using this in live code.''' Access transformers should always have the fewest and narrowest targets possible, and wildcard ATs violate this convention. Use of wildcard ATs may cause problems with both the ForgeGradle setup process. Wildcard ATs may be removed in a future update of the access transformer specification.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
The following are some examples of access transformer declarations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
# Makes public the ScreenConstructor class in MenuScreens&lt;br /&gt;
public net.minecraft.client.gui.screens.MenuScreens$ScreenConstructor&lt;br /&gt;
&lt;br /&gt;
# Makes protected the 'COLOR_WHITE' field in Gui&lt;br /&gt;
protected net.minecraft.client.gui.Gui f_168667_ # COLOR_WHITE&lt;br /&gt;
&lt;br /&gt;
# Makes protected and removes the final modifier from 'random' field in MinecraftServer&lt;br /&gt;
protected-f net.minecraft.server.MinecraftServer f_129758_ # random&lt;br /&gt;
&lt;br /&gt;
# Makes public the 'makeExecutor' method in Util,&lt;br /&gt;
# which accepts a String and returns an ExecutorService&lt;br /&gt;
public net.minecraft.Util m_137477_(Ljava/lang/String;)Ljava/util/concurrent/ExecutorService; # makeExecutor&lt;br /&gt;
&lt;br /&gt;
# Makes public the 'leastMostToIntArray' method in UUIDUtil,&lt;br /&gt;
# which accepts two longs and returns an int[]&lt;br /&gt;
public net.minecraft.core.UUIDUtil m_235872_(JJ)[I # leastMostToIntArray&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Dependencies&amp;diff=3286</id>
		<title>Dependencies</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Dependencies&amp;diff=3286"/>
		<updated>2022-06-18T14:32:04Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update to 1.19&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A '''dependency''' is the reliance of a piece of software on another piece of software. In the context of Minecraft Forge, it is a mod or library which another mod relies or ''depends'' on.&lt;br /&gt;
&lt;br /&gt;
Dependencies are declared in three ways:&lt;br /&gt;
* The &amp;lt;code&amp;gt;dependencies&amp;lt;/code&amp;gt; block in a Gradle buildscript defines compile-time and runtime dependencies, which are used by the build system and compiler when building or running the mod in the development environment.&lt;br /&gt;
* The act of using classes, fields, and methods from a library creates a dependency on the library in the compiled binaries. The library may be an explicitly declared dependency, or a dependency of an explicitly declared dependency (such as the Guava libraries that Minecraft depends on).&lt;br /&gt;
* [[Proper_Mod_Structuring#Dependency_Configurations|Dependency configurations]] are declared in the &amp;lt;tt&amp;gt;mods.toml&amp;lt;/tt&amp;gt; metafile, which is then checked by Forge on runtime on whether they are satisfied.&lt;br /&gt;
&lt;br /&gt;
== Hard and Soft Dependencies ==&lt;br /&gt;
There are two types of mod dependencies: hard dependencies, and soft dependencies.&lt;br /&gt;
&lt;br /&gt;
A '''hard dependency''' is a dependency where the dependent mod requires that the dependency is present. This may be in the form of a code dependency, wherein the JVM will crash due to the missing class, field, or method from the dependency, or it may be in the form of a dependency configuration which mandates that the dependency is present.&lt;br /&gt;
&lt;br /&gt;
Hard dependencies should be declared using a dependency configuration to allow the Forge Mod Loader to detect the missing dependency and gracefully handle it by showing an error screen to the user, rather than the JVM crashing with a non-user-friendly exception message.&lt;br /&gt;
&lt;br /&gt;
A '''soft dependency''' is a dependency where the dependent mod does not require the dependency is present, but extra features or compatibility is added in the case of the dependency being present. This often takes the form of cross-mod compatibility features, where a mod soft-depends on another mod or the mod's API.&lt;br /&gt;
&lt;br /&gt;
Soft dependencies usually take the form of isolated code dependencies, where the code that depends on the soft-dependency is isolated from the rest of the mod until the soft-dependency is detected as being present.&lt;br /&gt;
&lt;br /&gt;
== Declaring Dependencies ==&lt;br /&gt;
A mod declares a dependency on a mod or library through Gradle, through the &amp;lt;code&amp;gt;dependencies&amp;lt;/code&amp;gt; block.&amp;lt;ref&amp;gt;[https://docs.gradle.org/7.4.2/userguide/declaring_dependencies.html Gradle User Guide: ''Declaring dependencies'']&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, to declare a dependency on the &amp;lt;code&amp;gt;net:minecraftforge:eventbus:5.0.3&amp;lt;/code&amp;gt; library from the &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; source set:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;gradle&amp;quot;&amp;gt;&lt;br /&gt;
dependencies {&lt;br /&gt;
    // 'implementation' is for the main source set&lt;br /&gt;
    implementation &amp;quot;net.minecraftforge:eventbus:5.0.3&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Tip|ForgeGradle automatically adds the [https://files.minecraftforge.net/maven/ Forge Maven] and [https://maven.apache.org/repository/ Maven Central] repositories to projects. If a dependency is not present in these (such as dependencies on other mods), the repository containing the dependency must be declared in the &amp;lt;code&amp;gt;repositories&amp;lt;/code&amp;gt; block of the Gradle buildscript.&amp;lt;ref&amp;gt;[https://docs.gradle.org/current/userguide/declaring_repositories.html Gradle User Guide: ''Declaring repositories'']&amp;lt;/ref&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
=== Deobfuscating Dependencies ===&lt;br /&gt;
Mods (and libraries which use Minecraft code) are usually released as an SRG-obfuscated JAR, which prevents their direct use in development environments due to mismatch between SRG names from the mod/library and the MCP/mapped names in the development environment.&lt;br /&gt;
&lt;br /&gt;
These mods/libraries must be deobfuscated to the development environment's mappings first. This is done using the &amp;lt;code&amp;gt;fg.deobf&amp;lt;/code&amp;gt; function, which creates a dependency which is dynamically remapped to the local environment's mappings.&lt;br /&gt;
&lt;br /&gt;
For example, to declare a dependency on the &amp;lt;code&amp;gt;mezz.jei:jei-1.16.5:7.6.1.75&amp;lt;/code&amp;gt; library (which is obfuscated):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;gradle&amp;quot;&amp;gt;&lt;br /&gt;
dependencies {&lt;br /&gt;
    implementation fg.deobf(&amp;quot;mezz.jei:jei-1.16.5:7.6.1.75&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Flat Directory Repositories ===&lt;br /&gt;
There are occasions where it is needed to temporarily add a dependency on a JAR file that is not present in a Maven repository, such as to add a mod which adds some developer tools during runtime. Gradle allows declaring '''flat directory repositories''', which use a local directory as a simplified repository.&amp;lt;ref&amp;gt;[https://docs.gradle.org/current/userguide/declaring_repositories.html#sub:flat_dir_resolver Gradle User Guide: ''Flat directory repository'']&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A flat directory repository is declared using a &amp;lt;code&amp;gt;flatDir&amp;lt;/code&amp;gt; block within the &amp;lt;code&amp;gt;repositories&amp;lt;/code&amp;gt; block, and specifying directories using &amp;lt;code&amp;gt;dirs&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;gradle&amp;quot;&amp;gt;&lt;br /&gt;
repositories {&lt;br /&gt;
    flatDir {&lt;br /&gt;
        dirs 'lib'&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When a dependency artifact is searched for in a flat directory repository, it will look for the following files in order (&amp;lt;code&amp;gt;''ext''&amp;lt;/code&amp;gt; defaults to &amp;lt;code&amp;gt;jar&amp;lt;/code&amp;gt;)&amp;lt;ref&amp;gt;[https://github.com/gradle/gradle/blob/v7.4.2/subprojects/core-api/src/main/java/org/gradle/api/artifacts/repositories/FlatDirectoryArtifactRepository.java gradle/gradle; tag v7.4.2; org.gradle.api.artifacts.repositories.FlatDirectoryArtifactRepository]&amp;lt;/ref&amp;gt;:&lt;br /&gt;
* &amp;lt;code&amp;gt;''&amp;lt;artifact&amp;gt;''-''&amp;lt;version&amp;gt;''.''&amp;lt;ext&amp;gt;''&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;''&amp;lt;artifact&amp;gt;''-''&amp;lt;version&amp;gt;''-''&amp;lt;classifier&amp;gt;''.''&amp;lt;ext&amp;gt;''&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;''&amp;lt;artifact&amp;gt;''.''&amp;lt;ext&amp;gt;''&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;''&amp;lt;artifact&amp;gt;''-''&amp;lt;classifier&amp;gt;''.''&amp;lt;ext&amp;gt;''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, for the dependency &amp;lt;code&amp;gt;org.junit.jupiter:junit-jupiter-api:5.7.2&amp;lt;/code&amp;gt;, it will first search for &amp;lt;code&amp;gt;junit-jupiter-api-5.7.2.jar&amp;lt;/code&amp;gt; then &amp;lt;code&amp;gt;junit-jupiter-api.jar&amp;lt;/code&amp;gt;. The group ID in the dependency descriptor must be present (due to the presence of non-flat directory repositories as added by ForgeGradle), but it will always be ignored.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning&lt;br /&gt;
|Flat directory repositories should ''only'' be used temporarily in a local environment, and not used to include a required dependency for your project. For a actual dependency used by your mod, use a remote Maven repository holding the artifact.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== CurseMaven ===&lt;br /&gt;
A commonly used alternative is [https://www.cursemaven.com/ CurseMaven](credits to Wyn Price) which allows you to depend on any file uploaded to [https://www.curseforge.com/minecraft/mc-mods/ CurseForge].&lt;br /&gt;
&lt;br /&gt;
First add the CurseMaven Repository within the &amp;lt;code&amp;gt;repositories&amp;lt;/code&amp;gt; block:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;gradle&amp;quot;&amp;gt;&lt;br /&gt;
repositories {&lt;br /&gt;
    maven {&lt;br /&gt;
        url 'https://www.cursemaven.com'&lt;br /&gt;
        // FG4: It's recommended to uncomment the following block&lt;br /&gt;
        // content {&lt;br /&gt;
        //     includeGroup &amp;quot;curse.maven&amp;quot;&lt;br /&gt;
        // }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then declare a dependency using the following format:&lt;br /&gt;
* &amp;lt;code&amp;gt;''curse.maven'':''&amp;lt;description&amp;gt;-&amp;lt;project-id&amp;gt;'':''&amp;lt;file-id&amp;gt;''&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As an example, the dependency &amp;lt;code&amp;gt;curse.maven:jei-238222:3295418 &amp;lt;/code&amp;gt;, would resolve to [https://www.curseforge.com/minecraft/mc-mods/jei/files/3295418 this file] on CurseForge.&lt;br /&gt;
&lt;br /&gt;
For more information on usage, visit [https://www.cursemaven.com/ CurseMaven]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=User:ChampionAsh5357/Sandbox/Fluids_API&amp;diff=3279</id>
		<title>User:ChampionAsh5357/Sandbox/Fluids API</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=User:ChampionAsh5357/Sandbox/Fluids_API&amp;diff=3279"/>
		<updated>2022-06-15T12:23:46Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Add some examples&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In Forge 41.0.28, the Fluid API had been completely overhauled. These changes expanded the system to allow for custom physics logic and additional behavior not tied directly to the water and lava tags. This guide will go through all the changes and additions that Fluids now provide for you to use.&lt;br /&gt;
&lt;br /&gt;
An example of the new fluid system can be found in the [https://github.com/MinecraftForge/MinecraftForge/blob/1.19.x/src/test/java/net/minecraftforge/debug/fluid/FluidTypeTest.java test mod].&lt;br /&gt;
&lt;br /&gt;
== Quick Guide ==&lt;br /&gt;
&lt;br /&gt;
This is a quick guide representing the one to one conversions that the Fluid API changed&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; (This is a Forge Registry ''forge:fluid_type'')&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#BUCKET_VOLUME&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#BUCKET_VOLUME&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getBucket&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getBucket&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getBlock&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getBlockForFluidState&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getStateForPlacement&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getStateForPlacement&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#canBePlacedInWorld&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#canBePlacedInLevel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#isLighterThanAir&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#isLighterThanAir&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#doesVaporize&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#isVaporizedOnPlacement&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#vaporize&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#onVaporize&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getDisplayName(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getDescription(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getTranslationKey(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getDescriptionId(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getTranslationKey&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getDescriptionId&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getLuminosity&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getLightLevel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getDensity&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getDensity&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getTemperature&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getTemperature&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getViscosity&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getViscosity&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#isGaseous&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Tags$Fluids#GASEOUS&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getRarity&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getRarity&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getColor&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getColorTint&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getStillTexture&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getStillTexture&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getFlowingTexture&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getFlowingTexture&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getOverlayTexture&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getOverlayTexture&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getFillSound&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getSound(SoundActions.BUCKET_FILL)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getEmptySound&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getSound(SoundActions.BUCKET_EMPTY)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getLuminosity(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getLightLevel(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getDensity(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getDensity(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getTemperature(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getTemperature(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getViscosity(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getViscosity(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#isGaseous(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; REMOVED&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getColor(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getColorTint(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getStillTexture(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getStillTexture(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getFlowingTexture(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getFlowingTexture(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getFillSound(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getSound(FluidStack, SoundActions.BUCKET_FILL&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getEmptySound(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getSound(FluidStack, SoundActions.BUCKET_EMPTY)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getLuminosity(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getLightLevel(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getDensity(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getDensity(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getTemperature(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getTemperature(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getViscosity(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getViscosity(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#isGaseous(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; REMOVED&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getRarity(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; REMOVED&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getColor(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getColorTint(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getStillTexture(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getStillTexture(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getFlowingTexture(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getFlowingTexture(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getFillSound(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getSound(Player, BlockGetter, BlockPos, SoundActions.BUCKET_FILL)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getEmptySound(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getSound(Player, BlockGetter, BlockPos, SoundActions.BUCKET_EMPTY)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getTextures&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getTextures&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes$Builder&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType$Properties&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;IForgeBlock#getAiPathNodeType&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IForgeBlock#getBlockPathType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;IForgeEntity#canBeRiddenInWater&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IForgeEntity#canBeRiddenUnderFluidType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;IForgeFluid#isEntityInside&amp;lt;/code&amp;gt; -&amp;gt; REMOVED&lt;br /&gt;
* &amp;lt;code&amp;gt;IForgeFluid#isAABBInsideMaterial&amp;lt;/code&amp;gt; -&amp;gt; REMOVED&lt;br /&gt;
* &amp;lt;code&amp;gt;IForgeFluid#getAttributes&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IForgeFluid#getFluidType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;IForgeFluidState#isEntityInside&amp;lt;/code&amp;gt; -&amp;gt; REMOVED&lt;br /&gt;
* &amp;lt;code&amp;gt;ForgeFlowingFluid$Properties(Fluid, Fluid, FluidAttributes)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;ForgeFlowingFluid$Properties(FluidType, Fluid, Fluid)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ForgeFlowingFluid#canMultiply&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#canConvertToSource(FluidState, LevelReader, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Vanilla Breaking Change: No Physics in Tags ==&lt;br /&gt;
&lt;br /&gt;
One of the largest changes within the Fluid API is that Fluid Tags no longer control the physics of fluids. To account for this, a different unifying object which can represent any group of fluids must be chosen. After much consideration, this became &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt;, which replaced &amp;lt;code&amp;gt;FluidAttributes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Removal of FluidAttributes ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FluidAttributes&amp;lt;/code&amp;gt; has been completely removed with most of its logic being delegated to either &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;IFluidTypeRenderProperties&amp;lt;/code&amp;gt; for rendering. The object itself wasn't unique and tended to be reconstructed whenever referenced. As such, it was removed in favor of a more singleton approach.&lt;br /&gt;
&lt;br /&gt;
== FluidType ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; replaces &amp;lt;code&amp;gt;FluidAttributes&amp;lt;/code&amp;gt;. All fluids must override &amp;lt;code&amp;gt;IForgeFluid#getFluidType&amp;lt;/code&amp;gt; similar to the previous &amp;lt;code&amp;gt;#getAttributes&amp;lt;/code&amp;gt;. Additionally, the &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; can be accessed from the fluid or fluid state for convenience.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
private static final DeferredRegister&amp;lt;Fluid&amp;gt; FLUIDS = DeferredRegister.create(ForgeRegistries.FLUIDS, ID);&lt;br /&gt;
&lt;br /&gt;
// TestFluid extends FlowingFluid&lt;br /&gt;
private static final RegistryObject&amp;lt;FlowingFluid&amp;gt; TEST_FLUID = FLUIDS.register(&amp;quot;test_fluid&amp;quot;, () -&amp;gt; new TestFluid() {&lt;br /&gt;
    @Override&lt;br /&gt;
    public FluidType getFluidType() {&lt;br /&gt;
        return TEST_FLUID_TYPE.get();&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; is a forge registry, and as such needs to be registered. If using &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt;, you must use the one that takes in the registry name and modid since the registry does not exist during mod construction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
private static final DeferredRegister&amp;lt;FluidType&amp;gt; FLUID_TYPES = DeferredRegister.create(ForgeRegistries.Keys.FLUID_TYPES, ID);&lt;br /&gt;
&lt;br /&gt;
private static final RegistryObject&amp;lt;FluidType&amp;gt; TEST_FLUID_TYPE = FLUID_TYPES.register(&amp;quot;test_fluid&amp;quot;, () -&amp;gt; new FluidType(FluidType.Properties.create()));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== isVaporizedOnPlacement ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FluidType#isVaporizedOnPlacement&amp;lt;/code&amp;gt; has now been expanded to allow for vaporization to occur outside of only ultra warm dimensions. To do so, simply override the method.&lt;br /&gt;
&lt;br /&gt;
== IFluidTypeRenderProperties ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;IFluidTypeRenderProperties&amp;lt;/code&amp;gt; contains all rendering related logic to fluids. This includes the color tint, still texture, flowing texture, and overlay texture. Note that the still texture and flowing texture must be specified by overriding &amp;lt;code&amp;gt;#getStillTexture&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;#getFlowingTexture&amp;lt;/code&amp;gt; respectively.&lt;br /&gt;
&lt;br /&gt;
== Modified Accessors ==&lt;br /&gt;
&lt;br /&gt;
All properties in &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;IFluidTypeRenderProperties&amp;lt;/code&amp;gt; have either an entity, level, or stack based accessor attached to it. These provide context in question if the behavior of the fluid should change in relation to the entity its acting upon, the location of the fluid in the level, or the containing fluid stack respectively.&lt;br /&gt;
&lt;br /&gt;
There are some accessors with no parameters. These are typically because the use case may not be fully defined in every context that are available to the modder. They should not be used whenever possible as they may be removed in future releases once the context has been fully specified.&lt;br /&gt;
&lt;br /&gt;
== Chained Methods ==&lt;br /&gt;
&lt;br /&gt;
A good portion of the accessors in &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; are chained in some capacity. This means that modders who are using fluids from other mods can specify unique behavior without having to modify the fluid itself. Let's take two examples: &amp;lt;code&amp;gt;#canHydrate(Level Accessor)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;#supportsBoating&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;#canHydrate&amp;lt;/code&amp;gt; can be modified by the &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Fluid&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt;. This means that the &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; can define general behavior to use while the &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt; may define specific behavior for if it can be hydrated.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;#supportsBoating&amp;lt;/code&amp;gt; works similarly with &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Boat&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; can define in general if boats should work on it while a specific &amp;lt;code&amp;gt;Boat&amp;lt;/code&amp;gt; can determine whether it actually can float on the fluid.&lt;br /&gt;
&lt;br /&gt;
== Entity Pathing ==&lt;br /&gt;
&lt;br /&gt;
Entity pathing can now be specified for a given block or the underlying fluid using &amp;lt;code&amp;gt;IForgeBlock#getBlockPathType&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;IForgeBlock#getAdjacentBlockPathType&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;FluidType#getBlockPathType&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;FluidType#getAdjacentBlockPathType&amp;lt;/code&amp;gt;. For clarity, the regular block path type gets the raw type to be used if the adjacents are not specified. The adjacent path type specifically determines which one the entity will move to and will either default to &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WALKABLE&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;BLOCKED&amp;lt;/code&amp;gt; internally. Typically, the entity will pathfind to the smallest positive malus of the type, where negative numbers are considered intraversable. Additional types can be created using &amp;lt;code&amp;gt;BlockPathTypes#create&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== IForgeEntity ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;IForgeEntity&amp;lt;/code&amp;gt; now contains many additional commands to handle fluid physics logic. These include the height, which fluid the entity's eyes are in, and if an entity is in a fluid type. All of these methods are properly documented in the extension. Note that these replace their vanilla counterparts and should be used instead.&lt;br /&gt;
&lt;br /&gt;
== IForgeLivingEntity ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;IForgeLivingEntity&amp;lt;/code&amp;gt; contains two unique fluid logic handlers: how an entity &amp;quot;jumps&amp;quot; in a fluid, and how they &amp;quot;sink&amp;quot;. These methods can currently only be overridden on an entity and not by the &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== SoundAction ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SoundAction&amp;lt;/code&amp;gt; is the abstracted sound manager for defining which sound to play in a given context. It works exactly like &amp;lt;code&amp;gt;ToolAction&amp;lt;/code&amp;gt; where it simply defines a unique name that performs a given action. A new action can be created using &amp;lt;code&amp;gt;SoundAction#get&amp;lt;/code&amp;gt;. Vanilla actions are defined within &amp;lt;code&amp;gt;SoundActions&amp;lt;/code&amp;gt; (filling/empty bucket, vaporizing).&lt;br /&gt;
&lt;br /&gt;
== Fluid Interactions ==&lt;br /&gt;
&lt;br /&gt;
Fluid interactions are handled by the &amp;lt;code&amp;gt;FluidInteractionRegistry&amp;lt;/code&amp;gt;. Interactions define the behavior a block should handle in all directions besides down. The down direction must be defined by the fluid in &amp;lt;code&amp;gt;FlowingFluid#spreadTo&amp;lt;/code&amp;gt;, and will not be considered in this registry. An interaction can be registered using &amp;lt;code&amp;gt;#addInteraction&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;FMLCommonSetupEvent&amp;lt;/code&amp;gt; by specifying the source of the interaction (which is typically the fluid being replaced), and the interaction information which defines the conditions of when the interaction should occur and what the interaction should do.&lt;br /&gt;
&lt;br /&gt;
private void commonSetup(FMLCommonSetupEvent event) {&lt;br /&gt;
    // Test Fluid + Lava (source/flowing) -&amp;gt; Gold Block (Test fluid source/flowing gets replaced)&lt;br /&gt;
    FluidInteractionRegistry.addInteraction(TEST_FLUID_TYPE.get(), new FluidInteractionRegistry.InteractionInformation(ForgeMod.LAVA_TYPE.get(), Blocks.GOLD_BLOCK.defaultBlockState()));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
== Gaseous Fluids ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;Fluid&amp;lt;/code&amp;gt; is considered gaseous at room temperature if it is in the &amp;lt;code&amp;gt;forge:gaseous&amp;lt;/code&amp;gt; tag. This is typically correlated with a negative density.&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=User:ChampionAsh5357/Sandbox/Fluids_API&amp;diff=3276</id>
		<title>User:ChampionAsh5357/Sandbox/Fluids API</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=User:ChampionAsh5357/Sandbox/Fluids_API&amp;diff=3276"/>
		<updated>2022-06-15T01:43:11Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Quick primer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In Forge 41.0.28, the Fluid API had been completely overhauled. These changes expanded the system to allow for custom physics logic and additional behavior not tied directly to the water and lava tags. This guide will go through all the changes and additions that Fluids now provide for you to use.&lt;br /&gt;
&lt;br /&gt;
== Quick Guide ==&lt;br /&gt;
&lt;br /&gt;
This is a quick guide representing the one to one conversions that the Fluid API changed&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; (This is a Forge Registry ''forge:fluid_type'')&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#BUCKET_VOLUME&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#BUCKET_VOLUME&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getBucket&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getBucket&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getBlock&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getBlockForFluidState&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getStateForPlacement&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getStateForPlacement&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#canBePlacedInWorld&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#canBePlacedInLevel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#isLighterThanAir&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#isLighterThanAir&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#doesVaporize&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#isVaporizedOnPlacement&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#vaporize&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#onVaporize&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getDisplayName(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getDescription(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getTranslationKey(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getDescriptionId(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getTranslationKey&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getDescriptionId&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getLuminosity&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getLightLevel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getDensity&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getDensity&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getTemperature&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getTemperature&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getViscosity&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getViscosity&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#isGaseous&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Tags$Fluids#GASEOUS&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getRarity&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getRarity&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getColor&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getColorTint&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getStillTexture&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getStillTexture&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getFlowingTexture&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getFlowingTexture&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getOverlayTexture&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getOverlayTexture&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getFillSound&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getSound(SoundActions.BUCKET_FILL)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getEmptySound&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getSound(SoundActions.BUCKET_EMPTY)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getLuminosity(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getLightLevel(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getDensity(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getDensity(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getTemperature(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getTemperature(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getViscosity(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getViscosity(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#isGaseous(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; REMOVED&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getColor(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getColorTint(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getStillTexture(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getStillTexture(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getFlowingTexture(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getFlowingTexture(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getFillSound(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getSound(FluidStack, SoundActions.BUCKET_FILL&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getEmptySound(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getSound(FluidStack, SoundActions.BUCKET_EMPTY)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getLuminosity(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getLightLevel(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getDensity(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getDensity(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getTemperature(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getTemperature(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getViscosity(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getViscosity(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#isGaseous(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; REMOVED&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getRarity(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; REMOVED&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getColor(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getColorTint(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getStillTexture(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getStillTexture(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getFlowingTexture(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getFlowingTexture(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getFillSound(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getSound(Player, BlockGetter, BlockPos, SoundActions.BUCKET_FILL)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getEmptySound(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getSound(Player, BlockGetter, BlockPos, SoundActions.BUCKET_EMPTY)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getTextures&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getTextures&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes$Builder&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType$Properties&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;IForgeBlock#getAiPathNodeType&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IForgeBlock#getBlockPathType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;IForgeEntity#canBeRiddenInWater&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IForgeEntity#canBeRiddenUnderFluidType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;IForgeFluid#isEntityInside&amp;lt;/code&amp;gt; -&amp;gt; REMOVED&lt;br /&gt;
* &amp;lt;code&amp;gt;IForgeFluid#isAABBInsideMaterial&amp;lt;/code&amp;gt; -&amp;gt; REMOVED&lt;br /&gt;
* &amp;lt;code&amp;gt;IForgeFluid#getAttributes&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IForgeFluid#getFluidType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;IForgeFluidState#isEntityInside&amp;lt;/code&amp;gt; -&amp;gt; REMOVED&lt;br /&gt;
* &amp;lt;code&amp;gt;ForgeFlowingFluid$Properties(Fluid, Fluid, FluidAttributes)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;ForgeFlowingFluid$Properties(FluidType, Fluid, Fluid)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ForgeFlowingFluid#canMultiply&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#canConvertToSource(FluidState, LevelReader, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Vanilla Breaking Change: No Physics in Tags ==&lt;br /&gt;
&lt;br /&gt;
One of the largest changes within the Fluid API is that Fluid Tags no longer control the physics of fluids. To account for this, a different unifying object which can represent any group of fluids must be chosen. After much consideration, this became &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt;, which replaced &amp;lt;code&amp;gt;FluidAttributes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Removal of FluidAttributes ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FluidAttributes&amp;lt;/code&amp;gt; has been completely removed with most of its logic being delegated to either &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;IFluidTypeRenderProperties&amp;lt;/code&amp;gt; for rendering. The object itself wasn't unique and tended to be reconstructed whenever referenced. As such, it was removed in favor of a more singleton approach.&lt;br /&gt;
&lt;br /&gt;
== FluidType ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; replaces &amp;lt;code&amp;gt;FluidAttributes&amp;lt;/code&amp;gt;. All fluids must override &amp;lt;code&amp;gt;IForgeFluid#getFluidType&amp;lt;/code&amp;gt; similar to the previous &amp;lt;code&amp;gt;#getAttributes&amp;lt;/code&amp;gt;. Additionally, the &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; can be accessed from the fluid or fluid state for convenience.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; is a forge registry, and as such needs to be registered. If using &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt;, you must use the one that takes in the registry name and modid since the registry does not exist during mod construction.&lt;br /&gt;
&lt;br /&gt;
=== isVaporizedOnPlacement ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FluidType#isVaporizedOnPlacement&amp;lt;/code&amp;gt; has now been expanded to allow for vaporization to occur outside of only ultra warm dimensions. To do so, simply override the method.&lt;br /&gt;
&lt;br /&gt;
== IFluidTypeRenderProperties ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;IFluidTypeRenderProperties&amp;lt;/code&amp;gt; contains all rendering related logic to fluids. This includes the color tint, still texture, flowing texture, and overlay texture. Note that the still texture and flowing texture must be specified by overriding &amp;lt;code&amp;gt;#getStillTexture&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;#getFlowingTexture&amp;lt;/code&amp;gt; respectively.&lt;br /&gt;
&lt;br /&gt;
== Modified Accessors ==&lt;br /&gt;
&lt;br /&gt;
All properties in &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;IFluidTypeRenderProperties&amp;lt;/code&amp;gt; have either an entity, level, or stack based accessor attached to it. These provide context in question if the behavior of the fluid should change in relation to the entity its acting upon, the location of the fluid in the level, or the containing fluid stack respectively.&lt;br /&gt;
&lt;br /&gt;
There are some accessors with no parameters. These are typically because the use case may not be fully defined in every context that are available to the modder. They should not be used whenever possible as they may be removed in future releases once the context has been fully specified.&lt;br /&gt;
&lt;br /&gt;
== Chained Methods ==&lt;br /&gt;
&lt;br /&gt;
A good portion of the accessors in &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; are chained in some capacity. This means that modders who are using fluids from other mods can specify unique behavior without having to modify the fluid itself. Let's take two examples: &amp;lt;code&amp;gt;#canHydrate(Level Accessor)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;#supportsBoating&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;#canHydrate&amp;lt;/code&amp;gt; can be modified by the &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Fluid&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt;. This means that the &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; can define general behavior to use while the &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt; may define specific behavior for if it can be hydrated.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;#supportsBoating&amp;lt;/code&amp;gt; works similarly with &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Boat&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; can define in general if boats should work on it while a specific &amp;lt;code&amp;gt;Boat&amp;lt;/code&amp;gt; can determine whether it actually can float on the fluid.&lt;br /&gt;
&lt;br /&gt;
== Entity Pathing ==&lt;br /&gt;
&lt;br /&gt;
Entity pathing can now be specified for a given block or the underlying fluid using &amp;lt;code&amp;gt;IForgeBlock#getBlockPathType&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;IForgeBlock#getAdjacentBlockPathType&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;FluidType#getBlockPathType&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;FluidType#getAdjacentBlockPathType&amp;lt;/code&amp;gt;. For clarity, the regular block path type gets the raw type to be used if the adjacents are not specified. The adjacent path type specifically determines which one the entity will move to and will either default to &amp;lt;code&amp;gt;OPEN&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;WALKABLE&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;BLOCKED&amp;lt;/code&amp;gt; internally. Typically, the entity will pathfind to the smallest positive malus of the type, where negative numbers are considered intraversable. Additional types can be created using &amp;lt;code&amp;gt;BlockPathTypes#create&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== IForgeEntity ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;IForgeEntity&amp;lt;/code&amp;gt; now contains many additional commands to handle fluid physics logic. These include the height, which fluid the entity's eyes are in, and if an entity is in a fluid type. All of these methods are properly documented in the extension. Note that these replace their vanilla counterparts and should be used instead.&lt;br /&gt;
&lt;br /&gt;
== IForgeLivingEntity ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;IForgeLivingEntity&amp;lt;/code&amp;gt; contains two unique fluid logic handlers: how an entity &amp;quot;jumps&amp;quot; in a fluid, and how they &amp;quot;sink&amp;quot;. These methods can currently only be overridden on an entity and not by the &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== SoundAction ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SoundAction&amp;lt;/code&amp;gt; is the abstracted sound manager for defining which sound to play in a given context. It works exactly like &amp;lt;code&amp;gt;ToolAction&amp;lt;/code&amp;gt; where it simply defines a unique name that performs a given action. A new action can be created using &amp;lt;code&amp;gt;SoundAction#get&amp;lt;/code&amp;gt;. Vanilla actions are defined within &amp;lt;code&amp;gt;SoundActions&amp;lt;/code&amp;gt; (filling/empty bucket, vaporizing).&lt;br /&gt;
&lt;br /&gt;
== Fluid Interactions ==&lt;br /&gt;
&lt;br /&gt;
Fluid interactions are handled by the &amp;lt;code&amp;gt;FluidInteractionRegistry&amp;lt;/code&amp;gt;. Interactions define the behavior a block should handle in all directions besides down. The down direction must be defined by the fluid in &amp;lt;code&amp;gt;FlowingFluid#spreadTo&amp;lt;/code&amp;gt;, and will not be considered in this registry. An interaction can be registered using &amp;lt;code&amp;gt;#addInteraction&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;FMLCommonSetupEvent&amp;lt;/code&amp;gt; by specifying the source of the interaction (which is typically the fluid being replaced), and the interaction information which defines the conditions of when the interaction should occur and what the interaction should do.&lt;br /&gt;
&lt;br /&gt;
== Gaseous Fluids ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;Fluid&amp;lt;/code&amp;gt; is considered gaseous at room temperature if it is in the &amp;lt;code&amp;gt;forge:gaseous&amp;lt;/code&amp;gt; tag. This is typically correlated with a negative density.&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=User:ChampionAsh5357/Sandbox/Fluids_API&amp;diff=3271</id>
		<title>User:ChampionAsh5357/Sandbox/Fluids API</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=User:ChampionAsh5357/Sandbox/Fluids_API&amp;diff=3271"/>
		<updated>2022-06-14T23:06:27Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Start Fluid API writing.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In Forge 41.0.28, the Fluid API had been completely overhauled. These changes expanded the system to allow for custom physics logic and additional behavior not tied directly to the water and lava tags. This guide will go through all the changes and additions that Fluids now provide for you to use.&lt;br /&gt;
&lt;br /&gt;
== Quick Guide ==&lt;br /&gt;
&lt;br /&gt;
This is a quick guide representing the one to one conversions that the Fluid API changed&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType&amp;lt;/code&amp;gt; (This is a Forge Registry ''forge:fluid_type'')&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#BUCKET_VOLUME&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#BUCKET_VOLUME&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getBucket&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getBucket&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getBlock&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getBlockForFluidState&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getStateForPlacement&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getStateForPlacement&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#canBePlacedInWorld&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#canBePlacedInLevel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#isLighterThanAir&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#isLighterThanAir&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#doesVaporize&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#isVaporizedOnPlacement&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#vaporize&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#onVaporize&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getDisplayName(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getDescription(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getTranslationKey(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getDescriptionId(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getTranslationKey&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getDescriptionId&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getLuminosity&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getLightLevel&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getDensity&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getDensity&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getTemperature&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getTemperature&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getViscosity&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getViscosity&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#isGaseous&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Tags$Fluids#GASEOUS&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getRarity&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getRarity&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getColor&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getColorTint&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getStillTexture&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getStillTexture&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getFlowingTexture&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getFlowingTexture&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getOverlayTexture&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getOverlayTexture&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getFillSound&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getSound(SoundActions.BUCKET_FILL)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getEmptySound&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getSound(SoundActions.BUCKET_EMPTY)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getLuminosity(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getLightLevel(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getDensity(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getDensity(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getTemperature(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getTemperature(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getViscosity(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getViscosity(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#isGaseous(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; REMOVED&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getColor(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getColorTint(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getStillTexture(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getStillTexture(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getFlowingTexture(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getFlowingTexture(FluidStack)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getFillSound(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getSound(FluidStack, SoundActions.BUCKET_FILL&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getEmptySound(FluidStack)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getSound(FluidStack, SoundActions.BUCKET_EMPTY)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getLuminosity(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getLightLevel(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getDensity(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getDensity(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getTemperature(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getTemperature(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getViscosity(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getViscosity(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#isGaseous(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; REMOVED&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getRarity(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; REMOVED&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getColor(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getColorTint(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getStillTexture(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getStillTexture(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getFlowingTexture(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getFlowingTexture(FluidState, BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getFillSound(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getSound(Player, BlockGetter, BlockPos, SoundActions.BUCKET_FILL)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getEmptySound(BlockAndTintGetter, BlockPos)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#getSound(Player, BlockGetter, BlockPos, SoundActions.BUCKET_EMPTY)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes#getTextures&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IFluidTypeRenderProperties#getTextures&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FluidAttributes$Builder&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType$Properties&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;IForgeBlock#getAiPathNodeType&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IForgeBlock#getBlockPathType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;IForgeEntity#canBeRiddenInWater&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IForgeEntity#canBeRiddenUnderFluidType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;IForgeFluid#isEntityInside&amp;lt;/code&amp;gt; -&amp;gt; REMOVED&lt;br /&gt;
* &amp;lt;code&amp;gt;IForgeFluid#isAABBInsideMaterial&amp;lt;/code&amp;gt; -&amp;gt; REMOVED&lt;br /&gt;
* &amp;lt;code&amp;gt;IForgeFluid#getAttributes&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;IForgeFluid#getFluidType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;IForgeFluidState#isEntityInside&amp;lt;/code&amp;gt; -&amp;gt; REMOVED&lt;br /&gt;
* &amp;lt;code&amp;gt;ForgeFlowingFluid$Properties(Fluid, Fluid, FluidAttributes)&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;ForgeFlowingFluid$Properties(FluidType, Fluid, Fluid)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ForgeFlowingFluid#canMultiply&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;FluidType#canConvertToSource(FluidState, LevelReader, BlockPos)&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Registration&amp;diff=3270</id>
		<title>Registration</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Registration&amp;diff=3270"/>
		<updated>2022-06-14T11:29:37Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Fix ObjectHolder&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Registration is the process of making an object (such as an item or block) known to the game during runtime. If some objects are not registered, this could cause crashes even before the game is fully loaded or arbitrary behaviors such as bottlenecking mod compatibility for world generation.&lt;br /&gt;
&lt;br /&gt;
Most objects that are known within the game are handled by a &amp;lt;code&amp;gt;Registry&amp;lt;/code&amp;gt;. Each registry uniquely defines each object through a &amp;quot;registry name&amp;quot; via a [[Using Resources#ResourceLocation|ResourceLocation]].&lt;br /&gt;
&lt;br /&gt;
{{Tip|In a global context, each object is universally unique through its &amp;lt;code&amp;gt;ResourceKey&amp;lt;/code&amp;gt;: a concatenation of its registry's id and the object's registry name.}}&lt;br /&gt;
&lt;br /&gt;
Due to the inconsistent ordering and registration process vanilla uses, Forge wraps most vanilla registries using &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt;. This guarantees that the loading order for these wrapped registries will be &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt;, and then the rest of the wrapped registries in alphabetical order. All registries supported by Forge can be found within the &amp;lt;code&amp;gt;ForgeRegistries&amp;lt;/code&amp;gt; class. Since all registry names are unique to a specific registry, different registry objects within different registries can have the same name (e.g. a &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt; and an &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; each hold a registry object named &amp;lt;code&amp;gt;examplemod:object&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|If two registry objects within the same registry have the same name, the second object will override the first. The only registry that will throw an &amp;lt;code&amp;gt;IllegalArgumentException&amp;lt;/code&amp;gt; is the &amp;lt;code&amp;gt;DataSerializerEntry&amp;lt;/code&amp;gt; registry.}}&lt;br /&gt;
&lt;br /&gt;
== Methods for Registering ==&lt;br /&gt;
&lt;br /&gt;
There are two proper ways to register objects within an associated wrapped Forge registry: the &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; class, and the &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; lifecycle event.&lt;br /&gt;
&lt;br /&gt;
=== DeferredRegister ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; is an abstraction layer over the registry event used to register objects. It maintains a map of &amp;quot;registry name&amp;quot; to their associated suppliers and resolves those suppliers during &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; for the associated registry. This method is the currently recommended, and documented, way to handle these objects as it provides convenience and safety for those who want to statically initialize objects while avoiding some issues associated with it.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|When using &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt;s with non-vanilla registries, the registry key or the registry name should be supplied to the &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt; method. These include the custom Forge registries for entity data serializers, global loot modifier serializers, world presets, and biome modifier serializers. Calling &amp;lt;code&amp;gt;Supplier#get&amp;lt;/code&amp;gt; on a &amp;lt;code&amp;gt;Supplier&amp;lt;IForgeRegistry&amp;lt;?&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; when making a DeferredRegister will return null because the registry does not exist yet.}}&lt;br /&gt;
&lt;br /&gt;
An example of a mod registering a custom block:&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=private static final DeferredRegister&amp;lt;Block&amp;gt; BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;Block&amp;gt; EXAMPLE_BLOCK = BLOCKS.register(&amp;quot;example_block&amp;quot;, () -&amp;gt; new Block(BlockBehaviour.Properties.of(Material.STONE)));&lt;br /&gt;
&lt;br /&gt;
public ExampleMod() {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get().getModEventBus());&lt;br /&gt;
}&lt;br /&gt;
|kotlin=private val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID)&lt;br /&gt;
&lt;br /&gt;
val EXAMPLE_BLOCK: RegistryObject&amp;lt;Block&amp;gt; = BLOCKS.register(&amp;quot;example_block&amp;quot;) { Block(BlockBehaviour.Properties.of(Material.ROCK)) }&lt;br /&gt;
&lt;br /&gt;
internal class ExampleMod {&lt;br /&gt;
    init {&lt;br /&gt;
        BLOCKS.register(FMLJavaModLoadingContext.get().modEventBus)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
|scala=object ExampleMod {&lt;br /&gt;
    private final val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID)&lt;br /&gt;
&lt;br /&gt;
    final val EXAMPLE_BLOCK = registerBlock(&amp;quot;example_block&amp;quot;, () =&amp;gt; new Block(BlockBehaviour.Properties.of(Material.ROCK)))&lt;br /&gt;
}&lt;br /&gt;
class ExampleMod {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get.getModEventBus)&lt;br /&gt;
}&lt;br /&gt;
|groovy=private static final DeferredRegister&amp;lt;Block&amp;gt; BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;Block&amp;gt; EXAMPLE_BLOCK = BLOCKS.register(&amp;quot;example_block&amp;quot;, () -&amp;gt; new Block(BlockBehaviour.Properties.of(Material.STONE)));&lt;br /&gt;
&lt;br /&gt;
ExampleMod() {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get().modEventBus);&lt;br /&gt;
}&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip|When using a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; to register any object, the name inputted will be automatically prefixed with the mod id passed in, giving the above object a &amp;quot;registry name&amp;quot; of &amp;lt;code&amp;gt;examplemod:example_block&amp;lt;/code&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
=== RegisterEvent ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is the second way register objects. This [[Events|event]] is fired for each registry synchronously in vanilla registry order after &amp;lt;code&amp;gt;FMLConstructModEvent&amp;lt;/code&amp;gt; and before the configs are loaded. Objects are registered using &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; by passing in the registry key, the name of the registry object, and the object itself. There is an additional &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; overload which takes in a consumed helper to register an object with a given name. It is recommended to use this method to avoid unnecessary object creation.&lt;br /&gt;
&lt;br /&gt;
Here is an example: (the event handler is registered on the '''mod event bus''')&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=@SubscribeEvent&lt;br /&gt;
public void register(RegisterEvent event) {&lt;br /&gt;
    event.register(ForgeRegistries.Keys.BLOCKS,&lt;br /&gt;
        helper -&amp;gt; helper.register(new ResourceLocation(MODID, &amp;quot;example_block&amp;quot;), new Block(...))&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
|kotlin=@JvmStatic&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
private fun register(event: RegisterEvent) =&lt;br /&gt;
    event.register(ForgeRegistries.Keys.BLOCKS) {&lt;br /&gt;
        helper -&amp;gt; helper.register(ResourceLocation(MODID, &amp;quot;example_block&amp;quot;), Block(...))&lt;br /&gt;
    }&lt;br /&gt;
|scala=@SubscribeEvent&lt;br /&gt;
def register(event: RegisterEvent): Unit =&lt;br /&gt;
    event.register(ForgeRegistries.Keys.BLOCKS,&lt;br /&gt;
        helper =&amp;gt; helper.register(new ResourceLocation(MODID, &amp;quot;example_block&amp;quot;), new Block(...))&lt;br /&gt;
    )&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|Since all objects registered must be singleton, some classes cannot by themselves be registered. Instead, &amp;lt;code&amp;gt;*Type&amp;lt;/code&amp;gt; classes are registered and used in the formers' constructors to wrap the flyweight objects. For example, a [[Basics_of_Block_Entities|&amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt;]] is wrapped via &amp;lt;code&amp;gt;BlockEntityType&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;Entity&amp;lt;/code&amp;gt; is wrapped via &amp;lt;code&amp;gt;EntityType&amp;lt;/code&amp;gt;. These &amp;lt;code&amp;gt;*Type&amp;lt;/code&amp;gt; classes hold factories that simply create the containing type on demand.&lt;br /&gt;
&lt;br /&gt;
These factory holders are created through the use of their &amp;lt;code&amp;gt;*Type$Builder&amp;lt;/code&amp;gt; classes. An example: (&amp;lt;code&amp;gt;REGISTER&amp;lt;/code&amp;gt; here refers to a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;BlockEntityType&amp;lt;?&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final RegistryObject&amp;lt;BlockEntityType&amp;lt;ExampleBlockEntity&amp;gt;&amp;gt; EXAMPLE_BLOCK_ENTITY = REGISTER.register(&lt;br /&gt;
    &amp;quot;example_block_entity&amp;quot;, () -&amp;gt; BlockEntityType.Builder.of(ExampleBlockEntity::new, EXAMPLE_BLOCK.get()).build(null)&lt;br /&gt;
);&lt;br /&gt;
|kotlin=val EXAMPLE_BLOCK_ENTITY: RegistryObject&amp;lt;BlockEntityType&amp;lt;ExampleBlockEntity&amp;gt;&amp;gt; = REGISTER.register(&amp;quot;example_block_entity&amp;quot;) { BlockEntityType.Builder.of(::ExampleBlockEntity, EXAMPLE_BLOCK.get()).build(null)) }&lt;br /&gt;
|scala=final val EXAMPLE_BLOCK_ENTITY = REGISTER.register(&amp;quot;example_block_entity&amp;quot;, () =&amp;gt; BlockEntityType.Builder.of(() =&amp;gt; new ExampleBlockEntity(), GeneralRegistrar.EXAMPLE_BLOCK.get).build(null))&lt;br /&gt;
|}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Non-Forge Registries ===&lt;br /&gt;
&lt;br /&gt;
Not all vanilla registries are wrapped as a Forge registry. To register objects to any one of these registries, create a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; via the &amp;lt;code&amp;gt;#create&amp;lt;/code&amp;gt; overload which takes in a resource key of the registry and the mod id to register the entries for. Then simply call &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; like any other &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=private static final DeferredRegister&amp;lt;LootItemConditionType&amp;gt; REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;LootItemConditionType&amp;gt; EXAMPLE_LOOT_ITEM_CONDITION_TYPE = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;, () -&amp;gt; new LootItemConditionType(...));&lt;br /&gt;
|kotlin=private val REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID)&lt;br /&gt;
&lt;br /&gt;
val EXAMPLE_LOOT_ITEM_CONDITION_TYPE : RegistryObject&amp;lt;LootItemConditionType&amp;gt; = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;) {&lt;br /&gt;
    LootItemConditionType(...)&lt;br /&gt;
}&lt;br /&gt;
|scala=private final val REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID)&lt;br /&gt;
&lt;br /&gt;
final val EXAMPLE_LOOT_ITEM_CONDITION_TYPE = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;, () =&amp;gt; new LootItemConditionType(...))&lt;br /&gt;
|groovy=private static final DeferredRegister&amp;lt;LootItemConditionType&amp;gt; REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;LootItemConditionType&amp;gt; EXAMPLE_LOOT_ITEM_CONDITION_TYPE = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;, () -&amp;gt; new LootItemConditionType(...));&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
If you attempt to make one of these instances require an instance of another registry object, you should use the lazy initialization method mentioned above to register the object in the correct order.&lt;br /&gt;
&lt;br /&gt;
=== Data Driven Entries ===&lt;br /&gt;
&lt;br /&gt;
Registries are considered to be data driven if they are located within &amp;lt;code&amp;gt;RegistryAccess&amp;lt;/code&amp;gt; with the exception of &amp;lt;code&amp;gt;LevelStem&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Level&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
These registry objects only need to be registered within code if they are to be used within a pre-existing registry object (e.g. a &amp;lt;code&amp;gt;PlacedFeature&amp;lt;/code&amp;gt; for ore generation within an overworld &amp;lt;code&amp;gt;Biome&amp;lt;/code&amp;gt;). Otherwise, their instance can be purely registered using a JSON file.&lt;br /&gt;
&lt;br /&gt;
If a data driven registry object has to be registered within code, a dummy object should be supplied to hold a &amp;quot;registry name&amp;quot; and then constructed within a JSON file.&lt;br /&gt;
&lt;br /&gt;
== Referencing Registered Objects ==&lt;br /&gt;
&lt;br /&gt;
Each forge registered object should not be statically initialized nor reference another instance being registered. They must always be a new, singleton instance that is resolved during when &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is called for their registry. This is to maintain a sane loading order for registries and their objects along with dynamic loading/unloading of mods.&lt;br /&gt;
&lt;br /&gt;
Forge registered objects must always be referenced through a &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; or a field with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Using RegistryObjects===&lt;br /&gt;
&amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;s can be used to retrieve references to registered objects once they become available. Their references are updated along with all &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; annotations after the registry that &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is called for is dispatched and frozen.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; can be retrieved as a result of using &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; or calling the static factory &amp;lt;code&amp;gt;RegistryObject#create&amp;lt;/code&amp;gt;. Each static factory takes in the &amp;quot;registry name&amp;quot; of the object being referenced and one of the following: a &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt;, a registry name of the type &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt;, or a registry key of the type &amp;lt;code&amp;gt;ResourceKey&amp;lt;? extends Registry&amp;lt;?&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; can be stored within some field and retrieve the registered object using &amp;lt;code&amp;gt;#get&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
An example using &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;:&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final RegistryObject&amp;lt;Item&amp;gt; EXAMPLE_ITEM = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_item&amp;quot;), ForgeRegistries.ITEMS);&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
public static final RegistryObject&amp;lt;ExampleRegistry&amp;gt; EXAMPLE_OBJECT = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;); &lt;br /&gt;
|kotlin=val EXAMPLE_ITEM: RegistryObject&amp;lt;Item&amp;gt; = RegistryObject.create(ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_item&amp;quot;), ForgeRegistries.ITEMS)&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
val EXAMPLE_OBJECT: RegistryObject&amp;lt;ExampleRegistry&amp;gt; = RegistryObject.create(ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;)&lt;br /&gt;
|scala=final val EXAMPLE_ITEM = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_item&amp;quot;), ForgeRegistries.ITEMS)&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
final val EXAMPLE_OBJECT = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;); &lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|All vanilla objects are bootstrapped and registered before mods are loaded. As such, they can be referenced as is without any issues.}}&lt;br /&gt;
&lt;br /&gt;
=== Using @ObjectHolder ===&lt;br /&gt;
&lt;br /&gt;
Forge registry objects can also be injected into &amp;lt;code&amp;gt;public static&amp;lt;/code&amp;gt; fields with either their class or that field annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;. There must be enough information to construct a &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; to identify a single object within a specific registry.&lt;br /&gt;
&lt;br /&gt;
The rules for &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; are as follows:&lt;br /&gt;
&lt;br /&gt;
* If the class is annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;, its value will be the default namespace for all fields within if not explicitly defined&lt;br /&gt;
* If the class is annotated with &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt;, the modid will be the default namespace for all annotated fields within if not explicitly defined &lt;br /&gt;
* A field is considered for injection if:&lt;br /&gt;
** it has at least the modifiers &amp;lt;code&amp;gt;public static&amp;lt;/code&amp;gt;; and&lt;br /&gt;
** the '''field''' is annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;, and:&lt;br /&gt;
*** the name value is explicitly defined; and&lt;br /&gt;
*** the registry name value is explicitly defined&lt;br /&gt;
** ''An exception is thrown if a field does not have a corresponding registry.''&lt;br /&gt;
* ''An exception is thrown if the resulting &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; is incomplete or invalid (non-valid characters in path)''&lt;br /&gt;
* If no other errors or exceptions occur, the field will be injected&lt;br /&gt;
* If all of the above rules do not apply, no action will be taken (and a message may be logged)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; annotated fields are injected with their associated object values after &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is fired for their registry, along with &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;s.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|If the object does not exist in the registry when it is to be injected, a debug message will be logged, and no value will be injected. If the object is found, but the field cannot be set, a warning message will be logged instead.}}&lt;br /&gt;
&lt;br /&gt;
As these rules are rather complicated, here are some examples:&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; style=&amp;quot;border: solid 2px; padding: 2px 5px; margin-top: 3px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-weight:bold;line-height:1.6;&amp;quot;&amp;gt;Example uses of &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot; style=&amp;quot;overflow: auto; white-space: nowrap;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
class Holder {&lt;br /&gt;
    @ObjectHolder(registryName = &amp;quot;enchantment&amp;quot;, value = &amp;quot;minecraft:flame&amp;quot;)&lt;br /&gt;
    public static final Enchantment flame = null;     // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // Registry name is explicitly defined: &amp;quot;minecraft:enchantment&amp;quot;&lt;br /&gt;
                                                      // Resource location is explicitly defined: &amp;quot;minecraft:flame&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:flame&amp;quot; from the [Enchantment] registry&lt;br /&gt;
&lt;br /&gt;
    public static final Biome ice_flat = null;        // No annotation on the field.&lt;br /&gt;
                                                      // Therefore, the field is ignored.&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(&amp;quot;minecraft:creeper&amp;quot;)&lt;br /&gt;
    public static Entity creeper = null;              // Annotation present. [public static] is required.&lt;br /&gt;
                                                      // The registry has not been specified on the field.&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(registryName = &amp;quot;potion&amp;quot;)&lt;br /&gt;
    public static final Potion levitation = null;     // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // Registry name is explicitly defined: &amp;quot;minecraft:potion&amp;quot;&lt;br /&gt;
                                                      // Resource location is not specified on the field&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Creating Custom Registries ==&lt;br /&gt;
&lt;br /&gt;
Creating custom registries for your mod might be useful if you want other mods to add new things to your system. For example, you might have magic spells and want to allow other mods to add new spells. For this you will want to make a registry (eg. &amp;quot;mymagicmod:spells&amp;quot;). This way, other mods will be able to register things to that list, and you won't have to do anything else.&lt;br /&gt;
&lt;br /&gt;
Just like with registering a new item or block you have two ways of making a new registry. Each method takes in a &amp;lt;code&amp;gt;RegistryBuilder&amp;lt;/code&amp;gt; which is used to build an &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt;. Each builder should have its name set via &amp;lt;code&amp;gt;#setName&amp;lt;/code&amp;gt; before being created.&lt;br /&gt;
&lt;br /&gt;
=== With DeferredRegister ===&lt;br /&gt;
&lt;br /&gt;
The first method involves the second static constructor: &amp;lt;code&amp;gt;DeferredRegister#create(ResourceLocation, String)&amp;lt;/code&amp;gt;. From there, we can construct the registry using &amp;lt;code&amp;gt;#makeRegistry&amp;lt;/code&amp;gt;. This will already populate &amp;lt;code&amp;gt;#setName&amp;lt;/code&amp;gt; for us. This method also returns a supplier of the registry which we can use after the &amp;lt;code&amp;gt;NewRegistryEvent&amp;lt;/code&amp;gt; is called.&lt;br /&gt;
&lt;br /&gt;
Here is an example:&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final DeferredRegister&amp;lt;ExampleRegistry&amp;gt; EXAMPLE = DeferredRegister.create(new ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;), MODID);&lt;br /&gt;
&lt;br /&gt;
public static final Supplier&amp;lt;IForgeRegistry&amp;lt;ExampleRegistry&amp;gt;&amp;gt; REGISTRY = EXAMPLE.makeRegistry(RegistryBuilder::new);&lt;br /&gt;
|kotlin=val EXAMPLE: DeferredRegister&amp;lt;ExampleRegistry&amp;gt; = DeferredRegister.create(ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;), MODID)&lt;br /&gt;
&lt;br /&gt;
val REGISTRY: IForgeRegistry&amp;lt;ExampleRegistry&amp;gt; by lazy {&lt;br /&gt;
    EXAMPLE.makeRegistry(::RegistryBuilder).get()&lt;br /&gt;
}&lt;br /&gt;
|scala=final val EXAMPLE = DeferredRegister.create(new ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;), MODID)&lt;br /&gt;
&lt;br /&gt;
final lazy val REGISTRY = EXAMPLE.makeRegistry(() =&amp;gt; new RegistryBuilder).get&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
=== Using &amp;lt;code&amp;gt;NewRegistryEvent&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The second method can be done during the &amp;lt;code&amp;gt;NewRegistryEvent&amp;lt;/code&amp;gt; event. Using &amp;lt;code&amp;gt;NewRegistryEvent#create&amp;lt;/code&amp;gt;, you can pass in a &amp;lt;code&amp;gt;RegistryBuilder&amp;lt;/code&amp;gt; directly. This method will return a &amp;lt;code&amp;gt;Supplier&amp;lt;IForgeRegistry&amp;lt;V&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; that can be stored and queried after the event is fired to gain access to your &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt; instance.&lt;br /&gt;
&lt;br /&gt;
Here is an example: (the event handler is registered on the '''mod event bus''')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public static Supplier&amp;lt;IForgeRegistry&amp;lt;ExampleRegistry&amp;gt;&amp;gt; registrySupplier = null;&lt;br /&gt;
&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void onNewRegistry(NewRegistryEvent event){&lt;br /&gt;
    RegistryBuilder&amp;lt;ExampleRegistry&amp;gt; registryBuilder = new RegistryBuilder&amp;lt;&amp;gt;();&lt;br /&gt;
    registryBuilder.setName(new ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;);&lt;br /&gt;
    registrySupplier = event.create(registryBuilder);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Handling Missing Entries ==&lt;br /&gt;
&lt;br /&gt;
When loading a pre-existing world after removing mods or updating versions, there are cases where certain registry objects will cease to exist. In these cases, it is possible to specify actions to remove a mapping, prevent the world from loading, or remap the name as needed. This can be done through the third of the registry events: &amp;lt;code&amp;gt;MissingMappingsEvent&amp;lt;/code&amp;gt;. Within the event, you can grab an immutable list of missing mappings associated with a mod id for a given registry via &amp;lt;code&amp;gt;#getMappings&amp;lt;/code&amp;gt; or a list of all mappings via &amp;lt;code&amp;gt;#getAllMappings&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For each &amp;lt;code&amp;gt;Mapping&amp;lt;/code&amp;gt;, you can either execute one of the following methods:&lt;br /&gt;
* &amp;lt;code&amp;gt;#ignore&amp;lt;/code&amp;gt; which abandons the entry when loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#warn&amp;lt;/code&amp;gt; which warns the user about the missing entry but continues loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#fail&amp;lt;/code&amp;gt; which prevents the world from loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#remap&amp;lt;/code&amp;gt; which remaps the entry to the specified non-null object in the same registry&lt;br /&gt;
&lt;br /&gt;
If none of the above are specified, then the default action of notifying the user about the missing mappings occur.&lt;br /&gt;
&lt;br /&gt;
Here is an example:  (the event handler is registered on the '''forge event bus''')&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=// This will ignore any missing test items from the specified world&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void onMissing(final MissingMappingsEvent event) {&lt;br /&gt;
    event.getMappings(ForgeRegistries.Keys.ITEMS, MODID).stream()&lt;br /&gt;
        .filter(mapping -&amp;gt; mapping.key.getPath().contains(&amp;quot;test&amp;quot;))&lt;br /&gt;
            .forEach(Mapping::ignore);&lt;br /&gt;
}&lt;br /&gt;
|groovy=// This will ignore any missing test items from the specified world&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
void onMissing(final MissingMappingsEvent event) {&lt;br /&gt;
    event.getMappings(ForgeRegistries.Keys.ITEMS, MODID).stream()&lt;br /&gt;
        .filter(mapping -&amp;gt; mapping.key.path.contains(&amp;quot;test&amp;quot;))&lt;br /&gt;
            .forEach(Mapping::ignore);&lt;br /&gt;
}&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Common Concepts]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Custom_Recipes&amp;diff=3269</id>
		<title>Custom Recipes</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Custom_Recipes&amp;diff=3269"/>
		<updated>2022-06-13T20:07:08Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update to 1.19&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Recipes are a core concept within the use of items. They allow you to transform some item into another through the use of crafting, smelting, smithing, etc. all of which can be defined in JSON through datapacks. However, the recipe system in its entirety is not only limited to what vanilla can provide. Any modder can create their own custom recipe implementation.&lt;br /&gt;
&lt;br /&gt;
== Creating a New Recipe ==&lt;br /&gt;
&lt;br /&gt;
Creating a new recipe boils down to three things: &amp;lt;code&amp;gt;Recipe&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;RecipeType&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;RecipeSerializer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For a general overview:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;Recipe&amp;lt;/code&amp;gt;: The actual recipe implementation which handles the matching logic, construction logic, and the display data. All custom recipes need some implementation of this class.&lt;br /&gt;
* &amp;lt;code&amp;gt;RecipeType&amp;lt;/code&amp;gt;: The category the recipe belongs to. For example, a recipe placed in the &amp;lt;code&amp;gt;#CRAFTING&amp;lt;/code&amp;gt; category is expected to work within the crafting table. A custom recipe category indicates that recipes of that type will be used in that particular context.&lt;br /&gt;
* &amp;lt;code&amp;gt;RecipeSerializer&amp;lt;/code&amp;gt;: The serializer which handles decoding the data from JSON and handling the data when syncing across the network. Each serializer can serialize to one &amp;lt;code&amp;gt;Recipe&amp;lt;/code&amp;gt; implementation. The &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; field within any recipe JSON references the registry name of this serializer.&lt;br /&gt;
&lt;br /&gt;
How one uses the recipe and its data is up to the implementing modder.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|Creating a Recipe Book implementation will not be covered here. That is currently hardcoded to only accept vanilla categories.}}&lt;br /&gt;
&lt;br /&gt;
=== Recipe ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Recipe&amp;lt;/code&amp;gt; is an interface which holds data about the recipe being represented and how to test whether it is valid. It has a single parameterized type of some &amp;lt;code&amp;gt;Container&amp;lt;/code&amp;gt; subtype. This is used to get a snapshot of the current inventory container, and as such should only be read from in this class. In most cases, this can just be left as &amp;lt;code&amp;gt;Container&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The following methods must be implemented within your implementation:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Required Methods&lt;br /&gt;
|-&lt;br /&gt;
! Method !! Description&lt;br /&gt;
|-&lt;br /&gt;
| getId || This method represents the unique name of the recipe. This usually refers to the name of the JSON file and is passed in while decoding.&lt;br /&gt;
|-&lt;br /&gt;
| getSerializer || This method represents the serializer used to decode and send this recipe across the network.&lt;br /&gt;
|-&lt;br /&gt;
| getType || This method represents the category the recipe is in.&lt;br /&gt;
|-&lt;br /&gt;
| canCraftInDimensions || This takes in a width and height and checks whether the recipe can be created within those bounds. This is only used within the Recipe Book.&lt;br /&gt;
|-&lt;br /&gt;
| matches || This method checks if the passed in inventory container can craft using the recipe stored in this class. Using the standard &amp;lt;code&amp;gt;RecipeManager&amp;lt;/code&amp;gt; interface, this is always used to check whether the recipe can be used.&lt;br /&gt;
|-&lt;br /&gt;
| assemble || This creates the resulting &amp;lt;code&amp;gt;ItemStack&amp;lt;/code&amp;gt; to return to the player if the recipe has been crafted. This should always return a unique instance. If you are unsure whether yours does, call &amp;lt;code&amp;gt;ItemStack#copy&amp;lt;/code&amp;gt; on the decoded result before returning.&lt;br /&gt;
|-&lt;br /&gt;
| getResultItem || This shows the resulting item in displays like the Recipe Book. This does not need to return a unique instance and usually represents the decoded result directly.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|If you would like to use your own recipe checker because the inventory container does not provide you with enough data, you will need to reimplement the &amp;lt;code&amp;gt;RecipeManager&amp;lt;/code&amp;gt; methods yourself.}}&lt;br /&gt;
&lt;br /&gt;
There are some defaulted methods as well. Although optional, they will be covered as well:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Optional Methods&lt;br /&gt;
|-&lt;br /&gt;
! Method !! Description&lt;br /&gt;
|-&lt;br /&gt;
| getGroup || This gets the group the recipe is currently associated with. This is used by the Recipe Book to group similar recipes into one entry to reduce cluttering. This would be passed in from the decoded JSON. By default, this returns an empty string.&lt;br /&gt;
|-&lt;br /&gt;
| getIngredients || This gets the ingredients of the recipe. This is once again used by the Recipe Book to display the ingredients of the recipe. These are usually the decoded &amp;lt;code&amp;gt;Ingredient&amp;lt;/code&amp;gt;s from JSON. By default, this returns an empty list.&lt;br /&gt;
|-&lt;br /&gt;
| isSpecial || This usually signals that the recipe cannot purely be represented in JSON as it has some dynamic metadata preventing it from being so. Special recipes will not appear in the Recipe Book for this reason as they provide a number of combinations which cannot be simply expressed. By default, this is false.&lt;br /&gt;
|-&lt;br /&gt;
| getToastSymbol || This returns the symbol that appears when the recipe is seen in a toast, usually from unlocking via an advancement. This is not the actual recipe output itself, but it signifies what the recipe was made within. By default this returns a crafting table stack.&lt;br /&gt;
|-&lt;br /&gt;
| getRemainingItems || This returns what items remain in the inventory container after the recipe has been created. By default, this will return a list of container items.&lt;br /&gt;
|-&lt;br /&gt;
| isIncomplete || This returns whether the supplied ingredients is empty or if any &amp;lt;code&amp;gt;Ingredient&amp;lt;/code&amp;gt; has no items to test against. This is another check by the Recipe Book to prevent impossible recipes from appearing.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
When in practice, these will be decoded from a &amp;lt;code&amp;gt;RecipeSerializer&amp;lt;/code&amp;gt; and stored in a map with a key of the &amp;lt;code&amp;gt;RecipeType&amp;lt;/code&amp;gt; category it belongs to. The recipe itself is dynamically registered to the &amp;lt;code&amp;gt;RecipeManager&amp;lt;/code&amp;gt; for each decoded instance.&lt;br /&gt;
&lt;br /&gt;
=== RecipeType ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;RecipeType&amp;lt;/code&amp;gt; is another interface; however, it does not store any data itself. It is simply a forge-wrapped registry object which represents the category the &amp;lt;code&amp;gt;Recipe&amp;lt;/code&amp;gt; implementation belongs to.&lt;br /&gt;
&lt;br /&gt;
=== RecipeSerializer ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;RecipeSerializer&amp;lt;/code&amp;gt; is an interface which takes some JSON and transforms it into a &amp;lt;code&amp;gt;Recipe&amp;lt;/code&amp;gt;. It is also responsible for syncing the recipe data to the client.&lt;br /&gt;
&lt;br /&gt;
There are only three methods within &amp;lt;code&amp;gt;RecipeSerializer&amp;lt;/code&amp;gt;, but they all must be implemented:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Required Methods&lt;br /&gt;
|-&lt;br /&gt;
! Method !! Description&lt;br /&gt;
|-&lt;br /&gt;
| fromJson || This decodes a &amp;lt;code&amp;gt;Recipe&amp;lt;/code&amp;gt; from JSON. The &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; id is separated from the JSON object as it represents the file name and not data within the file.&lt;br /&gt;
|-&lt;br /&gt;
| toNetwork || This encodes a &amp;lt;code&amp;gt;Recipe&amp;lt;/code&amp;gt; on the server to send to the client. The data should be written to the &amp;lt;code&amp;gt;FriendlyByteBuf&amp;lt;/code&amp;gt; except for the id as that has already been written.&lt;br /&gt;
|-&lt;br /&gt;
| fromNetwork || This decodes a &amp;lt;code&amp;gt;Recipe&amp;lt;/code&amp;gt; on the client. Besides the id, the rest of the data can be read from the &amp;lt;code&amp;gt;FriendlyByteBuf&amp;lt;/code&amp;gt; in order of insertion.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Tip|There are some helpful methods for deserializing some objects from JSON such as &amp;lt;code&amp;gt;Ingredient#fromJson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;CraftingHelper#getItemStack&amp;lt;/code&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
This can be registered like any other forge wrapped registry object. The registry name supplied will represent the &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; supplied in the recipe JSON.&lt;br /&gt;
&lt;br /&gt;
Once that is done, you can create a recipe JSON within &amp;lt;code&amp;gt;data/&amp;lt;modid&amp;gt;/recipes/&amp;lt;path&amp;gt;.json&amp;lt;/code&amp;gt; and set the &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; field, along with any other data, to that handled by your serializer.&lt;br /&gt;
&lt;br /&gt;
== Data Generation ==&lt;br /&gt;
&lt;br /&gt;
Custom recipes can also be generated by the &amp;lt;code&amp;gt;RecipeProvider&amp;lt;/code&amp;gt; or as your own implementation. For simplicity purposes, this will be addressed as if one was creating a recipe within &amp;lt;code&amp;gt;RecipeProvider#buildCraftingRecipes&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For a recipe to be consumed by the data provider, whatever builder that is implemented must result in a &amp;lt;code&amp;gt;FinishedRecipe&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
All finished recipes must implement the following methods:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Required Methods&lt;br /&gt;
|-&lt;br /&gt;
! Method !! Description&lt;br /&gt;
|-&lt;br /&gt;
| getId || This gets the id of the recipe. When serialized, the recipe will be saved to &amp;lt;code&amp;gt;data/&amp;lt;namespace&amp;gt;/recipes/&amp;lt;path&amp;gt;.json&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| getType || This gets the &amp;lt;code&amp;gt;RecipeSerializer&amp;lt;/code&amp;gt; of the recipe. The registry name is set to the &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; field using this within &amp;lt;code&amp;gt;#serializeRecipe&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| serializeRecipeData || This encodes the data into the supplied JSON object. The data supplied should be the same as when needed to decode via the &amp;lt;code&amp;gt;RecipeSerializer&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;type&amp;lt;/code&amp;gt; field does not need to be specified as that is already set before this method is called.&lt;br /&gt;
|-&lt;br /&gt;
| getAdvancementId || This gets the advancement id of the recipe. This will be saved to &amp;lt;code&amp;gt;data/&amp;lt;namespace&amp;gt;/advancements/&amp;lt;path&amp;gt;.json&amp;lt;/code&amp;gt;. Usually the path contains &amp;lt;code&amp;gt;recipes/&amp;lt;/code&amp;gt; to represent it has a recipe and any other subdividing types like the &amp;lt;code&amp;gt;CreativeModeTab&amp;lt;/code&amp;gt;. If unwanted, this should return &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| serializeAdvancement || This encodes the advancement data into a JSON. If working with an &amp;lt;code&amp;gt;Advancement$Builder&amp;lt;/code&amp;gt;, this can be done simply by calling &amp;lt;code&amp;gt;Advancement$Builder#serializeToJson&amp;lt;/code&amp;gt;. If unwanted, this should return &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Once done, have the consumer accept the finished recipe.&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Registration&amp;diff=3268</id>
		<title>Registration</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Registration&amp;diff=3268"/>
		<updated>2022-06-13T19:50:17Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Fix ObjectHolder info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Registration is the process of making an object (such as an item or block) known to the game during runtime. If some objects are not registered, this could cause crashes even before the game is fully loaded or arbitrary behaviors such as bottlenecking mod compatibility for world generation.&lt;br /&gt;
&lt;br /&gt;
Most objects that are known within the game are handled by a &amp;lt;code&amp;gt;Registry&amp;lt;/code&amp;gt;. Each registry uniquely defines each object through a &amp;quot;registry name&amp;quot; via a [[Using Resources#ResourceLocation|ResourceLocation]].&lt;br /&gt;
&lt;br /&gt;
{{Tip|In a global context, each object is universally unique through its &amp;lt;code&amp;gt;ResourceKey&amp;lt;/code&amp;gt;: a concatenation of its registry's id and the object's registry name.}}&lt;br /&gt;
&lt;br /&gt;
Due to the inconsistent ordering and registration process vanilla uses, Forge wraps most vanilla registries using &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt;. This guarantees that the loading order for these wrapped registries will be &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt;, and then the rest of the wrapped registries in alphabetical order. All registries supported by Forge can be found within the &amp;lt;code&amp;gt;ForgeRegistries&amp;lt;/code&amp;gt; class. Since all registry names are unique to a specific registry, different registry objects within different registries can have the same name (e.g. a &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt; and an &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; each hold a registry object named &amp;lt;code&amp;gt;examplemod:object&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|If two registry objects within the same registry have the same name, the second object will override the first. The only registry that will throw an &amp;lt;code&amp;gt;IllegalArgumentException&amp;lt;/code&amp;gt; is the &amp;lt;code&amp;gt;DataSerializerEntry&amp;lt;/code&amp;gt; registry.}}&lt;br /&gt;
&lt;br /&gt;
== Methods for Registering ==&lt;br /&gt;
&lt;br /&gt;
There are two proper ways to register objects within an associated wrapped Forge registry: the &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; class, and the &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; lifecycle event.&lt;br /&gt;
&lt;br /&gt;
=== DeferredRegister ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; is an abstraction layer over the registry event used to register objects. It maintains a map of &amp;quot;registry name&amp;quot; to their associated suppliers and resolves those suppliers during &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; for the associated registry. This method is the currently recommended, and documented, way to handle these objects as it provides convenience and safety for those who want to statically initialize objects while avoiding some issues associated with it.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|When using &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt;s with non-vanilla registries, the registry key or the registry name should be supplied to the &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt; method. These include the custom Forge registries for entity data serializers, global loot modifier serializers, world presets, and biome modifier serializers. Calling &amp;lt;code&amp;gt;Supplier#get&amp;lt;/code&amp;gt; on a &amp;lt;code&amp;gt;Supplier&amp;lt;IForgeRegistry&amp;lt;?&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; when making a DeferredRegister will return null because the registry does not exist yet.}}&lt;br /&gt;
&lt;br /&gt;
An example of a mod registering a custom block:&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=private static final DeferredRegister&amp;lt;Block&amp;gt; BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;Block&amp;gt; EXAMPLE_BLOCK = BLOCKS.register(&amp;quot;example_block&amp;quot;, () -&amp;gt; new Block(BlockBehaviour.Properties.of(Material.STONE)));&lt;br /&gt;
&lt;br /&gt;
public ExampleMod() {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get().getModEventBus());&lt;br /&gt;
}&lt;br /&gt;
|kotlin=private val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID)&lt;br /&gt;
&lt;br /&gt;
val EXAMPLE_BLOCK: RegistryObject&amp;lt;Block&amp;gt; = BLOCKS.register(&amp;quot;example_block&amp;quot;) { Block(BlockBehaviour.Properties.of(Material.ROCK)) }&lt;br /&gt;
&lt;br /&gt;
internal class ExampleMod {&lt;br /&gt;
    init {&lt;br /&gt;
        BLOCKS.register(FMLJavaModLoadingContext.get().modEventBus)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
|scala=object ExampleMod {&lt;br /&gt;
    private final val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID)&lt;br /&gt;
&lt;br /&gt;
    final val EXAMPLE_BLOCK = registerBlock(&amp;quot;example_block&amp;quot;, () =&amp;gt; new Block(BlockBehaviour.Properties.of(Material.ROCK)))&lt;br /&gt;
}&lt;br /&gt;
class ExampleMod {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get.getModEventBus)&lt;br /&gt;
}&lt;br /&gt;
|groovy=private static final DeferredRegister&amp;lt;Block&amp;gt; BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;Block&amp;gt; EXAMPLE_BLOCK = BLOCKS.register(&amp;quot;example_block&amp;quot;, () -&amp;gt; new Block(BlockBehaviour.Properties.of(Material.STONE)));&lt;br /&gt;
&lt;br /&gt;
ExampleMod() {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get().modEventBus);&lt;br /&gt;
}&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip|When using a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; to register any object, the name inputted will be automatically prefixed with the mod id passed in, giving the above object a &amp;quot;registry name&amp;quot; of &amp;lt;code&amp;gt;examplemod:example_block&amp;lt;/code&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
=== RegisterEvent ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is the second way register objects. This [[Events|event]] is fired for each registry synchronously in vanilla registry order after &amp;lt;code&amp;gt;FMLConstructModEvent&amp;lt;/code&amp;gt; and before the configs are loaded. Objects are registered using &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; by passing in the registry key, the name of the registry object, and the object itself. There is an additional &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; overload which takes in a consumed helper to register an object with a given name. It is recommended to use this method to avoid unnecessary object creation.&lt;br /&gt;
&lt;br /&gt;
Here is an example: (the event handler is registered on the '''mod event bus''')&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=@SubscribeEvent&lt;br /&gt;
public void register(RegisterEvent event) {&lt;br /&gt;
    event.register(ForgeRegistries.Keys.BLOCKS,&lt;br /&gt;
        helper -&amp;gt; helper.register(new ResourceLocation(MODID, &amp;quot;example_block&amp;quot;), new Block(...))&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
|kotlin=@JvmStatic&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
private fun register(event: RegisterEvent) =&lt;br /&gt;
    event.register(ForgeRegistries.Keys.BLOCKS) {&lt;br /&gt;
        helper -&amp;gt; helper.register(ResourceLocation(MODID, &amp;quot;example_block&amp;quot;), Block(...))&lt;br /&gt;
    }&lt;br /&gt;
|scala=@SubscribeEvent&lt;br /&gt;
def register(event: RegisterEvent): Unit =&lt;br /&gt;
    event.register(ForgeRegistries.Keys.BLOCKS,&lt;br /&gt;
        helper =&amp;gt; helper.register(new ResourceLocation(MODID, &amp;quot;example_block&amp;quot;), new Block(...))&lt;br /&gt;
    )&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|Since all objects registered must be singleton, some classes cannot by themselves be registered. Instead, &amp;lt;code&amp;gt;*Type&amp;lt;/code&amp;gt; classes are registered and used in the formers' constructors to wrap the flyweight objects. For example, a [[Basics_of_Block_Entities|&amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt;]] is wrapped via &amp;lt;code&amp;gt;BlockEntityType&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;Entity&amp;lt;/code&amp;gt; is wrapped via &amp;lt;code&amp;gt;EntityType&amp;lt;/code&amp;gt;. These &amp;lt;code&amp;gt;*Type&amp;lt;/code&amp;gt; classes hold factories that simply create the containing type on demand.&lt;br /&gt;
&lt;br /&gt;
These factory holders are created through the use of their &amp;lt;code&amp;gt;*Type$Builder&amp;lt;/code&amp;gt; classes. An example: (&amp;lt;code&amp;gt;REGISTER&amp;lt;/code&amp;gt; here refers to a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;BlockEntityType&amp;lt;?&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final RegistryObject&amp;lt;BlockEntityType&amp;lt;ExampleBlockEntity&amp;gt;&amp;gt; EXAMPLE_BLOCK_ENTITY = REGISTER.register(&lt;br /&gt;
    &amp;quot;example_block_entity&amp;quot;, () -&amp;gt; BlockEntityType.Builder.of(ExampleBlockEntity::new, EXAMPLE_BLOCK.get()).build(null)&lt;br /&gt;
);&lt;br /&gt;
|kotlin=val EXAMPLE_BLOCK_ENTITY: RegistryObject&amp;lt;BlockEntityType&amp;lt;ExampleBlockEntity&amp;gt;&amp;gt; = REGISTER.register(&amp;quot;example_block_entity&amp;quot;) { BlockEntityType.Builder.of(::ExampleBlockEntity, EXAMPLE_BLOCK.get()).build(null)) }&lt;br /&gt;
|scala=final val EXAMPLE_BLOCK_ENTITY = REGISTER.register(&amp;quot;example_block_entity&amp;quot;, () =&amp;gt; BlockEntityType.Builder.of(() =&amp;gt; new ExampleBlockEntity(), GeneralRegistrar.EXAMPLE_BLOCK.get).build(null))&lt;br /&gt;
|}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Non-Forge Registries ===&lt;br /&gt;
&lt;br /&gt;
Not all vanilla registries are wrapped as a Forge registry. To register objects to any one of these registries, create a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; via the &amp;lt;code&amp;gt;#create&amp;lt;/code&amp;gt; overload which takes in a resource key of the registry and the mod id to register the entries for. Then simply call &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; like any other &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=private static final DeferredRegister&amp;lt;LootItemConditionType&amp;gt; REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;LootItemConditionType&amp;gt; EXAMPLE_LOOT_ITEM_CONDITION_TYPE = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;, () -&amp;gt; new LootItemConditionType(...));&lt;br /&gt;
|kotlin=private val REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID)&lt;br /&gt;
&lt;br /&gt;
val EXAMPLE_LOOT_ITEM_CONDITION_TYPE : RegistryObject&amp;lt;LootItemConditionType&amp;gt; = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;) {&lt;br /&gt;
    LootItemConditionType(...)&lt;br /&gt;
}&lt;br /&gt;
|scala=private final val REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID)&lt;br /&gt;
&lt;br /&gt;
final val EXAMPLE_LOOT_ITEM_CONDITION_TYPE = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;, () =&amp;gt; new LootItemConditionType(...))&lt;br /&gt;
|groovy=private static final DeferredRegister&amp;lt;LootItemConditionType&amp;gt; REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;LootItemConditionType&amp;gt; EXAMPLE_LOOT_ITEM_CONDITION_TYPE = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;, () -&amp;gt; new LootItemConditionType(...));&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
If you attempt to make one of these instances require an instance of another registry object, you should use the lazy initialization method mentioned above to register the object in the correct order.&lt;br /&gt;
&lt;br /&gt;
=== Data Driven Entries ===&lt;br /&gt;
&lt;br /&gt;
Registries are considered to be data driven if they are located within &amp;lt;code&amp;gt;RegistryAccess&amp;lt;/code&amp;gt; with the exception of &amp;lt;code&amp;gt;LevelStem&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Level&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
These registry objects only need to be registered within code if they are to be used within a pre-existing registry object (e.g. a &amp;lt;code&amp;gt;PlacedFeature&amp;lt;/code&amp;gt; for ore generation within an overworld &amp;lt;code&amp;gt;Biome&amp;lt;/code&amp;gt;). Otherwise, their instance can be purely registered using a JSON file.&lt;br /&gt;
&lt;br /&gt;
If a data driven registry object has to be registered within code, a dummy object should be supplied to hold a &amp;quot;registry name&amp;quot; and then constructed within a JSON file.&lt;br /&gt;
&lt;br /&gt;
== Referencing Registered Objects ==&lt;br /&gt;
&lt;br /&gt;
Each forge registered object should not be statically initialized nor reference another instance being registered. They must always be a new, singleton instance that is resolved during when &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is called for their registry. This is to maintain a sane loading order for registries and their objects along with dynamic loading/unloading of mods.&lt;br /&gt;
&lt;br /&gt;
Forge registered objects must always be referenced through a &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; or a field with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Using RegistryObjects===&lt;br /&gt;
&amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;s can be used to retrieve references to registered objects once they become available. Their references are updated along with all &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; annotations after the registry that &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is called for is dispatched and frozen.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; can be retrieved as a result of using &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; or calling the static factory &amp;lt;code&amp;gt;RegistryObject#create&amp;lt;/code&amp;gt;. Each static factory takes in the &amp;quot;registry name&amp;quot; of the object being referenced and one of the following: a &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt;, a registry name of the type &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt;, or a registry key of the type &amp;lt;code&amp;gt;ResourceKey&amp;lt;? extends Registry&amp;lt;?&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; can be stored within some field and retrieve the registered object using &amp;lt;code&amp;gt;#get&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
An example using &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;:&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final RegistryObject&amp;lt;Item&amp;gt; EXAMPLE_ITEM = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_item&amp;quot;), ForgeRegistries.ITEMS);&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
public static final RegistryObject&amp;lt;ExampleRegistry&amp;gt; EXAMPLE_OBJECT = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;); &lt;br /&gt;
|kotlin=val EXAMPLE_ITEM: RegistryObject&amp;lt;Item&amp;gt; = RegistryObject.create(ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_item&amp;quot;), ForgeRegistries.ITEMS)&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
val EXAMPLE_OBJECT: RegistryObject&amp;lt;ExampleRegistry&amp;gt; = RegistryObject.create(ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;)&lt;br /&gt;
|scala=final val EXAMPLE_ITEM = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_item&amp;quot;), ForgeRegistries.ITEMS)&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
final val EXAMPLE_OBJECT = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;); &lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|All vanilla objects are bootstrapped and registered before mods are loaded. As such, they can be referenced as is without any issues.}}&lt;br /&gt;
&lt;br /&gt;
=== Using @ObjectHolder ===&lt;br /&gt;
&lt;br /&gt;
Forge registry objects can also be injected into &amp;lt;code&amp;gt;public static&amp;lt;/code&amp;gt; fields with either their class or that field annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;. There must be enough information to construct a &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; to identify a single object within a specific registry.&lt;br /&gt;
&lt;br /&gt;
The rules for &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; are as follows:&lt;br /&gt;
&lt;br /&gt;
* If the class is annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;, its value will be the default namespace for all fields within if not explicitly defined&lt;br /&gt;
* If the class is annotated with &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt;, the modid will be the default namespace for all annotated fields within if not explicitly defined &lt;br /&gt;
* A field is considered for injection if:&lt;br /&gt;
** it has at least the modifiers &amp;lt;code&amp;gt;public static&amp;lt;/code&amp;gt;; and&lt;br /&gt;
** one of the following conditions are true:&lt;br /&gt;
*** the '''enclosing class''' has an &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; annotation, and the field is &amp;lt;code&amp;gt;final&amp;lt;/code&amp;gt;, and:&lt;br /&gt;
**** the name value is the field's name; and&lt;br /&gt;
**** the registry name value is the name of the object's registry; and&lt;br /&gt;
**** the namespace value is the enclosing class's namespace&lt;br /&gt;
**** ''An exception is thrown if the namespace value cannot be found and inherited''&lt;br /&gt;
*** the '''field''' is annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;, and:&lt;br /&gt;
**** the name value is explicitly defined; and&lt;br /&gt;
**** the registry name value is either explicitly defined or the enclosing class's registry name; and&lt;br /&gt;
**** the namespace value is either explicitly defined or the enclosing class's namespace&lt;br /&gt;
** ''An exception is thrown if a field does not have a corresponding registry.''&lt;br /&gt;
* ''An exception is thrown if the resulting &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; is incomplete or invalid (non-valid characters in path)''&lt;br /&gt;
* If no other errors or exceptions occur, the field will be injected&lt;br /&gt;
* If all of the above rules do not apply, no action will be taken (and a message may be logged)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; annotated fields are injected with their associated object values after &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is fired for their registry, along with &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;s.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|If the object does not exist in the registry when it is to be injected, a debug message will be logged, and no value will be injected. If the object is found, but the field cannot be set, a warning message will be logged instead.}}&lt;br /&gt;
&lt;br /&gt;
As these rules are rather complicated, here are some examples:&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; style=&amp;quot;border: solid 2px; padding: 2px 5px; margin-top: 3px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-weight:bold;line-height:1.6;&amp;quot;&amp;gt;Example uses of &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot; style=&amp;quot;overflow: auto; white-space: nowrap;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
@ObjectHolder(registryName = &amp;quot;block&amp;quot;, value = &amp;quot;minecraft&amp;quot;) // Registry: minecraft:block, Inheritable resource namespace: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
class AnnotatedHolder {&lt;br /&gt;
    public static final Block diamond_block = null;   // No annotation. [public static final] is required.&lt;br /&gt;
                                                      // Registry name is not explicitly defined.&lt;br /&gt;
                                                      // So, registry name is inherited from class annotation: &amp;quot;minecraft:block&amp;quot;&lt;br /&gt;
                                                      // Name path is the name of the field: &amp;quot;diamond_block&amp;quot;&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // So, namespace is inherited from class annotation: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:diamond_block&amp;quot; from the [Block] registry&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(registry = &amp;quot;sound_event&amp;quot;, value = &amp;quot;ambient.cave&amp;quot;)&lt;br /&gt;
    public static SoundEvent ambient_sound = null;    // Annotation present. [public static] is required.&lt;br /&gt;
                                                      // Registry name is explicitly defined: &amp;quot;minecraft:sound_event&amp;quot;&lt;br /&gt;
                                                      // Name path is the value of the annotation: &amp;quot;ambient.cave&amp;quot;&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // So, namespace is inherited from class annotation: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:ambient.cave&amp;quot; from the [SoundEvent] registry&lt;br /&gt;
&lt;br /&gt;
    // Assume for the next entry that [ManaType] is a valid registry.          &lt;br /&gt;
    @ObjectHolder(registryName = &amp;quot;neomagicae:mana_type&amp;quot;, value = &amp;quot;neomagicae:coffeinum&amp;quot;)&lt;br /&gt;
    public static final ManaType coffeinum = null;    // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // Registry name is explicitly defined: &amp;quot;neomagicae:mana_type&amp;quot; (custom registry)&lt;br /&gt;
                                                      // Resource location is explicitly defined: &amp;quot;neomagicae:coffeinum&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;neomagicae:coffeinum&amp;quot; from the [ManaType] registry&lt;br /&gt;
&lt;br /&gt;
    public static final Item ENDER_PEARL = null;      // No annotation. [public static final] is required.&lt;br /&gt;
                                                      // Registry name is not explicitly defined.&lt;br /&gt;
                                                      // So, registry name is inherited from class annotation: &amp;quot;minecraft:block&amp;quot;&lt;br /&gt;
                                                      // Name path is the name of the field: &amp;quot;ENDER_PEARL&amp;quot; -&amp;gt; &amp;quot;ender_pearl&amp;quot;&lt;br /&gt;
                                                      // !! ^ Field name is valid, because they are&lt;br /&gt;
                                                      //      converted to lowercase automatically.&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // So, namespace is inherited from class annotation: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
                                                      // When registering, this will attempt to force into a Block type, which is not a type or supertype of this object.&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(registryName = &amp;quot;item&amp;quot;, value = &amp;quot;minecraft:arrow&amp;quot;)&lt;br /&gt;
    public static final ArrowItem arrow = null;       // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // Registry name is explicitly defined: &amp;quot;minecraft:item&amp;quot;&lt;br /&gt;
                                                      // ArrowItem's supertype of Item has a corresponding registry: [Item]&lt;br /&gt;
                                                      // Resource location is explicitly defined: &amp;quot;minecraft:arrow&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:arrow&amp;quot; from the [Item] registry                                                    &lt;br /&gt;
&lt;br /&gt;
    public static Block bedrock = null;               // No annotation, so [public static final] is required.&lt;br /&gt;
                                                      // Therefore, the field is ignored.&lt;br /&gt;
    &lt;br /&gt;
    public static final CreativeModeTab group = null; // No annotation. [public static final] is required.&lt;br /&gt;
                                                      // Registry name is not explicitly defined.&lt;br /&gt;
                                                      // So, registry name is inherited from class annotation: &amp;quot;minecraft:block&amp;quot;&lt;br /&gt;
                                                      // When registering, this will attempt to force into a Block type, which is not a type or supertype of this object.&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class UnannotatedHolder { // Note the lack of an @ObjectHolder annotation on this class.&lt;br /&gt;
    @ObjectHolder(registryName = &amp;quot;enchantment&amp;quot;, value = &amp;quot;minecraft:flame&amp;quot;)&lt;br /&gt;
    public static final Enchantment flame = null;     // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // Registry name is explicitly defined: &amp;quot;minecraft:enchantment&amp;quot;&lt;br /&gt;
                                                      // Resource location is explicitly defined: &amp;quot;minecraft:flame&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:flame&amp;quot; from the [Enchantment] registry&lt;br /&gt;
&lt;br /&gt;
    public static final Biome ice_flat = null;        // No annotation on the enclosing class.&lt;br /&gt;
                                                      // Therefore, the field is ignored.&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(&amp;quot;minecraft:creeper&amp;quot;)&lt;br /&gt;
    public static Entity creeper = null;              // Annotation present. [public static] is required.&lt;br /&gt;
                                                      // Entity does not have a corresponding registry.&lt;br /&gt;
                                                      // The registry has not been specified on the class.&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(registryName = &amp;quot;potion&amp;quot;, value = &amp;quot;levitation&amp;quot;)&lt;br /&gt;
    public static final Potion levitation = null;     // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // Registry name is explicitly defined: &amp;quot;minecraft:potion&amp;quot;&lt;br /&gt;
                                                      // Name path is the value of the annotation: &amp;quot;levitation&amp;quot;&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // No annotation in enclosing class.&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Creating Custom Registries ==&lt;br /&gt;
&lt;br /&gt;
Creating custom registries for your mod might be useful if you want other mods to add new things to your system. For example, you might have magic spells and want to allow other mods to add new spells. For this you will want to make a registry (eg. &amp;quot;mymagicmod:spells&amp;quot;). This way, other mods will be able to register things to that list, and you won't have to do anything else.&lt;br /&gt;
&lt;br /&gt;
Just like with registering a new item or block you have two ways of making a new registry. Each method takes in a &amp;lt;code&amp;gt;RegistryBuilder&amp;lt;/code&amp;gt; which is used to build an &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt;. Each builder should have its name set via &amp;lt;code&amp;gt;#setName&amp;lt;/code&amp;gt; before being created.&lt;br /&gt;
&lt;br /&gt;
=== With DeferredRegister ===&lt;br /&gt;
&lt;br /&gt;
The first method involves the second static constructor: &amp;lt;code&amp;gt;DeferredRegister#create(ResourceLocation, String)&amp;lt;/code&amp;gt;. From there, we can construct the registry using &amp;lt;code&amp;gt;#makeRegistry&amp;lt;/code&amp;gt;. This will already populate &amp;lt;code&amp;gt;#setName&amp;lt;/code&amp;gt; for us. This method also returns a supplier of the registry which we can use after the &amp;lt;code&amp;gt;NewRegistryEvent&amp;lt;/code&amp;gt; is called.&lt;br /&gt;
&lt;br /&gt;
Here is an example:&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final DeferredRegister&amp;lt;ExampleRegistry&amp;gt; EXAMPLE = DeferredRegister.create(new ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;), MODID);&lt;br /&gt;
&lt;br /&gt;
public static final Supplier&amp;lt;IForgeRegistry&amp;lt;ExampleRegistry&amp;gt;&amp;gt; REGISTRY = EXAMPLE.makeRegistry(RegistryBuilder::new);&lt;br /&gt;
|kotlin=val EXAMPLE: DeferredRegister&amp;lt;ExampleRegistry&amp;gt; = DeferredRegister.create(ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;), MODID)&lt;br /&gt;
&lt;br /&gt;
val REGISTRY: IForgeRegistry&amp;lt;ExampleRegistry&amp;gt; by lazy {&lt;br /&gt;
    EXAMPLE.makeRegistry(::RegistryBuilder).get()&lt;br /&gt;
}&lt;br /&gt;
|scala=final val EXAMPLE = DeferredRegister.create(new ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;), MODID)&lt;br /&gt;
&lt;br /&gt;
final lazy val REGISTRY = EXAMPLE.makeRegistry(() =&amp;gt; new RegistryBuilder).get&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
=== Using &amp;lt;code&amp;gt;NewRegistryEvent&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The second method can be done during the &amp;lt;code&amp;gt;NewRegistryEvent&amp;lt;/code&amp;gt; event. Using &amp;lt;code&amp;gt;NewRegistryEvent#create&amp;lt;/code&amp;gt;, you can pass in a &amp;lt;code&amp;gt;RegistryBuilder&amp;lt;/code&amp;gt; directly. This method will return a &amp;lt;code&amp;gt;Supplier&amp;lt;IForgeRegistry&amp;lt;V&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; that can be stored and queried after the event is fired to gain access to your &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt; instance.&lt;br /&gt;
&lt;br /&gt;
Here is an example: (the event handler is registered on the '''mod event bus''')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public static Supplier&amp;lt;IForgeRegistry&amp;lt;ExampleRegistry&amp;gt;&amp;gt; registrySupplier = null;&lt;br /&gt;
&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void onNewRegistry(NewRegistryEvent event){&lt;br /&gt;
    RegistryBuilder&amp;lt;ExampleRegistry&amp;gt; registryBuilder = new RegistryBuilder&amp;lt;&amp;gt;();&lt;br /&gt;
    registryBuilder.setName(new ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;);&lt;br /&gt;
    registrySupplier = event.create(registryBuilder);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Handling Missing Entries ==&lt;br /&gt;
&lt;br /&gt;
When loading a pre-existing world after removing mods or updating versions, there are cases where certain registry objects will cease to exist. In these cases, it is possible to specify actions to remove a mapping, prevent the world from loading, or remap the name as needed. This can be done through the third of the registry events: &amp;lt;code&amp;gt;MissingMappingsEvent&amp;lt;/code&amp;gt;. Within the event, you can grab an immutable list of missing mappings associated with a mod id for a given registry via &amp;lt;code&amp;gt;#getMappings&amp;lt;/code&amp;gt; or a list of all mappings via &amp;lt;code&amp;gt;#getAllMappings&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For each &amp;lt;code&amp;gt;Mapping&amp;lt;/code&amp;gt;, you can either execute one of the following methods:&lt;br /&gt;
* &amp;lt;code&amp;gt;#ignore&amp;lt;/code&amp;gt; which abandons the entry when loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#warn&amp;lt;/code&amp;gt; which warns the user about the missing entry but continues loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#fail&amp;lt;/code&amp;gt; which prevents the world from loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#remap&amp;lt;/code&amp;gt; which remaps the entry to the specified non-null object in the same registry&lt;br /&gt;
&lt;br /&gt;
If none of the above are specified, then the default action of notifying the user about the missing mappings occur.&lt;br /&gt;
&lt;br /&gt;
Here is an example:  (the event handler is registered on the '''forge event bus''')&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=// This will ignore any missing test items from the specified world&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void onMissing(final MissingMappingsEvent event) {&lt;br /&gt;
    event.getMappings(ForgeRegistries.Keys.ITEMS, MODID).stream()&lt;br /&gt;
        .filter(mapping -&amp;gt; mapping.key.getPath().contains(&amp;quot;test&amp;quot;))&lt;br /&gt;
            .forEach(Mapping::ignore);&lt;br /&gt;
}&lt;br /&gt;
|groovy=// This will ignore any missing test items from the specified world&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
void onMissing(final MissingMappingsEvent event) {&lt;br /&gt;
    event.getMappings(ForgeRegistries.Keys.ITEMS, MODID).stream()&lt;br /&gt;
        .filter(mapping -&amp;gt; mapping.key.path.contains(&amp;quot;test&amp;quot;))&lt;br /&gt;
            .forEach(Mapping::ignore);&lt;br /&gt;
}&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Common Concepts]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Internationalization&amp;diff=3267</id>
		<title>Internationalization</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Internationalization&amp;diff=3267"/>
		<updated>2022-06-13T19:45:43Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update again&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Internationalization''' (shortened as '''i18n'''), is a way of designing code so that it requires no changes to be adapted for various languages. '''Localization''' (shortened as '''l10n''') is the process of adapting displayed text to the user’s language.&lt;br /&gt;
&lt;br /&gt;
Internationalization is implemented using ''translation keys''. A translation key is a string that identifies a piece of displayable text in no specific language. For example, &amp;lt;code&amp;gt;block.minecraft.dirt&amp;lt;/code&amp;gt; is the translation key referring to the name of the Dirt block. This way, displayable text may be referenced with no concern for a specific language. The code requires no changes to be adapted in a new language.&lt;br /&gt;
&lt;br /&gt;
Localization will happen in the game’s locale. In a Minecraft client the locale is specified by the language settings. On a dedicated server, the only supported locale is &amp;lt;code&amp;gt;en_us&amp;lt;/code&amp;gt;. A list of available locales can be found on the [https://minecraft.gamepedia.com/Language#Available_languages Minecraft Wiki].&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|The only purpose of a translation key is internationalization. Do not use them for logic, such as comparing if two blocks are equal. Use their [[Registration|registry names]] instead.}}&lt;br /&gt;
&lt;br /&gt;
== Language files ==&lt;br /&gt;
&lt;br /&gt;
Language files are located by &amp;lt;code&amp;gt;assets/[namespace]/lang/[locale].json&amp;lt;/code&amp;gt; (e.g. the US English translation for &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt; would be &amp;lt;code&amp;gt;assets/examplemod/lang/en_us.json&amp;lt;/code&amp;gt;). The file format is simply a json map from translation keys to values. The file must be encoded in UTF-8.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;item.examplemod.example_item&amp;quot;: &amp;quot;Example Item Name&amp;quot;,&lt;br /&gt;
  &amp;quot;block.examplemod.example_block&amp;quot;: &amp;quot;Example Block Name&amp;quot;,&lt;br /&gt;
  &amp;quot;commands.examplemod.example_command.error&amp;quot;: &amp;quot;Example Command Errored!&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Usage with Blocks and Items ==&lt;br /&gt;
&lt;br /&gt;
Block, Item, and a few other Minecraft classes have built-in translation keys used to display their names. These translation keys are specified by overriding &amp;lt;code&amp;gt;getDescriptionId()&amp;lt;/code&amp;gt;. Item also has &amp;lt;code&amp;gt;getDescriptionId(ItemStack)&amp;lt;/code&amp;gt; which can be overridden to provide different translation keys depending on &amp;lt;code&amp;gt;ItemStack&amp;lt;/code&amp;gt; NBT.&lt;br /&gt;
&lt;br /&gt;
By default, &amp;lt;code&amp;gt;getDescriptionId()&amp;lt;/code&amp;gt; will return &amp;lt;code&amp;gt;block&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;item&amp;lt;/code&amp;gt;. prepended to the registry name of the block or item, with the colon replaced by a dot. &amp;lt;code&amp;gt;BlockItem&amp;lt;/code&amp;gt;s will take their corresponding Block's translation key by default. For example, an item with ID &amp;lt;code&amp;gt;examplemod:example_item&amp;lt;/code&amp;gt; effectively requires the following line in a language file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;item.examplemod.example_item&amp;quot;: &amp;quot;Example Item Name&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Localization methods ==&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|A common issue is having the server localize for clients. The server can only localize in its own locale, which does not necessarily match the locale of connected clients.&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
To respect the language settings of clients, the server should have clients localize text in their own locale using components with &amp;lt;code&amp;gt;TranslatableContents&amp;lt;/code&amp;gt; or other methods preserving the language neutral translation keys.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3 id=&amp;quot;I18n&amp;quot;&amp;gt;&amp;lt;tt style=&amp;quot;font-size: 100%&amp;quot;&amp;gt;net.minecraft.client.resources.language.I18n&amp;lt;/tt&amp;gt;&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Tip/Danger|'''This I18n class can only be found on the [[Sides#Different_Kinds_of_Sides|physical client]]!''' It is intended to be used by code that only runs on the client. Attempts to use this on a server will throw exceptions and crash.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;get(String, Object...)&amp;lt;/code&amp;gt; localizes in the client’s locale with formatting. The first parameter is a translation key, and the rest are formatting arguments for &amp;lt;code&amp;gt;String.format(String, Object...)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt style=&amp;quot;font-size: 100%&amp;quot;&amp;gt;TranslatableContents&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;TranslatableContents&amp;lt;/code&amp;gt; is a &amp;lt;code&amp;gt;ComponentContents&amp;lt;/code&amp;gt; that is localized and formatted lazily. It is very useful when sending messages to players because it will be automatically localized in their own locale.&lt;br /&gt;
&lt;br /&gt;
The first parameter of the &amp;lt;code&amp;gt;TranslatableContents(String, Object...)&amp;lt;/code&amp;gt; constructor is a translation key, and the rest are used for formatting. The only supported format specifiers are &amp;lt;code&amp;gt;%s&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;%1$s&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;%2$s&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;%3$s&amp;lt;/code&amp;gt; etc. Formatting arguments may be other &amp;lt;code&amp;gt;Component&amp;lt;/code&amp;gt;s that will be inserted into the resulting formatted text with all their attributes preserved.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;MutableComponent&amp;lt;/code&amp;gt; can be created using &amp;lt;code&amp;gt;Component#translatable&amp;lt;/code&amp;gt; by passing in the &amp;lt;code&amp;gt;TranslatableContents&amp;lt;/code&amp;gt;'s parameters. It can also be created using &amp;lt;code&amp;gt;MutableComponent#create&amp;lt;/code&amp;gt; by passing in the &amp;lt;code&amp;gt;ComponentContents&amp;lt;/code&amp;gt; itself.&lt;br /&gt;
&lt;br /&gt;
[[Category:Common Concepts]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Sides&amp;diff=3266</id>
		<title>Sides</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Sides&amp;diff=3266"/>
		<updated>2022-06-13T19:43:53Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update to 1.19&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Under construction}} &amp;lt;!-- modloading process is missing --&amp;gt; &lt;br /&gt;
A very important concept to understand when modding Minecraft are the two sides: '''client''' and '''server'''. There are many, many common misconceptions and mistakes regarding siding, which can lead to bugs that might not crash the game, but can rather have unintended and often unpredictable effects.&lt;br /&gt;
&lt;br /&gt;
== Different Kinds of Sides ==&lt;br /&gt;
&lt;br /&gt;
When we say &amp;quot;client&amp;quot; or &amp;quot;server&amp;quot;, it usually follows with a fairly intuitive understanding of what part of the game we’re talking about. After all, a client is what the user interacts with, and a server is where the user connects for a multiplayer game. Easy, right?&lt;br /&gt;
&lt;br /&gt;
But because of the structure of how Minecraft works, there can be some ambiguity even with two such terms. Here we disambiguate the four possible meanings of &amp;quot;client&amp;quot; and &amp;quot;server&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
* '''Physical Client''' - The ''physical client'' is the entire program that runs whenever you launch Minecraft from the launcher. All threads, processes, and services that run during the game’s graphical, interactable lifetime are part of the physical client.&lt;br /&gt;
* '''Physical Server''' - Often known as the dedicated server, the ''physical server'' is the entire program that runs whenever you launch any dedicated server executable or JAR (&amp;lt;code&amp;gt;minecraft_server.jar&amp;lt;/code&amp;gt;) that does not bring up a playable GUI.&lt;br /&gt;
* '''Logical Server''' - The ''logical server'' is what runs game logic: mob spawning, weather, updating inventories, health, AI, and all other game mechanics. The logical server is present within the physical server, but is also can run inside a physical client together with a logical client, as a single player world. The logical server always runs in a thread named the &amp;lt;code&amp;gt;Server Thread&amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Logical Client''' - The ''logical client'' is what accepts input from the player and relays it to the logical server. In addition, it also receives information from the logical server and makes it available graphically to the player. The logical client runs in the &amp;lt;code&amp;gt;Render Thread&amp;lt;/code&amp;gt;, though often several other threads are spawned to handle things like audio and chunk render batching.&lt;br /&gt;
&lt;br /&gt;
In the Minecraft codebase, the physical sides are represented by an enum called &amp;lt;code&amp;gt;Dist&amp;lt;/code&amp;gt;, while the logical sides are represented by an enum called &amp;lt;code&amp;gt;LogicalSide&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Tip|It is guaranteed that the logical cient always runs on the physical client; however, the same cannot be said of the logical server.}}&lt;br /&gt;
&lt;br /&gt;
== Performing Side-Specific Operations ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;Level#isClientSide&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
This &amp;lt;code&amp;gt;boolean&amp;lt;/code&amp;gt; check is the most common way (and the most recommended way) to check the currently running '''logical side'''. Querying this field on a &amp;lt;code&amp;gt;Level&amp;lt;/code&amp;gt; object establishes the logical side that the level belongs to. That is, if this field is &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;, the level extends &amp;lt;code&amp;gt;ClientLevel&amp;lt;/code&amp;gt; and is currently running on the logical client, while if the field is &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;, the level extends &amp;lt;code&amp;gt;ServerLevel&amp;lt;/code&amp;gt; and is running on the logical server. &lt;br /&gt;
&lt;br /&gt;
It follows that the physical/dedicated server will always contain &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; in this field, but we cannot assume that &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; implies a physical server, since this field can also be &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; for the logical server inside a physical client (in other words, a single player world).&lt;br /&gt;
&lt;br /&gt;
Use this check whenever you need to determine if game logic and other mechanics should be run. For example, if you want to damage the player every time they click your block, or have your machine process dirt into diamonds, you should only do so after ensuring &amp;lt;code&amp;gt;level#isClientSide&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;. Applying game logic to the logical client can cause desynchronization (ghost entities, desynchronized stats, etc.) in the best case, and crashes in the worst case.&lt;br /&gt;
&lt;br /&gt;
This check should be used as your go-to default. Aside from the sided events and &amp;lt;code&amp;gt;DistExecutor&amp;lt;/code&amp;gt;, rarely will you need the other ways of determining sides and adjusting behavior.&lt;br /&gt;
&lt;br /&gt;
=== Sided Setup Events ===&lt;br /&gt;
&lt;br /&gt;
There are different events which are fired at different stages during the [[Stages_of_Modloading|modloading process]]. Most of these events are fired on both physical sides, except for the '''sided setup events''': &amp;lt;code&amp;gt;FMLClientSetupEvent&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;FMLDedicatedServerSetupEvent&amp;lt;/code&amp;gt;, which is fired on the physical client and the physical/dedicated server respectively.&lt;br /&gt;
&lt;br /&gt;
These events should be used for running side-specific initialization code. It is recommended to either put your sided event handler registration behind a &amp;lt;code&amp;gt;DistExecutor&amp;lt;/code&amp;gt; call, or use the &amp;lt;code&amp;gt;@Mod.EventBusSubscriber&amp;lt;/code&amp;gt; anntoation with '&amp;lt;code&amp;gt;value = Dist.CLIENT&amp;lt;/code&amp;gt; for clients (or &amp;lt;code&amp;gt;value = Dist.DEDICATED_SERVER&amp;lt;/code&amp;gt; for the dedicated server) to conditionally register your event handlers and prevent the classes referenced within from crashing upon being loaded.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;DistExecutor&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Considering the use of a single &amp;quot;universal&amp;quot; jar for client and server mods, and the separation of the physical sides into two jars, an important question comes to mind: How do we use code that is only present on one physical side? All code in &amp;lt;code&amp;gt;net.minecraft.client&amp;lt;/code&amp;gt; (such as anything rendering-related) is only present on the physical client, and all code in &amp;lt;code&amp;gt;net.minecraft.server.dedicated&amp;lt;/code&amp;gt; is only present on the physical server. &lt;br /&gt;
&lt;br /&gt;
If any class you write references those names in any way, they will crash the game when that respective class is loaded in an environment where those names do not exist. For example, a very common mistake in beginners is to call &amp;lt;code&amp;gt;Minecraft.getMinecraft().&amp;lt;doStuff&amp;gt;()&amp;lt;/code&amp;gt; in block or block entity classes, which will crash any physical/dedicated server as soon as the class is loaded.&lt;br /&gt;
&lt;br /&gt;
How do we resolve this? Forge provides the &amp;lt;code&amp;gt;DistExecutor&amp;lt;/code&amp;gt; utility class, which provides various methods to run and call different code depending on the physical side. There are two versions of each method: &amp;lt;code&amp;gt;safe*&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;unsafe&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;safe*&amp;lt;/code&amp;gt; methods accept a supplied method reference from another class; otherwise, an error will be thrown. &amp;lt;code&amp;gt;unsafe*&amp;lt;/code&amp;gt; methods accept a doubly supplied instance instead. &amp;lt;code&amp;gt;unsafe*&amp;lt;/code&amp;gt; methods could cause &amp;lt;code&amp;gt;ClassNotFoundException&amp;lt;/code&amp;gt;s depending on how they are used, though in standard cases referencing an external class within the double supplier should be safe. In any case, make sure you understand how the [https://docs.oracle.com/javase/specs/jvms/se16/html/jvms-5.html#jvms-5.4.1 class verifier] works to load classes before using this.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|&lt;br /&gt;
It is important to understand that &amp;lt;code&amp;gt;DistExecutor&amp;lt;/code&amp;gt; checks the '''physical''' side. A single player world (logical server + logical client within a physical client) will always use &amp;lt;code&amp;gt;Dist.CLIENT&amp;lt;/code&amp;gt;!}}&lt;br /&gt;
&lt;br /&gt;
=== Thread Groups ===&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;code&amp;gt;Thread.currentThread().getThreadGroup() == SidedThreadGroups.SERVER&amp;lt;/code&amp;gt;, it is likely the current thread is on the logical server. Otherwise, it is likely on the logical client. This is useful to retrieve the '''logical''' side when you do not have access to a &amp;lt;code&amp;gt;Level&amp;lt;/code&amp;gt; object to check &amp;lt;code&amp;gt;isClientSide&amp;lt;/code&amp;gt;. It ''guesses'' which logical side you are on by looking at the thread group of the currently running thread. Because it is a guess, this method should only be used when other options have been exhausted. In all other cases, you should prefer checking &amp;lt;code&amp;gt;level#isClientSide&amp;lt;/code&amp;gt; to this check.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;FMLEnvironment.dist&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FMLEnvironment.dist&amp;lt;/code&amp;gt; holds the '''physical''' side your code is running on, as a value of &amp;lt;code&amp;gt;Dist.CLIENT&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Dist.DEDICATED_SERVER&amp;lt;/code&amp;gt;. This is determined by the mod loading code, so it always hold the correct value. However, there is little reason to directly query this variable, as most use-cases can use &amp;lt;code&amp;gt;DistExecutor&amp;lt;/code&amp;gt; instead (which uses this value internally).&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;tt&amp;gt;@OnlyIn&amp;lt;/tt&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
Annotating a method or field with the &amp;lt;code&amp;gt;@OnlyIn(Dist)&amp;lt;/code&amp;gt; annotation indicates to the loader that the respective member should be completely stripped out of the definition not on the specified '''physical''' side. Usually, these are only seen when browsing through the decompiled Minecraft code, indicating methods that the Mojang obfuscator stripped out. &lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|There is '''NO''' reason for using this annotation directly. Use &amp;lt;code&amp;gt;DistExecutor&amp;lt;/code&amp;gt; or a check on &amp;lt;code&amp;gt;FMLEnvironment.dist&amp;lt;/code&amp;gt; instead.}}&lt;br /&gt;
&lt;br /&gt;
== Common Mistakes ==&lt;br /&gt;
&lt;br /&gt;
=== Reaching Across Logical Sides ===&lt;br /&gt;
&lt;br /&gt;
Whenever you want to send information from one logical side to another, you must '''always''' use [[SimpleChannel|network packets]]. It is incredibly tempting, when in a single player scenario, to directly transfer data from the logical server to the logical client.&lt;br /&gt;
&lt;br /&gt;
This is actually very commonly inadvertently done through static fields. Since the logical client and logical server share the same JVM instance in a single player scenario, both threads writing to and reading from static fields will cause all sorts of race conditions and classical issues associated with threading.&lt;br /&gt;
&lt;br /&gt;
This mistake can also be made explicitly by accessing physical client-only classes such as &amp;lt;code&amp;gt;Minecraft&amp;lt;/code&amp;gt; from common code that runs or can run on the logical server. This mistake is easy to miss for beginners, who debug in a physical client. The code will work there, but will immediately crash on a physical server. For this reason, it is always recommended to test your mod with the physical/dedicated server.&lt;br /&gt;
&lt;br /&gt;
===Writing One-Sided Mods===&lt;br /&gt;
Your mods are expected to always load, regardless of if they are loaded on the client or the server. For one-sided mods, this means that they must still run on the opposite physical side.&lt;br /&gt;
&lt;br /&gt;
So for one-sided mods, you would typically register your event handlers using [[#DistExecutor|&amp;lt;code&amp;gt;DistExecutor&amp;lt;/code&amp;gt;]] or &amp;lt;code&amp;gt;@EventBusSubscriber(value = Dist.*)&amp;lt;/code&amp;gt;, instead of directly calling the relevant registration methods in the constructor. The idea is that, if your mod is loaded on the wrong side, it should simply do nothing: listen to no events, do no special behaviors, and so on. A one-sided mod by nature should not register blocks, items, … since they would need to be available on the other side, too.&lt;br /&gt;
&lt;br /&gt;
Additionally, if your mod is one-sided, it typically does not forbid the user from joining a server that is lacking that mod. Therefore, you should set the &amp;lt;code&amp;gt;displayTest&amp;lt;/code&amp;gt; property in your [[Mods.toml|mods.toml]] to whatever value is necessary.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;toml&amp;gt;&lt;br /&gt;
[[mods]]&lt;br /&gt;
  # ...&lt;br /&gt;
  # MATCH_VERSION means that your mod will cause a red X if the versions on client and server differ. This is the default behaviour and should be what you choose if you have server and client elements to your mod.&lt;br /&gt;
  # IGNORE_SERVER_VERSION means that your mod will not cause a red X if it's present on the server but not on the client. This is what you should use if you're a server only mod.&lt;br /&gt;
  # IGNORE_ALL_VERSION means that your mod will not cause a red X if it's present on the client or the server. This is a special case and should only be used if your mod has no server component.&lt;br /&gt;
  # NONE means that no display test is set on your mod. You need to do this yourself, see IExtensionPoint.DisplayTest for more information. You can define any scheme you wish with this value.&lt;br /&gt;
  # IMPORTANT NOTE: this is NOT an instruction as to which environments (CLIENT or DEDICATED SERVER) your mod loads on. Your mod should load (and maybe do nothing!) whereever it finds itself.&lt;br /&gt;
  displayTest=&amp;quot;IGNORE_ALL_VERSION&amp;quot; # MATCH_VERSION is the default if nothing is specified (#optional)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a custom display test is to be used, then the &amp;lt;code&amp;gt;displayTest&amp;lt;/code&amp;gt; option should be set to &amp;lt;code&amp;gt;NONE&amp;lt;/code&amp;gt;, and an &amp;lt;code&amp;gt;IExtensionPoint$DisplayTest&amp;lt;/code&amp;gt; extension should be registered:&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=// Make sure the mod being absent on the other network side does not cause the client to display the server as incompatible&lt;br /&gt;
ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, () -&amp;gt; new IExtensionPoint.DisplayTest(() -&amp;gt; NetworkConstants.IGNORESERVERONLY, (a, b) -&amp;gt; true));&lt;br /&gt;
|kotlin=// Make sure the mod being absent on the other network side does not cause the client to display the server as incompatible&lt;br /&gt;
ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class) { IExtensionPoint.DisplayTest(Supplier { NetworkConstants.IGNORESERVERONLY }, BiPredicate { _: String, _: Boolean -&amp;gt; true }) }&lt;br /&gt;
|scala=import scala.compat.java8.FunctionConverters._&lt;br /&gt;
// Make sure the mod being absent on the other network side does not cause the client to display the server as incompatible&lt;br /&gt;
ModLoadingContext.get.registerExtensionPoint(IExtensionPoint.DisplayTest.class, (() =&amp;gt; new IExtensionPoint.DisplayTest((() =&amp;gt; NetworkConstants.IGNORESERVERONLY).asJava, asJavaBiPredicate((_: String, _: java.lang.Boolean) =&amp;gt; true))).asJava)&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
This tells the client that it should ignore the server version being absent, and tells the server that it should not tell the client this mod should be present.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Common Concepts]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Mods.toml&amp;diff=3265</id>
		<title>Mods.toml</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Mods.toml&amp;diff=3265"/>
		<updated>2022-06-13T19:34:15Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Basic display test info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Under construction}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file is read by the mod loader to determine what mods are packaged into your JAR file, and what information to display to the user in the Mods listing screen (accessible by pressing the &amp;quot;Mods&amp;quot; button on the main menu of the game). &lt;br /&gt;
&lt;br /&gt;
The file is formatted in [https://toml.io/en/ Tom's Obvious Minimal Language], or TOML for short. The example &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file in the MDK provides comments explaining the contents of the file. It should be stored under the &amp;lt;code&amp;gt;META-INF&amp;lt;/code&amp;gt; folder in your resources directory (&amp;lt;code&amp;gt;src/main/resources/META-INF/mods.toml&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Example &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;TOML&amp;quot;&amp;gt;&lt;br /&gt;
modLoader=&amp;quot;javafml&amp;quot;&lt;br /&gt;
# Forge for 1.19 is version 41&lt;br /&gt;
loaderVersion=&amp;quot;[41,)&amp;quot;&lt;br /&gt;
license=&amp;quot;All rights reserved&amp;quot;&lt;br /&gt;
issueTrackerURL=&amp;quot;github.com/MinecraftForge/MinecraftForge/issues&amp;quot;&lt;br /&gt;
showAsResourcePack=false&lt;br /&gt;
&lt;br /&gt;
[[mods]]&lt;br /&gt;
    modId=&amp;quot;examplemod&amp;quot;&lt;br /&gt;
    version=&amp;quot;1.0.0.0&amp;quot;&lt;br /&gt;
    displayName=&amp;quot;Example Mod&amp;quot;&lt;br /&gt;
    updateJSONURL=&amp;quot;minecraftforge.net/versions.json&amp;quot;&lt;br /&gt;
    displayURL=&amp;quot;minecraftforge.net&amp;quot;&lt;br /&gt;
    logoFile=&amp;quot;logo.png&amp;quot;&lt;br /&gt;
    credits=&amp;quot;I'd like to thank my mother and father.&amp;quot;&lt;br /&gt;
    authors=&amp;quot;Author&amp;quot;&lt;br /&gt;
    description='''&lt;br /&gt;
Lets you craft dirt into diamonds. This is a traditional mod that has existed for eons. It is ancient. The holy Notch created it. Jeb rainbowfied it. Dinnerbone made it upside down. Etc.&lt;br /&gt;
    '''&lt;br /&gt;
    displayTest=&amp;quot;MATCH_VERSION&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[dependencies.examplemod]]&lt;br /&gt;
    modId=&amp;quot;forge&amp;quot;&lt;br /&gt;
    mandatory=true&lt;br /&gt;
    versionRange=&amp;quot;[41,)&amp;quot;&lt;br /&gt;
    ordering=&amp;quot;NONE&amp;quot;&lt;br /&gt;
    side=&amp;quot;BOTH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[dependencies.examplemod]]&lt;br /&gt;
    modId=&amp;quot;minecraft&amp;quot;&lt;br /&gt;
    mandatory=true&lt;br /&gt;
    versionRange=&amp;quot;[1.19,1.20)&amp;quot;&lt;br /&gt;
    ordering=&amp;quot;NONE&amp;quot;&lt;br /&gt;
    side=&amp;quot;BOTH&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt; is specified as&amp;lt;code&amp;gt;${file.jarVersion}&amp;lt;/code&amp;gt;, Forge will replace the string with the 'Implementation Version' specified in the jar manifest at runtime. Since the userdev environment has no jar manifest to pull from, it will be &amp;lt;code&amp;gt;NONE&amp;lt;/code&amp;gt; instead. As such, it is usually recommended to leave this field alone.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; is split into three parts: the non-mod-specific properties, which are linked to the mod file; the mod properties, with a section for each mod; and dependency configurations, with a section for each mod's dependencies. Here is a table of attributes that may be given to a mod, where &amp;lt;code&amp;gt;mandatory&amp;lt;/code&amp;gt; means there is no default and the absence of the property causes an error.&lt;br /&gt;
&lt;br /&gt;
===Non-Mod-Specific Properties===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modLoader&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The language loader for the mod. Used to specify an alternative language for the mod, such as Kotlin, if one exists. The Forge-provided Java loader is &amp;lt;code&amp;gt;javafml&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;javafml&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;loaderVersion&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The acceptable version range of the language loader, expressed as a [https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html Maven version spec]. For the Forge-provided Java loader, the version is the major version of the Forge version.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;[41,)&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;license&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The license for the mod(s) in this JAR. This string may be any valid string, but it is suggested to set the value to be the name of your license, and/or a link to that license.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;GNU GPL v3, https://www.gnu.org/licenses/gpl-3.0.en.html&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;showAsResourcePack&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;&lt;br /&gt;
|Whether to display this mod's resources as a separate option in the resource pack menu. If disabled, the mod's resources will be rolled into the &amp;quot;Mod resources&amp;quot; pack.&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;properties&amp;lt;/code&amp;gt;&lt;br /&gt;
|table&lt;br /&gt;
|&amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;&lt;br /&gt;
|A table of custom substitution properties. This is used by &amp;lt;code&amp;gt;StringSubstitutor&amp;lt;/code&amp;gt; to replace values, using &amp;lt;code&amp;gt;${file.*}&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&amp;lt;code&amp;gt;{ &amp;quot;thingy&amp;quot; = 1 }&amp;lt;/code&amp;gt;, used in &amp;lt;code&amp;gt;${file.thingy}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;issueTrackerURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|A URL for an issues tracker. This should never be a blank string, as that will cause an error.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://my.issue.tracker/&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Mod Properties===&lt;br /&gt;
A mod entry is defined by a new section starting with a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[mods]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; header (In TOML, the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[mods]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; defines an [https://toml.io/en/v1.0.0-rc.2#array-of-tables array of tables]). All properties from that line until the next header will become the properties for that mod.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The mod's identifier (modid). This must match the following regex: &amp;lt;code&amp;gt;^[a-z][a-z0-9_-]{1,63}$&amp;lt;/code&amp;gt; (starts with a lowercase letter; other characters must be a lowercase letter, number, underscore or hyphen; must be 2-64 characters long).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;examplemod&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;namespace&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|value of &amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|An override namespace. Currently, there is no use for this property&lt;br /&gt;
|&amp;lt;code&amp;gt;example&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;1&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The mod's version, ideally conforming to [[Semantic Versioning|semantic versioning]]. The default value in the MDK for this is &amp;lt;code&amp;gt;${file.jarVersion}&amp;lt;/code&amp;gt;, which is replaced at runtime with the &amp;lt;code&amp;gt;Implementation-Version&amp;lt;/code&amp;gt; found in the jar's manifest file.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;0.2.4-beta1&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;displayName&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|value of &amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|The display name of the mod, for use in the Mods listing screen&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;Example Mod&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;MISSING DESCRIPTION&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The description of the mod, for use in the Mods listing screen. It's recommended to use a multiline string (surrounded by &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;'''&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;)&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;Adds things and stuff. &amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;logoFile&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|The path of the logo file image, for use in the Mods listing screen. The image must be in the root of the jar file, not in any subfolder thereof (e.g. the file is directly in &amp;lt;code&amp;gt;src/main/resources&amp;lt;/code&amp;gt;)&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;myAwesomeLogo.png&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;logoBlur&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|Whether to do some blurring on the mod's logo in the Mods listing screen. Has no effect if &amp;lt;code&amp;gt;logoFile&amp;lt;/code&amp;gt; is not set.&lt;br /&gt;
|&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;updateJSONURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|The update JSON URL, used by the [[Update_Checker|update checker]]. This should never be a blank string, as that will cause an error.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://myurl.me/path/to/update.json&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modproperties&amp;lt;/code&amp;gt;&lt;br /&gt;
|table&lt;br /&gt;
|&amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;&lt;br /&gt;
|A table of custom mod properties; this is not used for Forge, but is mainly for use by mods.&lt;br /&gt;
|&amp;lt;code&amp;gt;{ &amp;quot;useThing&amp;quot; = true }&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;credits&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|Credits and acknowledgements for the mod, for use in the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;This person and that guy&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;authors&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|Authors for the mod, for use in the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;ExampleDude&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;displayURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|A URL, displayed on the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://example.com/&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;displayTest&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;MATCH_VERSION&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|Controls the display of the mod in the server connection screen. Must be either &amp;lt;code&amp;gt;MATCH_VERSION&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;IGNORE_SERVER_VERSION&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;IGNORE_ALL_VERSION&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;NONE&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;IGNORE_ALL_VERSION&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Dependency Configurations===&lt;br /&gt;
Mods can define dependencies for their mods, which are checked by Forge before loading mods. This is used for e.g. ensuring your mod loads after another, or hard-crashing if a mod with a specified version does not exist.&lt;br /&gt;
&lt;br /&gt;
These dependency configurations, like the mod properties, are defined by a new section starting with &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[dependencies.modid]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, with &amp;lt;code&amp;gt;modid&amp;lt;/code&amp;gt; being the mod id that has this dependency. All properties from that line until the next header will become the properties of that dependency configuration.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The mod id of the dependency.&lt;br /&gt;
|&amp;lt;code&amp;gt;examplelibrary&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mandatory&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|Whether to crash if this dependency is not met.&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;versionRange&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The acceptable version range of the dependency, expressed as a [https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html Maven version spec]. An empty string is an unbounded version range, which matches any version.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;[1.0,2.0)&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;ordering&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;NONE&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|Defines if the mod must load before or after this dependency. The valid values are &amp;lt;code&amp;gt;BEFORE&amp;lt;/code&amp;gt; (must load before), &amp;lt;code&amp;gt;AFTER&amp;lt;/code&amp;gt; (must load after), and &amp;lt;code&amp;gt;NONE&amp;lt;/code&amp;gt; (does not care about order).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;AFTER&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;side&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;BOTH&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|physical side]]. The valid values are &amp;lt;code&amp;gt;CLIENT&amp;lt;/code&amp;gt; (present on the client), &amp;lt;code&amp;gt;SERVER&amp;lt;/code&amp;gt; (present on the dedicated server), and &amp;lt;code&amp;gt;BOTH&amp;lt;/code&amp;gt; (present on both sides).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;CLIENT&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|When specifying dependency ordering between two or more mods, beware of cyclic order!&lt;br /&gt;
An example: if mod A must load before mod B, and mod B must load before mod A, the game will crash because of the circular cycle.}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started]]&lt;br /&gt;
[[Category:Beginner Topics]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Getting_Started&amp;diff=3264</id>
		<title>Getting Started</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Getting_Started&amp;diff=3264"/>
		<updated>2022-06-13T19:27:01Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Buildscript updates&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Minecraft Forge''' is a modding framework, designed to allow different mods to load and work together to be compatible. Through the years, there has been many changes in the Forge tooling to make working with mods as seamless as possible. It is now easier than ever to start making your own mod.&lt;br /&gt;
&lt;br /&gt;
== The Mod Development Kit ==&lt;br /&gt;
The '''Mod Development Kit''' or '''MDK''' is a downloadable archive that contains the basic skeleton for starting a new mod. It contains the following files and folders:&lt;br /&gt;
&lt;br /&gt;
{{Tree list}}&lt;br /&gt;
* '''The Mod Development Kit'''&lt;br /&gt;
** &amp;lt;code&amp;gt;gradle/wrapper/&amp;lt;/code&amp;gt; - The folder containing the [https://docs.gradle.org/7.4.2/userguide/gradle_wrapper.html Gradle wrapper]'', Forge uses Version '''7.4.2'''''&lt;br /&gt;
** &amp;lt;code&amp;gt;src&amp;lt;/code&amp;gt; - The sources folder&lt;br /&gt;
*** &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; - The &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; source set&lt;br /&gt;
**** &amp;lt;code&amp;gt;java&amp;lt;/code&amp;gt; - The java sources for the &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; source set&lt;br /&gt;
***** ...&lt;br /&gt;
**** &amp;lt;code&amp;gt;resources&amp;lt;/code&amp;gt; - The resources for the &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; source set&lt;br /&gt;
***** &amp;lt;code&amp;gt;META-INF&amp;lt;/code&amp;gt; - The folder for '''meta'''data '''inf'''ormation files&amp;lt;ref&amp;gt;[https://stackoverflow.com/a/6075320/14416954 StackOverflow answer]: ''... Basically, if it was stored in META-INF, it was Meta-data Information...''&amp;lt;/ref&amp;gt;&lt;br /&gt;
****** &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; - The [[Mods.toml file|&amp;lt;tt&amp;gt;mods.toml&amp;lt;/tt&amp;gt; file]], where mods are declared&lt;br /&gt;
***** &amp;lt;code&amp;gt;pack.mcmeta&amp;lt;/code&amp;gt; - File used by Minecraft to [[mc:Data Pack#pack.mcmeta|identify data and resource packs]]&lt;br /&gt;
** &amp;lt;code&amp;gt;.gitattributes&amp;lt;/code&amp;gt; - Used by [[wikipedia:Git|Git]] for specifying attributes for files&amp;lt;ref&amp;gt;[https://git-scm.com/docs/gitattributes Official git documentation on &amp;lt;tt&amp;gt;.gitattributes&amp;lt;/tt&amp;gt;]&amp;lt;/ref&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;.gitignore&amp;lt;/code&amp;gt; - Used by Git for specifying intentionally untracked/ignored files&amp;lt;ref&amp;gt;[https://git-scm.com/docs/gitignore Official git documentation on &amp;lt;tt&amp;gt;.gitignore&amp;lt;/tt&amp;gt;]&amp;lt;/ref&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;build.gradle&amp;lt;/code&amp;gt; - The Gradle buildscript, which defines the project and tasks&amp;lt;ref&amp;gt;[https://docs.gradle.org/7.4.2/userguide/tutorial_using_tasks.html Gradle User Guide for 7.4.2: ''Build Script Basics'']&amp;lt;/ref&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;changelog.txt&amp;lt;/code&amp;gt; - The Forge version changelog&lt;br /&gt;
** &amp;lt;code&amp;gt;CREDITS.txt&amp;lt;/code&amp;gt; - Forge's credits/''thank you'' file&lt;br /&gt;
** &amp;lt;code&amp;gt;gradle.properties&amp;lt;/code&amp;gt; - The Gradle properties file, for defining additional variables and options&amp;lt;ref&amp;gt;[https://docs.gradle.org/7.4.2/userguide/build_environment.html#sec:gradle_configuration_properties Gradle User Guide for 7.4.2: ''Build Environment § Gradle properties'']&amp;lt;/ref&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;gradlew&amp;lt;/code&amp;gt; - The *nix shell file for executing the Gradle wrapper&lt;br /&gt;
** &amp;lt;code&amp;gt;gradlew.bat&amp;lt;/code&amp;gt; - The Windows batch file for executing the Gradle wrapper&lt;br /&gt;
** &amp;lt;code&amp;gt;LICENSE.txt&amp;lt;/code&amp;gt; - File containing the licensing information for Forge and libraries&lt;br /&gt;
** &amp;lt;code&amp;gt;README.txt&amp;lt;/code&amp;gt; - Readme file with the basic setup instructions&lt;br /&gt;
{{Tree list/end}}&lt;br /&gt;
&lt;br /&gt;
== Basic MDK Setup ==&lt;br /&gt;
# Download the MDK from the [https://files.minecraftforge.net/ official Minecraft Forge download site] and extract the MDK into an empty folder.&lt;br /&gt;
# Open your IDE of choice, and import the project as a Gradle project.&lt;br /&gt;
#* For '''Eclipse''': &amp;lt;tt&amp;gt;File &amp;gt; Import &amp;gt; Gradle &amp;gt; Existing Gradle Project&amp;lt;/tt&amp;gt;, select the folder for the &amp;lt;tt&amp;gt;Project root directory&amp;lt;/tt&amp;gt;, click &amp;lt;tt&amp;gt;Finish&amp;lt;/tt&amp;gt;&lt;br /&gt;
#* For '''IntelliJ IDEA''': &amp;lt;tt&amp;gt;File &amp;gt; Open&amp;lt;/tt&amp;gt;, select and open the folder, select the &amp;lt;tt&amp;gt;build.gradle&amp;lt;/tt&amp;gt; file, click &amp;lt;tt&amp;gt;OK&amp;lt;/tt&amp;gt;, click &amp;lt;tt&amp;gt;Open as Project&amp;lt;/tt&amp;gt;&lt;br /&gt;
#* For '''Visual Studio Code''': Run &amp;lt;code&amp;gt;./gradlew buildNeeded&amp;lt;/code&amp;gt; and then &amp;lt;code&amp;gt;./gradlew eclipse&amp;lt;/code&amp;gt;, then &amp;lt;tt&amp;gt;File &amp;gt; Open Folder...&amp;lt;/tt&amp;gt; and select the folder&lt;br /&gt;
# Wait for the setup process to complete and the Minecraft sources are decompiled.&lt;br /&gt;
#* For '''Visual Studio Code''': This step can be skipped as it was already done in the previous step&lt;br /&gt;
# Generate the run configurations for your IDE using the appropriate Gradle task. &amp;lt;br&amp;gt;These tasks can be run in the terminal using &amp;lt;code&amp;gt;./gradlew gen***Runs&amp;lt;/code&amp;gt;.&lt;br /&gt;
#* For '''Eclipse''': the task is &amp;lt;code&amp;gt;genEclipseRuns&amp;lt;/code&amp;gt;; to run in the IDE directly, open the &amp;lt;tt&amp;gt;Gradle Tasks&amp;lt;/tt&amp;gt; tab on the bottom panel, ''wait until the tasks have loaded'' then expand the folder, expand the &amp;lt;tt&amp;gt;fg_runs&amp;lt;/tt&amp;gt; folder, then double-click &amp;lt;tt&amp;gt;genEclipseRuns&amp;lt;/tt&amp;gt;.&lt;br /&gt;
#* For '''IntelliJ IDEA''': the task is &amp;lt;code&amp;gt;genIntellijRuns&amp;lt;/code&amp;gt;; to run in the IDE directly, open the &amp;lt;tt&amp;gt;Gradle&amp;lt;/tt&amp;gt; on the right, expand the project folder, double-click &amp;lt;tt&amp;gt;Tasks &amp;gt; fg_runs &amp;gt; genIntellijRuns&amp;lt;/tt&amp;gt;.&lt;br /&gt;
#* For '''Visual Studio Code''': the task is &amp;lt;code&amp;gt;genVSCodeRuns&amp;lt;/code&amp;gt;; the [https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-pack Extension Pack for Java] and [https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-gradle Gradle for Java plugin] should both be installed for smoother integration.&lt;br /&gt;
&lt;br /&gt;
{{Tip|The most popular IDEs used by Forge and mod developers are [https://www.eclipse.org/eclipseide/ Eclipse] and [https://www.jetbrains.com/idea/ IntelliJ IDEA]. While Visual Studio Code has a run generation task, because of its relative unpopularity as an IDE for Minecraft modding, the user will have to self-diagnose any issues that may arise from their use of it.}}&lt;br /&gt;
&lt;br /&gt;
== Customizing the MDK ==&lt;br /&gt;
The MDK provides default values for the buildscript and &amp;lt;tt&amp;gt;mods.toml&amp;lt;/tt&amp;gt; file. These values should be replaced with your own mod's information.&lt;br /&gt;
&lt;br /&gt;
All edits should be done below the &amp;lt;code&amp;gt;id 'net.minecraftforge.gradle'&amp;lt;/code&amp;gt; line. The lines above it are required for the Forge MDK to work correctly, and should not be modified without proper knowledge.&lt;br /&gt;
* All references to &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt; in the buildscript should be replaced with your modid.&lt;br /&gt;
** Use your IDE's find-and-replace function to quickly replace these values.&lt;br /&gt;
** Pick a unique and memorable modid. The modid must be between 2 and 64 characters, and must consist of lowercase letters, numbers, underscores (&amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;) and hyphens (&amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;). The recommendation is to avoid using acronyms and abbreviations.&lt;br /&gt;
* Change the &amp;lt;code&amp;gt;archivesBaseName&amp;lt;/code&amp;gt; variable to your modid. This is used as the base name for the JAR file when you build your mod, and as the &amp;lt;tt&amp;gt;artifactId&amp;lt;/tt&amp;gt; of your mod's [https://maven.apache.org/pom.html#Maven_Coordinates maven coordinates].&lt;br /&gt;
* Change the &amp;lt;code&amp;gt;group&amp;lt;/code&amp;gt; to your [[Proper Mod Structuring#Packaging|unique root java package]]. This is used as the &amp;lt;tt&amp;gt;groupId&amp;lt;/tt&amp;gt; of your mod's maven coordinates.&lt;br /&gt;
* In the &amp;lt;code&amp;gt;jar&amp;lt;/code&amp;gt; task, change the values of the &amp;lt;code&amp;gt;Specification-Vendor&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Implementation-Vendor&amp;lt;/code&amp;gt; keys to your username/brand name or other form of identification.&lt;br /&gt;
* ''Optional suggestion: '' Change the &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt; variable to have a 0 as the major version (ex. &amp;lt;code&amp;gt;'0.1'&amp;lt;/code&amp;gt;. This is to follow [[Semantic Versioning#During Development|semantic versioning guidelines]] for versions in active development.&lt;br /&gt;
&lt;br /&gt;
== Building and Testing ==&lt;br /&gt;
You can test your mod in the development environment using either your IDE's run configurations and built-in debugging utilities, or by running the &amp;lt;code&amp;gt;run*&amp;lt;/code&amp;gt; task as defined by the buildscript's run configurations.&lt;br /&gt;
&lt;br /&gt;
There are four default run configurations with the MDK:&lt;br /&gt;
* &amp;lt;code&amp;gt;runClient&amp;lt;/code&amp;gt;, for starting the client.&lt;br /&gt;
* &amp;lt;code&amp;gt;runServer&amp;lt;/code&amp;gt;, for starting the dedicated server. ''You will need to accept the EULA through the &amp;lt;tt&amp;gt;eula.txt&amp;lt;/tt&amp;gt; after running the server for the first time.''&lt;br /&gt;
* &amp;lt;code&amp;gt;runData&amp;lt;/code&amp;gt;, for starting the client in [[Datageneration|data generation]] mode.&lt;br /&gt;
* &amp;lt;code&amp;gt;runGameTestServer&amp;lt;/code&amp;gt;, for starting a build server to run [[Game_Tests|game tests]].&lt;br /&gt;
&lt;br /&gt;
{{Tip|Always test your mod in both the client and the dedicated server, even if you are making a one-sided mod. Mods should not crash when running on both sides, and one-sided mods should not crash if they run on the wrong side.}}&lt;br /&gt;
&lt;br /&gt;
You can build your mod's final JAR using the &amp;lt;code&amp;gt;build&amp;lt;/code&amp;gt; task. The resulting JAR will be located in the &amp;lt;code&amp;gt;build/libs&amp;lt;/code&amp;gt; folder under your project directory.&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Beginner Topics]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Making_Tools&amp;diff=3262</id>
		<title>Making Tools</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Making_Tools&amp;diff=3262"/>
		<updated>2022-06-12T18:52:37Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update to 1.19&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
Tools are simply an extension of the &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; class. Their implementations mainly rely on extending a specific class, the &amp;lt;code&amp;gt;TierSortingRegistry&amp;lt;/code&amp;gt;, and tags.&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;tt&amp;gt;Tier&amp;lt;/tt&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
To create any tool that does not derive from vanilla tiers, you will need your own implementation of &amp;lt;code&amp;gt;Tier&amp;lt;/code&amp;gt;. This is the basis of which all tool levels are created. If you would like to use a vanilla tier, then you should specify one of the enums within &amp;lt;code&amp;gt;Tiers&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Here are what each methods defines:&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; border=1&lt;br /&gt;
!Method !!Return Type !!Description &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;getUses&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;Integer&amp;lt;/code&amp;gt;   ||  The durability of all items in this tier. &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;getSpeed&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;Float&amp;lt;/code&amp;gt;   ||  The efficiency multiplier of all items in this tier. &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;getAttackDamageBonus&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;Float&amp;lt;/code&amp;gt;   ||  The base attack damage of all items in this tier. &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;getLevel&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;Integer&amp;lt;/code&amp;gt;   ||  The harvest level of this tier. Vanilla uses values 0-4. As of 37.0.31, Forge deprecates this value in favor of the sorting registry system discussed below. This value will be used if the tier is not registered however.&lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;getEnchantmentValue&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;Integer&amp;lt;/code&amp;gt;   ||  How enchantable an item of this tier is. &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;getRepairIngredient&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;Ingredient&amp;lt;/code&amp;gt;   ||  What ingredient can be used to repair this item. &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;getTag&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;TagKey&amp;lt;Block&amp;gt;&amp;lt;/code&amp;gt;   ||  What blocks this tier can mine. This should only encompass those blocks which are specific for this tier. Any blocks below this tier will be declared while registering. The naming convention of this tag is &amp;lt;code&amp;gt;&amp;lt;modid&amp;gt;:needs_&amp;lt;tier_name&amp;gt;_tool&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|An ingredient should be wrapped in a supplier to avoid calling the object directly. Tiers are loaded before registries are populated, so the call to the item needs to be deferred.}}&lt;br /&gt;
&lt;br /&gt;
{{Tip|Forge has a implementation class called &amp;lt;code&amp;gt;ForgeTier&amp;lt;/code&amp;gt; to create a common tier, though this does not have to be used.}}&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;tt&amp;gt;TierSortingRegistry&amp;lt;/tt&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
For a tier to be used in the new system, they need to be registered before items most commonly by static initialization. A tier can be registered via &amp;lt;code&amp;gt;TierSortingRegistry#registerTier&amp;lt;/code&amp;gt;. Any tier not defined in the sorting system will be defaulted to vanilla behavior.&lt;br /&gt;
&lt;br /&gt;
This has four parameters:&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; border=1&lt;br /&gt;
!Parameter !!Type !!Description &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;tier&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;Tier&amp;lt;/code&amp;gt;   ||  The tier object being registered.&lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt;   ||  The name of the tier for dependency resolution.&lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;after&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;List&amp;lt;Object&amp;gt;&amp;lt;/code&amp;gt;   ||  The list of tiers to place this tier after or the tiers of the same level that are weaker than this one. This can either be a &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;Tier&amp;lt;/code&amp;gt; where the first two are located by the &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; parameter above.&lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;before&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;List&amp;lt;Object&amp;gt;&amp;lt;/code&amp;gt;   ||  The list of tiers to place this tier before or the tiers of the same level that are stronger than this one. This can either be a &amp;lt;code&amp;gt;String&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;Tier&amp;lt;/code&amp;gt; where the first two are located by the &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; parameter above.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Tip|If your tier is equivalent to another tier, then &amp;lt;code&amp;gt;Tier#getTag&amp;lt;/code&amp;gt; should return an empty tag reference defined by &amp;lt;code&amp;gt;BlockTags#createOptional&amp;lt;/code&amp;gt; and have the equivalent tier be placed in the &amp;lt;code&amp;gt;after&amp;lt;/code&amp;gt; list when registering. If the tier is a vanilla tier, you should also specify the next tier above in the &amp;lt;code&amp;gt;before&amp;lt;/code&amp;gt; list.}}&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;tt&amp;gt;DiggerItem&amp;lt;/tt&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;DiggerItem&amp;lt;/code&amp;gt; is the base of which all tool items extend. You do not necessarily have to use this or any of its supertypes/subtypes. However, it is convenient if you are looking for standard behavior. The subtypes normally referenced are &amp;lt;code&amp;gt;AxeItem&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;HoeItem&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;PickaxeItem&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ShovelItem&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Each tool has four parameters: tier, attack damage, attack speed, and properties. Tiers and properties have already been explained in this and within the [[Making Items|item]] docs. Attack damage specifies how much damage to do above the current base set for that specific tier. Attack speed specifies the speed modifier to apply to your current attack speed (the base attack speed for a player is &amp;lt;code&amp;gt;4.0D&amp;lt;/code&amp;gt;). &lt;br /&gt;
&lt;br /&gt;
{{Tip|content=If you decide to extend &amp;lt;code&amp;gt;DiggerItem&amp;lt;/code&amp;gt;, there will be a fifth parameter which defines a tag of which blocks this item is effective on. The naming convention of these tags is &amp;lt;code&amp;gt;&amp;lt;modid&amp;gt;:mineable/&amp;lt;tool_name&amp;gt;&amp;lt;/code&amp;gt;. If this tag should be shared among other mods, the &amp;lt;code&amp;gt;forge&amp;lt;/code&amp;gt; namespace should be used instead. }}&lt;br /&gt;
&lt;br /&gt;
A tool's compatibility and partial implementation is defined by three methods:&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; border=1&lt;br /&gt;
!Method !!Return Type !!Description &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;getDestroySpeed&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;Float&amp;lt;/code&amp;gt;   ||  Defines whether a block will be mined faster than an empty hand or wrong tool.&lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;isCorrectToolForDrops&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;Boolean&amp;lt;/code&amp;gt;   ||  Defines which blocks can drop loot with your tool. If this returns false, then the destroy speed will always slow down mining. This should only be overridden if your item is not a &amp;lt;code&amp;gt;DiggerItem&amp;lt;/code&amp;gt; to implement &amp;lt;code&amp;gt;TierSortingRegistry#isCorrectTierForDrops&amp;lt;/code&amp;gt; which handles this logic.&lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;canPerformAction &amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;Boolean&amp;lt;/code&amp;gt;   ||  Queries whether a block can perform the associated action. By default, this will do nothing on its own since a &amp;lt;code&amp;gt;ToolAction&amp;lt;/code&amp;gt; is just a string. This can be combined with other logic to get the result of the performed action, usually by doing &amp;lt;code&amp;gt;BlockState#getToolModifiedState&amp;lt;/code&amp;gt;. New tool actions can be defined via &amp;lt;code&amp;gt;ToolAction#get&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Registering ==&lt;br /&gt;
&lt;br /&gt;
A tool must be [[Registration|registered]] the same as an item. Defining the tool type and tier level is done via the mineable tag implemented on your tool and the tier tag on your &amp;lt;code&amp;gt;Tier&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Category:Items]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=BlockStates&amp;diff=3261</id>
		<title>BlockStates</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=BlockStates&amp;diff=3261"/>
		<updated>2022-06-12T18:46:30Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Wrong param&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction of States ==&lt;br /&gt;
&lt;br /&gt;
The block state system abstracts out the details of the block's properties from the other behaviors of the block.&lt;br /&gt;
&lt;br /&gt;
Each &amp;lt;code&amp;gt;property&amp;lt;/code&amp;gt; of a block is described by an instance of &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Property&amp;lt;?&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Examples of block properties include instruments (&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Property&amp;lt;NoteBlockInstrument&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;), direction (&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Property&amp;lt;Direction&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;), poweredness (&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Property&amp;lt;Boolean&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;), etc. Each property has the value of the type &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;T&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; parametrized by &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Property&amp;lt;T&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A unique triple can be constructed from the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, the set of &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Property&amp;lt;?&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, and the set of values for those properties. This unique triple is called a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockState&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. For example, a stone button which is facing east and is powered or held down is represented by &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;minecraft:stone_button[facing=east,powered=true]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Proper Usage of Block States ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockState&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; is a flexible and powerful system, but it also has limitations. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockState&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s are immutable, and all combinations of their properties are generated on startup of the game. This means that having a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockState&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with many properties and possible values will slow down the loading of the game, and befuddle anyone trying to make sense of your block logic.&lt;br /&gt;
&lt;br /&gt;
Not all blocks and situations require the usage of &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockState&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;; only the most basic properties of a block should be put into one, and any other situation is better off with having a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockEntity&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; or being a separate &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Always consider if you actually need to use a state for your purposes.&lt;br /&gt;
&lt;br /&gt;
{{Colored box|title=Tip|content=A good rule of thumb is: '''if it has a different name, it should be a separate block'''.}}&lt;br /&gt;
&lt;br /&gt;
An example is making chair blocks: the ''direction'' of the chair should be a ''property'', while the different ''types of wood'' should be separated into different blocks.&lt;br /&gt;
An &amp;quot;Oak Chair&amp;quot; facing east (&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;oak_chair[facing=east]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;) is different from a &amp;quot;Spruce Chair&amp;quot; facing west (&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;spruce_chair[facing=west]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== Implementing Block States ==&lt;br /&gt;
&lt;br /&gt;
In your Block class, create or reference &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;static final&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Property&amp;lt;?&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; objects for every property that your Block has. You are free to make your own &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Property&amp;lt;?&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; implementations, but the means to do that are left as an exercise to the reader. The vanilla code provides several convenience implementations:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;IntegerProperty&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** Implements &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Property&amp;lt;Integer&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Defines a property that holds an integer value.&lt;br /&gt;
** Created by calling &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;IntegerProperty.create(String propertyName, int minimum, int maximum)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BooleanProperty&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** Implements &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Property&amp;lt;Boolean&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Defines a property that holds a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;true&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;false&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; value.&lt;br /&gt;
** Created by calling &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BooleanProperty.create(String propertyName)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;EnumProperty&amp;lt;E extends Enum&amp;lt;E&amp;gt;&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** Implements &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Property&amp;lt;E&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Defines a property that can take on the values of an Enum class.&lt;br /&gt;
** Created by calling &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;EnumProperty.create(String propertyName, Class&amp;lt;E&amp;gt; enumClass)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
** It is also possible to use only a subset of the Enum values (e.g. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;RailShape&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s that can only ascend and not turn). See the overloads of &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;EnumProperty.create&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;DirectionProperty&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** This is a convenience implementation of &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;EnumProperty&amp;lt;Direction&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
** Several convenience predicates are also provided. For example, to get a property that represents the cardinal directions, call &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;DirectionProperty.create(&amp;quot;&amp;lt;name&amp;gt;&amp;quot;, Direction.Plane.HORIZONTAL)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;; to get the X directions, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;DirectionProperty.create(&amp;quot;&amp;lt;name&amp;gt;&amp;quot;, Direction.Axis.X)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The class &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockStateProperties&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; contains shared vanilla properties which should be used or referenced whenever possible, in place of creating your own properties.&lt;br /&gt;
&lt;br /&gt;
When you have your desired &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Property&amp;lt;&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; objects, override &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block#createBlockStateDefinition(StateDefinition$Builder)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; in your ''Block'' class. In that method, call &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;StateDefinition$Builder#add(...);&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;  with the parameters as every &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Property&amp;lt;?&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; you wish the block to have.&lt;br /&gt;
&lt;br /&gt;
Every block will also have a &amp;quot;default&amp;quot; state that is automatically chosen for you. You can change this &amp;quot;default&amp;quot; state by calling the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block#registerDefaultState(BlockState)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; method from your constructor. When your block is placed it will become this &amp;quot;default&amp;quot; state. An example from &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;DoorBlock&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
this.registerDefaultState(&lt;br /&gt;
    this.stateDefinition.any()&lt;br /&gt;
        .setValue(FACING, Direction.NORTH)&lt;br /&gt;
        .setValue(OPEN, false)&lt;br /&gt;
        .setValue(HINGE, DoorHingeSide.LEFT)&lt;br /&gt;
        .setValue(POWERED, false)&lt;br /&gt;
        .setValue(HALF, DoubleBlockHalf.LOWER)&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you wish to change what &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockState&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; is used when placing your block, you can overwrite &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block#getStateForPlacement(BlockPlaceContext)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. This can be used to, for example, set the direction of your block depending on where the player is standing when they place it.&lt;br /&gt;
&lt;br /&gt;
Because &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockState&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s are immutable, and all combinations of their properties are generated on startup of the game, calling &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockState#setValue(Property&amp;lt;T&amp;gt;, T)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; will simply go to the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;'s &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;StateHolder&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and request the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockState&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with the set of values you want.&lt;br /&gt;
&lt;br /&gt;
Because all possible &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockState&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s are generated at startup, you are free and encouraged to use the reference equality operator (&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;==&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;) to check if two &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockState&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s are equal.&lt;br /&gt;
&lt;br /&gt;
== Using &amp;lt;tt&amp;gt;BlockState&amp;lt;/tt&amp;gt;s ==&lt;br /&gt;
&lt;br /&gt;
You can get the value of a property by calling &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockState#getValue(Property&amp;lt;?&amp;gt;)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, passing it the property you want to get the value of.&lt;br /&gt;
If you want to get a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockState&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with a different set of values, simply call &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockState#setValue(Property&amp;lt;T&amp;gt;, T)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with the property and its value.&lt;br /&gt;
&lt;br /&gt;
You can get and place &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockState&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s in the level using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Level#setBlockAndUpdate(BlockPos, BlockState)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Level#getBlockState(BlockPos)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. If you are placing a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, call &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block#defaultBlockState()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; to get the &amp;quot;default&amp;quot; state, and use subsequent calls to &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockState#setValue(Property&amp;lt;T&amp;gt;, T)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; as stated above to achieve the desired state.&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Registration&amp;diff=3260</id>
		<title>Registration</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Registration&amp;diff=3260"/>
		<updated>2022-06-12T18:44:14Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Add notice about non-vanilla registries for keys and names with DeferredRegister&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Registration is the process of making an object (such as an item or block) known to the game during runtime. If some objects are not registered, this could cause crashes even before the game is fully loaded or arbitrary behaviors such as bottlenecking mod compatibility for world generation.&lt;br /&gt;
&lt;br /&gt;
Most objects that are known within the game are handled by a &amp;lt;code&amp;gt;Registry&amp;lt;/code&amp;gt;. Each registry uniquely defines each object through a &amp;quot;registry name&amp;quot; via a [[Using Resources#ResourceLocation|ResourceLocation]].&lt;br /&gt;
&lt;br /&gt;
{{Tip|In a global context, each object is universally unique through its &amp;lt;code&amp;gt;ResourceKey&amp;lt;/code&amp;gt;: a concatenation of its registry's id and the object's registry name.}}&lt;br /&gt;
&lt;br /&gt;
Due to the inconsistent ordering and registration process vanilla uses, Forge wraps most vanilla registries using &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt;. This guarantees that the loading order for these wrapped registries will be &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt;, and then the rest of the wrapped registries in alphabetical order. All registries supported by Forge can be found within the &amp;lt;code&amp;gt;ForgeRegistries&amp;lt;/code&amp;gt; class. Since all registry names are unique to a specific registry, different registry objects within different registries can have the same name (e.g. a &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt; and an &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; each hold a registry object named &amp;lt;code&amp;gt;examplemod:object&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|If two registry objects within the same registry have the same name, the second object will override the first. The only registry that will throw an &amp;lt;code&amp;gt;IllegalArgumentException&amp;lt;/code&amp;gt; is the &amp;lt;code&amp;gt;DataSerializerEntry&amp;lt;/code&amp;gt; registry.}}&lt;br /&gt;
&lt;br /&gt;
== Methods for Registering ==&lt;br /&gt;
&lt;br /&gt;
There are two proper ways to register objects within an associated wrapped Forge registry: the &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; class, and the &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; lifecycle event.&lt;br /&gt;
&lt;br /&gt;
=== DeferredRegister ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; is an abstraction layer over the registry event used to register objects. It maintains a map of &amp;quot;registry name&amp;quot; to their associated suppliers and resolves those suppliers during &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; for the associated registry. This method is the currently recommended, and documented, way to handle these objects as it provides convenience and safety for those who want to statically initialize objects while avoiding some issues associated with it.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|When using &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt;s with non-vanilla registries, the registry key or the registry name should be supplied instead. These include registries for entity data serializers, global loot modifier serializers, world presets, and biome modifier serializers.}}&lt;br /&gt;
&lt;br /&gt;
An example of a mod registering a custom block:&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=private static final DeferredRegister&amp;lt;Block&amp;gt; BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;Block&amp;gt; EXAMPLE_BLOCK = BLOCKS.register(&amp;quot;example_block&amp;quot;, () -&amp;gt; new Block(BlockBehaviour.Properties.of(Material.STONE)));&lt;br /&gt;
&lt;br /&gt;
public ExampleMod() {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get().getModEventBus());&lt;br /&gt;
}&lt;br /&gt;
|kotlin=private val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID)&lt;br /&gt;
&lt;br /&gt;
val EXAMPLE_BLOCK: RegistryObject&amp;lt;Block&amp;gt; = BLOCKS.register(&amp;quot;example_block&amp;quot;) { Block(BlockBehaviour.Properties.of(Material.ROCK)) }&lt;br /&gt;
&lt;br /&gt;
internal class ExampleMod {&lt;br /&gt;
    init {&lt;br /&gt;
        BLOCKS.register(FMLJavaModLoadingContext.get().modEventBus)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
|scala=object ExampleMod {&lt;br /&gt;
    private final val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID)&lt;br /&gt;
&lt;br /&gt;
    final val EXAMPLE_BLOCK = registerBlock(&amp;quot;example_block&amp;quot;, () =&amp;gt; new Block(BlockBehaviour.Properties.of(Material.ROCK)))&lt;br /&gt;
}&lt;br /&gt;
class ExampleMod {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get.getModEventBus)&lt;br /&gt;
}&lt;br /&gt;
|groovy=private static final DeferredRegister&amp;lt;Block&amp;gt; BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;Block&amp;gt; EXAMPLE_BLOCK = BLOCKS.register(&amp;quot;example_block&amp;quot;, () -&amp;gt; new Block(BlockBehaviour.Properties.of(Material.STONE)));&lt;br /&gt;
&lt;br /&gt;
ExampleMod() {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get().modEventBus);&lt;br /&gt;
}&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip|When using a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; to register any object, the name inputted will be automatically prefixed with the mod id passed in, giving the above object a &amp;quot;registry name&amp;quot; of &amp;lt;code&amp;gt;examplemod:example_block&amp;lt;/code&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
=== RegisterEvent ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is the second way register objects. This [[Events|event]] is fired for each registry synchronously in vanilla registry order after &amp;lt;code&amp;gt;FMLConstructModEvent&amp;lt;/code&amp;gt; and before the configs are loaded. Objects are registered using &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; by passing in the registry key, the name of the registry object, and the object itself. There is an additional &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; overload which takes in a consumed helper to register an object with a given name. It is recommended to use this method to avoid unnecessary object creation.&lt;br /&gt;
&lt;br /&gt;
Here is an example: (the event handler is registered on the '''mod event bus''')&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=@SubscribeEvent&lt;br /&gt;
public void register(RegisterEvent event) {&lt;br /&gt;
    event.register(ForgeRegistries.Keys.BLOCKS,&lt;br /&gt;
        helper -&amp;gt; helper.register(new ResourceLocation(MODID, &amp;quot;example_block&amp;quot;), new Block(...))&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
|kotlin=@JvmStatic&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
private fun register(event: RegisterEvent) =&lt;br /&gt;
    event.register(ForgeRegistries.Keys.BLOCKS) {&lt;br /&gt;
        helper -&amp;gt; helper.register(ResourceLocation(MODID, &amp;quot;example_block&amp;quot;), Block(...))&lt;br /&gt;
    }&lt;br /&gt;
|scala=@SubscribeEvent&lt;br /&gt;
def register(event: RegisterEvent): Unit =&lt;br /&gt;
    event.register(ForgeRegistries.Keys.BLOCKS,&lt;br /&gt;
        helper =&amp;gt; helper.register(new ResourceLocation(MODID, &amp;quot;example_block&amp;quot;), new Block(...))&lt;br /&gt;
    )&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|Since all objects registered must be singleton, some classes cannot by themselves be registered. Instead, &amp;lt;code&amp;gt;*Type&amp;lt;/code&amp;gt; classes are registered and used in the formers' constructors to wrap the flyweight objects. For example, a [[Basics_of_Block_Entities|&amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt;]] is wrapped via &amp;lt;code&amp;gt;BlockEntityType&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;Entity&amp;lt;/code&amp;gt; is wrapped via &amp;lt;code&amp;gt;EntityType&amp;lt;/code&amp;gt;. These &amp;lt;code&amp;gt;*Type&amp;lt;/code&amp;gt; classes hold factories that simply create the containing type on demand.&lt;br /&gt;
&lt;br /&gt;
These factory holders are created through the use of their &amp;lt;code&amp;gt;*Type$Builder&amp;lt;/code&amp;gt; classes. An example: (&amp;lt;code&amp;gt;REGISTER&amp;lt;/code&amp;gt; here refers to a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;BlockEntityType&amp;lt;?&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final RegistryObject&amp;lt;BlockEntityType&amp;lt;ExampleBlockEntity&amp;gt;&amp;gt; EXAMPLE_BLOCK_ENTITY = REGISTER.register(&lt;br /&gt;
    &amp;quot;example_block_entity&amp;quot;, () -&amp;gt; BlockEntityType.Builder.of(ExampleBlockEntity::new, EXAMPLE_BLOCK.get()).build(null)&lt;br /&gt;
);&lt;br /&gt;
|kotlin=val EXAMPLE_BLOCK_ENTITY: RegistryObject&amp;lt;BlockEntityType&amp;lt;ExampleBlockEntity&amp;gt;&amp;gt; = REGISTER.register(&amp;quot;example_block_entity&amp;quot;) { BlockEntityType.Builder.of(::ExampleBlockEntity, EXAMPLE_BLOCK.get()).build(null)) }&lt;br /&gt;
|scala=final val EXAMPLE_BLOCK_ENTITY = REGISTER.register(&amp;quot;example_block_entity&amp;quot;, () =&amp;gt; BlockEntityType.Builder.of(() =&amp;gt; new ExampleBlockEntity(), GeneralRegistrar.EXAMPLE_BLOCK.get).build(null))&lt;br /&gt;
|}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Non-Forge Registries ===&lt;br /&gt;
&lt;br /&gt;
Not all vanilla registries are wrapped as a Forge registry. To register objects to any one of these registries, create a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; via the &amp;lt;code&amp;gt;#create&amp;lt;/code&amp;gt; overload which takes in a resource key of the registry and the mod id to register the entries for. Then simply call &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; like any other &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=private static final DeferredRegister&amp;lt;LootItemConditionType&amp;gt; REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;LootItemConditionType&amp;gt; EXAMPLE_LOOT_ITEM_CONDITION_TYPE = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;, () -&amp;gt; new LootItemConditionType(...));&lt;br /&gt;
|kotlin=private val REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID)&lt;br /&gt;
&lt;br /&gt;
val EXAMPLE_LOOT_ITEM_CONDITION_TYPE : RegistryObject&amp;lt;LootItemConditionType&amp;gt; = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;) {&lt;br /&gt;
    LootItemConditionType(...)&lt;br /&gt;
}&lt;br /&gt;
|scala=private final val REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID)&lt;br /&gt;
&lt;br /&gt;
final val EXAMPLE_LOOT_ITEM_CONDITION_TYPE = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;, () =&amp;gt; new LootItemConditionType(...))&lt;br /&gt;
|groovy=private static final DeferredRegister&amp;lt;LootItemConditionType&amp;gt; REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;LootItemConditionType&amp;gt; EXAMPLE_LOOT_ITEM_CONDITION_TYPE = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;, () -&amp;gt; new LootItemConditionType(...));&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
If you attempt to make one of these instances require an instance of another registry object, you should use the lazy initialization method mentioned above to register the object in the correct order.&lt;br /&gt;
&lt;br /&gt;
=== Data Driven Entries ===&lt;br /&gt;
&lt;br /&gt;
Registries are considered to be data driven if they are located within &amp;lt;code&amp;gt;RegistryAccess&amp;lt;/code&amp;gt; with the exception of &amp;lt;code&amp;gt;LevelStem&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Level&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
These registry objects only need to be registered within code if they are to be used within a pre-existing registry object (e.g. a &amp;lt;code&amp;gt;PlacedFeature&amp;lt;/code&amp;gt; for ore generation within an overworld &amp;lt;code&amp;gt;Biome&amp;lt;/code&amp;gt;). Otherwise, their instance can be purely registered using a JSON file.&lt;br /&gt;
&lt;br /&gt;
If a data driven registry object has to be registered within code, a dummy object should be supplied to hold a &amp;quot;registry name&amp;quot; and then constructed within a JSON file.&lt;br /&gt;
&lt;br /&gt;
== Referencing Registered Objects ==&lt;br /&gt;
&lt;br /&gt;
Each forge registered object should not be statically initialized nor reference another instance being registered. They must always be a new, singleton instance that is resolved during when &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is called for their registry. This is to maintain a sane loading order for registries and their objects along with dynamic loading/unloading of mods.&lt;br /&gt;
&lt;br /&gt;
Forge registered objects must always be referenced through a &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; or a field with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Using RegistryObjects===&lt;br /&gt;
&amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;s can be used to retrieve references to registered objects once they become available. Their references are updated along with all &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; annotations after the registry that &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is called for is dispatched and frozen.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; can be retrieved as a result of using &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; or calling the static factory &amp;lt;code&amp;gt;RegistryObject#create&amp;lt;/code&amp;gt;. Each static factory takes in the &amp;quot;registry name&amp;quot; of the object being referenced and one of the following: a &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt;, a registry name of the type &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt;, or a registry key of the type &amp;lt;code&amp;gt;ResourceKey&amp;lt;? extends Registry&amp;lt;?&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; can be stored within some field and retrieve the registered object using &amp;lt;code&amp;gt;#get&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
An example using &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;:&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final RegistryObject&amp;lt;Item&amp;gt; EXAMPLE_ITEM = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_item&amp;quot;), ForgeRegistries.ITEMS);&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
public static final RegistryObject&amp;lt;ExampleRegistry&amp;gt; EXAMPLE_OBJECT = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;); &lt;br /&gt;
|kotlin=val EXAMPLE_ITEM: RegistryObject&amp;lt;Item&amp;gt; = RegistryObject.create(ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_item&amp;quot;), ForgeRegistries.ITEMS)&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
val EXAMPLE_OBJECT: RegistryObject&amp;lt;ExampleRegistry&amp;gt; = RegistryObject.create(ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;)&lt;br /&gt;
|scala=final val EXAMPLE_ITEM = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_item&amp;quot;), ForgeRegistries.ITEMS)&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
final val EXAMPLE_OBJECT = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;); &lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|All vanilla objects are bootstrapped and registered before mods are loaded. As such, they can be referenced as is without any issues.}}&lt;br /&gt;
&lt;br /&gt;
=== Using @ObjectHolder ===&lt;br /&gt;
&lt;br /&gt;
Forge registry objects can also be injected into &amp;lt;code&amp;gt;public static&amp;lt;/code&amp;gt; fields with either their class or that field annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;. There must be enough information to construct a &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; to identify a single object within a specific registry.&lt;br /&gt;
&lt;br /&gt;
The rules for &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; are as follows:&lt;br /&gt;
&lt;br /&gt;
* If the class is annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;, its value will be the default namespace for all fields within if not explicitly defined&lt;br /&gt;
* If the class is annotated with &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt;, the modid will be the default namespace for all annotated fields within if not explicitly defined &lt;br /&gt;
* A field is considered for injection if:&lt;br /&gt;
** it has at least the modifiers &amp;lt;code&amp;gt;public static&amp;lt;/code&amp;gt;; and&lt;br /&gt;
** one of the following conditions are true:&lt;br /&gt;
*** the '''enclosing class''' has an &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; annotation, and the field is &amp;lt;code&amp;gt;final&amp;lt;/code&amp;gt;, and:&lt;br /&gt;
**** the name value is the field's name; and&lt;br /&gt;
**** the namespace value is the enclosing class's namespace&lt;br /&gt;
**** ''An exception is thrown if the namespace value cannot be found and inherited''&lt;br /&gt;
*** the '''field''' is annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;, and:&lt;br /&gt;
**** the name value is explicitly defined; and&lt;br /&gt;
**** the namespace value is either explicitly defined or the enclosing class's namespace&lt;br /&gt;
** the field type or one of its supertypes corresponds to a valid registry (e.g. &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;ArrowItem&amp;lt;/code&amp;gt; for the &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; registry)&lt;br /&gt;
** ''An exception is thrown if a field does not have a corresponding registry.''&lt;br /&gt;
* ''An exception is thrown if the resulting &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; is incomplete or invalid (non-valid characters in path)''&lt;br /&gt;
* If no other errors or exceptions occur, the field will be injected&lt;br /&gt;
* If all of the above rules do not apply, no action will be taken (and a message may be logged)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; annotated fields are injected with their associated object values after &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is fired for their registry, along with &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;s.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|If the object does not exist in the registry when it is to be injected, a debug message will be logged, and no value will be injected. If the object is found, but the field cannot be set, a warning message will be logged instead.}}&lt;br /&gt;
&lt;br /&gt;
As these rules are rather complicated, here are some examples:&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; style=&amp;quot;border: solid 2px; padding: 2px 5px; margin-top: 3px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-weight:bold;line-height:1.6;&amp;quot;&amp;gt;Example uses of &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot; style=&amp;quot;overflow: auto; white-space: nowrap;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
@ObjectHolder(&amp;quot;minecraft&amp;quot;) // Inheritable resource namespace: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
class AnnotatedHolder {&lt;br /&gt;
    public static final Block diamond_block = null;   // No annotation. [public static final] is required.&lt;br /&gt;
                                                      // Block has a corresponding registry: [Block]&lt;br /&gt;
                                                      // Name path is the name of the field: &amp;quot;diamond_block&amp;quot;&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // So, namespace is inherited from class annotation: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:diamond_block&amp;quot; from the [Block] registry&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(&amp;quot;ambient.cave&amp;quot;)&lt;br /&gt;
    public static SoundEvent ambient_sound = null;    // Annotation present. [public static] is required.&lt;br /&gt;
                                                      // SoundEvent has a corresponding registry: [SoundEvent]&lt;br /&gt;
                                                      // Name path is the value of the annotation: &amp;quot;ambient.cave&amp;quot;&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // So, namespace is inherited from class annotation: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:ambient.cave&amp;quot; from the [SoundEvent] registry&lt;br /&gt;
&lt;br /&gt;
    // Assume for the next entry that [ManaType] is a valid registry.          &lt;br /&gt;
    @ObjectHolder(&amp;quot;neomagicae:coffeinum&amp;quot;)&lt;br /&gt;
    public static final ManaType coffeinum = null;    // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // ManaType has a corresponding registry: [ManaType] (custom registry)&lt;br /&gt;
                                                      // Resource location is explicitly defined: &amp;quot;neomagicae:coffeinum&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;neomagicae:coffeinum&amp;quot; from the [ManaType] registry&lt;br /&gt;
&lt;br /&gt;
    public static final Item ENDER_PEARL = null;      // No annotation. [public static final] is required.&lt;br /&gt;
                                                      // Item has a corresponding registry: [Item].&lt;br /&gt;
                                                      // Name path is the name of the field: &amp;quot;ENDER_PEARL&amp;quot; -&amp;gt; &amp;quot;ender_pearl&amp;quot;&lt;br /&gt;
                                                      // !! ^ Field name is valid, because they are&lt;br /&gt;
                                                      //      converted to lowercase automatically.&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // So, namespace is inherited from class annotation: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:ender_pearl&amp;quot; from the [Item] registry&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(&amp;quot;minecraft:arrow&amp;quot;)&lt;br /&gt;
    public static final ArrowItem arrow = null;       // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // ArrowItem does not have a corresponding registry.&lt;br /&gt;
                                                      // ArrowItem's supertype of Item has a corresponding registry: [Item]&lt;br /&gt;
                                                      // Resource location is explicitly defined: &amp;quot;minecraft:arrow&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:arrow&amp;quot; from the [Item] registry                                                    &lt;br /&gt;
&lt;br /&gt;
    public static Block bedrock = null;               // No annotation, so [public static final] is required.&lt;br /&gt;
                                                      // Therefore, the field is ignored.&lt;br /&gt;
    &lt;br /&gt;
    public static final CreativeModeTab group = null; // No annotation. [public static final] is required.&lt;br /&gt;
                                                      // CreativeModeTab does not have a corresponding registry.&lt;br /&gt;
                                                      // No supertypes of CreativeModeTab has a corresponding registry.&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class UnannotatedHolder { // Note the lack of an @ObjectHolder annotation on this class.&lt;br /&gt;
    @ObjectHolder(&amp;quot;minecraft:flame&amp;quot;)&lt;br /&gt;
    public static final Enchantment flame = null;     // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // Enchantment has corresponding registry: [Enchantment].&lt;br /&gt;
                                                      // Resource location is explicitly defined: &amp;quot;minecraft:flame&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:flame&amp;quot; from the [Enchantment] registry&lt;br /&gt;
&lt;br /&gt;
    public static final Biome ice_flat = null;        // No annotation on the enclosing class.&lt;br /&gt;
                                                      // Therefore, the field is ignored.&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(&amp;quot;minecraft:creeper&amp;quot;)&lt;br /&gt;
    public static Entity creeper = null;              // Annotation present. [public static] is required.&lt;br /&gt;
                                                      // Entity does not have a corresponding registry.&lt;br /&gt;
                                                      // No supertypes of Entity has a corresponding registry.&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(&amp;quot;levitation&amp;quot;)&lt;br /&gt;
    public static final Potion levitation = null;     // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // Potion has a corresponding registry: [Potion].&lt;br /&gt;
                                                      // Name path is the value of the annotation: &amp;quot;levitation&amp;quot;&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // No annotation in enclosing class.&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Creating Custom Registries ==&lt;br /&gt;
&lt;br /&gt;
Creating custom registries for your mod might be useful if you want other mods to add new things to your system. For example, you might have magic spells and want to allow other mods to add new spells. For this you will want to make a registry (eg. &amp;quot;mymagicmod:spells&amp;quot;). This way, other mods will be able to register things to that list, and you won't have to do anything else.&lt;br /&gt;
&lt;br /&gt;
Just like with registering a new item or block you have two ways of making a new registry. Each method takes in a &amp;lt;code&amp;gt;RegistryBuilder&amp;lt;/code&amp;gt; which is used to build an &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt;. Each builder should have its name set via &amp;lt;code&amp;gt;#setName&amp;lt;/code&amp;gt; before being created.&lt;br /&gt;
&lt;br /&gt;
=== With DeferredRegister ===&lt;br /&gt;
&lt;br /&gt;
The first method involves the second static constructor: &amp;lt;code&amp;gt;DeferredRegister#create(ResourceLocation, String)&amp;lt;/code&amp;gt;. From there, we can construct the registry using &amp;lt;code&amp;gt;#makeRegistry&amp;lt;/code&amp;gt;. This will already populate &amp;lt;code&amp;gt;#setName&amp;lt;/code&amp;gt; for us. This method also returns a supplier of the registry which we can use after the &amp;lt;code&amp;gt;NewRegistryEvent&amp;lt;/code&amp;gt; is called.&lt;br /&gt;
&lt;br /&gt;
Here is an example:&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final DeferredRegister&amp;lt;ExampleRegistry&amp;gt; EXAMPLE = DeferredRegister.create(new ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;), MODID);&lt;br /&gt;
&lt;br /&gt;
public static final Supplier&amp;lt;IForgeRegistry&amp;lt;ExampleRegistry&amp;gt;&amp;gt; REGISTRY = EXAMPLE.makeRegistry(RegistryBuilder::new);&lt;br /&gt;
|kotlin=val EXAMPLE: DeferredRegister&amp;lt;ExampleRegistry&amp;gt; = DeferredRegister.create(ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;), MODID)&lt;br /&gt;
&lt;br /&gt;
val REGISTRY: IForgeRegistry&amp;lt;ExampleRegistry&amp;gt; by lazy {&lt;br /&gt;
    EXAMPLE.makeRegistry(::RegistryBuilder).get()&lt;br /&gt;
}&lt;br /&gt;
|scala=final val EXAMPLE = DeferredRegister.create(new ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;), MODID)&lt;br /&gt;
&lt;br /&gt;
final lazy val REGISTRY = EXAMPLE.makeRegistry(() =&amp;gt; new RegistryBuilder).get&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
=== Using &amp;lt;code&amp;gt;NewRegistryEvent&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The second method can be done during the &amp;lt;code&amp;gt;NewRegistryEvent&amp;lt;/code&amp;gt; event. Using &amp;lt;code&amp;gt;NewRegistryEvent#create&amp;lt;/code&amp;gt;, you can pass in a &amp;lt;code&amp;gt;RegistryBuilder&amp;lt;/code&amp;gt; directly. This method will return a &amp;lt;code&amp;gt;Supplier&amp;lt;IForgeRegistry&amp;lt;V&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; that can be stored and queried after the event is fired to gain access to your &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt; instance.&lt;br /&gt;
&lt;br /&gt;
Here is an example: (the event handler is registered on the '''mod event bus''')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public static Supplier&amp;lt;IForgeRegistry&amp;lt;ExampleRegistry&amp;gt;&amp;gt; registrySupplier = null;&lt;br /&gt;
&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void onNewRegistry(NewRegistryEvent event){&lt;br /&gt;
    RegistryBuilder&amp;lt;ExampleRegistry&amp;gt; registryBuilder = new RegistryBuilder&amp;lt;&amp;gt;();&lt;br /&gt;
    registryBuilder.setName(new ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;);&lt;br /&gt;
    registrySupplier = event.create(registryBuilder);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Handling Missing Entries ==&lt;br /&gt;
&lt;br /&gt;
When loading a pre-existing world after removing mods or updating versions, there are cases where certain registry objects will cease to exist. In these cases, it is possible to specify actions to remove a mapping, prevent the world from loading, or remap the name as needed. This can be done through the third of the registry events: &amp;lt;code&amp;gt;MissingMappingsEvent&amp;lt;/code&amp;gt;. Within the event, you can grab an immutable list of missing mappings associated with a mod id for a given registry via &amp;lt;code&amp;gt;#getMappings&amp;lt;/code&amp;gt; or a list of all mappings via &amp;lt;code&amp;gt;#getAllMappings&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For each &amp;lt;code&amp;gt;Mapping&amp;lt;/code&amp;gt;, you can either execute one of the following methods:&lt;br /&gt;
* &amp;lt;code&amp;gt;#ignore&amp;lt;/code&amp;gt; which abandons the entry when loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#warn&amp;lt;/code&amp;gt; which warns the user about the missing entry but continues loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#fail&amp;lt;/code&amp;gt; which prevents the world from loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#remap&amp;lt;/code&amp;gt; which remaps the entry to the specified non-null object in the same registry&lt;br /&gt;
&lt;br /&gt;
If none of the above are specified, then the default action of notifying the user about the missing mappings occur.&lt;br /&gt;
&lt;br /&gt;
Here is an example:  (the event handler is registered on the '''forge event bus''')&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=// This will ignore any missing test items from the specified world&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void onMissing(final MissingMappingsEvent event) {&lt;br /&gt;
    event.getMappings(ForgeRegistries.Keys.ITEMS, MODID).stream()&lt;br /&gt;
        .filter(mapping -&amp;gt; mapping.key.getPath().contains(&amp;quot;test&amp;quot;))&lt;br /&gt;
            .forEach(Mapping::ignore);&lt;br /&gt;
}&lt;br /&gt;
|groovy=// This will ignore any missing test items from the specified world&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
void onMissing(final MissingMappingsEvent event) {&lt;br /&gt;
    event.getMappings(ForgeRegistries.Keys.ITEMS, MODID).stream()&lt;br /&gt;
        .filter(mapping -&amp;gt; mapping.key.path.contains(&amp;quot;test&amp;quot;))&lt;br /&gt;
            .forEach(Mapping::ignore);&lt;br /&gt;
}&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Common Concepts]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Stages_of_Modloading&amp;diff=3257</id>
		<title>Stages of Modloading</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Stages_of_Modloading&amp;diff=3257"/>
		<updated>2022-06-11T17:29:03Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update to 1.19&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The FML mod loading process is broken into several stages, with each stage having associated events fired alongside with it on the mod-specific event bus. These events are known as the &amp;lt;code&amp;gt;mod lifecycle events&amp;lt;/code&amp;gt;, as they are fired during the different phases of a mod's life.&lt;br /&gt;
&lt;br /&gt;
The different mod loading stages are represented each by a value in the enum class &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;net.minecraftforge.fml.ModLoadingStage&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Their states are split between the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;net.minecraftforge.fml.core.ModStateProvider&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for mod states (construct, common setup, etc.) and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;net.minecraftforge.fmllegacy.ForgeStatesProvider&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for forge injected states (creating registries, injecting capabilities, etc.) Most of the mod lifecycle events are stored in the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;net.minecraftforge.fml.event.lifecycle&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; package.&lt;br /&gt;
&lt;br /&gt;
== Parallelism ==&lt;br /&gt;
&lt;br /&gt;
The mod loading system is parallelized to some extent. While all of the stages are changed at the same time across all mods, most of the events are fired in parallel to each mod. That is, all mods will concurrently receive the event, then FML will wait until all mods have processed the event before moving to the next stage and firing the next event. These concurrently dispatched events are distinguished by them extending &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ParallelDispatchEvent&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This does means that in these parallel mod lifecycle events, care must be taken to be thread-safe, like when calling external methods which are backed by non-thread-safe collections. Most of the systems in Forge are protected for this; however, vanilla systems and external mods' APIs may not be thread-safe. FML provides a way for mods to defer tasks/work until the event is finished dispatching, where it will be run sequentially along with other events on the main thread. This is done with the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;#enqueueWork&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; method, which is a member of all events which extend &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ParallelDispatchEvent&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Common Transition Stages and Events ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; border=1&lt;br /&gt;
!  Name  !!  Enum Constant  !!  Lifecycle Event  !!  Parallel?  !! Description &lt;br /&gt;
|-&lt;br /&gt;
|   Construction   ||   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;CONSTRUCT&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;FMLConstructModEvent&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;   ||   Yes   ||  Fired when the mod's constructor has been called. Can be used to initialize listeners outside of the constructor. There is usually no reason to use this event, as any code should be placed in the mod constructor instead.&lt;br /&gt;
|-&lt;br /&gt;
|   Registry Creation   ||   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;CREATE_REGISTRIES&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;NewRegistryEvent&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;   ||   No   ||  Fired for mods to create and initialize their custom registries. &lt;br /&gt;
|-&lt;br /&gt;
|   Registry Population   ||   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;LOAD_REGISTRIES&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;RegisterEvent&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;   ||   No   ||  Fired when a registry is open to registrations for any registrable objects, such as blocks, items, etc. &lt;br /&gt;
|-&lt;br /&gt;
|   Config Loading   ||   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;CONFIG_LOAD&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ModConfigEvent$Loading&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;   ||   No   ||   Loads config files associated with registered mod configs. Before this stage, mod config values only return their default values unless manually loaded earlier.&lt;br /&gt;
|-&lt;br /&gt;
|   Common Setup   ||   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;COMMON_SETUP&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;FMLCommonSetupEvent&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;   ||   Yes   ||  Used for doing any work or action that should be run on both '''physical''' sides. &lt;br /&gt;
|-&lt;br /&gt;
|   Sided Setup   ||   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;SIDED_SETUP&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;FMLClientSetupEvent&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for physical client, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;FMLDedicatedServerSetupEvent&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for physical server   ||   Yes   ||  Used for doing any physical side-specific initialization work. &lt;br /&gt;
|-&lt;br /&gt;
|   IMC Enqueue   ||   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ENQUEUE_IMC&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;InterModEnqueueEvent&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;   ||   Yes   ||  Fired for mods to enqueue messages for other mods using the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;InterModComms&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; system. &lt;br /&gt;
|-&lt;br /&gt;
|   IMC Processing   ||   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;PROCESS_IMC&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;InterModProcessEvent&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;   ||   Yes   ||  Fired for mods to process messages from other mods sent using the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;InterModComms&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; system in the previous stage. &lt;br /&gt;
|-&lt;br /&gt;
|   Loading Complete   ||   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;COMPLETE&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;FMLLoadCompleteEvent&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;   ||   Yes   ||  Fired when mod loading is complete, before handing control back to the main game. There is usually no reason to use this event, as most actions can be done during the Common or Sided Setup stages.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Registration&amp;diff=3256</id>
		<title>Registration</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Registration&amp;diff=3256"/>
		<updated>2022-06-11T17:25:34Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Missed something, whoops&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Under construction}}&lt;br /&gt;
&lt;br /&gt;
Registration is the process of making an object (such as an item or block) known to the game during runtime. If some objects are not registered, this could cause crashes even before the game is fully loaded or arbitrary behaviors such as bottlenecking mod compatibility for world generation.&lt;br /&gt;
&lt;br /&gt;
Most objects that are known within the game are handled by a &amp;lt;code&amp;gt;Registry&amp;lt;/code&amp;gt;. Each registry uniquely defines each object through a &amp;quot;registry name&amp;quot; via a [[Using Resources#ResourceLocation|ResourceLocation]].&lt;br /&gt;
&lt;br /&gt;
{{Tip|In a global context, each object is universally unique through its &amp;lt;code&amp;gt;ResourceKey&amp;lt;/code&amp;gt;: a concatenation of its registry's id and the object's registry name.}}&lt;br /&gt;
&lt;br /&gt;
Due to the inconsistent ordering and registration process vanilla uses, Forge wraps most vanilla registries using &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt;. This guarantees that the loading order for these wrapped registries will be &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt;, and then the rest of the wrapped registries in alphabetical order. All registries supported by Forge can be found within the &amp;lt;code&amp;gt;ForgeRegistries&amp;lt;/code&amp;gt; class. Since all registry names are unique to a specific registry, different registry objects within different registries can have the same name (e.g. a &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt; and an &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; each hold a registry object named &amp;lt;code&amp;gt;examplemod:object&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|If two registry objects within the same registry have the same name, the second object will override the first. The only registry that will throw an &amp;lt;code&amp;gt;IllegalArgumentException&amp;lt;/code&amp;gt; is the &amp;lt;code&amp;gt;DataSerializerEntry&amp;lt;/code&amp;gt; registry.}}&lt;br /&gt;
&lt;br /&gt;
== Methods for Registering ==&lt;br /&gt;
&lt;br /&gt;
There are two proper ways to register objects within an associated wrapped Forge registry: the &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; class, and the &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; lifecycle event.&lt;br /&gt;
&lt;br /&gt;
=== DeferredRegister ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; is an abstraction layer over the registry event used to register objects. It maintains a map of &amp;quot;registry name&amp;quot; to their associated suppliers and resolves those suppliers during &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; for the associated registry. This method is the currently recommended, and documented, way to handle these objects as it provides convenience and safety for those who want to statically initialize objects while avoiding some issues associated with it. &lt;br /&gt;
&lt;br /&gt;
An example of a mod registering a custom block:&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=private static final DeferredRegister&amp;lt;Block&amp;gt; BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;Block&amp;gt; EXAMPLE_BLOCK = BLOCKS.register(&amp;quot;example_block&amp;quot;, () -&amp;gt; new Block(BlockBehaviour.Properties.of(Material.STONE)));&lt;br /&gt;
&lt;br /&gt;
public ExampleMod() {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get().getModEventBus());&lt;br /&gt;
}&lt;br /&gt;
|kotlin=private val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID)&lt;br /&gt;
&lt;br /&gt;
val EXAMPLE_BLOCK: RegistryObject&amp;lt;Block&amp;gt; = BLOCKS.register(&amp;quot;example_block&amp;quot;) { Block(BlockBehaviour.Properties.of(Material.ROCK)) }&lt;br /&gt;
&lt;br /&gt;
internal class ExampleMod {&lt;br /&gt;
    init {&lt;br /&gt;
        BLOCKS.register(FMLJavaModLoadingContext.get().modEventBus)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
|scala=object ExampleMod {&lt;br /&gt;
    private final val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID)&lt;br /&gt;
&lt;br /&gt;
    final val EXAMPLE_BLOCK = registerBlock(&amp;quot;example_block&amp;quot;, () =&amp;gt; new Block(BlockBehaviour.Properties.of(Material.ROCK)))&lt;br /&gt;
}&lt;br /&gt;
class ExampleMod {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get.getModEventBus)&lt;br /&gt;
}&lt;br /&gt;
|groovy=private static final DeferredRegister&amp;lt;Block&amp;gt; BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;Block&amp;gt; EXAMPLE_BLOCK = BLOCKS.register(&amp;quot;example_block&amp;quot;, () -&amp;gt; new Block(BlockBehaviour.Properties.of(Material.STONE)));&lt;br /&gt;
&lt;br /&gt;
ExampleMod() {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get().modEventBus);&lt;br /&gt;
}&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip|When using a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; to register any object, the name inputted will be automatically prefixed with the mod id passed in, giving the above object a &amp;quot;registry name&amp;quot; of &amp;lt;code&amp;gt;examplemod:example_block&amp;lt;/code&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
=== RegisterEvent ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is the second way register objects. This [[Events|event]] is fired for each registry synchronously in vanilla registry order after &amp;lt;code&amp;gt;FMLConstructModEvent&amp;lt;/code&amp;gt; and before the configs are loaded. Objects are registered using &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; by passing in the registry key, the name of the registry object, and the object itself. There is an additional &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; overload which takes in a consumed helper to register an object with a given name. It is recommended to use this method to avoid unnecessary object creation.&lt;br /&gt;
&lt;br /&gt;
Here is an example: (the event handler is registered on the '''mod event bus''')&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=@SubscribeEvent&lt;br /&gt;
public void register(RegisterEvent event) {&lt;br /&gt;
    event.register(ForgeRegistries.Keys.BLOCKS,&lt;br /&gt;
        helper -&amp;gt; helper.register(new ResourceLocation(MODID, &amp;quot;example_block&amp;quot;), new Block(...))&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
|kotlin=@JvmStatic&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
private fun register(event: RegisterEvent) =&lt;br /&gt;
    event.register(ForgeRegistries.Keys.BLOCKS) {&lt;br /&gt;
        helper -&amp;gt; helper.register(ResourceLocation(MODID, &amp;quot;example_block&amp;quot;), Block(...))&lt;br /&gt;
    }&lt;br /&gt;
|scala=@SubscribeEvent&lt;br /&gt;
def register(event: RegisterEvent): Unit =&lt;br /&gt;
    event.register(ForgeRegistries.Keys.BLOCKS,&lt;br /&gt;
        helper =&amp;gt; helper.register(new ResourceLocation(MODID, &amp;quot;example_block&amp;quot;), new Block(...))&lt;br /&gt;
    )&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|Since all objects registered must be singleton, some classes cannot by themselves be registered. Instead, &amp;lt;code&amp;gt;*Type&amp;lt;/code&amp;gt; classes are registered and used in the formers' constructors to wrap the flyweight objects. For example, a [[Basics_of_Block_Entities|&amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt;]] is wrapped via &amp;lt;code&amp;gt;BlockEntityType&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;Entity&amp;lt;/code&amp;gt; is wrapped via &amp;lt;code&amp;gt;EntityType&amp;lt;/code&amp;gt;. These &amp;lt;code&amp;gt;*Type&amp;lt;/code&amp;gt; classes hold factories that simply create the containing type on demand.&lt;br /&gt;
&lt;br /&gt;
These factory holders are created through the use of their &amp;lt;code&amp;gt;*Type$Builder&amp;lt;/code&amp;gt; classes. An example: (&amp;lt;code&amp;gt;REGISTER&amp;lt;/code&amp;gt; here refers to a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;BlockEntityType&amp;lt;?&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final RegistryObject&amp;lt;BlockEntityType&amp;lt;ExampleBlockEntity&amp;gt;&amp;gt; EXAMPLE_BLOCK_ENTITY = REGISTER.register(&lt;br /&gt;
    &amp;quot;example_block_entity&amp;quot;, () -&amp;gt; BlockEntityType.Builder.of(ExampleBlockEntity::new, EXAMPLE_BLOCK.get()).build(null)&lt;br /&gt;
);&lt;br /&gt;
|kotlin=val EXAMPLE_BLOCK_ENTITY: RegistryObject&amp;lt;BlockEntityType&amp;lt;ExampleBlockEntity&amp;gt;&amp;gt; = REGISTER.register(&amp;quot;example_block_entity&amp;quot;) { BlockEntityType.Builder.of(::ExampleBlockEntity, EXAMPLE_BLOCK.get()).build(null)) }&lt;br /&gt;
|scala=final val EXAMPLE_BLOCK_ENTITY = REGISTER.register(&amp;quot;example_block_entity&amp;quot;, () =&amp;gt; BlockEntityType.Builder.of(() =&amp;gt; new ExampleBlockEntity(), GeneralRegistrar.EXAMPLE_BLOCK.get).build(null))&lt;br /&gt;
|}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Non-Forge Registries ===&lt;br /&gt;
&lt;br /&gt;
Not all vanilla registries are wrapped as a Forge registry. To register objects to any one of these registries, create a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; via the &amp;lt;code&amp;gt;#create&amp;lt;/code&amp;gt; overload which takes in a resource key of the registry and the mod id to register the entries for. Then simply call &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; like any other &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=private static final DeferredRegister&amp;lt;LootItemConditionType&amp;gt; REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;LootItemConditionType&amp;gt; EXAMPLE_LOOT_ITEM_CONDITION_TYPE = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;, () -&amp;gt; new LootItemConditionType(...));&lt;br /&gt;
|kotlin=private val REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID)&lt;br /&gt;
&lt;br /&gt;
val EXAMPLE_LOOT_ITEM_CONDITION_TYPE : RegistryObject&amp;lt;LootItemConditionType&amp;gt; = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;) {&lt;br /&gt;
    LootItemConditionType(...)&lt;br /&gt;
}&lt;br /&gt;
|scala=private final val REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID)&lt;br /&gt;
&lt;br /&gt;
final val EXAMPLE_LOOT_ITEM_CONDITION_TYPE = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;, () =&amp;gt; new LootItemConditionType(...))&lt;br /&gt;
|groovy=private static final DeferredRegister&amp;lt;LootItemConditionType&amp;gt; REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;LootItemConditionType&amp;gt; EXAMPLE_LOOT_ITEM_CONDITION_TYPE = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;, () -&amp;gt; new LootItemConditionType(...));&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
If you attempt to make one of these instances require an instance of another registry object, you should use the lazy initialization method mentioned above to register the object in the correct order.&lt;br /&gt;
&lt;br /&gt;
=== Data Driven Entries ===&lt;br /&gt;
&lt;br /&gt;
Registries are considered to be data driven if they are located within &amp;lt;code&amp;gt;RegistryAccess&amp;lt;/code&amp;gt; with the exception of &amp;lt;code&amp;gt;LevelStem&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Level&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
These registry objects only need to be registered within code if they are to be used within a pre-existing registry object (e.g. a &amp;lt;code&amp;gt;PlacedFeature&amp;lt;/code&amp;gt; for ore generation within an overworld &amp;lt;code&amp;gt;Biome&amp;lt;/code&amp;gt;). Otherwise, their instance can be purely registered using a JSON file.&lt;br /&gt;
&lt;br /&gt;
If a data driven registry object has to be registered within code, a dummy object should be supplied to hold a &amp;quot;registry name&amp;quot; and then constructed within a JSON file.&lt;br /&gt;
&lt;br /&gt;
== Referencing Registered Objects ==&lt;br /&gt;
&lt;br /&gt;
Each forge registered object should not be statically initialized nor reference another instance being registered. They must always be a new, singleton instance that is resolved during when &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is called for their registry. This is to maintain a sane loading order for registries and their objects along with dynamic loading/unloading of mods.&lt;br /&gt;
&lt;br /&gt;
Forge registered objects must always be referenced through a &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; or a field with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Using RegistryObjects===&lt;br /&gt;
&amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;s can be used to retrieve references to registered objects once they become available. Their references are updated along with all &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; annotations after the registry that &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is called for is dispatched and frozen.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; can be retrieved as a result of using &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; or calling the static factory &amp;lt;code&amp;gt;RegistryObject#create&amp;lt;/code&amp;gt;. Each static factory takes in the &amp;quot;registry name&amp;quot; of the object being referenced and one of the following: a &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt;, a registry name of the type &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt;, or a registry key of the type &amp;lt;code&amp;gt;ResourceKey&amp;lt;? extends Registry&amp;lt;?&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; can be stored within some field and retrieve the registered object using &amp;lt;code&amp;gt;#get&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
An example using &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;:&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final RegistryObject&amp;lt;Item&amp;gt; EXAMPLE_ITEM = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_item&amp;quot;), ForgeRegistries.ITEMS);&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
public static final RegistryObject&amp;lt;ExampleRegistry&amp;gt; EXAMPLE_OBJECT = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;); &lt;br /&gt;
|kotlin=val EXAMPLE_ITEM: RegistryObject&amp;lt;Item&amp;gt; = RegistryObject.create(ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_item&amp;quot;), ForgeRegistries.ITEMS)&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
val EXAMPLE_OBJECT: RegistryObject&amp;lt;ExampleRegistry&amp;gt; = RegistryObject.create(ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;)&lt;br /&gt;
|scala=final val EXAMPLE_ITEM = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_item&amp;quot;), ForgeRegistries.ITEMS)&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
final val EXAMPLE_OBJECT = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;); &lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|All vanilla objects are bootstrapped and registered before mods are loaded. As such, they can be referenced as is without any issues.}}&lt;br /&gt;
&lt;br /&gt;
=== Using @ObjectHolder ===&lt;br /&gt;
&lt;br /&gt;
Forge registry objects can also be injected into &amp;lt;code&amp;gt;public static&amp;lt;/code&amp;gt; fields with either their class or that field annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;. There must be enough information to construct a &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; to identify a single object within a specific registry.&lt;br /&gt;
&lt;br /&gt;
The rules for &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; are as follows:&lt;br /&gt;
&lt;br /&gt;
* If the class is annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;, its value will be the default namespace for all fields within if not explicitly defined&lt;br /&gt;
* If the class is annotated with &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt;, the modid will be the default namespace for all annotated fields within if not explicitly defined &lt;br /&gt;
* A field is considered for injection if:&lt;br /&gt;
** it has at least the modifiers &amp;lt;code&amp;gt;public static&amp;lt;/code&amp;gt;; and&lt;br /&gt;
** one of the following conditions are true:&lt;br /&gt;
*** the '''enclosing class''' has an &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; annotation, and the field is &amp;lt;code&amp;gt;final&amp;lt;/code&amp;gt;, and:&lt;br /&gt;
**** the name value is the field's name; and&lt;br /&gt;
**** the namespace value is the enclosing class's namespace&lt;br /&gt;
**** ''An exception is thrown if the namespace value cannot be found and inherited''&lt;br /&gt;
*** the '''field''' is annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;, and:&lt;br /&gt;
**** the name value is explicitly defined; and&lt;br /&gt;
**** the namespace value is either explicitly defined or the enclosing class's namespace&lt;br /&gt;
** the field type or one of its supertypes corresponds to a valid registry (e.g. &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;ArrowItem&amp;lt;/code&amp;gt; for the &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; registry)&lt;br /&gt;
** ''An exception is thrown if a field does not have a corresponding registry.''&lt;br /&gt;
* ''An exception is thrown if the resulting &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; is incomplete or invalid (non-valid characters in path)''&lt;br /&gt;
* If no other errors or exceptions occur, the field will be injected&lt;br /&gt;
* If all of the above rules do not apply, no action will be taken (and a message may be logged)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; annotated fields are injected with their associated object values after &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is fired for their registry, along with &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;s.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|If the object does not exist in the registry when it is to be injected, a debug message will be logged, and no value will be injected. If the object is found, but the field cannot be set, a warning message will be logged instead.}}&lt;br /&gt;
&lt;br /&gt;
As these rules are rather complicated, here are some examples:&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; style=&amp;quot;border: solid 2px; padding: 2px 5px; margin-top: 3px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-weight:bold;line-height:1.6;&amp;quot;&amp;gt;Example uses of &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot; style=&amp;quot;overflow: auto; white-space: nowrap;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
@ObjectHolder(&amp;quot;minecraft&amp;quot;) // Inheritable resource namespace: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
class AnnotatedHolder {&lt;br /&gt;
    public static final Block diamond_block = null;   // No annotation. [public static final] is required.&lt;br /&gt;
                                                      // Block has a corresponding registry: [Block]&lt;br /&gt;
                                                      // Name path is the name of the field: &amp;quot;diamond_block&amp;quot;&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // So, namespace is inherited from class annotation: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:diamond_block&amp;quot; from the [Block] registry&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(&amp;quot;ambient.cave&amp;quot;)&lt;br /&gt;
    public static SoundEvent ambient_sound = null;    // Annotation present. [public static] is required.&lt;br /&gt;
                                                      // SoundEvent has a corresponding registry: [SoundEvent]&lt;br /&gt;
                                                      // Name path is the value of the annotation: &amp;quot;ambient.cave&amp;quot;&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // So, namespace is inherited from class annotation: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:ambient.cave&amp;quot; from the [SoundEvent] registry&lt;br /&gt;
&lt;br /&gt;
    // Assume for the next entry that [ManaType] is a valid registry.          &lt;br /&gt;
    @ObjectHolder(&amp;quot;neomagicae:coffeinum&amp;quot;)&lt;br /&gt;
    public static final ManaType coffeinum = null;    // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // ManaType has a corresponding registry: [ManaType] (custom registry)&lt;br /&gt;
                                                      // Resource location is explicitly defined: &amp;quot;neomagicae:coffeinum&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;neomagicae:coffeinum&amp;quot; from the [ManaType] registry&lt;br /&gt;
&lt;br /&gt;
    public static final Item ENDER_PEARL = null;      // No annotation. [public static final] is required.&lt;br /&gt;
                                                      // Item has a corresponding registry: [Item].&lt;br /&gt;
                                                      // Name path is the name of the field: &amp;quot;ENDER_PEARL&amp;quot; -&amp;gt; &amp;quot;ender_pearl&amp;quot;&lt;br /&gt;
                                                      // !! ^ Field name is valid, because they are&lt;br /&gt;
                                                      //      converted to lowercase automatically.&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // So, namespace is inherited from class annotation: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:ender_pearl&amp;quot; from the [Item] registry&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(&amp;quot;minecraft:arrow&amp;quot;)&lt;br /&gt;
    public static final ArrowItem arrow = null;       // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // ArrowItem does not have a corresponding registry.&lt;br /&gt;
                                                      // ArrowItem's supertype of Item has a corresponding registry: [Item]&lt;br /&gt;
                                                      // Resource location is explicitly defined: &amp;quot;minecraft:arrow&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:arrow&amp;quot; from the [Item] registry                                                    &lt;br /&gt;
&lt;br /&gt;
    public static Block bedrock = null;               // No annotation, so [public static final] is required.&lt;br /&gt;
                                                      // Therefore, the field is ignored.&lt;br /&gt;
    &lt;br /&gt;
    public static final CreativeModeTab group = null; // No annotation. [public static final] is required.&lt;br /&gt;
                                                      // CreativeModeTab does not have a corresponding registry.&lt;br /&gt;
                                                      // No supertypes of CreativeModeTab has a corresponding registry.&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class UnannotatedHolder { // Note the lack of an @ObjectHolder annotation on this class.&lt;br /&gt;
    @ObjectHolder(&amp;quot;minecraft:flame&amp;quot;)&lt;br /&gt;
    public static final Enchantment flame = null;     // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // Enchantment has corresponding registry: [Enchantment].&lt;br /&gt;
                                                      // Resource location is explicitly defined: &amp;quot;minecraft:flame&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:flame&amp;quot; from the [Enchantment] registry&lt;br /&gt;
&lt;br /&gt;
    public static final Biome ice_flat = null;        // No annotation on the enclosing class.&lt;br /&gt;
                                                      // Therefore, the field is ignored.&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(&amp;quot;minecraft:creeper&amp;quot;)&lt;br /&gt;
    public static Entity creeper = null;              // Annotation present. [public static] is required.&lt;br /&gt;
                                                      // Entity does not have a corresponding registry.&lt;br /&gt;
                                                      // No supertypes of Entity has a corresponding registry.&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(&amp;quot;levitation&amp;quot;)&lt;br /&gt;
    public static final Potion levitation = null;     // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // Potion has a corresponding registry: [Potion].&lt;br /&gt;
                                                      // Name path is the value of the annotation: &amp;quot;levitation&amp;quot;&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // No annotation in enclosing class.&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Creating Custom Registries ==&lt;br /&gt;
&lt;br /&gt;
Creating custom registries for your mod might be useful if you want other mods to add new things to your system. For example, you might have magic spells and want to allow other mods to add new spells. For this you will want to make a registry (eg. &amp;quot;mymagicmod:spells&amp;quot;). This way, other mods will be able to register things to that list, and you won't have to do anything else.&lt;br /&gt;
&lt;br /&gt;
Just like with registering a new item or block you have two ways of making a new registry. Each method takes in a &amp;lt;code&amp;gt;RegistryBuilder&amp;lt;/code&amp;gt; which is used to build an &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt;. Each builder should have its name set via &amp;lt;code&amp;gt;#setName&amp;lt;/code&amp;gt; before being created.&lt;br /&gt;
&lt;br /&gt;
=== With DeferredRegister ===&lt;br /&gt;
&lt;br /&gt;
The first method involves the second static constructor: &amp;lt;code&amp;gt;DeferredRegister#create(ResourceLocation, String)&amp;lt;/code&amp;gt;. From there, we can construct the registry using &amp;lt;code&amp;gt;#makeRegistry&amp;lt;/code&amp;gt;. This will already populate &amp;lt;code&amp;gt;#setName&amp;lt;/code&amp;gt; for us. This method also returns a supplier of the registry which we can use after the &amp;lt;code&amp;gt;NewRegistryEvent&amp;lt;/code&amp;gt; is called.&lt;br /&gt;
&lt;br /&gt;
Here is an example:&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final DeferredRegister&amp;lt;ExampleRegistry&amp;gt; EXAMPLE = DeferredRegister.create(new ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;), MODID);&lt;br /&gt;
&lt;br /&gt;
public static final Supplier&amp;lt;IForgeRegistry&amp;lt;ExampleRegistry&amp;gt;&amp;gt; REGISTRY = EXAMPLE.makeRegistry(RegistryBuilder::new);&lt;br /&gt;
|kotlin=val EXAMPLE: DeferredRegister&amp;lt;ExampleRegistry&amp;gt; = DeferredRegister.create(ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;), MODID)&lt;br /&gt;
&lt;br /&gt;
val REGISTRY: IForgeRegistry&amp;lt;ExampleRegistry&amp;gt; by lazy {&lt;br /&gt;
    EXAMPLE.makeRegistry(::RegistryBuilder).get()&lt;br /&gt;
}&lt;br /&gt;
|scala=final val EXAMPLE = DeferredRegister.create(new ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;), MODID)&lt;br /&gt;
&lt;br /&gt;
final lazy val REGISTRY = EXAMPLE.makeRegistry(() =&amp;gt; new RegistryBuilder).get&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
=== Using `NewRegistryEvent` ===&lt;br /&gt;
&lt;br /&gt;
The second method can be done during the &amp;lt;code&amp;gt;NewRegistryEvent&amp;lt;/code&amp;gt; event. Using &amp;lt;code&amp;gt;NewRegistryEvent#create&amp;lt;/code&amp;gt;, you can pass in a &amp;lt;code&amp;gt;RegistryBuilder&amp;lt;/code&amp;gt; directly. This method will return a &amp;lt;code&amp;gt;Supplier&amp;lt;IForgeRegistry&amp;lt;V&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; that can be stored and queried after the event is fired to gain access to your &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt; instance.&lt;br /&gt;
&lt;br /&gt;
Here is an example: (the event handler is registered on the '''mod event bus''')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public static Supplier&amp;lt;IForgeRegistry&amp;lt;ExampleRegistry&amp;gt;&amp;gt; registrySupplier = null;&lt;br /&gt;
&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void onNewRegistry(NewRegistryEvent event){&lt;br /&gt;
    RegistryBuilder&amp;lt;ExampleRegistry&amp;gt; registryBuilder = new RegistryBuilder&amp;lt;&amp;gt;();&lt;br /&gt;
    registryBuilder.setName(new ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;);&lt;br /&gt;
    registrySupplier = event.create(registryBuilder);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Handling Missing Entries ==&lt;br /&gt;
&lt;br /&gt;
When loading a pre-existing world after removing mods or updating versions, there are cases where certain registry objects will cease to exist. In these cases, it is possible to specify actions to remove a mapping, prevent the world from loading, or remap the name as needed. This can be done through the third of the registry events: &amp;lt;code&amp;gt;MissingMappingsEvent&amp;lt;/code&amp;gt;. Within the event, you can grab an immutable list of missing mappings associated with a mod id for a given registry via &amp;lt;code&amp;gt;#getMappings&amp;lt;/code&amp;gt; or a list of all mappings via &amp;lt;code&amp;gt;#getAllMappings&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For each &amp;lt;code&amp;gt;Mapping&amp;lt;/code&amp;gt;, you can either execute one of the following methods:&lt;br /&gt;
* &amp;lt;code&amp;gt;#ignore&amp;lt;/code&amp;gt; which abandons the entry when loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#warn&amp;lt;/code&amp;gt; which warns the user about the missing entry but continues loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#fail&amp;lt;/code&amp;gt; which prevents the world from loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#remap&amp;lt;/code&amp;gt; which remaps the entry to the specified non-null object in the same registry&lt;br /&gt;
&lt;br /&gt;
If none of the above are specified, then the default action of notifying the user about the missing mappings occur.&lt;br /&gt;
&lt;br /&gt;
Here is an example:  (the event handler is registered on the '''forge event bus''')&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=// This will ignore any missing test items from the specified world&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void onMissing(final MissingMappingsEvent event) {&lt;br /&gt;
    event.getMappings(ForgeRegistries.Keys.ITEMS, MODID).stream()&lt;br /&gt;
        .filter(mapping -&amp;gt; mapping.key.getPath().contains(&amp;quot;test&amp;quot;))&lt;br /&gt;
            .forEach(Mapping::ignore);&lt;br /&gt;
}&lt;br /&gt;
|groovy=// This will ignore any missing test items from the specified world&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
void onMissing(final MissingMappingsEvent event) {&lt;br /&gt;
    event.getMappings(ForgeRegistries.Keys.ITEMS, MODID).stream()&lt;br /&gt;
        .filter(mapping -&amp;gt; mapping.key.path.contains(&amp;quot;test&amp;quot;))&lt;br /&gt;
            .forEach(Mapping::ignore);&lt;br /&gt;
}&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Common Concepts]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Registration&amp;diff=3255</id>
		<title>Registration</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Registration&amp;diff=3255"/>
		<updated>2022-06-11T17:24:38Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update to 1.19&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Under construction}}&lt;br /&gt;
&lt;br /&gt;
Registration is the process of making an object (such as an item or block) known to the game during runtime. If some objects are not registered, this could cause crashes even before the game is fully loaded or arbitrary behaviors such as bottlenecking mod compatibility for world generation.&lt;br /&gt;
&lt;br /&gt;
Most objects that are known within the game are handled by a &amp;lt;code&amp;gt;Registry&amp;lt;/code&amp;gt;. Each registry uniquely defines each object through a &amp;quot;registry name&amp;quot; via a [[Using Resources#ResourceLocation|ResourceLocation]].&lt;br /&gt;
&lt;br /&gt;
{{Tip|In a global context, each object is universally unique through its &amp;lt;code&amp;gt;ResourceKey&amp;lt;/code&amp;gt;: a concatenation of its registry's id and the object's registry name.}}&lt;br /&gt;
&lt;br /&gt;
Due to the inconsistent ordering and registration process vanilla uses, Forge wraps most vanilla registries using &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt;. This guarantees that the loading order for these wrapped registries will be &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt;, and then the rest of the wrapped registries in alphabetical order. All registries supported by Forge can be found within the &amp;lt;code&amp;gt;ForgeRegistries&amp;lt;/code&amp;gt; class. Since all registry names are unique to a specific registry, different registry objects within different registries can have the same name (e.g. a &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt; and an &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; each hold a registry object named &amp;lt;code&amp;gt;examplemod:object&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|If two registry objects within the same registry have the same name, the second object will override the first. The only registry that will throw an &amp;lt;code&amp;gt;IllegalArgumentException&amp;lt;/code&amp;gt; is the &amp;lt;code&amp;gt;DataSerializerEntry&amp;lt;/code&amp;gt; registry.}}&lt;br /&gt;
&lt;br /&gt;
== Methods for Registering ==&lt;br /&gt;
&lt;br /&gt;
There are two proper ways to register objects within an associated wrapped Forge registry: the &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; class, and the &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; lifecycle event.&lt;br /&gt;
&lt;br /&gt;
=== DeferredRegister ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; is an abstraction layer over the registry event used to register objects. It maintains a map of &amp;quot;registry name&amp;quot; to their associated suppliers and resolves those suppliers during &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; for the associated registry. This method is the currently recommended, and documented, way to handle these objects as it provides convenience and safety for those who want to statically initialize objects while avoiding some issues associated with it. &lt;br /&gt;
&lt;br /&gt;
An example of a mod registering a custom block:&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=private static final DeferredRegister&amp;lt;Block&amp;gt; BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;Block&amp;gt; EXAMPLE_BLOCK = BLOCKS.register(&amp;quot;example_block&amp;quot;, () -&amp;gt; new Block(BlockBehaviour.Properties.of(Material.STONE)));&lt;br /&gt;
&lt;br /&gt;
public ExampleMod() {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get().getModEventBus());&lt;br /&gt;
}&lt;br /&gt;
|kotlin=private val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID)&lt;br /&gt;
&lt;br /&gt;
val EXAMPLE_BLOCK: RegistryObject&amp;lt;Block&amp;gt; = BLOCKS.register(&amp;quot;example_block&amp;quot;) { Block(BlockBehaviour.Properties.of(Material.ROCK)) }&lt;br /&gt;
&lt;br /&gt;
internal class ExampleMod {&lt;br /&gt;
    init {&lt;br /&gt;
        BLOCKS.register(FMLJavaModLoadingContext.get().modEventBus)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
|scala=object ExampleMod {&lt;br /&gt;
    private final val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID)&lt;br /&gt;
&lt;br /&gt;
    final val EXAMPLE_BLOCK = registerBlock(&amp;quot;example_block&amp;quot;, () =&amp;gt; new Block(BlockBehaviour.Properties.of(Material.ROCK)))&lt;br /&gt;
}&lt;br /&gt;
class ExampleMod {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get.getModEventBus)&lt;br /&gt;
}&lt;br /&gt;
|groovy=private static final DeferredRegister&amp;lt;Block&amp;gt; BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;Block&amp;gt; EXAMPLE_BLOCK = BLOCKS.register(&amp;quot;example_block&amp;quot;, () -&amp;gt; new Block(BlockBehaviour.Properties.of(Material.STONE)));&lt;br /&gt;
&lt;br /&gt;
ExampleMod() {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get().modEventBus);&lt;br /&gt;
}&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip|When using a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; to register any object, the name inputted will be automatically prefixed with the mod id passed in, giving the above object a &amp;quot;registry name&amp;quot; of &amp;lt;code&amp;gt;examplemod:example_block&amp;lt;/code&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
=== RegisterEvent ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is the second way register objects. This [[Events|event]] is fired for each registry synchronously in vanilla registry order after &amp;lt;code&amp;gt;FMLConstructModEvent&amp;lt;/code&amp;gt; and before the configs are loaded. Objects are registered using &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; by passing in the registry key, the name of the registry object, and the object itself. There is an additional &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; overload which takes in a consumed helper to register an object with a given name. It is recommended to use this method to avoid unnecessary object creation.&lt;br /&gt;
&lt;br /&gt;
Here is an example: (the event handler is registered on the '''mod event bus''')&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=@SubscribeEvent&lt;br /&gt;
public void register(RegisterEvent event) {&lt;br /&gt;
    event.register(ForgeRegistries.Keys.BLOCKS,&lt;br /&gt;
        helper -&amp;gt; helper.register(new ResourceLocation(MODID, &amp;quot;example_block&amp;quot;), new Block(...))&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
|kotlin=@JvmStatic&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
private fun register(event: RegisterEvent) =&lt;br /&gt;
    event.register(ForgeRegistries.Keys.BLOCKS) {&lt;br /&gt;
        helper -&amp;gt; helper.register(ResourceLocation(MODID, &amp;quot;example_block&amp;quot;), Block(...))&lt;br /&gt;
    }&lt;br /&gt;
|scala=@SubscribeEvent&lt;br /&gt;
def register(event: RegisterEvent): Unit =&lt;br /&gt;
    event.register(ForgeRegistries.Keys.BLOCKS,&lt;br /&gt;
        helper =&amp;gt; helper.register(new ResourceLocation(MODID, &amp;quot;example_block&amp;quot;), new Block(...))&lt;br /&gt;
    )&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|Since all objects registered must be singleton, some classes cannot by themselves be registered. Instead, &amp;lt;code&amp;gt;*Type&amp;lt;/code&amp;gt; classes are registered and used in the formers' constructors to wrap the flyweight objects. For example, a [[Basics_of_Block_Entities|&amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt;]] is wrapped via &amp;lt;code&amp;gt;BlockEntityType&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;Entity&amp;lt;/code&amp;gt; is wrapped via &amp;lt;code&amp;gt;EntityType&amp;lt;/code&amp;gt;. These &amp;lt;code&amp;gt;*Type&amp;lt;/code&amp;gt; classes hold factories that simply create the containing type on demand.&lt;br /&gt;
&lt;br /&gt;
These factory holders are created through the use of their &amp;lt;code&amp;gt;*Type$Builder&amp;lt;/code&amp;gt; classes. An example: (&amp;lt;code&amp;gt;REGISTER&amp;lt;/code&amp;gt; here refers to a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;BlockEntityType&amp;lt;?&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final RegistryObject&amp;lt;BlockEntityType&amp;lt;ExampleBlockEntity&amp;gt;&amp;gt; EXAMPLE_BLOCK_ENTITY = REGISTER.register(&lt;br /&gt;
    &amp;quot;example_block_entity&amp;quot;, () -&amp;gt; BlockEntityType.Builder.of(ExampleBlockEntity::new, EXAMPLE_BLOCK.get()).build(null)&lt;br /&gt;
);&lt;br /&gt;
|kotlin=val EXAMPLE_BLOCK_ENTITY: RegistryObject&amp;lt;BlockEntityType&amp;lt;ExampleBlockEntity&amp;gt;&amp;gt; = REGISTER.register(&amp;quot;example_block_entity&amp;quot;) { BlockEntityType.Builder.of(::ExampleBlockEntity, EXAMPLE_BLOCK.get()).build(null)) }&lt;br /&gt;
|scala=final val EXAMPLE_BLOCK_ENTITY = REGISTER.register(&amp;quot;example_block_entity&amp;quot;, () =&amp;gt; BlockEntityType.Builder.of(() =&amp;gt; new ExampleBlockEntity(), GeneralRegistrar.EXAMPLE_BLOCK.get).build(null))&lt;br /&gt;
|}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Non-Forge Registries ===&lt;br /&gt;
&lt;br /&gt;
Not all vanilla registries are wrapped as a Forge registry. To register objects to any one of these registries, create a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; via the &amp;lt;code&amp;gt;#create&amp;lt;/code&amp;gt; overload which takes in a resource key of the registry and the mod id to register the entries for. Then simply call &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; like any other &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=private static final DeferredRegister&amp;lt;LootItemConditionType&amp;gt; REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;LootItemConditionType&amp;gt; EXAMPLE_LOOT_ITEM_CONDITION_TYPE = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;, () -&amp;gt; new LootItemConditionType(...));&lt;br /&gt;
|kotlin=private val REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID)&lt;br /&gt;
&lt;br /&gt;
val EXAMPLE_LOOT_ITEM_CONDITION_TYPE : RegistryObject&amp;lt;LootItemConditionType&amp;gt; = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;) {&lt;br /&gt;
    LootItemConditionType(...)&lt;br /&gt;
}&lt;br /&gt;
|scala=private final val REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID)&lt;br /&gt;
&lt;br /&gt;
final val EXAMPLE_LOOT_ITEM_CONDITION_TYPE = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;, () =&amp;gt; new LootItemConditionType(...))&lt;br /&gt;
|groovy=private static final DeferredRegister&amp;lt;LootItemConditionType&amp;gt; REGISTER = DeferredRegister.create(Registry.LOOT_ITEM_REGISTRY, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;LootItemConditionType&amp;gt; EXAMPLE_LOOT_ITEM_CONDITION_TYPE = REGISTER.register(&amp;quot;example_loot_item_condition_type&amp;quot;, () -&amp;gt; new LootItemConditionType(...));&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
If you attempt to make one of these instances require an instance of another registry object, you should use the lazy initialization method mentioned above to register the object in the correct order.&lt;br /&gt;
&lt;br /&gt;
=== Data Driven Entries ===&lt;br /&gt;
&lt;br /&gt;
Registries are considered to be data driven if they are located within &amp;lt;code&amp;gt;RegistryAccess&amp;lt;/code&amp;gt; with the exception of &amp;lt;code&amp;gt;LevelStem&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Level&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
These registry objects only need to be registered within code if they are to be used within a pre-existing registry object (e.g. a &amp;lt;code&amp;gt;PlacedFeature&amp;lt;/code&amp;gt; for ore generation within an overworld &amp;lt;code&amp;gt;Biome&amp;lt;/code&amp;gt;). Otherwise, their instance can be purely registered using a JSON file.&lt;br /&gt;
&lt;br /&gt;
If a data driven registry object has to be registered within code, a dummy object should be supplied to hold a &amp;quot;registry name&amp;quot; and then constructed within a JSON file.&lt;br /&gt;
&lt;br /&gt;
== Referencing Registered Objects ==&lt;br /&gt;
&lt;br /&gt;
Each forge registered object should not be statically initialized nor reference another instance being registered. They must always be a new, singleton instance that is resolved during when &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is called for their registry. This is to maintain a sane loading order for registries and their objects along with dynamic loading/unloading of mods.&lt;br /&gt;
&lt;br /&gt;
Forge registered objects must always be referenced through a &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; or a field with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Using RegistryObjects===&lt;br /&gt;
&amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;s can be used to retrieve references to registered objects once they become available. Their references are updated along with all &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; annotations after the registry that &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is called for is dispatched and frozen.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; can be retrieved as a result of using &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; or calling the static factory &amp;lt;code&amp;gt;RegistryObject#create&amp;lt;/code&amp;gt;. Each static factory takes in the &amp;quot;registry name&amp;quot; of the object being referenced and one of the following: a &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt;, a registry name of the type &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt;, or a registry key of the type &amp;lt;code&amp;gt;ResourceKey&amp;lt;? extends Registry&amp;lt;?&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; can be stored within some field and retrieve the registered object using &amp;lt;code&amp;gt;#get&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
An example using &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;:&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final RegistryObject&amp;lt;Item&amp;gt; EXAMPLE_ITEM = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_item&amp;quot;), ForgeRegistries.ITEMS);&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
public static final RegistryObject&amp;lt;ExampleRegistry&amp;gt; EXAMPLE_OBJECT = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;); &lt;br /&gt;
|kotlin=val EXAMPLE_ITEM: RegistryObject&amp;lt;Item&amp;gt; = RegistryObject.create(ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_item&amp;quot;), ForgeRegistries.ITEMS)&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
val EXAMPLE_OBJECT: RegistryObject&amp;lt;ExampleRegistry&amp;gt; = RegistryObject.create(ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;)&lt;br /&gt;
|scala=final val EXAMPLE_ITEM = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_item&amp;quot;), ForgeRegistries.ITEMS)&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
final val EXAMPLE_OBJECT = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;); &lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|All vanilla objects are bootstrapped and registered before mods are loaded. As such, they can be referenced as is without any issues.}}&lt;br /&gt;
&lt;br /&gt;
=== Using @ObjectHolder ===&lt;br /&gt;
&lt;br /&gt;
Forge registry objects can also be injected into &amp;lt;code&amp;gt;public static&amp;lt;/code&amp;gt; fields with either their class or that field annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;. There must be enough information to construct a &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; to identify a single object within a specific registry.&lt;br /&gt;
&lt;br /&gt;
The rules for &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; are as follows:&lt;br /&gt;
&lt;br /&gt;
* If the class is annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;, its value will be the default namespace for all fields within if not explicitly defined&lt;br /&gt;
* If the class is annotated with &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt;, the modid will be the default namespace for all annotated fields within if not explicitly defined &lt;br /&gt;
* A field is considered for injection if:&lt;br /&gt;
** it has at least the modifiers &amp;lt;code&amp;gt;public static&amp;lt;/code&amp;gt;; and&lt;br /&gt;
** one of the following conditions are true:&lt;br /&gt;
*** the '''enclosing class''' has an &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; annotation, and the field is &amp;lt;code&amp;gt;final&amp;lt;/code&amp;gt;, and:&lt;br /&gt;
**** the name value is the field's name; and&lt;br /&gt;
**** the namespace value is the enclosing class's namespace&lt;br /&gt;
**** ''An exception is thrown if the namespace value cannot be found and inherited''&lt;br /&gt;
*** the '''field''' is annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;, and:&lt;br /&gt;
**** the name value is explicitly defined; and&lt;br /&gt;
**** the namespace value is either explicitly defined or the enclosing class's namespace&lt;br /&gt;
** the field type or one of its supertypes corresponds to a valid registry (e.g. &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;ArrowItem&amp;lt;/code&amp;gt; for the &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; registry)&lt;br /&gt;
** ''An exception is thrown if a field does not have a corresponding registry.''&lt;br /&gt;
* ''An exception is thrown if the resulting &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; is incomplete or invalid (non-valid characters in path)''&lt;br /&gt;
* If no other errors or exceptions occur, the field will be injected&lt;br /&gt;
* If all of the above rules do not apply, no action will be taken (and a message may be logged)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; annotated fields are injected with their associated object values after &amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt; is fired for their registry, along with &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;s.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|If the object does not exist in the registry when it is to be injected, a debug message will be logged, and no value will be injected. If the object is found, but the field cannot be set, a warning message will be logged instead.}}&lt;br /&gt;
&lt;br /&gt;
As these rules are rather complicated, here are some examples:&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; style=&amp;quot;border: solid 2px; padding: 2px 5px; margin-top: 3px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-weight:bold;line-height:1.6;&amp;quot;&amp;gt;Example uses of &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot; style=&amp;quot;overflow: auto; white-space: nowrap;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
@ObjectHolder(&amp;quot;minecraft&amp;quot;) // Inheritable resource namespace: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
class AnnotatedHolder {&lt;br /&gt;
    public static final Block diamond_block = null;   // No annotation. [public static final] is required.&lt;br /&gt;
                                                      // Block has a corresponding registry: [Block]&lt;br /&gt;
                                                      // Name path is the name of the field: &amp;quot;diamond_block&amp;quot;&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // So, namespace is inherited from class annotation: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:diamond_block&amp;quot; from the [Block] registry&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(&amp;quot;ambient.cave&amp;quot;)&lt;br /&gt;
    public static SoundEvent ambient_sound = null;    // Annotation present. [public static] is required.&lt;br /&gt;
                                                      // SoundEvent has a corresponding registry: [SoundEvent]&lt;br /&gt;
                                                      // Name path is the value of the annotation: &amp;quot;ambient.cave&amp;quot;&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // So, namespace is inherited from class annotation: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:ambient.cave&amp;quot; from the [SoundEvent] registry&lt;br /&gt;
&lt;br /&gt;
    // Assume for the next entry that [ManaType] is a valid registry.          &lt;br /&gt;
    @ObjectHolder(&amp;quot;neomagicae:coffeinum&amp;quot;)&lt;br /&gt;
    public static final ManaType coffeinum = null;    // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // ManaType has a corresponding registry: [ManaType] (custom registry)&lt;br /&gt;
                                                      // Resource location is explicitly defined: &amp;quot;neomagicae:coffeinum&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;neomagicae:coffeinum&amp;quot; from the [ManaType] registry&lt;br /&gt;
&lt;br /&gt;
    public static final Item ENDER_PEARL = null;      // No annotation. [public static final] is required.&lt;br /&gt;
                                                      // Item has a corresponding registry: [Item].&lt;br /&gt;
                                                      // Name path is the name of the field: &amp;quot;ENDER_PEARL&amp;quot; -&amp;gt; &amp;quot;ender_pearl&amp;quot;&lt;br /&gt;
                                                      // !! ^ Field name is valid, because they are&lt;br /&gt;
                                                      //      converted to lowercase automatically.&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // So, namespace is inherited from class annotation: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:ender_pearl&amp;quot; from the [Item] registry&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(&amp;quot;minecraft:arrow&amp;quot;)&lt;br /&gt;
    public static final ArrowItem arrow = null;       // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // ArrowItem does not have a corresponding registry.&lt;br /&gt;
                                                      // ArrowItem's supertype of Item has a corresponding registry: [Item]&lt;br /&gt;
                                                      // Resource location is explicitly defined: &amp;quot;minecraft:arrow&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:arrow&amp;quot; from the [Item] registry                                                    &lt;br /&gt;
&lt;br /&gt;
    public static Block bedrock = null;               // No annotation, so [public static final] is required.&lt;br /&gt;
                                                      // Therefore, the field is ignored.&lt;br /&gt;
    &lt;br /&gt;
    public static final CreativeModeTab group = null; // No annotation. [public static final] is required.&lt;br /&gt;
                                                      // CreativeModeTab does not have a corresponding registry.&lt;br /&gt;
                                                      // No supertypes of CreativeModeTab has a corresponding registry.&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class UnannotatedHolder { // Note the lack of an @ObjectHolder annotation on this class.&lt;br /&gt;
    @ObjectHolder(&amp;quot;minecraft:flame&amp;quot;)&lt;br /&gt;
    public static final Enchantment flame = null;     // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // Enchantment has corresponding registry: [Enchantment].&lt;br /&gt;
                                                      // Resource location is explicitly defined: &amp;quot;minecraft:flame&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:flame&amp;quot; from the [Enchantment] registry&lt;br /&gt;
&lt;br /&gt;
    public static final Biome ice_flat = null;        // No annotation on the enclosing class.&lt;br /&gt;
                                                      // Therefore, the field is ignored.&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(&amp;quot;minecraft:creeper&amp;quot;)&lt;br /&gt;
    public static Entity creeper = null;              // Annotation present. [public static] is required.&lt;br /&gt;
                                                      // Entity does not have a corresponding registry.&lt;br /&gt;
                                                      // No supertypes of Entity has a corresponding registry.&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(&amp;quot;levitation&amp;quot;)&lt;br /&gt;
    public static final Potion levitation = null;     // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // Potion has a corresponding registry: [Potion].&lt;br /&gt;
                                                      // Name path is the value of the annotation: &amp;quot;levitation&amp;quot;&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // No annotation in enclosing class.&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Creating Custom Registries ==&lt;br /&gt;
&lt;br /&gt;
Creating custom registries for your mod might be useful if you want other mods to add new things to your system. For example, you might have magic spells and want to allow other mods to add new spells. For this you will want to make a registry (eg. &amp;quot;mymagicmod:spells&amp;quot;). This way, other mods will be able to register things to that list, and you won't have to do anything else.&lt;br /&gt;
&lt;br /&gt;
Just like with registering a new item or block you have two ways of making a new registry. Each method takes in a &amp;lt;code&amp;gt;RegistryBuilder&amp;lt;/code&amp;gt; which is used to build an &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt;. Each builder should have its name set via &amp;lt;code&amp;gt;#setName&amp;lt;/code&amp;gt; before being created.&lt;br /&gt;
&lt;br /&gt;
=== With DeferredRegister ===&lt;br /&gt;
&lt;br /&gt;
The first method involves the second static constructor: &amp;lt;code&amp;gt;DeferredRegister#create(ResourceLocation, String)&amp;lt;/code&amp;gt;. From there, we can construct the registry using &amp;lt;code&amp;gt;#makeRegistry&amp;lt;/code&amp;gt;. This will already populate &amp;lt;code&amp;gt;#setName&amp;lt;/code&amp;gt; for us. This method also returns a supplier of the registry which we can use after the &amp;lt;code&amp;gt;NewRegistryEvent&amp;lt;/code&amp;gt; is called.&lt;br /&gt;
&lt;br /&gt;
Here is an example:&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final DeferredRegister&amp;lt;ExampleRegistry&amp;gt; EXAMPLE = DeferredRegister.create(new ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;), MODID);&lt;br /&gt;
&lt;br /&gt;
public static final Supplier&amp;lt;IForgeRegistry&amp;lt;ExampleRegistry&amp;gt;&amp;gt; REGISTRY = EXAMPLE.makeRegistry(RegistryBuilder::new);&lt;br /&gt;
|kotlin=val EXAMPLE: DeferredRegister&amp;lt;ExampleRegistry&amp;gt; = DeferredRegister.create(ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;), MODID)&lt;br /&gt;
&lt;br /&gt;
val REGISTRY: IForgeRegistry&amp;lt;ExampleRegistry&amp;gt; by lazy {&lt;br /&gt;
    EXAMPLE.makeRegistry(::RegistryBuilder).get()&lt;br /&gt;
}&lt;br /&gt;
|scala=final val EXAMPLE = DeferredRegister.create(new ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;), MODID)&lt;br /&gt;
&lt;br /&gt;
final lazy val REGISTRY = EXAMPLE.makeRegistry(() =&amp;gt; new RegistryBuilder).get&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
=== Using `NewRegistryEvent` ===&lt;br /&gt;
&lt;br /&gt;
The second method can be done during the &amp;lt;code&amp;gt;NewRegistryEvent&amp;lt;/code&amp;gt; event. Using &amp;lt;code&amp;gt;NewRegistryEvent#create&amp;lt;/code&amp;gt;, you can pass in a &amp;lt;code&amp;gt;RegistryBuilder&amp;lt;/code&amp;gt; directly. This method will return a &amp;lt;code&amp;gt;Supplier&amp;lt;IForgeRegistry&amp;lt;V&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; that can be stored and queried after the event is fired to gain access to your &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt; instance.&lt;br /&gt;
&lt;br /&gt;
Here is an example: (the event handler is registered on the '''mod event bus''')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public static Supplier&amp;lt;IForgeRegistry&amp;lt;ExampleRegistry&amp;gt;&amp;gt; registrySupplier = null;&lt;br /&gt;
&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void onNewRegistry(NewRegistryEvent event){&lt;br /&gt;
    RegistryBuilder&amp;lt;ExampleRegistry&amp;gt; registryBuilder = new RegistryBuilder&amp;lt;&amp;gt;();&lt;br /&gt;
    registryBuilder.setName(new ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;);&lt;br /&gt;
    registryBuilder.setType(ExampleRegistry.class);&lt;br /&gt;
    registrySupplier = event.create(registryBuilder);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Handling Missing Entries ==&lt;br /&gt;
&lt;br /&gt;
When loading a pre-existing world after removing mods or updating versions, there are cases where certain registry objects will cease to exist. In these cases, it is possible to specify actions to remove a mapping, prevent the world from loading, or remap the name as needed. This can be done through the third of the registry events: &amp;lt;code&amp;gt;MissingMappingsEvent&amp;lt;/code&amp;gt;. Within the event, you can grab an immutable list of missing mappings associated with a mod id for a given registry via &amp;lt;code&amp;gt;#getMappings&amp;lt;/code&amp;gt; or a list of all mappings via &amp;lt;code&amp;gt;#getAllMappings&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For each &amp;lt;code&amp;gt;Mapping&amp;lt;/code&amp;gt;, you can either execute one of the following methods:&lt;br /&gt;
* &amp;lt;code&amp;gt;#ignore&amp;lt;/code&amp;gt; which abandons the entry when loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#warn&amp;lt;/code&amp;gt; which warns the user about the missing entry but continues loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#fail&amp;lt;/code&amp;gt; which prevents the world from loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#remap&amp;lt;/code&amp;gt; which remaps the entry to the specified non-null object in the same registry&lt;br /&gt;
&lt;br /&gt;
If none of the above are specified, then the default action of notifying the user about the missing mappings occur.&lt;br /&gt;
&lt;br /&gt;
Here is an example:  (the event handler is registered on the '''forge event bus''')&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=// This will ignore any missing test items from the specified world&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void onMissing(final MissingMappingsEvent event) {&lt;br /&gt;
    event.getMappings(ForgeRegistries.Keys.ITEMS, MODID).stream()&lt;br /&gt;
        .filter(mapping -&amp;gt; mapping.key.getPath().contains(&amp;quot;test&amp;quot;))&lt;br /&gt;
            .forEach(Mapping::ignore);&lt;br /&gt;
}&lt;br /&gt;
|groovy=// This will ignore any missing test items from the specified world&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
void onMissing(final MissingMappingsEvent event) {&lt;br /&gt;
    event.getMappings(ForgeRegistries.Keys.ITEMS, MODID).stream()&lt;br /&gt;
        .filter(mapping -&amp;gt; mapping.key.path.contains(&amp;quot;test&amp;quot;))&lt;br /&gt;
            .forEach(Mapping::ignore);&lt;br /&gt;
}&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Common Concepts]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Internationalization&amp;diff=3254</id>
		<title>Internationalization</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Internationalization&amp;diff=3254"/>
		<updated>2022-06-11T17:05:12Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update to 1.19&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Internationalization''' (shortened as '''i18n'''), is a way of designing code so that it requires no changes to be adapted for various languages. '''Localization''' (shortened as '''l10n''') is the process of adapting displayed text to the user’s language.&lt;br /&gt;
&lt;br /&gt;
Internationalization is implemented using ''translation keys''. A translation key is a string that identifies a piece of displayable text in no specific language. For example, &amp;lt;code&amp;gt;block.minecraft.dirt&amp;lt;/code&amp;gt; is the translation key referring to the name of the Dirt block. This way, displayable text may be referenced with no concern for a specific language. The code requires no changes to be adapted in a new language.&lt;br /&gt;
&lt;br /&gt;
Localization will happen in the game’s locale. In a Minecraft client the locale is specified by the language settings. On a dedicated server, the only supported locale is &amp;lt;code&amp;gt;en_us&amp;lt;/code&amp;gt;. A list of available locales can be found on the [https://minecraft.gamepedia.com/Language#Available_languages Minecraft Wiki].&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|The only purpose of a translation key is internationalization. Do not use them for logic, such as comparing if two blocks are equal. Use their [[Registration|registry names]] instead.}}&lt;br /&gt;
&lt;br /&gt;
== Language files ==&lt;br /&gt;
&lt;br /&gt;
Language files are located by &amp;lt;code&amp;gt;assets/[namespace]/lang/[locale].json&amp;lt;/code&amp;gt; (e.g. the US English translation for &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt; would be &amp;lt;code&amp;gt;assets/examplemod/lang/en_us.json&amp;lt;/code&amp;gt;). The file format is simply a json map from translation keys to values. The file must be encoded in UTF-8.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;item.examplemod.example_item&amp;quot;: &amp;quot;Example Item Name&amp;quot;,&lt;br /&gt;
  &amp;quot;block.examplemod.example_block&amp;quot;: &amp;quot;Example Block Name&amp;quot;,&lt;br /&gt;
  &amp;quot;commands.examplemod.example_command.error&amp;quot;: &amp;quot;Example Command Errored!&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Usage with Blocks and Items ==&lt;br /&gt;
&lt;br /&gt;
Block, Item, and a few other Minecraft classes have built-in translation keys used to display their names. These translation keys are specified by overriding &amp;lt;code&amp;gt;getDescriptionId()&amp;lt;/code&amp;gt;. Item also has &amp;lt;code&amp;gt;getDescriptionId(ItemStack)&amp;lt;/code&amp;gt; which can be overridden to provide different translation keys depending on &amp;lt;code&amp;gt;ItemStack&amp;lt;/code&amp;gt; NBT.&lt;br /&gt;
&lt;br /&gt;
By default, &amp;lt;code&amp;gt;getDescriptionId()&amp;lt;/code&amp;gt; will return &amp;lt;code&amp;gt;block&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;item&amp;lt;/code&amp;gt;. prepended to the registry name of the block or item, with the colon replaced by a dot. &amp;lt;code&amp;gt;BlockItem&amp;lt;/code&amp;gt;s will take their corresponding Block's translation key by default. For example, an item with ID &amp;lt;code&amp;gt;examplemod:example_item&amp;lt;/code&amp;gt; effectively requires the following line in a language file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;item.examplemod.example_item&amp;quot;: &amp;quot;Example Item Name&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Localization methods ==&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|A common issue is having the server localize for clients. The server can only localize in its own locale, which does not necessarily match the locale of connected clients.&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
To respect the language settings of clients, the server should have clients localize text in their own locale using components with &amp;lt;code&amp;gt;TranslatableContents&amp;lt;/code&amp;gt; or other methods preserving the language neutral translation keys.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3 id=&amp;quot;I18n&amp;quot;&amp;gt;&amp;lt;tt style=&amp;quot;font-size: 100%&amp;quot;&amp;gt;net.minecraft.client.resources.language.I18n&amp;lt;/tt&amp;gt;&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Tip/Danger|'''This I18n class can only be found on the [[Sides#Different_Kinds_of_Sides|physical client]]!''' It is intended to be used by code that only runs on the client. Attempts to use this on a server will throw exceptions and crash.}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;get(String, Object...)&amp;lt;/code&amp;gt; localizes in the client’s locale with formatting. The first parameter is a translation key, and the rest are formatting arguments for &amp;lt;code&amp;gt;String.format(String, Object...)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt style=&amp;quot;font-size: 100%&amp;quot;&amp;gt;TranslatableContents&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;TranslatableContents&amp;lt;/code&amp;gt; is a &amp;lt;code&amp;gt;ComponentContents&amp;lt;/code&amp;gt; that is localized and formatted lazily. A &amp;lt;code&amp;gt;Component&amp;lt;/code&amp;gt; can be created for this using &amp;lt;code&amp;gt;Component#translatable&amp;lt;/code&amp;gt;. It is very useful when sending messages to players because it will be automatically localized in their own locale.&lt;br /&gt;
&lt;br /&gt;
The first parameter of the &amp;lt;code&amp;gt;TranslatableContents(String, Object...)&amp;lt;/code&amp;gt; constructor is a translation key, and the rest are used for formatting. The only supported format specifiers are &amp;lt;code&amp;gt;%s&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;%1$s&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;%2$s&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;%3$s&amp;lt;/code&amp;gt; etc. Formatting arguments may be other &amp;lt;code&amp;gt;Component&amp;lt;/code&amp;gt;s that will be inserted into the resulting formatted text with all their attributes preserved.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Common Concepts]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Events/Forge_bus&amp;diff=3253</id>
		<title>Events/Forge bus</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Events/Forge_bus&amp;diff=3253"/>
		<updated>2022-06-11T17:02:31Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update to 1.19&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Tree list}}&lt;br /&gt;
* &amp;lt;code&amp;gt;Event&amp;lt;/code&amp;gt; - ''The root superclass for all events''&lt;br /&gt;
**&amp;lt;code&amp;gt;MissingMappingsEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;RecipesUpdatedEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;FurnaceFuelBurnTimeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;DrawSelectionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;HighlightBlock&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;DrawSelectionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;HighlightEntity&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;DrawSelectionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;VillagerTradesEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;AddReloadListenerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;GameShuttingDownEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;ClientPlayerChangeGameTypeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;PlayerNegotiationEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;RenderHandEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;RenderLivingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderLivingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderLivingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;RegisterCommandsEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;RenderItemInFrameEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;RenderBlockOverlayEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;BlockToolModificationEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;NeighborNotifyEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;NoteBlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;Change&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;NoteBlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;Play&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;NoteBlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;BreakEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;EntityPlaceEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;EntityMultiPlaceEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;PistonEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PistonEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PistonEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;PortalSpawnEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;FarmlandTrampleEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;FluidPlaceBlockEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;CropGrowEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;CropGrowEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;CropGrowEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;WorldEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Load&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;WorldEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;CreateSpawnPosition&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;WorldEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Unload&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;WorldEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;ChunkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;Load&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ChunkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;Unload&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ChunkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;ChunkDataEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Save&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ChunkDataEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Load&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ChunkDataEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;SleepFinishedTimeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Save&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;WorldEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;SaplingGrowTreeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;PlayLevelSoundEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;AtEntity&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayLevelSoundEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;AtPosition&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayLevelSoundEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;RegisterStructureConversionsEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;ContainerScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;DrawBackground&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ContainerScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;DrawForeground&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ContainerScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;BabyEntitySpawnEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;ServerChatEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;KeyboardKeyEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;KeyboardKeyReleasedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;KeyboardKeyReleasedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;KeyboardKeyReleasedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;KeyboardKeyPressedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;KeyboardKeyPressedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;KeyboardKeyPressedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;InitScreenEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;InitScreenEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;InitScreenEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;MouseInputEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;MouseReleasedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;MouseReleasedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;MouseReleasedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;MouseScrollEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;MouseScrollEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;MouseScrollEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;MouseClickedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;MouseClickedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;MouseClickedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;MouseDragEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;MouseDragEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;MouseDragEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;KeyboardCharTypedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;KeyboardCharTypedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;KeyboardCharTypedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;PotionSizeEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;DrawScreenEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;DrawScreenEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;DrawScreenEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;BackgroundDrawnEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;VillageSiegeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;LootTableLoadEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;TagsUpdatedEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;PotionBrewEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PotionBrewEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PotionBrewEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;ClientChatReceivedEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;InputEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;ClickInputEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;InputEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;KeyInputEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;InputEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;MouseInputEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;InputEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;RawMouseEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;InputEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;MouseScrollEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;InputEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;RegisterClientCommandsEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;GatherComponents&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderTooltipEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;DifficultyChangeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;ScreenshotEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;ServerLifecycleEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;ServerStoppingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;ServerStoppedEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;ServerAboutToStartEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;ServerStartedEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;ServerStartingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;EnchantmentLevelSetEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;RenderTooltipEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderTooltipEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Color&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderTooltipEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;IdMappingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;CreateFluidSourceEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;VanillaGameEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;RenderGameOverlayEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderGameOverlayEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;Text&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderGameOverlayEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;BossInfo&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderGameOverlayEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;PreLayer&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderGameOverlayEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;Chat&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderGameOverlayEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderGameOverlayEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;PostLayer&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderGameOverlayEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;ClientChatEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;CommandEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;PermissionGatherEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Handler&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PermissionGatherEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Nodes&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PermissionGatherEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;OnDatapackSyncEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;StructureSpawnListGatherEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;GenericEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;AttachCapabilitiesEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;ExplosionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Detonate&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ExplosionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Start&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ExplosionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;SoundEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;SoundSourceEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;SoundEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;PlaySoundSourceEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;PlayStreamingSourceEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;PlaySoundEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;AnvilUpdateEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;ScreenOpenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;RenderArmEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;RenderLevelLastEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;TickEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;PlayerTickEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;TickEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;ServerTickEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;TickEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;WorldTickEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;TickEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;ClientTickEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;TickEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;RenderTickEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;TickEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;WandererTradesEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;ItemAttributeModifierEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;EntityViewRenderEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;FieldOfView&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityViewRenderEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;RenderFogEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityViewRenderEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;FogColors&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityViewRenderEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;CameraSetup&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityViewRenderEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;ClientPlayerNetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;LoggedOutEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ClientPlayerNetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;LoggedInEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ClientPlayerNetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;RespawnEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ClientPlayerNetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;FOVModifierEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;EntityEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;EntityTeleportEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;SpreadPlayersCommand&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityTeleportEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;EnderEntity&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityTeleportEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;EnderPearl&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityTeleportEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;TeleportCommand&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityTeleportEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;ChorusFruit&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityTeleportEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;ProjectileImpactEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;EntityTravelToDimensionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;EntityMobGriefingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;RenderNameplateEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;EntityConstructing&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;EntityMountEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;EntityStruckByLightningEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Size&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;EntityJoinWorldEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;EnteringSection&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;LivingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingEquipmentChangeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;SleepingLocationCheckEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingUpdateEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;PotionColorCalculationEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingExperienceDropEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingDamageEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingAttackEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingEntityUseItemEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Start&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingEntityUseItemEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Tick&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingEntityUseItemEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Stop&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingEntityUseItemEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Finish&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingEntityUseItemEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;PotionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;PotionExpiryEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PotionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;PotionApplicableEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PotionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;PotionRemoveEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PotionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;PotionAddedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PotionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;EnderManAngerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingPackSizeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;PlayerChangeGameModeEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;PlayerContainerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
******&amp;lt;code&amp;gt;Close&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerContainerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
******&amp;lt;code&amp;gt;Open&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerContainerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;PlayerWakeUpEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;BreakSpeed&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;ItemSmeltedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;ArrowLooseEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Clone&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;MovementInputUpdateEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;AdvancementEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;AnvilRepairEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;PlayerSleepInBedEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;PlayerLoggedOutEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;PlayerXpEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
******&amp;lt;code&amp;gt;XpChange&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerXpEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
******&amp;lt;code&amp;gt;LevelChange&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerXpEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
******&amp;lt;code&amp;gt;PickupXp&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerXpEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;StopTracking&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;FillBucketEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;PlayerDestroyItemEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;BonemealEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;SleepingTimeCheckEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;PlayerInteractEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
******&amp;lt;code&amp;gt;EntityInteractSpecific&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerInteractEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
******&amp;lt;code&amp;gt;RightClickBlock&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerInteractEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
******&amp;lt;code&amp;gt;EntityInteract&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerInteractEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
******&amp;lt;code&amp;gt;RightClickEmpty&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerInteractEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
******&amp;lt;code&amp;gt;RightClickItem&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerInteractEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
******&amp;lt;code&amp;gt;LeftClickEmpty&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerInteractEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
******&amp;lt;code&amp;gt;LeftClickBlock&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerInteractEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;EntityItemPickupEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;HarvestCheck&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;ItemPickupEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;TabListNameFormat&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;PlayerChangedDimensionEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;PlayerSetSpawnEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;PlayerFlyableFallEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;LoadFromFile&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;PermissionsChangedEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;CriticalHitEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;StartTracking&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;ItemFishedEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;ArrowNockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;PlayerRespawnEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;ItemTooltipEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;SaveToFile&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;PlayerLoggedInEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;ItemCraftedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;NameFormat&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;RenderPlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
******&amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderPlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
******&amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderPlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;AttackEntityEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;PlayerBrewedPotionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;ShieldBlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingHealEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LootingLevelEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingDestroyBlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingConversionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingConversionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingConversionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingKnockBackEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingHurtEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingVisibilityEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingDeathEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;AnimalTameEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingFallEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingGetProjectileEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingSetAttackTargetEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingSpawnEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;AllowDespawn&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingSpawnEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;CheckSpawn&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingSpawnEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*****&amp;lt;code&amp;gt;SpecialSpawn&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingSpawnEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingJumpEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;LivingDropsEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;ZombieEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;SummonAidEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ZombieEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;EntityLeaveWorldEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;ItemEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;ItemTossEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;ItemExpireEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;NetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;ServerCustomPayloadEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;NetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;ServerCustomPayloadLoginEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;NetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;LoginPayloadEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;NetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;ChannelRegistrationChangeEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;NetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;ClientCustomPayloadEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;NetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;ClientCustomPayloadLoginEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;NetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;GatherLoginPayloadsEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;NetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;ChunkWatchEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;UnWatch&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ChunkWatchEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Watch&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ChunkWatchEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
{{Tree list/end}}&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Events/Mod_bus&amp;diff=3252</id>
		<title>Events/Mod bus</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Events/Mod_bus&amp;diff=3252"/>
		<updated>2022-06-11T16:56:44Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update to 1.19&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Tree list}}&lt;br /&gt;
* &amp;lt;code&amp;gt;IModBusEvent&amp;lt;/code&amp;gt; - ''The interface for all mod bus events''&lt;br /&gt;
**&amp;lt;code&amp;gt;ModelBakeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;EntityRenderersEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;AddLayers&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityRenderersEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;CreateSkullModels&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityRenderersEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;RegisterRenderers&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityRenderersEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;RegisterLayerDefinitions&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityRenderersEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;ModelRegistryEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;GatherDataEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;RegisterShadersEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;AddPackFindersEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;ModLifecycleEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;ParallelDispatchEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;FMLCommonSetupEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;InterModProcessEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;FMLDedicatedServerSetupEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;FMLConstructModEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;InterModEnqueueEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;FMLClientSetupEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****&amp;lt;code&amp;gt;FMLLoadCompleteEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;EntityAttributeCreationEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;NewRegistryEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;RegisterGameTestsEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;ParticleFactoryRegisterEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;RegisterCapabilitiesEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;TextureStitchEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;TextureStitchEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;TextureStitchEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;EntityAttributeModificationEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;SoundEngineLoadEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;RegisterClientReloadListenersEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;RegisterEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;ColorHandlerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ColorHandlerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ColorHandlerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**&amp;lt;code&amp;gt;ModConfigEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Reloading&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ModConfigEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***&amp;lt;code&amp;gt;Loading&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ModConfigEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
{{Tree list/end}}&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Version_Checker&amp;diff=3251</id>
		<title>Version Checker</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Version_Checker&amp;diff=3251"/>
		<updated>2022-06-11T16:48:38Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update to 1.19&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''Version Checker''' is a Forge-provided utility for mods to check for new versions based on an online update JSON file. It is lightweight, toggleable, asynchoronous to the main mod loading, and integrates cleanly with the mods list menu.&lt;br /&gt;
&lt;br /&gt;
If there are outdated mods according to the version checker, a flashing emerald indicator will be shown on the Mods button on the main menu. The entries for the outdated mods in the mods list screen have the flashing emerald indicator. The information screen for outdated mods will have an &amp;lt;code&amp;gt;Update available:&amp;lt;/code&amp;gt; line with the &amp;lt;code&amp;gt;homepage&amp;lt;/code&amp;gt; URL from the update JSON file, and a list of mod versions and corresponding text after the mod description, for the mod versions between the most up-to-date and the currently installed version.&lt;br /&gt;
&amp;lt;!-- TODO: add images of these --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The version checker can be configured through the &amp;lt;code&amp;gt;versionCheck&amp;lt;/code&amp;gt; option in the FML config (&amp;lt;tt&amp;gt;config/fml.toml&amp;lt;/tt&amp;gt;). This option controls the version checking for all mods, including Forge.&lt;br /&gt;
&lt;br /&gt;
== Update JSON format ==&lt;br /&gt;
The version checker checks the update JSON, specified by the &amp;lt;code&amp;gt;updateJSONURL&amp;lt;/code&amp;gt; for the [[Proper Mod Structuring#Mod Properties|mod in the &amp;lt;tt&amp;gt;mods.toml&amp;lt;/tt&amp;gt;]]. An example of a JSON file is the [https://files.minecraftforge.net/maven/net/minecraftforge/forge/promotions_slim.json update JSON for Minecraft Forge]. The JSON file must be in the following format:&lt;br /&gt;
{{Tree list}}&lt;br /&gt;
* '''Root object'''&lt;br /&gt;
** &amp;lt;code&amp;gt;homepage&amp;lt;/code&amp;gt; (string): A URL, displayed on the mod's information screen on the Mods list screen&lt;br /&gt;
** &amp;lt;code&amp;gt;promos&amp;lt;/code&amp;gt; (object)&lt;br /&gt;
*** &amp;lt;code&amp;gt;'''''&amp;lt;nowiki&amp;gt;&amp;lt;minecraft version&amp;gt;&amp;lt;/nowiki&amp;gt;'''''-latest&amp;lt;/code&amp;gt; (string): A version string, for the latest mod version corresponding to the given Minecraft version&lt;br /&gt;
*** &amp;lt;code&amp;gt;'''''&amp;lt;nowiki&amp;gt;&amp;lt;minecraft version&amp;gt;&amp;lt;/nowiki&amp;gt;'''''-recommended&amp;lt;/code&amp;gt; (string): A version string, for the recommended mod version corresponding to the given Minecraft version&lt;br /&gt;
*** ...&lt;br /&gt;
** &amp;lt;code&amp;gt;'''''&amp;lt;nowiki&amp;gt;&amp;lt;minecraft version&amp;gt;&amp;lt;/nowiki&amp;gt;'''''&amp;lt;/code&amp;gt; (object)&lt;br /&gt;
*** &amp;lt;code&amp;gt;'''''&amp;lt;nowiki&amp;gt;&amp;lt;mod version&amp;gt;&amp;lt;/nowiki&amp;gt;'''''&amp;lt;/code&amp;gt; (string): Any text, displayed when the the specified mod version in the key is ahead of currently installed version; used as a changelog&lt;br /&gt;
*** ...&lt;br /&gt;
{{Tree list/end}}&lt;br /&gt;
&lt;br /&gt;
== Update status ==&lt;br /&gt;
There are 7 possible version checker statuses, according to the &amp;lt;code&amp;gt;VersionChecker.Status&amp;lt;/code&amp;gt; enum:&lt;br /&gt;
* &amp;lt;code&amp;gt;PENDING&amp;lt;/code&amp;gt; - The version checker has not or is currently retrieving the version from the update JSON. This is temporary, and will change into one of the other statuses.&lt;br /&gt;
* &amp;lt;code&amp;gt;FAILED&amp;lt;/code&amp;gt; - The version checker failed, either to retrieve the update JSON or some other error (such as failure to parse broken JSON).&lt;br /&gt;
* &amp;lt;code&amp;gt;UP_TO_CODE&amp;lt;/code&amp;gt; - The currently installed version is the same as the recommended version for the current Minecraft version.&lt;br /&gt;
* &amp;lt;code&amp;gt;OUTDATED&amp;lt;/code&amp;gt; - The currently installed version is either behind the recommended version for the MC version, or ahead of the recommended version, but behind the latest version for the MC version.&lt;br /&gt;
* &amp;lt;code&amp;gt;AHEAD&amp;lt;/code&amp;gt; - The currently installed version is ahead of the recommended version for the MC version, and there is no more up-to-date latest version for the MC version. &amp;lt;!-- might reword the second part --&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;BETA&amp;lt;/code&amp;gt; - There is no recommended version, and either the currently installed version is up-to-date or ahead of the latest version, or there is no latest version for the MC version.&lt;br /&gt;
* &amp;lt;code&amp;gt;BETA_OUTDATED&amp;lt;/code&amp;gt; - There is no recommended version, and the currently installed version is behind the latest version for the MC version.&lt;br /&gt;
&lt;br /&gt;
==&amp;lt;tt&amp;gt;CheckResult&amp;lt;/tt&amp;gt;==&lt;br /&gt;
The version checker result for a mod can be retrieving using the &amp;lt;code&amp;gt;VersionChecker.getResult(IModInfo)&amp;lt;/code&amp;gt; static method which returns a &amp;lt;code&amp;gt;CheckResult&amp;lt;/code&amp;gt;. (&amp;lt;code&amp;gt;IModInfo&amp;lt;/code&amp;gt; is the information for a specific mod; see &amp;lt;code&amp;gt;ModList#getModContainerById(String)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ModContainer#getModInfo()&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;CheckResult&amp;lt;/code&amp;gt; contains four methods:&lt;br /&gt;
* &amp;lt;code&amp;gt;status&amp;lt;/code&amp;gt;, the version checker status as a &amp;lt;code&amp;gt;VersionChecker.Status&amp;lt;/code&amp;gt; enum value.&lt;br /&gt;
* &amp;lt;code&amp;gt;target&amp;lt;/code&amp;gt;, the version which caused the &amp;lt;code&amp;gt;OUTDATED&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;BETA&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;BETA_OUTDATED&amp;lt;/code&amp;gt;&lt;br /&gt;
** If the status is &amp;lt;code&amp;gt;OUTDATED&amp;lt;/code&amp;gt;, this is the newest recommended or latest version from the JSON.&lt;br /&gt;
** If the status is &amp;lt;code&amp;gt;BETA_OUTDATED&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;BETA&amp;lt;/code&amp;gt;, this is the highest newest version from the JSON.&lt;br /&gt;
** This may be &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; if the status is &amp;lt;code&amp;gt;BETA&amp;lt;/code&amp;gt;, and there is no recommended or latest version defined in the JSON file.&lt;br /&gt;
* &amp;lt;code&amp;gt;changes&amp;lt;/code&amp;gt;, an unmodifiable map of mod versions and their corresponding text based on the MC version, where the mod versions are higher than the currently installed version. This information is shown on the mods information screen, as a changelog.&lt;br /&gt;
* &amp;lt;code&amp;gt;url&amp;lt;/code&amp;gt;, the URL from the &amp;lt;code&amp;gt;homepage&amp;lt;/code&amp;gt; string in the update JSON, displayed on the mods information screen.&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Mods.toml&amp;diff=3250</id>
		<title>Mods.toml</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Mods.toml&amp;diff=3250"/>
		<updated>2022-06-11T16:46:36Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update to 1.19, note to look at feature system later&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Under construction}}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file is read by the mod loader to determine what mods are packaged into your JAR file, and what information to display to the user in the Mods listing screen (accessible by pressing the &amp;quot;Mods&amp;quot; button on the main menu of the game). &lt;br /&gt;
&lt;br /&gt;
The file is formatted in [https://toml.io/en/ Tom's Obvious Minimal Language], or TOML for short. The example &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file in the MDK provides comments explaining the contents of the file. It should be stored under the &amp;lt;code&amp;gt;META-INF&amp;lt;/code&amp;gt; folder in your resources directory (&amp;lt;code&amp;gt;src/main/resources/META-INF/mods.toml&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Example &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;TOML&amp;quot;&amp;gt;&lt;br /&gt;
modLoader=&amp;quot;javafml&amp;quot;&lt;br /&gt;
# Forge for 1.19 is version 41&lt;br /&gt;
loaderVersion=&amp;quot;[41,)&amp;quot;&lt;br /&gt;
license=&amp;quot;All rights reserved&amp;quot;&lt;br /&gt;
issueTrackerURL=&amp;quot;github.com/MinecraftForge/MinecraftForge/issues&amp;quot;&lt;br /&gt;
showAsResourcePack=false&lt;br /&gt;
&lt;br /&gt;
[[mods]]&lt;br /&gt;
    modId=&amp;quot;examplemod&amp;quot;&lt;br /&gt;
    version=&amp;quot;1.0.0.0&amp;quot;&lt;br /&gt;
    displayName=&amp;quot;Example Mod&amp;quot;&lt;br /&gt;
    updateJSONURL=&amp;quot;minecraftforge.net/versions.json&amp;quot;&lt;br /&gt;
    displayURL=&amp;quot;minecraftforge.net&amp;quot;&lt;br /&gt;
    logoFile=&amp;quot;logo.png&amp;quot;&lt;br /&gt;
    credits=&amp;quot;I'd like to thank my mother and father.&amp;quot;&lt;br /&gt;
    authors=&amp;quot;Author&amp;quot;&lt;br /&gt;
    description='''&lt;br /&gt;
Lets you craft dirt into diamonds. This is a traditional mod that has existed for eons. It is ancient. The holy Notch created it. Jeb rainbowfied it. Dinnerbone made it upside down. Etc.&lt;br /&gt;
    '''&lt;br /&gt;
&lt;br /&gt;
[[dependencies.examplemod]]&lt;br /&gt;
    modId=&amp;quot;forge&amp;quot;&lt;br /&gt;
    mandatory=true&lt;br /&gt;
    versionRange=&amp;quot;[41,)&amp;quot;&lt;br /&gt;
    ordering=&amp;quot;NONE&amp;quot;&lt;br /&gt;
    side=&amp;quot;BOTH&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[dependencies.examplemod]]&lt;br /&gt;
    modId=&amp;quot;minecraft&amp;quot;&lt;br /&gt;
    mandatory=true&lt;br /&gt;
    versionRange=&amp;quot;[1.19,1.20)&amp;quot;&lt;br /&gt;
    ordering=&amp;quot;NONE&amp;quot;&lt;br /&gt;
    side=&amp;quot;BOTH&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt; is specified as&amp;lt;code&amp;gt;${file.jarVersion}&amp;lt;/code&amp;gt;, Forge will replace the string with the 'Implementation Version' specified in the jar manifest at runtime. Since the userdev environment has no jar manifest to pull from, it will be &amp;lt;code&amp;gt;NONE&amp;lt;/code&amp;gt; instead. As such, it is usually recommended to leave this field alone.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; is split into three parts: the non-mod-specific properties, which are linked to the mod file; the mod properties, with a section for each mod; and dependency configurations, with a section for each mod's dependencies. Here is a table of attributes that may be given to a mod, where &amp;lt;code&amp;gt;mandatory&amp;lt;/code&amp;gt; means there is no default and the absence of the property causes an error.&lt;br /&gt;
&lt;br /&gt;
===Non-Mod-Specific Properties===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modLoader&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The language loader for the mod. Used to specify an alternative language for the mod, such as Kotlin, if one exists. The Forge-provided Java loader is &amp;lt;code&amp;gt;javafml&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;javafml&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;loaderVersion&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The acceptable version range of the language loader, expressed as a [https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html Maven version spec]. For the Forge-provided Java loader, the version is the major version of the Forge version.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;[41,)&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;license&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The license for the mod(s) in this JAR. This string may be any valid string, but it is suggested to set the value to be the name of your license, and/or a link to that license.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;GNU GPL v3, https://www.gnu.org/licenses/gpl-3.0.en.html&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;showAsResourcePack&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;&lt;br /&gt;
|Whether to display this mod's resources as a separate option in the resource pack menu. If disabled, the mod's resources will be rolled into the &amp;quot;Mod resources&amp;quot; pack.&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;properties&amp;lt;/code&amp;gt;&lt;br /&gt;
|table&lt;br /&gt;
|&amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;&lt;br /&gt;
|A table of custom substitution properties. This is used by &amp;lt;code&amp;gt;StringSubstitutor&amp;lt;/code&amp;gt; to replace values, using &amp;lt;code&amp;gt;${file.*}&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&amp;lt;code&amp;gt;{ &amp;quot;thingy&amp;quot; = 1 }&amp;lt;/code&amp;gt;, used in &amp;lt;code&amp;gt;${file.thingy}&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;issueTrackerURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|A URL for an issues tracker. This should never be a blank string, as that will cause an error.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://my.issue.tracker/&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Mod Properties===&lt;br /&gt;
A mod entry is defined by a new section starting with a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[mods]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; header (In TOML, the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[mods]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; defines an [https://toml.io/en/v1.0.0-rc.2#array-of-tables array of tables]). All properties from that line until the next header will become the properties for that mod.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The mod's identifier (modid). This must match the following regex: &amp;lt;code&amp;gt;^[a-z][a-z0-9_-]{1,63}$&amp;lt;/code&amp;gt; (starts with a lowercase letter; other characters must be a lowercase letter, number, underscore or hyphen; must be 2-64 characters long).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;examplemod&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;namespace&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|value of &amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|An override namespace. Currently, there is no use for this property&lt;br /&gt;
|&amp;lt;code&amp;gt;example&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;1&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The mod's version, ideally conforming to [[Semantic Versioning|semantic versioning]]. The default value in the MDK for this is &amp;lt;code&amp;gt;${file.jarVersion}&amp;lt;/code&amp;gt;, which is replaced at runtime with the &amp;lt;code&amp;gt;Implementation-Version&amp;lt;/code&amp;gt; found in the jar's manifest file.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;0.2.4-beta1&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;displayName&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|value of &amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|The display name of the mod, for use in the Mods listing screen&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;Example Mod&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;description&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;MISSING DESCRIPTION&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The description of the mod, for use in the Mods listing screen. It's recommended to use a multiline string (surrounded by &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;'''&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;)&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;Adds things and stuff. &amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;logoFile&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|The path of the logo file image, for use in the Mods listing screen. The image must be in the root of the jar file, not in any subfolder thereof (e.g. the file is directly in &amp;lt;code&amp;gt;src/main/resources&amp;lt;/code&amp;gt;)&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;myAwesomeLogo.png&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;logoBlur&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|Whether to do some blurring on the mod's logo in the Mods listing screen. Has no effect if &amp;lt;code&amp;gt;logoFile&amp;lt;/code&amp;gt; is not set.&lt;br /&gt;
|&amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;updateJSONURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|The update JSON URL, used by the [[Update_Checker|update checker]]. This should never be a blank string, as that will cause an error.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://myurl.me/path/to/update.json&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modproperties&amp;lt;/code&amp;gt;&lt;br /&gt;
|table&lt;br /&gt;
|&amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt;&lt;br /&gt;
|A table of custom mod properties; this is not used for Forge, but is mainly for use by mods.&lt;br /&gt;
|&amp;lt;code&amp;gt;{ &amp;quot;useThing&amp;quot; = true }&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;credits&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|Credits and acknowledgements for the mod, for use in the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;This person and that guy&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;authors&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|Authors for the mod, for use in the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;ExampleDude&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;displayURL&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|''nothing''&lt;br /&gt;
|A URL, displayed on the Mods listing screen. Can be any string.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;quot;http://example.com/&amp;quot;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Dependency Configurations===&lt;br /&gt;
Mods can define dependencies for their mods, which are checked by Forge before loading mods. This is used for e.g. ensuring your mod loads after another, or hard-crashing if a mod with a specified version does not exist.&lt;br /&gt;
&lt;br /&gt;
These dependency configurations, like the mod properties, are defined by a new section starting with &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;[[dependencies.modid]]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, with &amp;lt;code&amp;gt;modid&amp;lt;/code&amp;gt; being the mod id that has this dependency. All properties from that line until the next header will become the properties of that dependency configuration.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!|Property&lt;br /&gt;
!|Type&lt;br /&gt;
!|Defaults&lt;br /&gt;
!|Description&lt;br /&gt;
!|Example&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;modId&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|The mod id of the dependency.&lt;br /&gt;
|&amp;lt;code&amp;gt;examplelibrary&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;mandatory&amp;lt;/code&amp;gt;&lt;br /&gt;
|boolean&lt;br /&gt;
|'''mandatory'''&lt;br /&gt;
|Whether to crash if this dependency is not met.&lt;br /&gt;
|&amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;versionRange&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|The acceptable version range of the dependency, expressed as a [https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html Maven version spec]. An empty string is an unbounded version range, which matches any version.&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;[1.0,2.0)&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;ordering&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;NONE&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|Defines if the mod must load before or after this dependency. The valid values are &amp;lt;code&amp;gt;BEFORE&amp;lt;/code&amp;gt; (must load before), &amp;lt;code&amp;gt;AFTER&amp;lt;/code&amp;gt; (must load after), and &amp;lt;code&amp;gt;NONE&amp;lt;/code&amp;gt; (does not care about order).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;AFTER&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;side&amp;lt;/code&amp;gt;&lt;br /&gt;
|string&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;BOTH&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|physical side]]. The valid values are &amp;lt;code&amp;gt;CLIENT&amp;lt;/code&amp;gt; (present on the client), &amp;lt;code&amp;gt;SERVER&amp;lt;/code&amp;gt; (present on the dedicated server), and &amp;lt;code&amp;gt;BOTH&amp;lt;/code&amp;gt; (present on both sides).&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;CLIENT&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|When specifying dependency ordering between two or more mods, beware of cyclic order!&lt;br /&gt;
An example: if mod A must load before mod B, and mod B must load before mod A, the game will crash because of the circular cycle.}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started]]&lt;br /&gt;
[[Category:Beginner Topics]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Getting_Started&amp;diff=3249</id>
		<title>Getting Started</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Getting_Started&amp;diff=3249"/>
		<updated>2022-06-11T16:39:53Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update to 1.19&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Minecraft Forge''' is a modding framework, designed to allow different mods to load and work together to be compatible. Through the years, there has been many changes in the Forge tooling to make working with mods as seamless as possible. It is now easier than ever to start making your own mod.&lt;br /&gt;
&lt;br /&gt;
== The Mod Development Kit ==&lt;br /&gt;
The '''Mod Development Kit''' or '''MDK''' is a downloadable archive that contains the basic skeleton for starting a new mod. It contains the following files and folders:&lt;br /&gt;
&lt;br /&gt;
{{Tree list}}&lt;br /&gt;
* '''The Mod Development Kit'''&lt;br /&gt;
** &amp;lt;code&amp;gt;gradle/wrapper/&amp;lt;/code&amp;gt; - The folder containing the [https://docs.gradle.org/7.4.2/userguide/gradle_wrapper.html Gradle wrapper]'', Forge uses Version '''7.4.2'''''&lt;br /&gt;
** &amp;lt;code&amp;gt;src&amp;lt;/code&amp;gt; - The sources folder&lt;br /&gt;
*** &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; - The &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; source set&lt;br /&gt;
**** &amp;lt;code&amp;gt;java&amp;lt;/code&amp;gt; - The java sources for the &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; source set&lt;br /&gt;
***** ...&lt;br /&gt;
**** &amp;lt;code&amp;gt;resources&amp;lt;/code&amp;gt; - The resources for the &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; source set&lt;br /&gt;
***** &amp;lt;code&amp;gt;META-INF&amp;lt;/code&amp;gt; - The folder for '''meta'''data '''inf'''ormation files&amp;lt;ref&amp;gt;[https://stackoverflow.com/a/6075320/14416954 StackOverflow answer]: ''... Basically, if it was stored in META-INF, it was Meta-data Information...''&amp;lt;/ref&amp;gt;&lt;br /&gt;
****** &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; - The [[Mods.toml file|&amp;lt;tt&amp;gt;mods.toml&amp;lt;/tt&amp;gt; file]], where mods are declared&lt;br /&gt;
***** &amp;lt;code&amp;gt;pack.mcmeta&amp;lt;/code&amp;gt; - File used by Minecraft to [[mc:Data Pack#pack.mcmeta|identify data and resource packs]]&lt;br /&gt;
** &amp;lt;code&amp;gt;.gitattributes&amp;lt;/code&amp;gt; - Used by [[wikipedia:Git|Git]] for specifying attributes for files&amp;lt;ref&amp;gt;[https://git-scm.com/docs/gitattributes Official git documentation on &amp;lt;tt&amp;gt;.gitattributes&amp;lt;/tt&amp;gt;]&amp;lt;/ref&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;.gitignore&amp;lt;/code&amp;gt; - Used by Git for specifying intentionally untracked/ignored files&amp;lt;ref&amp;gt;[https://git-scm.com/docs/gitignore Official git documentation on &amp;lt;tt&amp;gt;.gitignore&amp;lt;/tt&amp;gt;]&amp;lt;/ref&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;build.gradle&amp;lt;/code&amp;gt; - The Gradle buildscript, which defines the project and tasks&amp;lt;ref&amp;gt;[https://docs.gradle.org/7.4.2/userguide/tutorial_using_tasks.html Gradle User Guide for 7.4.2: ''Build Script Basics'']&amp;lt;/ref&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;changelog.txt&amp;lt;/code&amp;gt; - The Forge version changelog&lt;br /&gt;
** &amp;lt;code&amp;gt;CREDITS.txt&amp;lt;/code&amp;gt; - Forge's credits/''thank you'' file&lt;br /&gt;
** &amp;lt;code&amp;gt;gradle.properties&amp;lt;/code&amp;gt; - The Gradle properties file, for defining additional variables and options&amp;lt;ref&amp;gt;[https://docs.gradle.org/7.4.2/userguide/build_environment.html#sec:gradle_configuration_properties Gradle User Guide for 7.4.2: ''Build Environment § Gradle properties'']&amp;lt;/ref&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;gradlew&amp;lt;/code&amp;gt; - The *nix shell file for executing the Gradle wrapper&lt;br /&gt;
** &amp;lt;code&amp;gt;gradlew.bat&amp;lt;/code&amp;gt; - The Windows batch file for executing the Gradle wrapper&lt;br /&gt;
** &amp;lt;code&amp;gt;LICENSE.txt&amp;lt;/code&amp;gt; - File containing the licensing information for Forge and libraries&lt;br /&gt;
** &amp;lt;code&amp;gt;README.txt&amp;lt;/code&amp;gt; - Readme file with the basic setup instructions&lt;br /&gt;
{{Tree list/end}}&lt;br /&gt;
&lt;br /&gt;
== Basic MDK Setup ==&lt;br /&gt;
# Download the MDK from the [https://files.minecraftforge.net/ official Minecraft Forge download site] and extract the MDK into an empty folder.&lt;br /&gt;
# Open your IDE of choice, and import the project as a Gradle project.&lt;br /&gt;
#* For '''Eclipse''': &amp;lt;tt&amp;gt;File &amp;gt; Import &amp;gt; Gradle &amp;gt; Existing Gradle Project&amp;lt;/tt&amp;gt;, select the folder for the &amp;lt;tt&amp;gt;Project root directory&amp;lt;/tt&amp;gt;, click &amp;lt;tt&amp;gt;Finish&amp;lt;/tt&amp;gt;&lt;br /&gt;
#* For '''IntelliJ IDEA''': &amp;lt;tt&amp;gt;File &amp;gt; Open&amp;lt;/tt&amp;gt;, select and open the folder, select the &amp;lt;tt&amp;gt;build.gradle&amp;lt;/tt&amp;gt; file, click &amp;lt;tt&amp;gt;OK&amp;lt;/tt&amp;gt;, click &amp;lt;tt&amp;gt;Open as Project&amp;lt;/tt&amp;gt;&lt;br /&gt;
#* For '''Visual Studio Code''': Run &amp;lt;code&amp;gt;./gradlew buildNeeded&amp;lt;/code&amp;gt; and then &amp;lt;code&amp;gt;./gradlew eclipse&amp;lt;/code&amp;gt;, then &amp;lt;tt&amp;gt;File &amp;gt; Open Folder...&amp;lt;/tt&amp;gt; and select the folder&lt;br /&gt;
# Wait for the setup process to complete and the Minecraft sources are decompiled.&lt;br /&gt;
#* For '''Visual Studio Code''': This step can be skipped as it was already done in the previous step&lt;br /&gt;
# Generate the run configurations for your IDE using the appropriate Gradle task. &amp;lt;br&amp;gt;These tasks can be run in the terminal using &amp;lt;code&amp;gt;./gradlew gen***Runs&amp;lt;/code&amp;gt;.&lt;br /&gt;
#* For '''Eclipse''': the task is &amp;lt;code&amp;gt;genEclipseRuns&amp;lt;/code&amp;gt;; to run in the IDE directly, open the &amp;lt;tt&amp;gt;Gradle Tasks&amp;lt;/tt&amp;gt; tab on the bottom panel, ''wait until the tasks have loaded'' then expand the folder, expand the &amp;lt;tt&amp;gt;fg_runs&amp;lt;/tt&amp;gt; folder, then double-click &amp;lt;tt&amp;gt;genEclipseRuns&amp;lt;/tt&amp;gt;.&lt;br /&gt;
#* For '''IntelliJ IDEA''': the task is &amp;lt;code&amp;gt;genIntellijRuns&amp;lt;/code&amp;gt;; to run in the IDE directly, open the &amp;lt;tt&amp;gt;Gradle&amp;lt;/tt&amp;gt; on the right, expand the project folder, double-click &amp;lt;tt&amp;gt;Tasks &amp;gt; fg_runs &amp;gt; genIntellijRuns&amp;lt;/tt&amp;gt;.&lt;br /&gt;
#* For '''Visual Studio Code''': the task is &amp;lt;code&amp;gt;genVSCodeRuns&amp;lt;/code&amp;gt;; the [https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-pack Extension Pack for Java] and [https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-gradle Gradle for Java plugin] should both be installed for smoother integration.&lt;br /&gt;
&lt;br /&gt;
{{Tip|The most popular IDEs used by Forge and mod developers are [https://www.eclipse.org/eclipseide/ Eclipse] and [https://www.jetbrains.com/idea/ IntelliJ IDEA]. While Visual Studio Code has a run generation task, because of its relative unpopularity as an IDE for Minecraft modding, the user will have to self-diagnose any issues that may arise from their use of it.}}&lt;br /&gt;
&lt;br /&gt;
== Customizing the MDK ==&lt;br /&gt;
The MDK provides default values for the buildscript and &amp;lt;tt&amp;gt;mods.toml&amp;lt;/tt&amp;gt; file. These values should be replaced with your own mod's information.&lt;br /&gt;
&lt;br /&gt;
All edits should be done below the &amp;lt;code&amp;gt;apply plugin: 'net.minecraftforge.gradle'&amp;lt;/code&amp;gt; line. The lines above it are required for the Forge MDK to work correctly, and should not be modified without proper knowledge.&lt;br /&gt;
* All references to &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt; in the buildscript should be replaced with your modid.&lt;br /&gt;
** Use your IDE's find-and-replace function to quickly replace these values.&lt;br /&gt;
** Pick a unique and memorable modid. The modid must be between 2 and 64 characters, and must consist of lowercase letters, numbers, underscores (&amp;lt;code&amp;gt;_&amp;lt;/code&amp;gt;) and hyphens (&amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;). The recommendation is to avoid using acronyms and abbreviations.&lt;br /&gt;
* Change the &amp;lt;code&amp;gt;archivesBaseName&amp;lt;/code&amp;gt; variable to your modid. This is used as the base name for the JAR file when you build your mod, and as the &amp;lt;tt&amp;gt;artifactId&amp;lt;/tt&amp;gt; of your mod's [https://maven.apache.org/pom.html#Maven_Coordinates maven coordinates].&lt;br /&gt;
* Change the &amp;lt;code&amp;gt;group&amp;lt;/code&amp;gt; to your [[Proper Mod Structuring#Packaging|unique root java package]]. This is used as the &amp;lt;tt&amp;gt;groupId&amp;lt;/tt&amp;gt; of your mod's maven coordinates.&lt;br /&gt;
* In the &amp;lt;code&amp;gt;jar&amp;lt;/code&amp;gt; task, change the values of the &amp;lt;code&amp;gt;Specification-Vendor&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Implementation-Vendor&amp;lt;/code&amp;gt; keys to your username/brand name or other form of identification.&lt;br /&gt;
* ''Optional suggestion: '' Change the &amp;lt;code&amp;gt;version&amp;lt;/code&amp;gt; variable to have a 0 as the major version (ex. &amp;lt;code&amp;gt;'0.1'&amp;lt;/code&amp;gt;. This is to follow [[Semantic Versioning#During Development|semantic versioning guidelines]] for versions in active development.&lt;br /&gt;
&lt;br /&gt;
== Building and Testing ==&lt;br /&gt;
You can test your mod in the development environment using either your IDE's run configurations and built-in debugging utilities, or by running the &amp;lt;code&amp;gt;run*&amp;lt;/code&amp;gt; task as defined by the buildscript's run configurations.&lt;br /&gt;
&lt;br /&gt;
There are four default run configurations with the MDK:&lt;br /&gt;
* &amp;lt;code&amp;gt;runClient&amp;lt;/code&amp;gt;, for starting the client.&lt;br /&gt;
* &amp;lt;code&amp;gt;runServer&amp;lt;/code&amp;gt;, for starting the dedicated server. ''You will need to accept the EULA through the &amp;lt;tt&amp;gt;eula.txt&amp;lt;/tt&amp;gt; after running the server for the first time.''&lt;br /&gt;
* &amp;lt;code&amp;gt;runData&amp;lt;/code&amp;gt;, for starting the client in [[Datageneration|data generation]] mode.&lt;br /&gt;
* &amp;lt;code&amp;gt;runGameTestServer&amp;lt;/code&amp;gt;, for starting a build server to run [[Game_Tests|game tests]].&lt;br /&gt;
&lt;br /&gt;
{{Tip|Always test your mod in both the client and the dedicated server, even if you are making a one-sided mod. Mods should not crash when running on both sides, and one-sided mods should not crash if they run on the wrong side.}}&lt;br /&gt;
&lt;br /&gt;
You can build your mod's final JAR using the &amp;lt;code&amp;gt;build&amp;lt;/code&amp;gt; task. The resulting JAR will be located in the &amp;lt;code&amp;gt;build/libs&amp;lt;/code&amp;gt; folder under your project directory.&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Beginner Topics]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Main_Page&amp;diff=3139</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Main_Page&amp;diff=3139"/>
		<updated>2022-04-20T04:03:11Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Add game tests link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;templatestyles src=&amp;quot;:Main_Page/styles.css&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;center title&amp;quot;&amp;gt;Forge Community Wiki&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Forge Community Wiki exists so that the community can:&lt;br /&gt;
&lt;br /&gt;
* collectively keep track of major changes and updates to Forge and Vanilla code;&lt;br /&gt;
* create and edit articles with in-depth explanations about a variety of Forge-related subjects; and&lt;br /&gt;
* contribute example code and tutorials for both simple and difficult concepts.&lt;br /&gt;
&lt;br /&gt;
This wiki is editable by any registered user with an account. This is to allow tracking of harmful edits, but isn't imposing any annoying limits. We welcome any edit, however small. Join the [https://discord.gg/Nn42eAh Discord] to discuss changes and edits to the wiki with others and the staff.&lt;br /&gt;
&lt;br /&gt;
{{Supported versions}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;center round_warning&amp;quot;&amp;gt;&lt;br /&gt;
Please read the [[FCWMeta:Wiki Policy|wiki policy]] before editing!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;center&amp;quot; style=&amp;quot;margin-bottom: 2em&amp;quot;&amp;gt;&lt;br /&gt;
{{Supported versions|text=1}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box_container center&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Beginner Topics&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Getting Started]]&lt;br /&gt;
* [[Proper Mod Structuring]]&lt;br /&gt;
* [[Mods.toml file]]&lt;br /&gt;
* [[Debug Profiler|The Debug Profiler]]&lt;br /&gt;
* [[Version Checker]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Common Concepts&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Sides|Understanding Sides]]&lt;br /&gt;
* [[Events|Understanding Events]]&lt;br /&gt;
* [[Registration]]&lt;br /&gt;
* [[Internationalization]]&lt;br /&gt;
* [[Configs]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Forge Conventions&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Semantic Versioning]]&lt;br /&gt;
* [[Stages of Modloading]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Resources and Data&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Using Resources|Introduction]]&lt;br /&gt;
* [[Recipes]]&lt;br /&gt;
* [[Tags]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Blocks&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Making Blocks|Creating Blocks]]&lt;br /&gt;
* [[Understanding Blockstates]] &lt;br /&gt;
* [[Interacting With Blocks|Block Interactions]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Items&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Making Items]]&lt;br /&gt;
* [[Making Tools]]&lt;br /&gt;
* [[BlockEntityWithoutLevelRenderer|&amp;lt;tt&amp;gt;BlockEntityWithoutLevelRenderer&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Data Generation&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Datageneration|Introduction]]&lt;br /&gt;
* [[Datageneration/Recipes|Recipes]]&lt;br /&gt;
* [[Datageneration/Tags|Tags]]&lt;br /&gt;
* [[Datageneration/Loot_Tables|Loot Tables]]&lt;br /&gt;
* [[Datageneration/I18n|Localization]]&lt;br /&gt;
* [[Datageneration/States and Models|&amp;lt;tt&amp;gt;BlockState&amp;lt;/tt&amp;gt;s and Models]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Block Entities&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Block Entities|Introduction]]&lt;br /&gt;
* [[Block Entity Renderer|&amp;lt;tt&amp;gt;BlockEntityRenderer&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Models&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Introduction to Models|Introduction]]&lt;br /&gt;
* [[Model JSONs]]&lt;br /&gt;
* [[BlockState JSONs]]&lt;br /&gt;
* [[Coloring textures dynamically|Dynamically Colored Textures]]&lt;br /&gt;
* [[Item Properties]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Handling Information&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Understanding Networking|Introduction]]&lt;br /&gt;
* [[Using NBT|Named Binary Tag (NBT)]]&lt;br /&gt;
* [[Using FriendlyByteBuf|Using &amp;lt;tt&amp;gt;FriendlyByteBuf&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
* [[Sending Packets|Sending and Receiving Packets]]&lt;br /&gt;
* [[Using SimpleChannel|Using &amp;lt;tt&amp;gt;SimpleChannel&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
* [[Networking with Entities]]&lt;br /&gt;
* [[DynamicOps|Using DynamicOps]]&lt;br /&gt;
* [[Codecs|Using Codecs]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Data Storage&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Capabilities|Understanding Capabilities]] &lt;br /&gt;
* [[Capabilities/Attaching|Attaching Capabilities]]&lt;br /&gt;
* [[Saved Data]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Game Effects&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Mob Effects]]&lt;br /&gt;
* [[Potions]]&lt;br /&gt;
* [[Particles]]&lt;br /&gt;
* [[Sounds]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Events&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Events|Understanding Events]]&lt;br /&gt;
* [[Entity Events]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Others&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Dependencies]]&lt;br /&gt;
* [[Dynamic Loot Modification]]&lt;br /&gt;
* [[Components|Components and Translation Keys]]&lt;br /&gt;
* [[Key Mappings]]&lt;br /&gt;
* [[Access Transformers]]&lt;br /&gt;
* [[Toolchain]]&lt;br /&gt;
* [[Game_Tests|Game Tests]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Recipes&amp;lt;/h3&amp;gt;&lt;br /&gt;
* [[Recipes]]&lt;br /&gt;
* [[Custom Recipes|Custom Recipe Types]]&lt;br /&gt;
* [[Datageneration/Recipes|Datageneration]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Game_Tests&amp;diff=3138</id>
		<title>Game Tests</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Game_Tests&amp;diff=3138"/>
		<updated>2022-04-20T04:02:15Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Add game tests page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Game Tests are a way to run in-game unit tests. The system was designed to be scalable and in parallel to run large numbers of different tests efficiently. Testing object interactions and behaviors are simply a few of the many applications of this framework.&lt;br /&gt;
&lt;br /&gt;
== Creating a Game Test ==&lt;br /&gt;
&lt;br /&gt;
A standard Game Test follows three basic steps:&lt;br /&gt;
&lt;br /&gt;
# A structure, or template, is loaded holding the scene on which the interaction or behavior is tested.&lt;br /&gt;
# A method conducts the logic to perform on the scene.&lt;br /&gt;
# The method logic executes. If a successful state is reached, then the test succeeds. Otherwise, the test fails and the result is stored within a lectern adjacent to the scene.&lt;br /&gt;
&lt;br /&gt;
As such, to create a Game Test, there must be an existing template holding the initial start state of the scene and a method which provides the logic of execution.&lt;br /&gt;
&lt;br /&gt;
=== The Test Method ===&lt;br /&gt;
&lt;br /&gt;
A Game Test method is a &amp;lt;code&amp;gt;Consumer&amp;lt;GameTestHelper&amp;gt;&amp;lt;/code&amp;gt; reference, meaning it takes in a &amp;lt;code&amp;gt;GameTestHelper&amp;lt;/code&amp;gt; and returns nothing. For a Game Test method to be recognized, it must have a &amp;lt;code&amp;gt;@GameTest&amp;lt;/code&amp;gt; annotation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class ExampleGameTests {&lt;br /&gt;
  @GameTest&lt;br /&gt;
  public static void exampleTest(GameTestHelper helper) {&lt;br /&gt;
    // Do stuff&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;@GameTest&amp;lt;/code&amp;gt; annotation also contains members which configure how the game test should run.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// In some class&lt;br /&gt;
@GameTest(&lt;br /&gt;
  setupTicks = 20L, // The test spends 20 ticks to set up for execution&lt;br /&gt;
  required = false // The failure is logged but does not affect the execution of the batch&lt;br /&gt;
)&lt;br /&gt;
public static void exampleConfiguredTest(GameTestHelper helper) {&lt;br /&gt;
  // Do stuff&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Relative Positioning ====&lt;br /&gt;
&lt;br /&gt;
All &amp;lt;code&amp;gt;GameTestHelper&amp;lt;/code&amp;gt; methods translate relative coordinates within the structure template scene to its absolute coordinates using the structure block's current location. To allow for easy conversion between relative and absolute positioning, &amp;lt;code&amp;gt;GameTestHelper#absolutePos&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;GameTestHelper#relativePos&amp;lt;/code&amp;gt; can be used respectively.&lt;br /&gt;
&lt;br /&gt;
The relative position of a structure template can be obtained in-game by loading the structure via the [[#Running_Game_Tests|test command]], placing the player at the wanted location, and finally running the &amp;lt;code&amp;gt;/test pos&amp;lt;/code&amp;gt; command. This will grab the coordinates of the player relative to the closest structure within 200 blocks of the player. The command will export the relative position as a copyable text component in the chat to be used as a final local variable.&lt;br /&gt;
&lt;br /&gt;
{{Tip|The local variable generated by &amp;lt;code&amp;gt;/test pos&amp;lt;/code&amp;gt; can specify its reference name by appending it to the end of the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
/test pos &amp;lt;var&amp;gt; # Exports 'final BlockPos &amp;lt;var&amp;gt; = new BlockPos(...);'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==== Successful Completion ====&lt;br /&gt;
&lt;br /&gt;
A Game Test method is responsible for one thing: marking the test was successful on a valid completion. If no success state was achieved before the timeout is reached (as defined by &amp;lt;code&amp;gt;GameTest#timeoutTicks&amp;lt;/code&amp;gt;), then the test automatically fails.&lt;br /&gt;
&lt;br /&gt;
There are many abstracted methods within &amp;lt;code&amp;gt;GameTestHelper&amp;lt;/code&amp;gt; which can be used to define a successful state; however, four are extremely important to be aware of.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Method !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#succeed&amp;lt;/code&amp;gt; || The test is marked as successful.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#succeedIf&amp;lt;/code&amp;gt; || The supplied &amp;lt;code&amp;gt;Runnable&amp;lt;/code&amp;gt; is tested immediately and succeeds if no &amp;lt;code&amp;gt;GameTestAssertException&amp;lt;/code&amp;gt; is thrown. If the test does not succeed on the immediate tick, then it is marked as a failure.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#succeedWhen&amp;lt;/code&amp;gt; || The supplied &amp;lt;code&amp;gt;Runnable&amp;lt;/code&amp;gt; is tested every tick until timeout and succeeds if the check on one of the ticks does not throw a &amp;lt;code&amp;gt;GameTestAssertException&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#succeedOnTickWhen&amp;lt;/code&amp;gt; || The supplied &amp;lt;code&amp;gt;Runnable&amp;lt;/code&amp;gt; is tested on the specified tick and will succeed if no &amp;lt;code&amp;gt;GameTestAssertException&amp;lt;/code&amp;gt; is thrown. If the &amp;lt;code&amp;gt;Runnable&amp;lt;/code&amp;gt; succeeds on any other tick, then it is marked as a failure.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|Game Tests are executed every tick until the test is marked as a success. As such, methods which schedule success on a given tick must be careful to always fail on any previous tick.}}&lt;br /&gt;
&lt;br /&gt;
==== Scheduling Actions ====&lt;br /&gt;
&lt;br /&gt;
Not all actions will occur when a test begins. Actions can be scheduled to occur at specific times or intervals:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Method !! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#runAtTickTime&amp;lt;/code&amp;gt; || The action is ran on the specified tick.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#runAfterDelay&amp;lt;/code&amp;gt; || The action is ran &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; ticks after the current tick.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;#onEachTick&amp;lt;/code&amp;gt; || The action is ran every tick.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Assertions ====&lt;br /&gt;
&lt;br /&gt;
At any time during a Game Test, an assertion can be made to check if a given condition is true. There are numerous assertion methods within &amp;lt;code&amp;gt;GameTestHelper&amp;lt;/code&amp;gt;; however, it simplifies to throwing a &amp;lt;code&amp;gt;GameTestAssertException&amp;lt;/code&amp;gt; whenever the appropriate state is not met.&lt;br /&gt;
&lt;br /&gt;
=== Generated Test Methods ===&lt;br /&gt;
&lt;br /&gt;
If Game Test methods need to be generated dynamically, a test method generator can be created. These methods take in no parameters and return a collection of &amp;lt;code&amp;gt;TestFunction&amp;lt;/code&amp;gt;s. For a test method generator to be recognized, it must have a &amp;lt;code&amp;gt;@GameTestGenerator&amp;lt;/code&amp;gt; annotation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class ExampleGameTests {&lt;br /&gt;
  @GameTestGenerator&lt;br /&gt;
  public static Collection&amp;lt;TestFunction&amp;gt; exampleTests() {&lt;br /&gt;
    // Return a collection of TestFunctions&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== TestFunction ====&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;TestFunction&amp;lt;/code&amp;gt; is the boxed information held by the &amp;lt;code&amp;gt;@GameTest&amp;lt;/code&amp;gt; annotation and the method running the test.&lt;br /&gt;
&lt;br /&gt;
{{Tip|Any methods annotated using &amp;lt;code&amp;gt;@GameTest&amp;lt;/code&amp;gt; are translated into a &amp;lt;code&amp;gt;TestFunction&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;GameTestRegistry#turnMethodIntoTestFunction&amp;lt;/code&amp;gt;. That method can be used as a reference for creating &amp;lt;code&amp;gt;TestFunction&amp;lt;/code&amp;gt;s without the use of the annotation.}}&lt;br /&gt;
&lt;br /&gt;
=== Batching ===&lt;br /&gt;
&lt;br /&gt;
Game Tests can be executed in batches instead of registration order. A test can be added to a batch by having the same supplied &amp;lt;code&amp;gt;GameTest#batch&amp;lt;/code&amp;gt; string.&lt;br /&gt;
&lt;br /&gt;
On its own, batching does not provide anything useful. However, batching can be used to perform setup and teardown states on the current level the tests are running in. This is done by annotating a method with either &amp;lt;code&amp;gt;@BeforeBatch&amp;lt;/code&amp;gt; for setup or &amp;lt;code&amp;gt;@AfterBatch&amp;lt;/code&amp;gt; for takedown. The `#batch` methods must match the string supplied to the game test.&lt;br /&gt;
&lt;br /&gt;
Batch methods are &amp;lt;code&amp;gt;Consumer&amp;lt;ServerLevel&amp;gt;&amp;lt;/code&amp;gt; references, meaning they take in a &amp;lt;code&amp;gt;ServerLevel&amp;lt;/code&amp;gt; and return nothing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class ExampleGameTests {&lt;br /&gt;
  @BeforeBatch(batch = &amp;quot;firstBatch&amp;quot;)&lt;br /&gt;
  public static void beforeTest(ServerLevel level) {&lt;br /&gt;
    // Perform setup&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  @GameTest(batch = &amp;quot;firstBatch&amp;quot;)&lt;br /&gt;
  public static void exampleTest2(GameTestHelper helper) {&lt;br /&gt;
    // Do stuff&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Registering a Game Test ==&lt;br /&gt;
&lt;br /&gt;
A Game Test must be registered to be ran in-game. There are two methods of doing so: via the &amp;lt;code&amp;gt;@GameTestHolder&amp;lt;/code&amp;gt; annotation or &amp;lt;code&amp;gt;RegisterGameTestsEvent&amp;lt;/code&amp;gt;. Both registration methods still require the test methods to be annotated with either &amp;lt;code&amp;gt;@GameTest&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;@GameTestGenerator&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;@BeforeBatch&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;@AfterBatch&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== GameTestHolder ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;@GameTestHolder&amp;lt;/code&amp;gt; annotation registers any test methods within the type (class, interface, enum, or record). &amp;lt;code&amp;gt;@GameTestHolder&amp;lt;/code&amp;gt; contains a single method which has multiple uses. In this instance, the supplied &amp;lt;code&amp;gt;#value&amp;lt;/code&amp;gt; must be the mod id of the mod; otherwise, the test will not run under default configurations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
@GameTestHolder(MODID)&lt;br /&gt;
public class ExampleGameTests {&lt;br /&gt;
  // ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== RegisterGameTestsEvent ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;RegisterGameTestEvent&amp;lt;/code&amp;gt; can also register either classes or methods using &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt;. The event listener must be [[Events#Event_Listeners|added]] to the mod event bus. Test methods registered this way must supply their mod id to &amp;lt;code&amp;gt;GameTest#templateNamespace&amp;lt;/code&amp;gt; on every method annotated with &amp;lt;code&amp;gt;@GameTest&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// In some class&lt;br /&gt;
public void registerTests(RegisterGameTestsEvent event) {&lt;br /&gt;
  event.register(ExampleGameTests.class);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// In ExampleGameTests&lt;br /&gt;
@GameTest(templateNamespace = MODID)&lt;br /&gt;
public static void exampleTest3(GameTestHelper helper) {&lt;br /&gt;
  // Perform setup&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Tip|The value supplied to &amp;lt;code&amp;gt;GameTestHolder#value&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;GameTest#templateNamespace&amp;lt;/code&amp;gt; can be different from the current mod id. The configuration within the [[#Enabling_Other_Namespaces|buildscript]] would need to be changed.}}&lt;br /&gt;
&lt;br /&gt;
== Structure Templates ==&lt;br /&gt;
&lt;br /&gt;
Game Tests are performed within scenes loaded by structures, or templates. All templates define the dimensions of the scene and the initial data (blocks and entities) that will be loaded. The template must be stored as an &amp;lt;code&amp;gt;.nbt&amp;lt;/code&amp;gt; file within &amp;lt;code&amp;gt;data/&amp;lt;namespace&amp;gt;/structures&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Tip|A structure template can be created and saved using a structure block.}}&lt;br /&gt;
&lt;br /&gt;
The location of the template is specified by a few factors:&lt;br /&gt;
&lt;br /&gt;
* If the namespace of the template is specified.&lt;br /&gt;
* If the class should be prepended to the name of the template.&lt;br /&gt;
* If the name of the template is specified.&lt;br /&gt;
&lt;br /&gt;
The namespace of the template is determined by &amp;lt;code&amp;gt;GameTest#templateNamespace&amp;lt;/code&amp;gt;, then &amp;lt;code&amp;gt;GameTestHolder#value&amp;lt;/code&amp;gt; if not specified, then &amp;lt;code&amp;gt;minecraft&amp;lt;/code&amp;gt; if neither is specified.&lt;br /&gt;
&lt;br /&gt;
The simple class name is not prepended to the name of the template if the &amp;lt;code&amp;gt;@PrefixGameTestTemplate&amp;lt;/code&amp;gt; is applied to a class or method with the test annotations and set to &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;. Otherwise, the simple class name is made lowercase and prepended and followed by a dot before the template name.&lt;br /&gt;
&lt;br /&gt;
The name of the template is determined by &amp;lt;code&amp;gt;GameTest#template&amp;lt;/code&amp;gt;. If not specified, then the lowercase name of the method is used instead.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Modid for all structures will be MODID&lt;br /&gt;
@GameTestHolder(MODID)&lt;br /&gt;
public class ExampleGameTests {&lt;br /&gt;
&lt;br /&gt;
  // Class name is prepended, template name is not specified&lt;br /&gt;
  // Template Location at 'modid:examplegametests.exampletest'&lt;br /&gt;
  @GameTest&lt;br /&gt;
  public static void exampleTest(GameTestHelper helper) { /*...*/ }&lt;br /&gt;
&lt;br /&gt;
  // Class name is not prepended, template name is not specified&lt;br /&gt;
  // Template Location at 'modid:exampletest2'&lt;br /&gt;
  @PrefixGameTestTemplate(false)&lt;br /&gt;
  @GameTest&lt;br /&gt;
  public static void exampleTest2(GameTestHelper helper) { /*...*/ }&lt;br /&gt;
&lt;br /&gt;
  // Class name is prepended, template name is specified&lt;br /&gt;
  // Template Location at 'modid:examplegametests.test_template'&lt;br /&gt;
  @GameTest(template = &amp;quot;test_template&amp;quot;)&lt;br /&gt;
  public static void exampleTest3(GameTestHelper helper) { /*...*/ }&lt;br /&gt;
&lt;br /&gt;
  // Class name is not prepended, template name is specified&lt;br /&gt;
  // Template Location at 'modid:test_template2'&lt;br /&gt;
  @PrefixGameTestTemplate(false)&lt;br /&gt;
  @GameTest(template = &amp;quot;test_template2&amp;quot;)&lt;br /&gt;
  public static void exampleTest4(GameTestHelper helper) { /*...*/ }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Running Game Tests ==&lt;br /&gt;
&lt;br /&gt;
Game Tests can be run using the &amp;lt;code&amp;gt;/test&amp;lt;/code&amp;gt; command. The &amp;lt;code&amp;gt;test&amp;lt;/code&amp;gt; command is highly configurable; however, only a few are of importance to running tests:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Header text !! Header text&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;run&amp;lt;/code&amp;gt; || Runs the specified test: &amp;lt;code&amp;gt;run &amp;lt;test_name&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;runall&amp;lt;/code&amp;gt; || Runs all available tests.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;runthis&amp;lt;/code&amp;gt; || Runs the nearest test to the player within 15 blocks.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;runthese&amp;lt;/code&amp;gt; || Runs tests within 200 blocks of the player.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;runfailed&amp;lt;/code&amp;gt; || Runs all tests that failed in the previous run.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Tip|Subcommands follow the test command: &amp;lt;code&amp;gt;/test &amp;lt;subcommand&amp;gt;&amp;lt;/code&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
== Buildscript Configurations ==&lt;br /&gt;
&lt;br /&gt;
Game Tests provide additional configuration settings within a buildscript (the &amp;lt;code&amp;gt;build.gradle&amp;lt;/code&amp;gt; file) to run and integrate into different settings.&lt;br /&gt;
&lt;br /&gt;
=== Enabling Other Namespaces ===&lt;br /&gt;
&lt;br /&gt;
If the buildscript was [[Getting_Started#Customizing_the_MDK|setup as recommended]], then only Game Tests under the current mod id would be enabled. To enable other namespaces to load Game Tests from, a run configuration must set the property &amp;lt;code&amp;gt;forge.enabledGameTestNamespaces&amp;lt;/code&amp;gt; to a string specifying each namespace separated by a comma. If the property is empty or not set, then all namespaces will be loaded.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;gradle&amp;quot;&amp;gt;&lt;br /&gt;
// Inside a run configuration&lt;br /&gt;
property 'forge.enabledGameTestNamespaces', 'modid1,modid2,modid3'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|There must be no spaces in-between namespaces; otherwise, the namespace will not be loaded correctly.}}&lt;br /&gt;
&lt;br /&gt;
=== Game Test Server Run Configuration ===&lt;br /&gt;
&lt;br /&gt;
The Game Test Server is a special configuration which runs a build server. The build server returns an exit code of the number of required, failed Game Tests. All failed tests, whether required or optional, are logged. This server can be run using &amp;lt;code&amp;gt;gradlew runGameTestServer&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Enabling Game Tests in Other Run Configurations ===&lt;br /&gt;
&lt;br /&gt;
By default, only the &amp;lt;code&amp;gt;client&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;server&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;gameTestServer&amp;lt;/code&amp;gt; run configurations have Game Tests enabled. If another run configuration should run Game Tests, then the &amp;lt;code&amp;gt;forge.enableGameTest&amp;lt;/code&amp;gt; property must be set to &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;gradle&amp;quot;&amp;gt;&lt;br /&gt;
// Inside a run configuration&lt;br /&gt;
property 'forge.enableGameTest', 'true'&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Events&amp;diff=3136</id>
		<title>Events</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Events&amp;diff=3136"/>
		<updated>2022-04-03T13:09:50Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Add mod bus list&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Under construction}}&lt;br /&gt;
&lt;br /&gt;
An '''event''' is a signal that is fired on an '''event bus''' to inform registered listeners about some type of action or state. This is the primary way by which Forge allows mods to hook into vanilla and game behavior; Forge has an array of different events which are fired when different actions happen within the game, and mods may act upon receiving these events.  &lt;br /&gt;
&lt;br /&gt;
Additionally, mods may create their own events and fire them for other mods to listen for, allowing for higher compatibility. For a class to be considered an event, it must be a subclass of &amp;lt;code&amp;gt;Event&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Generic Events ==&lt;br /&gt;
'''Generic events''' are events which supply additional generic type information, allowing event listeners to filter based on that secondary type. Generic events must implement &amp;lt;code&amp;gt;IGenericEvent&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt;, and return their generic type from the &amp;lt;code&amp;gt;IGenericEvent#getType()&amp;lt;/code&amp;gt; method. As a convenience, events that wish to be generic events may extend the &amp;lt;code&amp;gt;GenericEvent&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; instead of manually implementing the interface.&lt;br /&gt;
&lt;br /&gt;
For generic events, the generic type must be an exact match with the listener's generic type filter to pass; if an &amp;lt;code&amp;gt;AttachCapabilitiesEvent&amp;lt;ItemStack&amp;gt;&amp;lt;/code&amp;gt; is fired and a listener is listening for &amp;lt;code&amp;gt;AttachCapabilitiesEvent&amp;lt;Object&amp;gt;&amp;lt;/code&amp;gt;, the listener does not receive the event. If an event listener is registered using &amp;lt;code&amp;gt;EventBus#register(Object)&amp;lt;/code&amp;gt;, it may listen to events with any generic type by supplying a wildcard generic (&amp;lt;code&amp;gt;&amp;lt;?&amp;gt;&amp;lt;/code&amp;gt;). Nested generic types are ignored.&lt;br /&gt;
&lt;br /&gt;
== Cancellable Events ==&lt;br /&gt;
An event may be marked as '''cancellable''', which allows event listeners to cancel the event.&lt;br /&gt;
&lt;br /&gt;
A cancellable event may be cancelled by using &amp;lt;code&amp;gt;Event#setCanceled(true)&amp;lt;/code&amp;gt;. Attempting to call this method on a non-cancellable event will result in a &amp;lt;code&amp;gt;UnsupportedOperationException&amp;lt;/code&amp;gt;. A cancelled event behaves similarly to a regular noncancelled event, with one main difference: an event listener will not receive cancelled events unless they are explicitly registered to listen for cancelled events.&lt;br /&gt;
&lt;br /&gt;
To mark an event as cancellable, the event class should be annotated with &amp;lt;code&amp;gt;@Cancelable&amp;lt;/code&amp;gt;. This will automatically make &amp;lt;code&amp;gt;Event#isCancelable()&amp;lt;/code&amp;gt; return &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;. Modders may check if an event has a result through the presence of the annotation or by calling the given method.&lt;br /&gt;
&lt;br /&gt;
== Events with Results ==&lt;br /&gt;
An event may have a '''result''', which is an enum of &amp;lt;code&amp;gt;Event.Result&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;Event.Result&amp;lt;/code&amp;gt; enum has three values: &amp;lt;code&amp;gt;ALLOW&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;DEFAULT&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;DENY&amp;lt;/code&amp;gt;. The meaning of these result values is entirely dependent on the event itself.&lt;br /&gt;
 &lt;br /&gt;
An event's current result can be retrieved through &amp;lt;code&amp;gt;Event#getResult()&amp;lt;/code&amp;gt;. The result on an event can be set through &amp;lt;code&amp;gt;Event#setResult(Event.Result)&amp;lt;/code&amp;gt;. You can set the result for an event which is not marked as having a result, however this will cause nothing to happen if the event does not use the result value.&lt;br /&gt;
&lt;br /&gt;
To mark an event as having a result, the event class should be annotated with &amp;lt;code&amp;gt;@Event.HasResult&amp;lt;/code&amp;gt;. This will automatically make &amp;lt;code&amp;gt;Event#hasResult&amp;lt;/code&amp;gt; return &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;. Modders may check if an event has a result through the presence of the annotation or by calling the given method.&lt;br /&gt;
&lt;br /&gt;
==Event Bus==&lt;br /&gt;
An '''event bus''' is an object which holds a list of event listeners, and the logic for firing the events. Events may be posted on these event buses, which then invokes the handlers. The main class for event buses is &amp;lt;code&amp;gt;IEventBus&amp;lt;/code&amp;gt;, and a bus is created using &amp;lt;code&amp;gt;BusBuilder&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
You can find a more detailed explanation on the Event Bus pattern [https://dzone.com/articles/design-patterns-event-bus here.] &lt;br /&gt;
===Existing Buses===&lt;br /&gt;
Forge exposes three main families of event buses: the main Forge event bus, the mod-specific event buses, and the network channel event buses.&lt;br /&gt;
====Main Forge Event Bus====&lt;br /&gt;
The '''main Forge event bus''' is located at &amp;lt;code&amp;gt;MinecraftForge#EVENT_BUS&amp;lt;/code&amp;gt;, and is where most events relating to ingame actions or events are fired on, such as events for ticking, block interactions, and entity interactions. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
List of events fired on the main Forge event bus{{:Events/Forge bus}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Mod-Specific Event Buses====&lt;br /&gt;
The '''mod-specific event buses''' are the family of event buses where mod-related initialization and registration events are fired, such as the events for [[Registration|registering objects]] or setup on different physical sides. Only events which implement &amp;lt;code&amp;gt;IModBusEvent&amp;lt;/code&amp;gt; may be fired or listened for on these event buses.&lt;br /&gt;
&lt;br /&gt;
Each loaded mod has their own instance of a mod-specific event bus. The mod-specific event bus for the currently loading mod can be retrieved from &amp;lt;code&amp;gt;FMLModContainer#getEventBus()&amp;lt;/code&amp;gt;, which is also accessible from &amp;lt;code&amp;gt;FMLJavaModLoadingContext#getModEventBus()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Tip|title=Tip|The mod-specific event buses are provided by the &amp;lt;code&amp;gt;javafml&amp;lt;/code&amp;gt; language provider which is builtin to Forge Mod Loader. Custom language providers may provide other ways for mods to receive the different mod-related initialization and registration events; see the documentation of your custom language provider for details.}}&lt;br /&gt;
&lt;br /&gt;
List of events fired on the Mod-Specific event bus{{:Events/Mod bus}}&lt;br /&gt;
&lt;br /&gt;
====Network Channel Event Buses====&lt;br /&gt;
The '''network channel event buses''' are the family of event buses where different network-related events are fired. Each registered [[Networking|networking channel]] has their own instance of an event-bus in &amp;lt;code&amp;gt;NetworkInstance&amp;lt;/code&amp;gt;, where only events pertinent to that channel are fired on.&lt;br /&gt;
&lt;br /&gt;
The network channel event buses cannot be accessed directly; &amp;lt;code&amp;gt;EventNetworkChannel&amp;lt;/code&amp;gt; provides methods to register events listeners to the event bus.&lt;br /&gt;
&lt;br /&gt;
== Event Listeners ==&lt;br /&gt;
An '''event listener''' (also known as an '''event handler''') is a class, object, or method registered to an event bus to capture for specific events (and their subclasses).&lt;br /&gt;
&lt;br /&gt;
[[File:Guide to Event Handlers.png|thumb|upright 0.9|A visual guide on how event listeners are registered.]]&lt;br /&gt;
&lt;br /&gt;
An event listener may be registered in three ways:&lt;br /&gt;
* The &amp;lt;code&amp;gt;IEventBus#register(Object)&amp;lt;/code&amp;gt; method on a class or instance;&lt;br /&gt;
* The &amp;lt;code&amp;gt;@EventBusSubscriber&amp;lt;/code&amp;gt; annotation on a class; or&lt;br /&gt;
* The &amp;lt;code&amp;gt;IEventBus#addListener&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;IEventBus#addGenericListener&amp;lt;/code&amp;gt; on a method reference or lambda.&lt;br /&gt;
&lt;br /&gt;
=== Priority and Receiving Cancelled Events ===&lt;br /&gt;
An event listener may be registered to a specific '''event priority''' and whether to '''receive cancelled events'''.&lt;br /&gt;
&lt;br /&gt;
The event priority levels allows a listener to react to an event before other event listeners of a lower level, such as to change the values within an event or cancel it outright.&lt;br /&gt;
&lt;br /&gt;
There are five levels of event listeners priority; in descending order from first to receive an event to last: &amp;lt;code&amp;gt;HIGHEST&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;HIGH&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;NORMAL&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;LOW&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;LOWEST&amp;lt;/code&amp;gt;. Event listeners are registered by default on a priority of &amp;lt;code&amp;gt;NORMAL&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
An event listener normally never receives a cancelled event, however they may change this by being registered to receive these cancelled events. Non-cancellable events are unaffected by this, and will always be sent to all event listeners (in the order specified by their priority).&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;IEventBus.register&amp;lt;/tt&amp;gt; ===&lt;br /&gt;
The &amp;lt;code&amp;gt;IEventBus#register(Object)&amp;lt;/code&amp;gt; method allows for registering an object instance or a &amp;lt;code&amp;gt;Class&amp;lt;?&amp;gt;&amp;lt;/code&amp;gt; to the event bus. The method exhibits two different behaviors, depending on what is passed into it:&lt;br /&gt;
&lt;br /&gt;
* '''an object instance''' - registers all ''instance or non-&amp;lt;code&amp;gt;static&amp;lt;/code&amp;gt;'' methods annotated with &amp;lt;code&amp;gt;@SubscribeEvent&amp;lt;/code&amp;gt; from the object&lt;br /&gt;
* '''a &amp;lt;code&amp;gt;Class&amp;lt;?&amp;gt;&amp;lt;/code&amp;gt; instance''' - registers all ''class or &amp;lt;code&amp;gt;static&amp;lt;/code&amp;gt;'' methods annotated with &amp;lt;code&amp;gt;@SubscribeEvent&amp;lt;/code&amp;gt; from the class which is represented by the passed in &amp;lt;code&amp;gt;Class&amp;lt;?&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tab collapsed name=&amp;quot;Example of how event listeners are registered with the IEventBus.register method&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
class EventHandler {&lt;br /&gt;
	public static void nonAnnotatedStatic(Event event) {}&lt;br /&gt;
&lt;br /&gt;
	@SubscribeEvent&lt;br /&gt;
	public static void annotatedStatic(Event event) {}&lt;br /&gt;
&lt;br /&gt;
	public void nonAnnotatedInstance(Event event) {}&lt;br /&gt;
&lt;br /&gt;
	@SubscribeEvent&lt;br /&gt;
	public void annotatedInstance(Event event) {}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Within the execution of the program&lt;br /&gt;
IEventBus bus = ...;&lt;br /&gt;
&lt;br /&gt;
// This will register the &amp;quot;annotatedStatic&amp;quot; method from the class&lt;br /&gt;
bus.register(EventHandler.class);&lt;br /&gt;
// This would register &amp;quot;annotatedStatic&amp;quot;, but it is already registered&lt;br /&gt;
bus.register(EventHandler.class);&lt;br /&gt;
&lt;br /&gt;
EventHandler instanceA = new EventHandler();&lt;br /&gt;
EventHandler instanceB = new EventHandler();&lt;br /&gt;
&lt;br /&gt;
// This will register the &amp;quot;annotatedInstance&amp;quot; method from the instanceA object, and will not touch the instanceB object&lt;br /&gt;
bus.register(instanceA);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
If an &amp;lt;code&amp;gt;Event&amp;lt;/code&amp;gt; were to be fired on the event bus in the example above, the &amp;lt;code&amp;gt;EventHandler#annotatedStatic&amp;lt;/code&amp;gt; would receive the event, and the &amp;lt;code&amp;gt;annotatedInstance&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;instanceA&amp;lt;/code&amp;gt; object instance would receive the event.&lt;br /&gt;
&lt;br /&gt;
Neither the unnannotated methods will receive the event, nor will the &amp;lt;code&amp;gt;annotatedInstance&amp;lt;/code&amp;gt; method from the &amp;lt;code&amp;gt;instanceB&amp;lt;/code&amp;gt; object instance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/tab&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;tt&amp;gt;@SubscribeEvent&amp;lt;/tt&amp;gt; ====&lt;br /&gt;
The &amp;lt;code&amp;gt;@SubscribeEvent&amp;lt;/code&amp;gt; annotation is used to mark a method as an event listener when its containing class or object is registered using &amp;lt;code&amp;gt;IEventBus#register&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
They have two fields: &amp;lt;code&amp;gt;EventPriority priority&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;boolean receiveCancelled&amp;lt;/code&amp;gt;, which sets the event priority for the listener and whether the listener receives cancelled events, respectively.&lt;br /&gt;
&lt;br /&gt;
= WIP =&lt;br /&gt;
TODO: @EventBusSubscriber, addListener, Generic Events? (probably higher up)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tab name=&amp;quot;Partial previous content of page, to be removed&amp;quot; collapsed&amp;gt;&lt;br /&gt;
== Forge and Mod Buses ==&lt;br /&gt;
There are two event buses of note to a mod: the '''main Forge event bus''', and the '''mod-specific event bus'''.&lt;br /&gt;
&lt;br /&gt;
The Forge event bus, which can be referenced through &amp;lt;code&amp;gt;MinecraftForge.EVENT_BUS&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;EventBusSubscriber.Bus.FORGE&amp;lt;/code&amp;gt; (the latter being an enum that provides handy references to both busses), fires events that depend solely on the game state. This means that:&lt;br /&gt;
* Entity Events&lt;br /&gt;
* Ticking Events&lt;br /&gt;
* Server Events&lt;br /&gt;
and more, are fired on the Forge bus.&lt;br /&gt;
&lt;br /&gt;
The Mod bus, referenced through &amp;lt;code&amp;gt;FMLJavaModLoadingContext.get().getModEventBus()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;EventBusSubscriber.Bus.MOD&amp;lt;/code&amp;gt;, fires events that depend solely on mod state, or which are used to initialise such.&lt;br /&gt;
This means that:&lt;br /&gt;
* Registration Events&lt;br /&gt;
* Mod Lifecycle Events&lt;br /&gt;
* Model Events (bake and register)&lt;br /&gt;
* Config Events&lt;br /&gt;
* Data Provider Events&lt;br /&gt;
and more, are fired on the Mod bus. See [[Stages of Modloading|mod loading events]]. Note that some of these are fired in parallel.&lt;br /&gt;
&lt;br /&gt;
== Sub Events ==&lt;br /&gt;
&lt;br /&gt;
Many events have different variations of themselves, these can be different but all based around one common factor (e.g. &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;) or can be an event that has multiple phases (e.g. &amp;lt;code&amp;gt;PotionBrewEvent&amp;lt;/code&amp;gt;). Take note that if you listen to the parent event class, you will receive calls to your method for ''all'' subclasses.&lt;br /&gt;
&lt;br /&gt;
== Event Handlers ==&lt;br /&gt;
Event handlers are methods, which have four main properties. They are communicated to the event bus you want them to listen on, and when the event is posted on that bus, the hander is invoked.&lt;br /&gt;
&lt;br /&gt;
Event handlers' properties are as such:&lt;br /&gt;
- Registered to an event bus&lt;br /&gt;
- May be static or instance&lt;br /&gt;
- Have a single argument, which is used to determine the event that is being listened for&lt;br /&gt;
- The argument given is the instance of the Event being posted.&lt;br /&gt;
&lt;br /&gt;
Note that handlers may take the form of anonymous functions - lambdas.&lt;br /&gt;
&lt;br /&gt;
== Registering Event Handlers ==&lt;br /&gt;
Event handlers are registered typically one of four ways:&lt;br /&gt;
* &amp;lt;code&amp;gt;EventBusSubscriber&amp;lt;/code&amp;gt; (which requires a static, annotated handler method)&lt;br /&gt;
* &amp;lt;code&amp;gt;EventBus#register(T.class)&amp;lt;/code&amp;gt; (which requires a static, annotated handler method)&lt;br /&gt;
* &amp;lt;code&amp;gt;EventBus#register(new X())&amp;lt;/code&amp;gt; (which requires an instance, annotated handler method)&lt;br /&gt;
* &amp;lt;code&amp;gt;EventBus#addListener(Class::function)&amp;lt;/code&amp;gt; (which requires an instance, non-annotated handler method)&lt;br /&gt;
* as an extension of the above: &amp;lt;code&amp;gt;EventBus#&amp;lt;LivingHurtEvent&amp;gt;addListener(event -&amp;gt; { code })&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each of these will be explained in detail as follows.&lt;br /&gt;
&lt;br /&gt;
=== Annotated Event Handlers ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class MyForgeEventHandler {&lt;br /&gt;
    @SubscribeEvent&lt;br /&gt;
    public void pickupItem(EntityItemPickupEvent event) {&lt;br /&gt;
        System.out.println(&amp;quot;Item picked up!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This event handler listens for the &amp;lt;code&amp;gt;EntityItemPickupEvent&amp;lt;/code&amp;gt;, which is, as the name states, posted to the event bus whenever an &amp;lt;code&amp;gt;Entity&amp;lt;/code&amp;gt; picks up an item.&lt;br /&gt;
&lt;br /&gt;
This function would be registered with &amp;lt;code&amp;gt;EventBus#register(new X())&amp;lt;/code&amp;gt; in the above examples.&lt;br /&gt;
&lt;br /&gt;
=== Static Event Handlers ===&lt;br /&gt;
&lt;br /&gt;
An event handler may also be static. The handling method is still annotated with &amp;lt;code&amp;gt;@SubscribeEvent&amp;lt;/code&amp;gt; with the only difference from an instance handler is that it is also marked static. In order to register a static event handler, an instance of the class won’t do, the Class itself has to be passed in. An example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class MyStaticForgeEventHandler {&lt;br /&gt;
    @SubscribeEvent&lt;br /&gt;
    public static void arrowNocked(ArrowNockEvent event) {&lt;br /&gt;
        System.out.println(&amp;quot;Arrow nocked!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which must be registered &amp;lt;code&amp;gt;EventBus#register(MyStaticForgeEventHandler.class)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3 id=&amp;quot;eventbussubscriber&amp;quot;&amp;gt;Using &amp;lt;tt style=&amp;quot;font-size: 100%&amp;quot;&amp;gt;@Mod.EventBusSubscriber&amp;lt;/tt&amp;gt;&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A class may be annotated with the &amp;lt;code&amp;gt;@Mod.EventBusSubscriber&amp;lt;/code&amp;gt; annotation. Such a class is automatically registered to the configured bus when the &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt; class itself is constructed. This is essentially equivalent to adding &amp;lt;code&amp;gt;EventBus#register(AnnotatedClass.class);&amp;lt;/code&amp;gt; at the end of the &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt; class's constructor.&lt;br /&gt;
&lt;br /&gt;
The mod ID must be specified unless your class is already annotated with an &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt; annotation. You can pass the bus you want to listen to inside the &amp;lt;code&amp;gt;@Mod.EventBusSubscriber&amp;lt;/code&amp;gt; annotation.&lt;br /&gt;
&lt;br /&gt;
The bus registered with &amp;lt;code&amp;gt;EventBusSubscriber&amp;lt;/code&amp;gt; defaults to the Forge event bus.&lt;br /&gt;
&lt;br /&gt;
You can also specify the &amp;lt;code&amp;gt;Dist&amp;lt;/code&amp;gt;s to load this event subscriber on. This can be used to not load client specific event subscribers on the dedicated server.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An example for a static event listener listening to &amp;lt;code&amp;gt;RenderLevelLastEvent&amp;lt;/code&amp;gt; which will only be called on the physical client: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
@Mod.EventBusSubscriber(modid = &amp;quot;examplemod&amp;quot;, dist = Dist.CLIENT)&lt;br /&gt;
public class MyStaticClientOnlyEventHandler {&lt;br /&gt;
    @SubscribeEvent&lt;br /&gt;
    public static void drawLast(RenderLevelLastEvent event) {&lt;br /&gt;
        System.out.println(&amp;quot;Drawing!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|This does not register an instance of the class; it registers the class itself (i.e. the event handling methods must be static).}}&lt;br /&gt;
&lt;br /&gt;
=== Non-Annotated Event Handlers ===&lt;br /&gt;
&lt;br /&gt;
Event handlers do not need to be annotated if they are directly referred to using &amp;lt;code&amp;gt;EventBus#addListener&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;EventBus#addGenericListener&amp;lt;/code&amp;gt; for generic events).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
@Mod(&amp;quot;examplemod&amp;quot;)&lt;br /&gt;
public class MyMainModClass {&lt;br /&gt;
&lt;br /&gt;
  public MyMainModClass() {&lt;br /&gt;
    FMLJavaModLoadingContext.get().getModEventBus().addGenericListener(Entity.class, this::entityCap);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  private void entityCap(AttachCapabilitiesEvent&amp;lt;Entity&amp;gt; event) {&lt;br /&gt;
    System.out.println(&amp;quot;Capability attached!&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|The generic passed into the event must be referenced directly within the code itself. Otherwise, the event will not be called whatsoever. For example, if you use &amp;lt;code&amp;gt;AttachCapabilitiesEvent&amp;lt;LivingEntity&amp;gt;&amp;lt;/code&amp;gt;, the event will never be called as no call of this event uses &amp;lt;code&amp;gt;LivingEntity&amp;lt;/code&amp;gt;, only &amp;lt;code&amp;gt;Entity&amp;lt;/code&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
== Cancelling ==&lt;br /&gt;
&lt;br /&gt;
If an event can be cancelled, it will be marked with the &amp;lt;code&amp;gt;@Cancelable&amp;lt;/code&amp;gt; annotation, and the method &amp;lt;code&amp;gt;Event#isCancelable()&amp;lt;/code&amp;gt; will return &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;. The cancel state of a cancellable event may be modified by calling &amp;lt;code&amp;gt;Event#setCanceled(boolean canceled)&amp;lt;/code&amp;gt;, wherein passing the boolean value &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; is interpreted as cancelling the event, and passing the boolean value &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; is interpreted as “un-cancelling” the event.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|Not all events can be cancelled! Attempting to cancel an event that is not cancellable will result in an unchecked &amp;lt;code&amp;gt;UnsupportedOperationException&amp;lt;/code&amp;gt; being thrown, which is expected to result in the game crashing. Always check that an event can be cancelled using &amp;lt;code&amp;gt;Event#isCancelable()&amp;lt;/code&amp;gt; before attempting to cancel it.}}&lt;br /&gt;
&lt;br /&gt;
== Results ==&lt;br /&gt;
&lt;br /&gt;
Some events have an &amp;lt;code&amp;gt;Event.Result&amp;lt;/code&amp;gt; as denoted by &amp;lt;code&amp;gt;@HasResult&amp;lt;/code&amp;gt;. A result can be one of three things: &amp;lt;code&amp;gt;DENY&amp;lt;/code&amp;gt; which stops the event, &amp;lt;code&amp;gt;DEFAULT&amp;lt;/code&amp;gt; which uses the Vanilla behavior, and &amp;lt;code&amp;gt;ALLOW&amp;lt;/code&amp;gt; which forces the action to take place, regardless of if it would have originally. The result of an event can be set by calling &amp;lt;code&amp;gt;setResult&amp;lt;/code&amp;gt; with an Event.Result on the event.&lt;br /&gt;
&lt;br /&gt;
{{Colored box|title=Information|content=Different events may use results in different ways, refer to the event's JavaDoc before using the result.}}&lt;br /&gt;
&lt;br /&gt;
== Priority ==&lt;br /&gt;
&lt;br /&gt;
Event handler methods have a priority. You can set the &amp;lt;code&amp;gt;priority&amp;lt;/code&amp;gt; of an event handler method by setting the priority value of the annotation or the listener. The priority can be any value of the &amp;lt;code&amp;gt;EventPriority&amp;lt;/code&amp;gt; enum (&amp;lt;code&amp;gt;HIGHEST&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;HIGH&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;NORMAL&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;LOW&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;LOWEST&amp;lt;/code&amp;gt;). Event handlers with priority &amp;lt;code&amp;gt;HIGHEST&amp;lt;/code&amp;gt; are executed first and from there in descending order until &amp;lt;code&amp;gt;LOWEST&amp;lt;/code&amp;gt; events which are executed last.&lt;br /&gt;
&lt;br /&gt;
== Mod Event Bus ==&lt;br /&gt;
The mod event bus is primarily used for listening to lifecycle events in which mods should initialize. Many of these events are also ran in parallel so mods can be initialized at the same time. This does mean you cannot directly execute code from other mods in these events. Use the &amp;lt;code&amp;gt;InterModComms&amp;lt;/code&amp;gt; system for that.&lt;br /&gt;
&lt;br /&gt;
It is impossible for an event to be posted on the Mod bus that does not inherit the IModBusEvent interface.&lt;br /&gt;
Thus, this provides a good, easy way to tell which events are fired on this bus.&lt;br /&gt;
&lt;br /&gt;
These are the four most commonly used lifecycle events that are called during mod initialization on the mod event bus: &lt;br /&gt;
* &amp;lt;code&amp;gt;FMLCommonSetupEvent&amp;lt;/code&amp;gt; &lt;br /&gt;
* &amp;lt;code&amp;gt;FMLClientSetupEvent&amp;lt;/code&amp;gt; &amp;amp; &amp;lt;code&amp;gt;FMLDedicatedServerSetupEvent&amp;lt;/code&amp;gt; (''These events are only called on their respective [[Sides#Different_Kinds_of_Sides|physical side]].'')&lt;br /&gt;
* &amp;lt;code&amp;gt;InterModEnqueueEvent&amp;lt;/code&amp;gt; &lt;br /&gt;
* &amp;lt;code&amp;gt;InterModProcessEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These four lifecycle events are all ran in parallel. If you want to run code on the main thread during these events you can use the &amp;lt;code&amp;gt;enqueueWork&amp;lt;/code&amp;gt; methods within the events to do so.&lt;br /&gt;
&lt;br /&gt;
Next to the lifecycle events there are a few miscellaneous events that are fired on the mod event bus where you can register, set up, or initialize various things. Most of these events are not ran in parallel in contrast to the lifecycle events:&lt;br /&gt;
* &amp;lt;code&amp;gt;ColorHandlerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ModelBakeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;TextureStitchEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;RegistryEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;GatherDataEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;SoundLoadEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ParticleFactoryRegisterEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ModConfigEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A good rule of thumb: events are fired on the mod event bus when they should be handled during initialization of a mod. or where they are used to set state (eg. the config event.)&lt;br /&gt;
&lt;br /&gt;
Detailed information about these events will be found in their respective pages, once they are ready.&lt;br /&gt;
&lt;br /&gt;
== Forge Event Bus ==&lt;br /&gt;
The Forge event bus is where game state events are fired. If anything changes to do with the game, or anything happens that you would need to know about, there's a good chance it's sent here.&lt;br /&gt;
&lt;br /&gt;
A full list of the events fired here is as follows, split into discrete categories:&lt;br /&gt;
&lt;br /&gt;
{{Tree list}}&lt;br /&gt;
* &amp;lt;code&amp;gt;Event&amp;lt;/code&amp;gt; - ''The root event class''&lt;br /&gt;
** '''Rendering events''' ('''client-only''')&lt;br /&gt;
*** &amp;lt;code&amp;gt;RenderLevelLastEvent&amp;lt;/code&amp;gt; - Fired after level rendering to allow mods to add custom renders&lt;br /&gt;
*** &amp;lt;code&amp;gt;RenderHandEvent&amp;lt;/code&amp;gt; - Fired before and after the hand of the player is rendered in the first person POV&lt;br /&gt;
*** &amp;lt;code&amp;gt;RenderLivingEvent&amp;lt;/code&amp;gt; - Fired before and after a &amp;lt;code&amp;gt;LivingRenderer&amp;lt;/code&amp;gt; is executed&lt;br /&gt;
*** &amp;lt;code&amp;gt;RenderItemInFrameEvent&amp;lt;/code&amp;gt; - Fired before the item in an &amp;lt;code&amp;gt;ItemFrameEntity&amp;lt;/code&amp;gt; is rendered&lt;br /&gt;
*** &amp;lt;code&amp;gt;RenderBlockOverlayEvent&amp;lt;/code&amp;gt; - Fired before the block overlay for the player's screen is rendered&lt;br /&gt;
*** &amp;lt;code&amp;gt;DrawHighlightEvent&amp;lt;/code&amp;gt; - Fired before the block highlight outline is rendered&lt;br /&gt;
*** &amp;lt;code&amp;gt;RenderTooltipEvent&amp;lt;/code&amp;gt; - Fired before and during rendering of a text tooltip on a screen&lt;br /&gt;
*** &amp;lt;code&amp;gt;EntityViewRenderEvent&amp;lt;/code&amp;gt; - Superclass for events relating to the player's viewpoint&lt;br /&gt;
*** &amp;lt;code&amp;gt;RenderGameOverlayEvent&amp;lt;/code&amp;gt; - Superclass, fired for each element on the player's HUD or game overlay&lt;br /&gt;
*** &amp;lt;code&amp;gt;FOVModifierEvent&amp;lt;/code&amp;gt; - Fired when the FOV of the player is requested (?)&lt;br /&gt;
** '''Screen events''' ('''client-only''')&lt;br /&gt;
*** &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt; - Superclass for events relating to &amp;lt;code&amp;gt;Screen&amp;lt;/code&amp;gt;s&lt;br /&gt;
*** &amp;lt;code&amp;gt;ScreenContainerEvent&amp;lt;/code&amp;gt; - Superclsas for events relating to &amp;lt;code&amp;gt;ContainerScreen&amp;lt;/code&amp;gt;s&lt;br /&gt;
*** &amp;lt;code&amp;gt;ScreenOpenEvent&amp;lt;/code&amp;gt; - Fired before a new screen is opened on the game window&lt;br /&gt;
** '''Superclass events''' - ''These events exist to be superclasses of other events''&lt;br /&gt;
*** &amp;lt;code&amp;gt;GenericEvent&amp;lt;/code&amp;gt; - ''from EventBus'', superclass of events which have a generic type&lt;br /&gt;
*** &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt; - Superclass for events relating to a block within the level&lt;br /&gt;
*** &amp;lt;code&amp;gt;LevelEvent&amp;lt;/code&amp;gt; - Superclass for events relating to the level&lt;br /&gt;
*** &amp;lt;code&amp;gt;InputEvent&amp;lt;/code&amp;gt; - ('''client-only''') Superclass for events relating to the player's keyboard and mouse inputs&lt;br /&gt;
*** &amp;lt;code&amp;gt;NetworkEvent&amp;lt;/code&amp;gt; - Superclass for events relating to networking&lt;br /&gt;
*** &amp;lt;code&amp;gt;ExplosionEvent&amp;lt;/code&amp;gt; - Fired before an explosion explodes in the level&lt;br /&gt;
*** &amp;lt;code&amp;gt;SoundEvent&amp;lt;/code&amp;gt; - ('''client-only''') Superclass for events related to sounds&lt;br /&gt;
*** &amp;lt;code&amp;gt;EntityEvent&amp;lt;/code&amp;gt; - Superclass for events relating to entities&lt;br /&gt;
*** &amp;lt;code&amp;gt;TickEvent&amp;lt;/code&amp;gt; - Superclass for events fired before and after ticking&lt;br /&gt;
** '''Chat events'''&lt;br /&gt;
*** &amp;lt;code&amp;gt;ServerChatEvent&amp;lt;/code&amp;gt; ('''server-only''') - Fired when the server receives a chat message and before it relays the message&lt;br /&gt;
*** &amp;lt;code&amp;gt;ClientChatEvent&amp;lt;/code&amp;gt; ('''client-only''') - Fired before the client is about to send a chat message&lt;br /&gt;
*** &amp;lt;code&amp;gt;ClientChatReceivedEvent&amp;lt;/code&amp;gt; ('''client-only''') - Fired when the client receives a chat message from the server&lt;br /&gt;
** '''Data loading events'''&lt;br /&gt;
*** &amp;lt;code&amp;gt;RecipesUpdatedEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;BiomeLoadingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;LootTableLoadEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;StructureSpawnListGatherEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** '''Startup events'''&lt;br /&gt;
*** &amp;lt;code&amp;gt;AddReloadListenerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;RegisterCommandsEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ServerLifecycleEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** '''Gamemode events'''&lt;br /&gt;
*** &amp;lt;code&amp;gt;DifficultyChangeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ClientPlayerChangeGameTypeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**'''Trade events'''&lt;br /&gt;
*** &amp;lt;code&amp;gt;WandererTradesEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;VillagerTradesEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** '''Other events'''&lt;br /&gt;
*** &amp;lt;code&amp;gt;FurnaceFuelBurnTimeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;BabyEntitySpawnEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;VillageSiegeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;TagsUpdatedEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;PotionBrewEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ScreenshotEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;EnchantmentLevelSetEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;CommandEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;AnvilUpdateEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ItemAttributeModifierEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ClientPlayerNetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ChunkWatchEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
{{Tree list/end}}&lt;br /&gt;
&lt;br /&gt;
Like before, each of these events (especially the Super Events, which contain most of the useful events in the game) will have their own article explaining their purpose and usefulness.&lt;br /&gt;
&amp;lt;/tab&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Events]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Common Concepts]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Events/Mod_bus&amp;diff=3135</id>
		<title>Events/Mod bus</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Events/Mod_bus&amp;diff=3135"/>
		<updated>2022-04-03T13:08:10Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Add mod event list&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Tree list}}&lt;br /&gt;
* &amp;lt;code&amp;gt;IModBusEvent&amp;lt;/code&amp;gt; - ''The interface for all mod bus events''&lt;br /&gt;
** &amp;lt;code&amp;gt;ModelBakeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;EntityRenderersEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;AddLayers&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityRenderersEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;CreateSkullModels&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityRenderersEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;RegisterRenderers&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityRenderersEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;RegisterLayerDefinitions&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityRenderersEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;VanillaRegisterEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;SoundLoadEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;ModelRegistryEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;GatherDataEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;RegisterShadersEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;AddPackFindersEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;ModLifecycleEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ParallelDispatchEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;FMLCommonSetupEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;InterModProcessEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;FMLDedicatedServerSetupEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;FMLConstructModEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;InterModEnqueueEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;FMLClientSetupEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;FMLLoadCompleteEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;EntityAttributeCreationEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;NewRegistryEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;RegisterGameTestsEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;ParticleFactoryRegisterEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;RegisterCapabilitiesEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;TextureStitchEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;TextureStitchEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;TextureStitchEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;EntityAttributeModificationEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;RegistryEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Register&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RegistryEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;MissingMappings&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RegistryEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;RegisterClientReloadListenersEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;ColorHandlerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ColorHandlerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ColorHandlerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;ModConfigEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Reloading&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ModConfigEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Loading&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ModConfigEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
{{Tree list/end}}&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Events/Forge_bus&amp;diff=3134</id>
		<title>Events/Forge bus</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Events/Forge_bus&amp;diff=3134"/>
		<updated>2022-04-03T13:07:29Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update event list&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Tree list}}&lt;br /&gt;
* &amp;lt;code&amp;gt;Event&amp;lt;/code&amp;gt; - ''The root superclass for all events''&lt;br /&gt;
** &amp;lt;code&amp;gt;RecipesUpdatedEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;BiomeLoadingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;FurnaceFuelBurnTimeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;DrawSelectionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;HighlightBlock&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;DrawSelectionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;HighlightEntity&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;DrawSelectionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;VillagerTradesEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;AddReloadListenerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;ClientPlayerChangeGameTypeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;RenderHandEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;RenderLivingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderLivingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderLivingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;RegisterCommandsEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;RenderItemInFrameEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;IdMappingEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RegistryEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;RenderBlockOverlayEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;NoteBlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;Change&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;NoteBlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;Play&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;NoteBlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;NeighborNotifyEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;BlockToolInteractEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;BreakEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;EntityPlaceEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;EntityMultiPlaceEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;PistonEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PistonEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PistonEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;PortalSpawnEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;FarmlandTrampleEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;FluidPlaceBlockEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;CropGrowEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;CropGrowEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;CropGrowEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;WorldEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Load&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;WorldEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;CreateSpawnPosition&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;WorldEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Unload&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;WorldEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ChunkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;Load&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ChunkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;Unload&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ChunkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;ChunkDataEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Save&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ChunkDataEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Load&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ChunkDataEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;SleepFinishedTimeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Save&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;WorldEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;SaplingGrowTreeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;BabyEntitySpawnEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;ContainerScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;DrawBackground&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ContainerScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;DrawForeground&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ContainerScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;ServerChatEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;PotionShiftEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;KeyboardKeyEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;KeyboardKeyReleasedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;KeyboardKeyReleasedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;KeyboardKeyReleasedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;KeyboardKeyPressedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;KeyboardKeyPressedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;KeyboardKeyPressedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;InitScreenEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;InitScreenEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;InitScreenEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;MouseInputEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;MouseReleasedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;MouseReleasedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;MouseReleasedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;MouseScrollEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;MouseScrollEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;MouseScrollEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;MouseClickedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;MouseClickedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;MouseClickedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;MouseDragEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;MouseDragEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;MouseDragEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;KeyboardCharTypedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;KeyboardCharTypedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;KeyboardCharTypedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;PotionSizeEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;DrawScreenEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;DrawScreenEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;DrawScreenEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;BackgroundDrawnEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ScreenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;VillageSiegeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;LootTableLoadEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;TagsUpdatedEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;PotionBrewEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PotionBrewEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PotionBrewEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;ClientChatReceivedEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;InputEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ClickInputEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;InputEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;KeyInputEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;InputEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;MouseInputEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;InputEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;RawMouseEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;InputEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;MouseScrollEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;InputEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;RegisterClientCommandsEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;GatherComponents&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderTooltipEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;DifficultyChangeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;ServerLifecycleEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ServerStoppingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ServerStoppedEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ServerAboutToStartEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ServerStartedEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ServerStartingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;ScreenshotEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;EnchantmentLevelSetEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;RenderTooltipEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderTooltipEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Color&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderTooltipEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;CreateFluidSourceEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;BlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;VanillaGameEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;RenderGameOverlayEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderGameOverlayEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;Text&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderGameOverlayEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;BossInfo&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderGameOverlayEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;PreLayer&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderGameOverlayEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;Chat&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderGameOverlayEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderGameOverlayEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;PostLayer&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderGameOverlayEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;ClientChatEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;CommandEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;StructureSpawnListGatherEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;PermissionGatherEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Handler&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PermissionGatherEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Nodes&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PermissionGatherEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;OnDatapackSyncEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;GenericEvent&amp;lt;/code&amp;gt; - (from EventBus) ''the superclass for events with generic types''&lt;br /&gt;
*** &amp;lt;code&amp;gt;AttachCapabilitiesEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;ExplosionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Detonate&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ExplosionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Start&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ExplosionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;SoundEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;SoundSetupEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;SoundSourceEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;SoundEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;PlaySoundSourceEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;PlayStreamingSourceEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;PlaySoundEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;AnvilUpdateEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;ScreenOpenEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;RenderArmEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;RenderLevelLastEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;TickEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;PlayerTickEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;TickEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ServerTickEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;TickEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;WorldTickEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;TickEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ClientTickEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;TickEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;RenderTickEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;TickEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;WandererTradesEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;ItemAttributeModifierEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;EntityViewRenderEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;FieldOfView&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityViewRenderEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;FogEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityViewRenderEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;RenderFogEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityViewRenderEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;FogDensity&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityViewRenderEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;FogColors&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityViewRenderEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;CameraSetup&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityViewRenderEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;ClientPlayerNetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;LoggedOutEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ClientPlayerNetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;LoggedInEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ClientPlayerNetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;RespawnEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ClientPlayerNetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;FOVModifierEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;EntityEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;EntityTeleportEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;SpreadPlayersCommand&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityTeleportEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;EnderEntity&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityTeleportEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;EnderPearl&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityTeleportEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;TeleportCommand&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityTeleportEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;ChorusFruit&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityTeleportEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ProjectileImpactEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;EntityTravelToDimensionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;EntityMobGriefingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;RenderNameplateEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;EntityConstructing&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;EntityMountEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;EntityStruckByLightningEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;CanUpdate&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Size&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;EntityJoinWorldEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;EnteringSection&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;EntityEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;LivingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingEquipmentChangeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;SleepingLocationCheckEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingUpdateEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;PotionColorCalculationEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingExperienceDropEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingDamageEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingAttackEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingEntityUseItemEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Start&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingEntityUseItemEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Tick&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingEntityUseItemEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Stop&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingEntityUseItemEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Finish&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingEntityUseItemEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;PotionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;PotionExpiryEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PotionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;PotionApplicableEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PotionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;PotionRemoveEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PotionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;PotionAddedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PotionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingPackSizeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;PlayerChangeGameModeEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;PlayerContainerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****** &amp;lt;code&amp;gt;Close&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerContainerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****** &amp;lt;code&amp;gt;Open&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerContainerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;PlayerWakeUpEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;BreakSpeed&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;ItemSmeltedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;ArrowLooseEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Clone&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;UseHoeEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;MovementInputUpdateEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;AdvancementEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;AnvilRepairEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;PlayerSleepInBedEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;PlayerLoggedOutEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;PlayerXpEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****** &amp;lt;code&amp;gt;XpChange&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerXpEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****** &amp;lt;code&amp;gt;LevelChange&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerXpEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****** &amp;lt;code&amp;gt;PickupXp&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerXpEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;StopTracking&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;PlayerDestroyItemEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;FillBucketEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;BonemealEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;SleepingTimeCheckEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;PlayerInteractEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****** &amp;lt;code&amp;gt;EntityInteractSpecific&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerInteractEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****** &amp;lt;code&amp;gt;RightClickBlock&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerInteractEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****** &amp;lt;code&amp;gt;EntityInteract&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerInteractEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****** &amp;lt;code&amp;gt;RightClickEmpty&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerInteractEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****** &amp;lt;code&amp;gt;RightClickItem&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerInteractEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****** &amp;lt;code&amp;gt;LeftClickEmpty&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerInteractEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****** &amp;lt;code&amp;gt;LeftClickBlock&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerInteractEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;EntityItemPickupEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;HarvestCheck&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;ItemPickupEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;TabListNameFormat&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;PlayerChangedDimensionEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;PlayerSetSpawnEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;PlayerFlyableFallEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;LoadFromFile&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;PermissionsChangedEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;CriticalHitEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;StartTracking&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;ItemFishedEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;ArrowNockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;PlayerRespawnEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;ItemTooltipEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;SaveToFile&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;PlayerLoggedInEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;ItemCraftedEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;NameFormat&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;PlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;RenderPlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****** &amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderPlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
****** &amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;RenderPlayerEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;AttackEntityEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;PlayerBrewedPotionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingHealEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;ShieldBlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LootingLevelEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingDestroyBlockEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingConversionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Pre&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingConversionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;Post&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingConversionEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingKnockBackEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingHurtEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingVisibilityEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingDeathEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingFallEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;AnimalTameEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingGetProjectileEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingSpawnEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;AllowDespawn&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingSpawnEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;CheckSpawn&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingSpawnEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
***** &amp;lt;code&amp;gt;SpecialSpawn&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingSpawnEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingSetAttackTargetEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingJumpEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;LivingEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;LivingDropsEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ZombieEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;SummonAidEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ZombieEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;PlaySoundAtEntityEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;EntityLeaveWorldEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ItemEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;ItemTossEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;ItemExpireEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;NetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ServerCustomPayloadEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;NetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;ServerCustomPayloadLoginEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;NetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;LoginPayloadEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;NetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ChannelRegistrationChangeEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;NetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;ClientCustomPayloadEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;NetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
**** &amp;lt;code&amp;gt;ClientCustomPayloadLoginEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;NetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;GatherLoginPayloadsEvent&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;NetworkEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
** &amp;lt;code&amp;gt;ChunkWatchEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;UnWatch&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ChunkWatchEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
*** &amp;lt;code&amp;gt;Watch&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;ChunkWatchEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
{{Tree list/end}}&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Registration&amp;diff=3133</id>
		<title>Registration</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Registration&amp;diff=3133"/>
		<updated>2022-04-02T23:36:50Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Update registry docs to 8527&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Under construction}}&lt;br /&gt;
&lt;br /&gt;
Registration is the process of making an object (such as an item or block) known to the game during runtime. If some objects are not registered, this could cause crashes even before the game is fully loaded or arbitrary behaviors such as bottlenecking mod compatibility for world generation.&lt;br /&gt;
&lt;br /&gt;
Most objects that are known within the game are handled by a &amp;lt;code&amp;gt;Registry&amp;lt;/code&amp;gt;. Each registry uniquely defines each object through a &amp;quot;registry name&amp;quot; via a [[Using Resources#ResourceLocation|ResourceLocation]]. This &amp;quot;registry name&amp;quot; can be accessed with its respective getter and setter: &amp;lt;code&amp;gt;#getRegistryName&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;#setRegistryName&amp;lt;/code&amp;gt;. You can only set the &amp;quot;registry name&amp;quot; of a given object once; otherwise, an exception will be thrown.&lt;br /&gt;
&lt;br /&gt;
{{Tip|In a global context, each object is universally unique through its &amp;lt;code&amp;gt;ResourceKey&amp;lt;/code&amp;gt;: a concatenation of its registry's id and the object's registry name.}}&lt;br /&gt;
&lt;br /&gt;
Due to the inconsistent ordering and registration process vanilla uses, Forge wraps most vanilla registries using &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt;. This guarantees that the loading order for these wrapped registries will be &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt;, and then the rest of the wrapped registries in alphabetical order. All registries supported by Forge can be found within the &amp;lt;code&amp;gt;ForgeRegistries&amp;lt;/code&amp;gt; class. Since all registry names are unique to a specific registry, different registry objects within different registries can have the same name (e.g. a &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt; and an &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; each hold a registry object named &amp;lt;code&amp;gt;examplemod:object&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|If two registry objects within the same registry have the same name, the second object will override the first. The only registry that will throw an &amp;lt;code&amp;gt;IllegalArgumentException&amp;lt;/code&amp;gt; is the &amp;lt;code&amp;gt;DataSerializerEntry&amp;lt;/code&amp;gt; registry.}}&lt;br /&gt;
&lt;br /&gt;
== Methods for Registering ==&lt;br /&gt;
&lt;br /&gt;
There are two proper ways to register objects within an associated wrapped Forge registry: the &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; class, and the &amp;lt;code&amp;gt;RegistryEvent$Register&amp;lt;/code&amp;gt; lifecycle event.&lt;br /&gt;
&lt;br /&gt;
For objects with '''no''' associated Forge registry, you can register the associated entry during the &amp;lt;code&amp;gt;FMLCommonSetupEvent&amp;lt;/code&amp;gt; lifecycle event. In some cases, although not recommended, you may also statically initialize and register these entries.&lt;br /&gt;
&lt;br /&gt;
=== DeferredRegister ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; is an abstraction layer over the registry event used to register objects. It maintains a map of &amp;quot;registry name&amp;quot; to their associated suppliers and resolves those suppliers during the proper &amp;lt;code&amp;gt;RegistryEvent$Register&amp;lt;/code&amp;gt; event. This method is the currently recommended, and documented, way to handle these objects as it provides convenience and safety for those who want to statically initialize objects while avoiding some issues associated with it. &lt;br /&gt;
&lt;br /&gt;
An example of a mod registering a custom block:&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=private static final DeferredRegister&amp;lt;Block&amp;gt; BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;Block&amp;gt; EXAMPLE_BLOCK = BLOCKS.register(&amp;quot;example_block&amp;quot;, () -&amp;gt; new Block(BlockBehaviour.Properties.of(Material.STONE)));&lt;br /&gt;
&lt;br /&gt;
public ExampleMod() {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get().getModEventBus());&lt;br /&gt;
}&lt;br /&gt;
|kotlin=private val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID)&lt;br /&gt;
&lt;br /&gt;
val EXAMPLE_BLOCK: RegistryObject&amp;lt;Block&amp;gt; = BLOCKS.register(&amp;quot;example_block&amp;quot;) { Block(BlockBehaviour.Properties.of(Material.ROCK)) }&lt;br /&gt;
&lt;br /&gt;
internal class ExampleMod {&lt;br /&gt;
    init {&lt;br /&gt;
        BLOCKS.register(FMLJavaModLoadingContext.get().modEventBus)&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
|scala=object ExampleMod {&lt;br /&gt;
    private final val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID)&lt;br /&gt;
&lt;br /&gt;
    final val EXAMPLE_BLOCK = registerBlock(&amp;quot;example_block&amp;quot;, () =&amp;gt; new Block(BlockBehaviour.Properties.of(Material.ROCK)))&lt;br /&gt;
}&lt;br /&gt;
class ExampleMod {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get.getModEventBus)&lt;br /&gt;
}&lt;br /&gt;
|groovy=private static final DeferredRegister&amp;lt;Block&amp;gt; BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;Block&amp;gt; EXAMPLE_BLOCK = BLOCKS.register(&amp;quot;example_block&amp;quot;, () -&amp;gt; new Block(BlockBehaviour.Properties.of(Material.STONE)));&lt;br /&gt;
&lt;br /&gt;
ExampleMod() {&lt;br /&gt;
    BLOCKS.register(FMLJavaModLoadingContext.get().modEventBus);&lt;br /&gt;
}&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip|When using a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; to register any object, the name inputted will be automatically prefixed with the mod id passed in, giving the above object a &amp;quot;registry name&amp;quot; of &amp;lt;code&amp;gt;examplemod:example_block&amp;lt;/code&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
=== RegistryEvent.Register ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;RegistryEvent&amp;lt;/code&amp;gt;s are another, more slightly flexible way to register objects. These [[Events|events]] are fired synchronously after &amp;lt;code&amp;gt;FMLConstructModEvent&amp;lt;/code&amp;gt; and before the configs are loaded.&lt;br /&gt;
&lt;br /&gt;
The event used to register objects is &amp;lt;code&amp;gt;RegistryEvent.Register&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt;, where the type parameter &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; is the object type being registered. You can grab the associated registry using &amp;lt;code&amp;gt;#getRegistry&amp;lt;/code&amp;gt; and register the objects within using either &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; (pass in a single object) or &amp;lt;code&amp;gt;#registerAll&amp;lt;/code&amp;gt; (pass in ''varargs'' or an array of objects). The latter is useful for minimizing calls to &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt;, although it provides no benefit time-complexity wise.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|The type parameter specified must be the exact class used within the Forge registry, not its superclass nor its subclass. If the class specified is not referenced as a type parameter within the associated Forge registries, then the event will not be called.}}&lt;br /&gt;
&lt;br /&gt;
Here is an example: (the event handler is registered on the '''mod event bus''')&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=@SubscribeEvent&lt;br /&gt;
public void registerBlocks(RegistryEvent.Register&amp;lt;Block&amp;gt; event) {&lt;br /&gt;
    event.getRegistry().registerAll(new Block(...).setRegistryName(new ResourceLocation(MODID, &amp;quot;example_block1&amp;quot;)), new Block(...).setRegistryName(new ResourceLocation(MODID, &amp;quot;example_block2&amp;quot;)), ...);&lt;br /&gt;
}&lt;br /&gt;
|kotlin=@JvmStatic&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
private fun registerBlocks(event: RegistryEvent.Register&amp;lt;Block&amp;gt;) =&lt;br /&gt;
    event.registry.registerAll(Block(...).setRegistryName(new ResourceLocation(MODID, &amp;quot;example_block1&amp;quot;)), Block(...).setRegistryName(new ResourceLocation(MODID, &amp;quot;example_block2&amp;quot;)), ...)&lt;br /&gt;
|scala=@SubscribeEvent&lt;br /&gt;
def registerBlocks(event: RegistryEvent.Register[Block]): Unit =&lt;br /&gt;
    event.getRegistry.registerAll(new Block(...).setRegistryName(new ResourceLocation(MODID, &amp;quot;example_block1&amp;quot;)), new Block(...).setRegistryName(new ResourceLocation(MODID, &amp;quot;example_block2&amp;quot;)), ...)&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|Since all objects registered must be singleton, some classes cannot by themselves be registered. Instead, &amp;lt;code&amp;gt;*Type&amp;lt;/code&amp;gt; classes are registered and used in the formers' constructors to wrap the flyweight objects. For example, a [[Basics_of_Block_Entities|&amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt;]] is wrapped via &amp;lt;code&amp;gt;BlockEntityType&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;Entity&amp;lt;/code&amp;gt; is wrapped via &amp;lt;code&amp;gt;EntityType&amp;lt;/code&amp;gt;. These &amp;lt;code&amp;gt;*Type&amp;lt;/code&amp;gt; classes hold factories that simply create the containing type on demand.&lt;br /&gt;
&lt;br /&gt;
These factory holders are created through the use of their &amp;lt;code&amp;gt;*Type$Builder&amp;lt;/code&amp;gt; classes. An example: (&amp;lt;code&amp;gt;REGISTER&amp;lt;/code&amp;gt; here refers to a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;BlockEntityType&amp;lt;?&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final RegistryObject&amp;lt;BlockEntityType&amp;lt;ExampleBlockEntity&amp;gt;&amp;gt; EXAMPLE_BLOCK_ENTITY = REGISTER.register(&lt;br /&gt;
    &amp;quot;example_block_entity&amp;quot;, () -&amp;gt; BlockEntityType.Builder.of(ExampleBlockEntity::new, EXAMPLE_BLOCK.get()).build(null)&lt;br /&gt;
);&lt;br /&gt;
|kotlin=val EXAMPLE_BLOCK_ENTITY: RegistryObject&amp;lt;BlockEntityType&amp;lt;ExampleBlockEntity&amp;gt;&amp;gt; = REGISTER.register(&amp;quot;example_block_entity&amp;quot;) { BlockEntityType.Builder.of(::ExampleBlockEntity, EXAMPLE_BLOCK.get()).build(null)) }&lt;br /&gt;
|scala=final val EXAMPLE_BLOCK_ENTITY = REGISTER.register(&amp;quot;example_block_entity&amp;quot;, () =&amp;gt; BlockEntityType.Builder.of(() =&amp;gt; new ExampleBlockEntity(), GeneralRegistrar.EXAMPLE_BLOCK.get).build(null))&lt;br /&gt;
|}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=== Non-Forge Registries ===&lt;br /&gt;
&lt;br /&gt;
Not all vanilla registries are wrapped as a Forge registry. This is because the registry is fully independent from any other registry, completely data driven, or just has not been wrapped yet.&lt;br /&gt;
&lt;br /&gt;
These registries include:&lt;br /&gt;
* Custom Stats (a &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; registry)&lt;br /&gt;
* &amp;lt;code&amp;gt;RuleTestType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;PosRuleTestType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;RecipeType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;GameEvent&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;PositionSourceType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;VillagerType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;LootPoolEntryType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;LootItemFunctionType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;LootItemConditionType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;LootNumberProviderType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;LootNbtProviderType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;LootScoreProviderType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FloatProviderType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;IntProviderType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;HeightProviderType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;StructurePieceType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;TrunkPlacerType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;FeatureSizeType&amp;lt;/code&amp;gt;&lt;br /&gt;
* A &amp;lt;code&amp;gt;Codec&amp;lt;/code&amp;gt; of &amp;lt;code&amp;gt;BiomeSource&amp;lt;/code&amp;gt;&lt;br /&gt;
* A &amp;lt;code&amp;gt;Codec&amp;lt;/code&amp;gt; of &amp;lt;code&amp;gt;ChunkGenerator&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;StructureProcessorType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;StructurePoolElementType&amp;lt;/code&amp;gt;&lt;br /&gt;
* All registries within &amp;lt;code&amp;gt;BuiltinRegistries&amp;lt;/code&amp;gt; excluding &amp;lt;code&amp;gt;Biome&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To register objects to any one of these registries, create a &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; via the &amp;lt;code&amp;gt;#create&amp;lt;/code&amp;gt; overload which takes in a resource key of the registry and the mod id to register the entries for. Then simply call &amp;lt;code&amp;gt;#register&amp;lt;/code&amp;gt; like any other &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=private static final DeferredRegister&amp;lt;RecipeType&amp;lt;?&amp;gt;&amp;gt; RECIPE_TYPES = DeferredRegister.create(Registry.RECIPE_TYPE_REGISTRY, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;RecipeType&amp;lt;ExampleRecipe&amp;gt;&amp;gt; EXAMPLE_RECIPE = RECIPE_TYPES.register(&amp;quot;example_recipe&amp;quot;, () -&amp;gt; new RecipeType&amp;lt;&amp;gt;() {});&lt;br /&gt;
|kotlin=private val RECIPE_TYPES = DeferredRegister.create(Registry.RECIPE_TYPE_REGISTRY, MODID)&lt;br /&gt;
&lt;br /&gt;
val EXAMPLE_RECIPE: RegistryObject&amp;lt;RecipeType&amp;lt;ExampleRecipe&amp;gt;&amp;gt; = RECIPE_TYPES.register(&amp;quot;example_recipe&amp;quot;) {&lt;br /&gt;
    RecipeType&amp;lt;&amp;gt;() {}&lt;br /&gt;
}&lt;br /&gt;
|scala=private final val RECIPE_TYPES = DeferredRegister.create(Registry.RECIPE_TYPE_REGISTRY, MODID)&lt;br /&gt;
&lt;br /&gt;
final val EXAMPLE_RECIPE = RECIPE_TYPES.register(&amp;quot;example_recipe&amp;quot;, () =&amp;gt; new RecipeType&amp;lt;&amp;gt;() {})&lt;br /&gt;
|groovy=private static final DeferredRegister&amp;lt;RecipeType&amp;lt;?&amp;gt;&amp;gt; RECIPE_TYPES = DeferredRegister.create(Registry.RECIPE_TYPE_REGISTRY, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final RegistryObject&amp;lt;RecipeType&amp;lt;ExampleRecipe&amp;gt;&amp;gt; EXAMPLE_RECIPE = RECIPE_TYPES.register(&amp;quot;example_recipe&amp;quot;, () -&amp;gt; new RecipeType&amp;lt;&amp;gt;() {});&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
If you attempt to make one of these instances require an instance of another registry object, you must use the lazy initialization method mentioned above to register the object in the correct order.&lt;br /&gt;
&lt;br /&gt;
=== Data Driven Entries ===&lt;br /&gt;
&lt;br /&gt;
Registries are considered to be data driven if they are located within &amp;lt;code&amp;gt;RegistryAccess&amp;lt;/code&amp;gt; with the exception of &amp;lt;code&amp;gt;LevelStem&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Level&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The following registries are data driven:&lt;br /&gt;
* &amp;lt;code&amp;gt;ConfiguredSurfaceBuilder&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ConfiguredWorldCarver&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ConfiguredFeature&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;ConfiguredStructureFeature&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;StructureProcessorList&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;StructureTemplatePool&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;Biome&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;NoiseGeneratorSettings&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;DimensionType&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;LevelStem&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;Level&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These registry objects only need to be registered within code if they are to be used within a pre-existing registry object (e.g. a &amp;lt;code&amp;gt;ConfiguredFeature&amp;lt;/code&amp;gt; for ore generation within an overworld &amp;lt;code&amp;gt;Biome&amp;lt;/code&amp;gt;). Otherwise, their instance can be purely registered using a JSON file.&lt;br /&gt;
&lt;br /&gt;
If a data driven registry object has to be registered within code, a dummy object should be supplied to hold a &amp;quot;registry name&amp;quot; and then constructed within a JSON file.&lt;br /&gt;
&lt;br /&gt;
== Referencing Registered Objects ==&lt;br /&gt;
&lt;br /&gt;
Each forge registered object should not be statically initialized nor reference another instance being registered. They must always be a new, singleton instance that is resolved during their respective &amp;lt;code&amp;gt;RegistryEvent$Register&amp;lt;/code&amp;gt; event. This is to maintain a sane loading order for registries and their objects along with dynamic loading/unloading of mods.&lt;br /&gt;
&lt;br /&gt;
Forge registered objects must always be referenced through a &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; or a field with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Using RegistryObjects===&lt;br /&gt;
&amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;s can be used to retrieve references to registered objects once they become available. Their references are updated along with all &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; annotations after the associated &amp;lt;code&amp;gt;RegistryEvent$Register&amp;lt;/code&amp;gt; has been dispatched and frozen.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; can be retrieved as a result of using &amp;lt;code&amp;gt;DeferredRegister&amp;lt;/code&amp;gt; or calling the static constructor &amp;lt;code&amp;gt;RegistryObject::create&amp;lt;/code&amp;gt;. Each static constructor takes in the &amp;quot;registry name&amp;quot; of the object being referenced and either a &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt; or, if custom registries are used, a supplier of the object class implementing &amp;lt;code&amp;gt;IForgeRegistryEntry&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt; can be stored within some field and retrieve the registered object using &amp;lt;code&amp;gt;#get&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
An example using &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;:&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final RegistryObject&amp;lt;Item&amp;gt; EXAMPLE_ITEM = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod:example_item&amp;quot;), ForgeRegistries.ITEMS);&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
public static final RegistryObject&amp;lt;ExampleRegistry&amp;gt; EXAMPLE_OBJECT = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;); &lt;br /&gt;
|kotlin=val EXAMPLE_ITEM: RegistryObject&amp;lt;Item&amp;gt; = RegistryObject.create(ResourceLocation(&amp;quot;examplemod:example_item&amp;quot;), ForgeRegistries.ITEMS)&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
val EXAMPLE_OBJECT: RegistryObject&amp;lt;ExampleRegistry&amp;gt; = RegistryObject.create(ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;)&lt;br /&gt;
|scala=final val EXAMPLE_ITEM = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod:example_item&amp;quot;), ForgeRegistries.ITEMS)&lt;br /&gt;
&lt;br /&gt;
// Assume that 'examplemod:example_registry' is a valid registry, and 'examplemod:example_object' is a valid object within that registry&lt;br /&gt;
final val EXAMPLE_OBJECT = RegistryObject.create(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_object&amp;quot;), new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_registry&amp;quot;), &amp;quot;examplemod&amp;quot;); &lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|All vanilla objects are bootstrapped and registered before mods are loaded. As such, they can be referenced as is without any issues, assuming the entries are not replaced.}}&lt;br /&gt;
&lt;br /&gt;
=== Using @ObjectHolder ===&lt;br /&gt;
&lt;br /&gt;
Forge registry objects can also be injected into &amp;lt;code&amp;gt;public static&amp;lt;/code&amp;gt; fields with either their class or that field annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;. There must be enough information to construct a &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; to identify a single object within a specific registry.&lt;br /&gt;
&lt;br /&gt;
The rules for &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; are as follows:&lt;br /&gt;
&lt;br /&gt;
* If the class is annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;, its value will be the default namespace for all fields within if not explicitly defined&lt;br /&gt;
* If the class is annotated with &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt;, the modid will be the default namespace for all annotated fields within if not explicitly defined &lt;br /&gt;
* A field is considered for injection if:&lt;br /&gt;
** it has at least the modifiers &amp;lt;code&amp;gt;public static&amp;lt;/code&amp;gt;; and&lt;br /&gt;
** one of the following conditions are true:&lt;br /&gt;
*** the '''enclosing class''' has an &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; annotation, and the field is &amp;lt;code&amp;gt;final&amp;lt;/code&amp;gt;, and:&lt;br /&gt;
**** the name value is the field's name; and&lt;br /&gt;
**** the namespace value is the enclosing class's namespace&lt;br /&gt;
**** ''An exception is thrown if the namespace value cannot be found and inherited''&lt;br /&gt;
*** the '''field''' is annotated with &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;, and:&lt;br /&gt;
**** the name value is explicitly defined; and&lt;br /&gt;
**** the namespace value is either explicitly defined or the enclosing class's namespace&lt;br /&gt;
** the field type or one of its supertypes corresponds to a valid registry (e.g. &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;ArrowItem&amp;lt;/code&amp;gt; for the &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; registry)&lt;br /&gt;
** ''An exception is thrown if a field does not have a corresponding registry.''&lt;br /&gt;
* ''An exception is thrown if the resulting &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; is incomplete or invalid (non-valid characters in path)''&lt;br /&gt;
* If no other errors or exceptions occur, the field will be injected&lt;br /&gt;
* If all of the above rules do not apply, no action will be taken (and a message may be logged)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt; annotated fields are injected with their associated object values after their corresponding registry's &amp;lt;code&amp;gt;RegistryEvent$Register&amp;lt;/code&amp;gt; event is fired, along with &amp;lt;code&amp;gt;RegistryObject&amp;lt;/code&amp;gt;s.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|If the object does not exist in the registry when it is to be injected, a debug message will be logged, and no value will be injected. If the object is found, but the field cannot be set, a warning message will be logged instead.}}&lt;br /&gt;
&lt;br /&gt;
As these rules are rather complicated, here are some examples:&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; style=&amp;quot;border: solid 2px; padding: 2px 5px; margin-top: 3px&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-weight:bold;line-height:1.6;&amp;quot;&amp;gt;Example uses of &amp;lt;code&amp;gt;@ObjectHolder&amp;lt;/code&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot; style=&amp;quot;overflow: auto; white-space: nowrap;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
@ObjectHolder(&amp;quot;minecraft&amp;quot;) // Inheritable resource namespace: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
class AnnotatedHolder {&lt;br /&gt;
    public static final Block diamond_block = null;   // No annotation. [public static final] is required.&lt;br /&gt;
                                                      // Block has a corresponding registry: [Block]&lt;br /&gt;
                                                      // Name path is the name of the field: &amp;quot;diamond_block&amp;quot;&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // So, namespace is inherited from class annotation: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:diamond_block&amp;quot; from the [Block] registry&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(&amp;quot;ambient.cave&amp;quot;)&lt;br /&gt;
    public static SoundEvent ambient_sound = null;    // Annotation present. [public static] is required.&lt;br /&gt;
                                                      // SoundEvent has a corresponding registry: [SoundEvent]&lt;br /&gt;
                                                      // Name path is the value of the annotation: &amp;quot;ambient.cave&amp;quot;&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // So, namespace is inherited from class annotation: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:ambient.cave&amp;quot; from the [SoundEvent] registry&lt;br /&gt;
&lt;br /&gt;
    // Assume for the next entry that [ManaType] is a valid registry.          &lt;br /&gt;
    @ObjectHolder(&amp;quot;neomagicae:coffeinum&amp;quot;)&lt;br /&gt;
    public static final ManaType coffeinum = null;    // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // ManaType has a corresponding registry: [ManaType] (custom registry)&lt;br /&gt;
                                                      // Resource location is explicitly defined: &amp;quot;neomagicae:coffeinum&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;neomagicae:coffeinum&amp;quot; from the [ManaType] registry&lt;br /&gt;
&lt;br /&gt;
    public static final Item ENDER_PEARL = null;      // No annotation. [public static final] is required.&lt;br /&gt;
                                                      // Item has a corresponding registry: [Item].&lt;br /&gt;
                                                      // Name path is the name of the field: &amp;quot;ENDER_PEARL&amp;quot; -&amp;gt; &amp;quot;ender_pearl&amp;quot;&lt;br /&gt;
                                                      // !! ^ Field name is valid, because they are&lt;br /&gt;
                                                      //      converted to lowercase automatically.&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // So, namespace is inherited from class annotation: &amp;quot;minecraft&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:ender_pearl&amp;quot; from the [Item] registry&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(&amp;quot;minecraft:arrow&amp;quot;)&lt;br /&gt;
    public static final ArrowItem arrow = null;       // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // ArrowItem does not have a corresponding registry.&lt;br /&gt;
                                                      // ArrowItem's supertype of Item has a corresponding registry: [Item]&lt;br /&gt;
                                                      // Resource location is explicitly defined: &amp;quot;minecraft:arrow&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:arrow&amp;quot; from the [Item] registry                                                    &lt;br /&gt;
&lt;br /&gt;
    public static Block bedrock = null;               // No annotation, so [public static final] is required.&lt;br /&gt;
                                                      // Therefore, the field is ignored.&lt;br /&gt;
    &lt;br /&gt;
    public static final CreativeModeTab group = null; // No annotation. [public static final] is required.&lt;br /&gt;
                                                      // CreativeModeTab does not have a corresponding registry.&lt;br /&gt;
                                                      // No supertypes of CreativeModeTab has a corresponding registry.&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
class UnannotatedHolder { // Note the lack of an @ObjectHolder annotation on this class.&lt;br /&gt;
    @ObjectHolder(&amp;quot;minecraft:flame&amp;quot;)&lt;br /&gt;
    public static final Enchantment flame = null;     // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // Enchantment has corresponding registry: [Enchantment].&lt;br /&gt;
                                                      // Resource location is explicitly defined: &amp;quot;minecraft:flame&amp;quot;&lt;br /&gt;
                                                      // To inject: &amp;quot;minecraft:flame&amp;quot; from the [Enchantment] registry&lt;br /&gt;
&lt;br /&gt;
    public static final Biome ice_flat = null;        // No annotation on the enclosing class.&lt;br /&gt;
                                                      // Therefore, the field is ignored.&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(&amp;quot;minecraft:creeper&amp;quot;)&lt;br /&gt;
    public static Entity creeper = null;              // Annotation present. [public static] is required.&lt;br /&gt;
                                                      // Entity does not have a corresponding registry.&lt;br /&gt;
                                                      // No supertypes of Entity has a corresponding registry.&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
&lt;br /&gt;
    @ObjectHolder(&amp;quot;levitation&amp;quot;)&lt;br /&gt;
    public static final Potion levitation = null;     // Annotation present. [public static] is required. [final] is optional.&lt;br /&gt;
                                                      // Potion has a corresponding registry: [Potion].&lt;br /&gt;
                                                      // Name path is the value of the annotation: &amp;quot;levitation&amp;quot;&lt;br /&gt;
                                                      // Namespace is not explicitly defined.&lt;br /&gt;
                                                      // No annotation in enclosing class.&lt;br /&gt;
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Creating Custom Registries ==&lt;br /&gt;
&lt;br /&gt;
Creating custom registries for your mod might be useful if you want other mods to add new things to your system. For example, you might have magic spells and want to allow other mods to add new spells. For this you will want to make a registry (eg. &amp;quot;mymagicmod:spells&amp;quot;). This way, other mods will be able to register things to that list, and you won't have to do anything else.&lt;br /&gt;
&lt;br /&gt;
Just like with registering a new item or block you have two ways of making a new registry. Each method takes in a &amp;lt;code&amp;gt;RegistryBuilder&amp;lt;/code&amp;gt; which is used to build an &amp;lt;code&amp;gt;IForgeRegistry&amp;lt;/code&amp;gt; for an object class that implements &amp;lt;code&amp;gt;IForgeRegistryEntry&amp;lt;/code&amp;gt;. Each builder should have its name and type set via &amp;lt;code&amp;gt;#setName&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;#setType&amp;lt;/code&amp;gt; respectively before being created.&lt;br /&gt;
&lt;br /&gt;
For the class that implements &amp;lt;code&amp;gt;IForgeRegistryEntry&amp;lt;/code&amp;gt;, it is recommended in most cases to extend the default implementation of &amp;lt;code&amp;gt;ForgeRegistryEntry&amp;lt;/code&amp;gt;. For interfaces, it should extend &amp;lt;code&amp;gt;IForgeRegistryEntry&amp;lt;/code&amp;gt; with its implementations extending &amp;lt;code&amp;gt;ForgeRegistryEntry&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== With DeferredRegister ===&lt;br /&gt;
&lt;br /&gt;
The first method involves the second static constructor: &amp;lt;code&amp;gt;DeferredRegister::create(ResourceLocation, String)&amp;lt;/code&amp;gt;. From there, we can construct the registry using &amp;lt;code&amp;gt;#makeRegistry&amp;lt;/code&amp;gt;. This will already populate &amp;lt;code&amp;gt;#setName&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;#setType&amp;lt;/code&amp;gt; for us. This method also returns a supplier of the registry which we can use after the &amp;lt;code&amp;gt;RegistryEvent$NewRegistry&amp;lt;/code&amp;gt; event.&lt;br /&gt;
&lt;br /&gt;
Here is an example:&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public static final DeferredRegister&amp;lt;ExampleRegistry&amp;gt; EXAMPLE = DeferredRegister.create(&amp;quot;example_registry&amp;quot;, MODID);&lt;br /&gt;
&lt;br /&gt;
public static final Supplier&amp;lt;IForgeRegistry&amp;lt;ExampleRegistry&amp;gt;&amp;gt; REGISTRY = EXAMPLE.makeRegistry(ExampleRegistry.class, RegistryBuilder::new);&lt;br /&gt;
|kotlin=val EXAMPLE: DeferredRegister&amp;lt;ExampleRegistry&amp;gt; = DeferredRegister.create(&amp;quot;example_registry&amp;quot;, MODID)&lt;br /&gt;
&lt;br /&gt;
val REGISTRY: IForgeRegistry&amp;lt;ExampleRegistry&amp;gt; by lazy {&lt;br /&gt;
    EXAMPLE.makeRegistry(ExampleRegistry::class.java, ::RegistryBuilder).get()&lt;br /&gt;
}&lt;br /&gt;
|scala=final val EXAMPLE = DeferredRegister.create(&amp;quot;example_registry&amp;quot;, MODID)&lt;br /&gt;
&lt;br /&gt;
final lazy val REGISTRY = EXAMPLE.makeRegistry(classOf[ExampleRegistry], () =&amp;gt; new RegistryBuilder).get&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
=== Using RegistryEvent$NewRegistry ===&lt;br /&gt;
&lt;br /&gt;
The second method can be done during the &amp;lt;code&amp;gt;RegistryEvent$NewRegistry&amp;lt;/code&amp;gt; event. This will call a new instance of the builder directly. From there, the registry can be built and stored via &amp;lt;code&amp;gt;RegistryBuilder#create&amp;lt;/code&amp;gt;. This will cause the registry to be registered to the &amp;lt;code&amp;gt;RegistryManager&amp;lt;/code&amp;gt; and returned to the caller for additional processing.&lt;br /&gt;
&lt;br /&gt;
Here is an example: (the event handler is registered on the '''mod event bus''')&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Java&amp;quot;&amp;gt;&lt;br /&gt;
public static IForgeRegistry&amp;lt;ExampleRegistry&amp;gt; registry = null;&lt;br /&gt;
&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void onNewRegistry(RegistryEvent.NewRegistry event){&lt;br /&gt;
    RegistryBuilder&amp;lt;ExampleRegistry&amp;gt; registryBuilder = new RegistryBuilder&amp;lt;&amp;gt;();&lt;br /&gt;
    registryBuilder.setName(new ResourceLocation(MODID, &amp;quot;example_registry&amp;quot;);&lt;br /&gt;
    registryBuilder.setType(ExampleRegistry.class);&lt;br /&gt;
    registry = registryBuilder.create();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Handling Missing Entries ==&lt;br /&gt;
&lt;br /&gt;
When loading a pre-existing world after removing mods or updating versions, there are cases where certain registry objects will cease to exist. In these cases, it is possible to specify actions to remove a mapping, prevent the world from loading, or remap the name as needed. This can be done through the third of the registry events: &amp;lt;code&amp;gt;RegistryEvent$MissingMappings&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt;, where the type parameter &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt; is the object type being registered. Within the event, you can grab an immutable list of missing mappings associated with a mod id via &amp;lt;code&amp;gt;#getMappings&amp;lt;/code&amp;gt; or a list of all mappings via &amp;lt;code&amp;gt;#getAllMappings&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For each &amp;lt;code&amp;gt;Mapping&amp;lt;/code&amp;gt;, you can either execute one of the following methods:&lt;br /&gt;
* &amp;lt;code&amp;gt;#ignore&amp;lt;/code&amp;gt; which abandons the entry when loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#warn&amp;lt;/code&amp;gt; which warns the user about the missing entry but continues loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#fail&amp;lt;/code&amp;gt; which prevents the world from loading&lt;br /&gt;
* &amp;lt;code&amp;gt;#remap&amp;lt;/code&amp;gt; which remaps the entry to the specified non-null object in the same registry&lt;br /&gt;
&lt;br /&gt;
If none of the above are specified, then the default action of notifying the user about the missing mappings occur.&lt;br /&gt;
&lt;br /&gt;
Here is an example:  (the event handler is registered on the '''mod event bus''')&lt;br /&gt;
&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=// This will ignore any missing test items from the specified world&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
public void onMissingItems(final RegistryEvent.MissingMappings&amp;lt;Item&amp;gt; event) {&lt;br /&gt;
    event.getMappings(MODID).stream()&lt;br /&gt;
        .filter(mapping -&amp;gt; mapping.key.getPath().contains(&amp;quot;test&amp;quot;))&lt;br /&gt;
            .forEach(Mapping::ignore);&lt;br /&gt;
}&lt;br /&gt;
|groovy=// This will ignore any missing test items from the specified world&lt;br /&gt;
@SubscribeEvent&lt;br /&gt;
void onMissingItems(final RegistryEvent.MissingMappings&amp;lt;Item&amp;gt; event) {&lt;br /&gt;
    event.getMappings(MODID).stream()&lt;br /&gt;
        .filter(mapping -&amp;gt; mapping.key.path.contains(&amp;quot;test&amp;quot;))&lt;br /&gt;
            .forEach(Mapping::ignore);&lt;br /&gt;
}&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Common Concepts]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=SimpleChannel&amp;diff=3131</id>
		<title>SimpleChannel</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=SimpleChannel&amp;diff=3131"/>
		<updated>2022-03-29T00:30:35Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: There's your code example shrimp!&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SimpleChannel is the name given to the packet system that revolves around the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;SimpleChannel&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; class. Using this system is by far the easiest way to send custom data between clients and the server.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
First you need to create your &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;SimpleChannel&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; object. We recommend that you do this in a separate class, possibly something like &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ModidPacketHandler&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Create your &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;SimpleChannel&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; as a static field in this class, like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
private static final String PROTOCOL_VERSION = &amp;quot;1&amp;quot;;&lt;br /&gt;
public static final SimpleChannel INSTANCE = NetworkRegistry.newSimpleChannel(&lt;br /&gt;
    new ResourceLocation(&amp;quot;mymodid&amp;quot;, &amp;quot;main&amp;quot;),&lt;br /&gt;
    () -&amp;gt; PROTOCOL_VERSION,&lt;br /&gt;
    PROTOCOL_VERSION::equals,&lt;br /&gt;
    PROTOCOL_VERSION::equals&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first argument is a name for the channel. The second argument is a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Supplier&amp;lt;String&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; returning the current network protocol version. The third and fourth arguments respectively are &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Predicate&amp;lt;String&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; checking whether an incoming connection protocol version is network-compatible with the client or server, respectively.&lt;br /&gt;
Here, we simply compare with the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;PROTOCOL_VERSION&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; field directly, meaning that the client and server &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;PROTOCOL_VERSION&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s must always match or FML will deny login.&lt;br /&gt;
&lt;br /&gt;
== Protocol Versions ==&lt;br /&gt;
If your mod does not require the other side to have a specific network channel, or to be a Forge instance at all, you should take care that you properly define your version compatibility checkers (the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Predicate&amp;lt;String&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; parameters) to handle additional &amp;quot;meta-versions&amp;quot; (defined in &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;NetworkRegistry&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;) that can be received by the version checker. These are:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ABSENT&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; - if this channel is missing on the other endpoint. Note that in this case, the endpoint is still a Forge endpoint, and may have other mods.&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ACCEPTVANILLA&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; - if the endpoint is a vanilla (or non-Forge) endpoint.&lt;br /&gt;
&lt;br /&gt;
Returning &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;false&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for both means that this channel must be present on the other endpoint. If you just copy the code above, this is what it does. Note that these values are also used during the list ping compatibility check, which is responsible for showing the green check / red cross in the multiplayer server select screen.&lt;br /&gt;
&lt;br /&gt;
== Registering Packets ==&lt;br /&gt;
&lt;br /&gt;
Next, we must declare the types of messages that we would like to send and receive. This is done using the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;INSTANCE.registerMessage&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; method, which takes 5 parameters.&lt;br /&gt;
&lt;br /&gt;
* The first parameter is the discriminator for the packet. This is a per-channel unique ID for the packet. We recommend you use a local variable to hold the ID, and then call registerMessage using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;id++&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. This will guarantee 100% unique IDs.&lt;br /&gt;
* The second parameter is the actual packet class &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;MSG&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
* The third parameter is a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BiConsumer&amp;lt;MSG, FriendlyByteBuf&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; responsible for encoding the message into the provided &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;FriendlyByteBuf&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* The fourth parameter is a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Function&amp;lt;FriendlyByteBuf, MSG&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; responsible for decoding the message from the provided &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;FriendlyByteBuf&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* The final parameter is a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BiConsumer&amp;lt;MSG, Supplier&amp;lt;NetworkEvent.Context&amp;gt;&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; responsible for handling the message itself&lt;br /&gt;
&lt;br /&gt;
The last three parameters can be method references to either static or instance methods in Java. Remember that an instance method &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;MSG.encode(FriendlyByteBuf)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; still satisfies &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BiConsumer&amp;lt;MSG, FriendlyByteBuf&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;MSG&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; simply becomes the implicit first argument.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// A class MessagePacket&lt;br /&gt;
public void encoder(FriendlyByteBuf buffer) {&lt;br /&gt;
   // Write to buffer&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static MessagePacket decoder(FriendlyByteBuf buffer) {&lt;br /&gt;
  // Create packet from buffer data&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public void messageConsumer(Supplier&amp;lt;NetworkEvent.Context&amp;gt;&amp;gt; ctx) {&lt;br /&gt;
  // Handle message&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// For some SimpleChannel channel&lt;br /&gt;
channel.registerMessage(id, MessagePacket::encoder, MessagePacket::decoder, MessagePacket::messageConsumer);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Handling Packets ==&lt;br /&gt;
&lt;br /&gt;
There are a couple things to highlight in a packet handler. A packet handler has both the message object and the network context available to it. The context allows access to the player that sent the packet (if on the server), and a way to enqueue threadsafe work.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static void handle(MyMessage msg, Supplier&amp;lt;NetworkEvent.Context&amp;gt; ctx) {&lt;br /&gt;
    ctx.get().enqueueWork(() -&amp;gt; {&lt;br /&gt;
        // Work that needs to be threadsafe (most work)&lt;br /&gt;
        ServerPlayer sender = ctx.get().getSender(); // the client that sent this packet&lt;br /&gt;
        // do stuff&lt;br /&gt;
    });&lt;br /&gt;
    ctx.get().setPacketHandled(true);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Packets sent from the server to the client should be handled in another class and wrapped via &amp;lt;code&amp;gt;DistExecutor#unsafeRunWhenOn&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// In Packet class&lt;br /&gt;
public static void handle(MyClientMessage msg, Supplier&amp;lt;NetworkEvent.Context&amp;gt; ctx) {&lt;br /&gt;
    ctx.get().enqueueWork(() -&amp;gt;&lt;br /&gt;
        // Make sure it's only executed on the physical client&lt;br /&gt;
        DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -&amp;gt; () -&amp;gt; ClientPacketHandlerClass.handlePacket(msg, ctx))&lt;br /&gt;
    );&lt;br /&gt;
    ctx.get().setPacketHandled(true);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// In ClientPacketHandlerClass&lt;br /&gt;
public static void handlePacket(MyClientMessage msg, Supplier&amp;lt;NetworkEvent.Context&amp;gt; ctx) {&lt;br /&gt;
    // Do stuff&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the presence of &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;#setPacketHandled&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, which used to tell the network system that the packet has successfully completed handling.&lt;br /&gt;
&lt;br /&gt;
=== Common Packet Handling Pitfalls ===&lt;br /&gt;
&lt;br /&gt;
{{Colored box|title=Know that packets are by default handled on the network thread.|content=&lt;br /&gt;
That means that your handler can ''not'' interact with most game objects directly.&lt;br /&gt;
Forge provides a convenient way to make your code execute on the main thread through the supplied &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;NetworkEvent$Context&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
Simply call &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;NetworkEvent$Context#enqueueWork(Runnable)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, which will call the given &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Runnable&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; on the main thread at the next opportunity.}}&lt;br /&gt;
&lt;br /&gt;
{{Colored box|title=Be defensive when handling packets on the server.|content=&lt;br /&gt;
A client could attempt to exploit the packet handling by sending unexpected data.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
A common problem is vulnerability to &amp;lt;code&amp;gt;arbitrary chunk generation&amp;lt;/code&amp;gt;. This typically happens when the server is trusting a block position sent by a client to access blocks and block entities. When accessing blocks and block entities in unloaded areas of the level, the server will either generate or load this area from disk, then promply write it to disk. This can be exploited to cause &amp;lt;code&amp;gt;catastrophic damage&amp;lt;/code&amp;gt; to a server's performance and storage space without leaving a trace.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
To avoid this problem, a general rule of thumb is to only access blocks and block entities if &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Level#hasChunkAt&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; is true.}}&lt;br /&gt;
&lt;br /&gt;
{{Colored box|title=Register encoders on the physical client, as well as the physical server.|content=&lt;br /&gt;
If you only register an encoder for a clientbound packet on the physical server, your mod will likely crash or present unintended behaviour in single-player worlds. ''Forge will happily send packets that have no encoder defined, '''without a warning or error message!''''' They will be encoded as a 256-long byte buffer filled only with null bytes, by default.&lt;br /&gt;
&amp;lt;br&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
== Sending Packets ==&lt;br /&gt;
&lt;br /&gt;
=== Sending to the Server ===&lt;br /&gt;
&lt;br /&gt;
There is but one way to send a packet to the server. This is because there is only ever *one* server the client can be connected to at once. To do so, we must again use that &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;SimpleChannel&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; that was defined earlier. Simply call &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;INSTANCE.sendToServer(new MyMessage())&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. The message will be sent to the handler for its type, if one exists.&lt;br /&gt;
&lt;br /&gt;
=== Sending to Clients ===&lt;br /&gt;
&lt;br /&gt;
Packets can be sent directly to a client using the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;SimpleChannel&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;HANDLER.sendTo(MSG, serverPlayer.connection.getConnection(), NetworkDirection.PLAY_TO_CLIENT)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. However, this can be quite inconvenient. Forge has some convenience functions that can be used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Sending to one player&lt;br /&gt;
INSTANCE.send(PacketDistributor.PLAYER.with(serverPlayer), new MyMessage());&lt;br /&gt;
&lt;br /&gt;
// Send to all players tracking this level chunk&lt;br /&gt;
INSTANCE.send(PacketDistributor.TRACKING_CHUNK.with(levelChunk), new MyMessage());&lt;br /&gt;
&lt;br /&gt;
// Sending to all connected players&lt;br /&gt;
INSTANCE.send(PacketDistributor.ALL.noArg(), new MyMessage());&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are additional &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;PacketDistributor&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; types available, check the documentation on the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;PacketDistributor&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; class for more details.&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Tags&amp;diff=3130</id>
		<title>Tags</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Tags&amp;diff=3130"/>
		<updated>2022-03-22T13:27:32Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: add missing code tag end&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tags are generalized sets of objects in the game, used for grouping related things together and providing fast membership checks.&lt;br /&gt;
&lt;br /&gt;
== Declaring Your Own Groupings ==&lt;br /&gt;
Tags are declared in your mod’s [https://mcforge.readthedocs.io/en/latest/utilities/tags/datapacks.md datapack]. For example, a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;TagKey&amp;lt;Block&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with a given identifier of  &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;modid:foo/tagname&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; will reference a tag at &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;/data/&amp;lt;modid&amp;gt;/tags/blocks/foo/tagname.json&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Tags for &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Item&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;EntityType&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Fluid&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;GameEvent&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s use the plural forms for their folder location while all other registries use the singular version (&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;EntityType&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; uses the folder &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;entity_types&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; while &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Potion&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; would use the folder &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;potion&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;). Similarly, you may append to or override tags declared in other domains, such as Vanilla, by declaring your own JSONs. For example, to add your own mod’s saplings to the Vanilla sapling tag, you would specify it in &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;/data/minecraft/tags/blocks/saplings.json&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, and Vanilla will merge everything into one tag at reload, if the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;replace&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; option is false. If &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;replace&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; is true, then all entries before the json specifying &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;replace&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; will be removed.&lt;br /&gt;
&lt;br /&gt;
Values listed that are not present will cause the tag to error unless the value is listed using an &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;id&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; string and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;required&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; boolean set to false, as in the following example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;replace&amp;quot;: false,&lt;br /&gt;
  &amp;quot;values&amp;quot;: [&lt;br /&gt;
    &amp;quot;minecraft:gold_ingot&amp;quot;,&lt;br /&gt;
    &amp;quot;mymod:my_ingot&amp;quot;,&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;othermod:ingot_other&amp;quot;,&lt;br /&gt;
      &amp;quot;required&amp;quot;: false&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See the [https://minecraft.gamepedia.com/Tag#JSON_format Vanilla wiki] for a description of the base syntax.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There is also a Forge extension on the Vanilla syntax.&lt;br /&gt;
You may declare a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;remove&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; array of the same format as the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;values&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; array. Any values listed here will be removed from the tag. This acts as a finer grained version of the Vanilla &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;replace&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
==Using Tags In Code==&lt;br /&gt;
Tags for all registries are automatically sent from the server to any remote clients on login and reload. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Item&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;EntityType&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Fluid&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;GameEvent&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s are special cased as they have &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Holder&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s allowing for available tags to be accessible through the object itself.&lt;br /&gt;
&lt;br /&gt;
Tags wrappers can be created using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;TagKey#create&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; where the registry the tag should belong to and the tag name are supplied. Some vanilla defined helpers are also available to create wrappers via &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;*Tags#create&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; where &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; refers to the name of the registry object. Forge wrapped registries can create a tag using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ITagManager&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; via &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;IForgeRegistry#tags&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;TagKey&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s can then be obtained via &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ITagManager#createTagKey&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Forge wrapped registry objects can grab their associated holder using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;IForgeRegistry#getHolder&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Additionally, other streamlined operations can be performed using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ITagManager&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Non-Forge registry objects use either &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Registry#getHolder&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Registry#getHolderOrThrow&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; to get the current holder.&lt;br /&gt;
&lt;br /&gt;
They then can compare if the registry object has a tag using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Holder#is&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Tag-holding registry objects contain a method called &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;#is&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; in either their registry object or state-aware class to check whether the object belongs to a certain tag.&lt;br /&gt;
&lt;br /&gt;
As an example: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static final TagKey&amp;lt;Item&amp;gt; myItemTag = ItemTags.create(new ResourceLocation(&amp;quot;mymod&amp;quot;, &amp;quot;myitemgroup&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
public static final TagKey&amp;lt;Potion&amp;gt; myPotionTag = ForgeRegistries.POTIONS.tags().createTagKey(new ResourceLocation(&amp;quot;mymod&amp;quot;, &amp;quot;mypotiongroup&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
public static final TagKey&amp;lt;VillagerType&amp;gt; myVillagerTypeTag = TagKey.create(Registry.VILLAGER_TYPE, new ResourceLocation(&amp;quot;mymod&amp;quot;, &amp;quot;myvillagertypegroup&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
// In some method where stack is an ItemStack&lt;br /&gt;
boolean isInItemGroup = stack.is(myItemTag);&lt;br /&gt;
&lt;br /&gt;
// In some method where potion is a Potion&lt;br /&gt;
boolean isInPotionGroup = ForgeRegistries.POTIONS.tags().getTag(myPotionTag).contains(potion);&lt;br /&gt;
&lt;br /&gt;
// In some method where villagerTypeKey is a ResourceKey&amp;lt;VillagerType&amp;gt;&lt;br /&gt;
boolean isInVillagerTypeGroup = Registry.VILLAGER_TYPE.getHolder(villagerTypeKey).map(holder -&amp;gt; holder.is(myVillagerTypeTag)).orElse(false);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Migration from OreDictionary ==&lt;br /&gt;
* For recipes, tags can be used directly in the vanilla recipe format (see below)&lt;br /&gt;
* For matching items in code, see the section above.&lt;br /&gt;
* If you are declaring a new type of item grouping, follow a couple naming conventions:&lt;br /&gt;
** Use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;domain:type/material&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. When the name is a common one that all modders should adopt, use the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;forge&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; domain.&lt;br /&gt;
** For example, brass ingots should be registered under the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;forge:ingots/brass&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; tag, and cobalt nuggets under the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;forge:nuggets/cobalt&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; tag.&lt;br /&gt;
&lt;br /&gt;
== Using Tags in Recipes and Advancements  ==&lt;br /&gt;
Tags are directly supported by Vanilla, see the respective Vanilla wiki pages for [https://minecraft.gamepedia.com/Recipe#JSON_format recipes] and [https://minecraft.gamepedia.com/Advancements advancements] for usage details.&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
&lt;br /&gt;
There are several conventions that will help facilitate compatibility in the ecosystem: &lt;br /&gt;
   * If there is a Vanilla tag that fits your block or item, add it to that tag. See the [https://minecraft.gamepedia.com/Tag#List_of_tags list of Vanilla tags]. &lt;br /&gt;
   * If there is a Forge tag that fits your block or item, add it to that tag. The list of tags declared by Forge can be seen on [https://github.com/MinecraftForge/MinecraftForge/tree/1.18.x/src/generated/resources/data/forge/tags GitHub]. &lt;br /&gt;
   * If there is a group of something you feel should be shared by the community, consider PR-ing it to Forge instead of making your own tag &lt;br /&gt;
   * Tag naming conventions should follow Vanilla conventions. In particular, item and block groupings are plural instead of singular. E.g. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;minecraft:logs&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;minecraft:saplings&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. &lt;br /&gt;
   * Item tags should be sorted into subdirectories according to the type of item, e.g. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;forge:ingots/iron&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;forge:nuggets/brass&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
=== Forge Tags ===&lt;br /&gt;
&lt;br /&gt;
This is a list of all [https://github.com/MinecraftForge/MinecraftForge/tree/1.18.x/src/generated/resources/data/forge/tags tags] using the &amp;lt;code&amp;gt;forge&amp;lt;/code&amp;gt; namespace that are currently defined by Forge along those that are commonly used by other mods. These can all be found within the [https://github.com/MinecraftForge/MinecraftForge/blob/1.18.x/src/main/java/net/minecraftforge/common/Tags.java &amp;lt;code&amp;gt;Tags&amp;lt;/code&amp;gt;] class.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|Tags that are not officially defined within the Forge codebase will have &amp;lt;code&amp;gt;*&amp;lt;/code&amp;gt; as a suffix. To use those outside the Forge codebase, an &amp;lt;code&amp;gt;IOptionalNamedTag&amp;lt;/code&amp;gt; must be created using &amp;lt;code&amp;gt;*Tags#createOptional&amp;lt;/code&amp;gt; where the asterisk can be replaced by its associated class name.}}&lt;br /&gt;
&lt;br /&gt;
==== Blocks ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Super Tag(s) !! Contains&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:barrels&amp;lt;/code&amp;gt; || None || Barrels&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:barrels/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:barrels&amp;lt;/code&amp;gt; || Wooden barrels&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || None || Chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests/ender&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || Ender chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests/trapped&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || Trapped chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || Wooden chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || None || Cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/normal&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Normal cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/infested&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Infested cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/mossy&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Mossy cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/deepslate&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Deepslate cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:end_stones&amp;lt;/code&amp;gt; || None || End stones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:enderman_place_on_blacklist&amp;lt;/code&amp;gt; || None || Blocks that an enderman cannot place its held block on&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fence_gates&amp;lt;/code&amp;gt; || None || Fence gates&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fence_gates/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:fence_gates&amp;lt;/code&amp;gt; || Wooden fence gates&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fences&amp;lt;/code&amp;gt; || None || Fences&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fences/nether_brick&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:fences&amp;lt;/code&amp;gt; || Nether brick fences&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fences/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:fences&amp;lt;/code&amp;gt; || Wooden fences&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || None || Glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/black&amp;lt;/code&amp;gt; || None || Black glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/blue&amp;lt;/code&amp;gt; || None || Blue glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/brown&amp;lt;/code&amp;gt; || None || Brown glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/colorless&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || Normal glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/cyan&amp;lt;/code&amp;gt; || None || Cyan glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/gray&amp;lt;/code&amp;gt; || None || Gray glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/green&amp;lt;/code&amp;gt; || None || Green glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/light_blue&amp;lt;/code&amp;gt; || None || Light blue glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/light_gray&amp;lt;/code&amp;gt; || None || Light gray glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/lime&amp;lt;/code&amp;gt; || None || Lime glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/magenta&amp;lt;/code&amp;gt; || None || Magenta glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/orange&amp;lt;/code&amp;gt; || None || Orange glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/pink&amp;lt;/code&amp;gt; || None || Pink glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/purple&amp;lt;/code&amp;gt; || None || Purple glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/red&amp;lt;/code&amp;gt; || None || Red glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/silica&amp;lt;/code&amp;gt; || None || Sand-based glass with minor ingredient variation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/tinted&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || Tinted glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/white&amp;lt;/code&amp;gt; || None || White glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/yellow&amp;lt;/code&amp;gt; || None || Yellow glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes&amp;lt;/code&amp;gt; || None || Glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/black&amp;lt;/code&amp;gt; || None || Black glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/blue&amp;lt;/code&amp;gt; || None || Blue glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/brown&amp;lt;/code&amp;gt; || None || Brown glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/colorless&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass_panes&amp;lt;/code&amp;gt; || Normal glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/cyan&amp;lt;/code&amp;gt; || None || Cyan glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/gray&amp;lt;/code&amp;gt; || None || Gray glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/green&amp;lt;/code&amp;gt; || None || Green glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/light_blue&amp;lt;/code&amp;gt; || None || Light blue glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/light_gray&amp;lt;/code&amp;gt; || None || Light gray glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/lime&amp;lt;/code&amp;gt; || None || Lime glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/magenta&amp;lt;/code&amp;gt; || None || Magenta glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/orange&amp;lt;/code&amp;gt; || None || Orange glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/pink&amp;lt;/code&amp;gt; || None || Pink glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/purple&amp;lt;/code&amp;gt; || None || Purple glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/red&amp;lt;/code&amp;gt; || None || Red glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/white&amp;lt;/code&amp;gt; || None || White glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/yellow&amp;lt;/code&amp;gt; || None || Yellow glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gravel&amp;lt;/code&amp;gt; || None || Gravel&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:netherrack&amp;lt;/code&amp;gt; || None || Netherrack&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:obsidian&amp;lt;/code&amp;gt; || None || Obsidian&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_bearing_ground/deepslate&amp;lt;/code&amp;gt; || None || Blocks replaced by deepslate ores during world generation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_bearing_ground/netherrack&amp;lt;/code&amp;gt; || None || Blocks replaced by netherrack ores during world generation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_bearing_ground/stone&amp;lt;/code&amp;gt; || None || Blocks replaced by stone ores during world generation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_rates/dense&amp;lt;/code&amp;gt; || None || Ores which produce numerous resources on average&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_rates/singular&amp;lt;/code&amp;gt; || None || Ores which produce a single resource on average&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_rates/sparse&amp;lt;/code&amp;gt; || None || Ores which produce less than a single resource on average&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || None || Ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/coal&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Coal ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Copper ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/diamond&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Diamond ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/emerald&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Emerald ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Gold ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/lapis&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Lapis ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/netherite_scrap&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Netherite scrap ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/quartz&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Quartz ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/redstone&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Redstone ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores_in_ground/deepslate&amp;lt;/code&amp;gt; || None || Ores which can be found in deepslate&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores_in_ground/netherrack&amp;lt;/code&amp;gt; || None || Ores which can be found in netherrack&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores_in_ground/stone&amp;lt;/code&amp;gt; || None || Ores which can be found in stone&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sand&amp;lt;/code&amp;gt; || None || Sand&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sand/colorless&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:sand&amp;lt;/code&amp;gt; || Normal sand&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sand/red&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:sand&amp;lt;/code&amp;gt; || Red sand&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sandstone&amp;lt;/code&amp;gt; || None || Sandstone&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:stained_glass&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || Stained glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:stained_glass_panes&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass_panes&amp;lt;/code&amp;gt; || Stained glass planes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:stone&amp;lt;/code&amp;gt; || None || Stones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || None || Storage blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/amethyst&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Amethyst blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/coal&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Coal blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Copper blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/diamond&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Diamond blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/emerald&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Emerald blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Gold blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Iron blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/lapis&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Lapis blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/netherite&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Netherite blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/quartz&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Quartz blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/raw_copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Raw copper blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/raw_gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Raw gold blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/raw_iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Raw iron blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/redstone&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Redstone blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:needs_wood_tool&amp;lt;/code&amp;gt; || None || Blocks which need a wooden tool to be mined efficiently&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:needs_gold_tool&amp;lt;/code&amp;gt; || None || Blocks which need a gold tool to be mined efficiently&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:needs_netherite_tool&amp;lt;/code&amp;gt; || None || Blocks which need a netherite tool to be mined efficiently&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Items ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Super Tag(s) !! Contains&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:barrels&amp;lt;/code&amp;gt; || None || Barrels&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:barrels/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:barrels&amp;lt;/code&amp;gt; || Wooden barrels&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:bones&amp;lt;/code&amp;gt; || None || Bones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:bookshelves&amp;lt;/code&amp;gt; || None || Bookshelves&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || None || Chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests/ender&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || Ender chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests/trapped&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || Trapped chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || Wooden chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || None || Cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/normal&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Normal cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/infested&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Infested cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/mossy&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Mossy cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/deepslate&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Deepslate cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:crops&amp;lt;/code&amp;gt; || None || Crops&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:crops/beetroot&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:crops&amp;lt;/code&amp;gt; || Beetroot crops&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:crops/carrot&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:crops&amp;lt;/code&amp;gt; || Carrot crops&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:crops/nether_wart&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:crops&amp;lt;/code&amp;gt; || Nether wart crops&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:crops/potato&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:crops&amp;lt;/code&amp;gt;  || Potato crops&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:crops/wheat&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:crops&amp;lt;/code&amp;gt; || Wheat crops&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dusts&amp;lt;/code&amp;gt; || None || Dusts&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dusts/prismarine&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dusts&amp;lt;/code&amp;gt; || Prismarine dusts&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dusts/redstone&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dusts&amp;lt;/code&amp;gt; || Redstone dusts&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dusts/glowstone&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dusts&amp;lt;/code&amp;gt; || Glowstone dusts&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || None || Dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/black&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Black dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/blue&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Blue dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/brown&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Brown dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/cyan&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Cyan dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/gray&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Gray dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/green&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Green dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/light_blue&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt;  || Light blue dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/light_gray&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Light green dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/lime&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt;  || Lime dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/magenta&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Magenta dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/orange&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Orange dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/pink&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Pink dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/purple&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Purple dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/red&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Red dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/white&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || White dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/yellow&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Yellow dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:eggs&amp;lt;/code&amp;gt; || None || Eggs&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:enchanting_fuels&amp;lt;/code&amp;gt; || None || Enchantment table fuels&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:end_stones&amp;lt;/code&amp;gt; || None || End stones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ender_pearls&amp;lt;/code&amp;gt; || None || Ender pearls&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:feathers&amp;lt;/code&amp;gt; || None || Feathers&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fence_gates&amp;lt;/code&amp;gt; || None || Fence gates&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fence_gates/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:fence_gates&amp;lt;/code&amp;gt; || Wooden fence gates&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fences&amp;lt;/code&amp;gt; || None || Fences&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fences/nether_brick&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:fences&amp;lt;/code&amp;gt; || Nether brick fences&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fences/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:fences&amp;lt;/code&amp;gt; || Wooden fences&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; || None || Gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems/amethyst&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; || Amethyst gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems/diamond&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; || Diamond gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems/emerald&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; || Emerald gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems/lapis&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;forge:enchanting_fuels&amp;lt;/code&amp;gt; || Lapis gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems/prismarine&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; || Prismarine gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems/quartz&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; || Quartz gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || None || Glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/black&amp;lt;/code&amp;gt; || None || Black glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/blue&amp;lt;/code&amp;gt; || None || Blue glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/brown&amp;lt;/code&amp;gt; || None || Brown glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/colorless&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || Normal glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/cyan&amp;lt;/code&amp;gt; || None || Cyan glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/gray&amp;lt;/code&amp;gt; || None || Gray glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/green&amp;lt;/code&amp;gt; || None || Green glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/light_blue&amp;lt;/code&amp;gt; || None || Light blue glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/light_gray&amp;lt;/code&amp;gt; || None || Light gray glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/lime&amp;lt;/code&amp;gt; || None || Lime glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/magenta&amp;lt;/code&amp;gt; || None || Magenta glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/orange&amp;lt;/code&amp;gt; || None || Orange glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/pink&amp;lt;/code&amp;gt; || None || Pink glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/purple&amp;lt;/code&amp;gt; || None || Purple glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/red&amp;lt;/code&amp;gt; || None || Red glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/silica&amp;lt;/code&amp;gt; || None || Sand-based glass with minor ingredient variation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/tinted&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || Tinted glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/white&amp;lt;/code&amp;gt; || None || White glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/yellow&amp;lt;/code&amp;gt; || None || Yellow glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes&amp;lt;/code&amp;gt; || None || Glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/black&amp;lt;/code&amp;gt; || None || Black glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/blue&amp;lt;/code&amp;gt; || None || Blue glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/brown&amp;lt;/code&amp;gt; || None || Brown glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/colorless&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass_panes&amp;lt;/code&amp;gt; || Normal glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/cyan&amp;lt;/code&amp;gt; || None || Cyan glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/gray&amp;lt;/code&amp;gt; || None || Gray glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/green&amp;lt;/code&amp;gt; || None || Green glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/light_blue&amp;lt;/code&amp;gt; || None || Light blue glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/light_gray&amp;lt;/code&amp;gt; || None || Light gray glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/lime&amp;lt;/code&amp;gt; || None || Lime glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/magenta&amp;lt;/code&amp;gt; || None || Magenta glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/orange&amp;lt;/code&amp;gt; || None || Orange glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/pink&amp;lt;/code&amp;gt; || None || Pink glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/purple&amp;lt;/code&amp;gt; || None || Purple glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/red&amp;lt;/code&amp;gt; || None || Red glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/white&amp;lt;/code&amp;gt; || None || White glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/yellow&amp;lt;/code&amp;gt; || None || Yellow glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gravel&amp;lt;/code&amp;gt; || None || Gravel&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gunpowder&amp;lt;/code&amp;gt; || None || Gunpowder&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:heads&amp;lt;/code&amp;gt; || None || Heads&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || None || Ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots/brick&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || Brick ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots/copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || Copper ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || Gold ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots/iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || Iron ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots/netherite&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || Netherite ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots/nether_brick&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || Nether brick ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:leather&amp;lt;/code&amp;gt; || None || Leather&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:mushrooms&amp;lt;/code&amp;gt; || None || Mushrooms&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:nether_stars&amp;lt;/code&amp;gt; || None || Nether stars&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:netherrack&amp;lt;/code&amp;gt; || None || Netherrack&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:nuggets&amp;lt;/code&amp;gt; || None || Nuggets&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:nuggets/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:nuggets&amp;lt;/code&amp;gt; || Gold nuggets&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:nuggets/iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:nuggets&amp;lt;/code&amp;gt; || Iron nuggets&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:obsidian&amp;lt;/code&amp;gt; || None || Obsidian&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_bearing_ground/deepslate&amp;lt;/code&amp;gt; || None || Blocks replaced by deepslate ores during world generation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_bearing_ground/netherrack&amp;lt;/code&amp;gt; || None || Blocks replaced by netherrack ores during world generation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_bearing_ground/stone&amp;lt;/code&amp;gt; || None || Blocks replaced by stone ores during world generation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_rates/dense&amp;lt;/code&amp;gt; || None || Ores which produce numerous resources on average&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_rates/singular&amp;lt;/code&amp;gt; || None || Ores which produce a single resource on average&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_rates/sparse&amp;lt;/code&amp;gt; || None || Ores which produce less than a single resource on average&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || None || Ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/coal&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Coal ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Copper ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/diamond&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Diamond ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/emerald&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Emerald ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Gold ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/lapis&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Lapis ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/netherite_scrap&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Netherite scrap ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/quartz&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Quartz ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/redstone&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Redstone ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores_in_ground/deepslate&amp;lt;/code&amp;gt; || None || Ores which can be found in deepslate&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores_in_ground/netherrack&amp;lt;/code&amp;gt; || None || Ores which can be found in netherrack&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores_in_ground/stone&amp;lt;/code&amp;gt; || None || Ores which can be found in stone&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:raw_materials&amp;lt;/code&amp;gt; || None || Raw materials&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:raw_materials/copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:raw_materials&amp;lt;/code&amp;gt; || Copper raw materials&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:raw_materials/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:raw_materials&amp;lt;/code&amp;gt; || Gold raw materials&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:raw_materials/iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:raw_materials&amp;lt;/code&amp;gt; || Iron raw materials&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:rods&amp;lt;/code&amp;gt; || None || Rods&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:rods/blaze&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:rods&amp;lt;/code&amp;gt; || Blaze rods&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:rods/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:rods&amp;lt;/code&amp;gt; || Wooden rods&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sand&amp;lt;/code&amp;gt; || None || Sand&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sand/colorless&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:sand&amp;lt;/code&amp;gt; || Normal sand&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sand/red&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:sand&amp;lt;/code&amp;gt; || Red sand&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sandstone&amp;lt;/code&amp;gt; || None || Sandstone&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:seeds&amp;lt;/code&amp;gt; || None || Seeds&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:seeds/beetroot&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:seeds&amp;lt;/code&amp;gt; || Beetroot seeds&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:seeds/melon&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:seeds&amp;lt;/code&amp;gt; || Melon seeds&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:seeds/pumpkin&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:seeds&amp;lt;/code&amp;gt; || Pumpkin seeds&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:seeds/wheat&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:seeds&amp;lt;/code&amp;gt; || Wheat seeds&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:shears&amp;lt;/code&amp;gt; || None || Shears&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:slimeballs&amp;lt;/code&amp;gt; || None || Slimeballs&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:stained_glass&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || Stained glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:stained_glass_panes&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass_panes&amp;lt;/code&amp;gt; || Stained glass planes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:stone&amp;lt;/code&amp;gt; || None || Stones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || None || Storage blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/amethyst&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Amethyst blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/coal&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Coal blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Copper blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/diamond&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Diamond blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/emerald&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Emerald blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Gold blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Iron blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/lapis&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Lapis blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/netherite&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Netherite blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/quartz&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Quartz blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/raw_copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Raw copper blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/raw_gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Raw gold blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/raw_iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Raw iron blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/redstone&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Redstone blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:string&amp;lt;/code&amp;gt; || None || String&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Fluids ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Super Tag(s) !! Contains&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:milk&amp;lt;/code&amp;gt; || None || Milk&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:Resources and Data]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Tags&amp;diff=3129</id>
		<title>Tags</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Tags&amp;diff=3129"/>
		<updated>2022-03-22T13:26:57Z</updated>

		<summary type="html">&lt;p&gt;ChampionAsh5357: Happy now Shrimp? ITagManager is included&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tags are generalized sets of objects in the game, used for grouping related things together and providing fast membership checks.&lt;br /&gt;
&lt;br /&gt;
== Declaring Your Own Groupings ==&lt;br /&gt;
Tags are declared in your mod’s [https://mcforge.readthedocs.io/en/latest/utilities/tags/datapacks.md datapack]. For example, a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;TagKey&amp;lt;Block&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; with a given identifier of  &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;modid:foo/tagname&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; will reference a tag at &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;/data/&amp;lt;modid&amp;gt;/tags/blocks/foo/tagname.json&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Tags for &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Item&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;EntityType&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Fluid&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;GameEvent&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s use the plural forms for their folder location while all other registries use the singular version (&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;EntityType&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; uses the folder &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;entity_types&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; while &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Potion&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; would use the folder &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;potion&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;). Similarly, you may append to or override tags declared in other domains, such as Vanilla, by declaring your own JSONs. For example, to add your own mod’s saplings to the Vanilla sapling tag, you would specify it in &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;/data/minecraft/tags/blocks/saplings.json&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, and Vanilla will merge everything into one tag at reload, if the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;replace&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; option is false. If &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;replace&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; is true, then all entries before the json specifying &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;replace&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; will be removed.&lt;br /&gt;
&lt;br /&gt;
Values listed that are not present will cause the tag to error unless the value is listed using an &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;id&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; string and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;required&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; boolean set to false, as in the following example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;replace&amp;quot;: false,&lt;br /&gt;
  &amp;quot;values&amp;quot;: [&lt;br /&gt;
    &amp;quot;minecraft:gold_ingot&amp;quot;,&lt;br /&gt;
    &amp;quot;mymod:my_ingot&amp;quot;,&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;othermod:ingot_other&amp;quot;,&lt;br /&gt;
      &amp;quot;required&amp;quot;: false&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See the [https://minecraft.gamepedia.com/Tag#JSON_format Vanilla wiki] for a description of the base syntax.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There is also a Forge extension on the Vanilla syntax.&lt;br /&gt;
You may declare a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;remove&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; array of the same format as the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;values&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; array. Any values listed here will be removed from the tag. This acts as a finer grained version of the Vanilla &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;replace&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; option.&lt;br /&gt;
&lt;br /&gt;
==Using Tags In Code==&lt;br /&gt;
Tags for all registries are automatically sent from the server to any remote clients on login and reload. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Item&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;EntityType&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Fluid&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s, and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;GameEvent&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s are special cased as they have &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Holder&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s allowing for available tags to be accessible through the object itself.&lt;br /&gt;
&lt;br /&gt;
Tags wrappers can be created using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;TagKey#create&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; where the registry the tag should belong to and the tag name are supplied. Some vanilla defined helpers are also available to create wrappers via &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;*Tags#create&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; where &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; refers to the name of the registry object. Forge wrapped registries can create a tag using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ITagManager&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; via &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;IForgeRegistry#tags&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;TagKey&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s can then be obtained via &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ITagManager#createTagKey&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Forge wrapped registry objects can grab their associated holder using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;IForgeRegistry#getHolder&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Additionally, other streamlined operations can be performed using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ITagManager&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Non-Forge registry objects use either &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Registry#getHolder&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Registry#getHolderOrThrow&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; to get the current holder.&lt;br /&gt;
&lt;br /&gt;
They then can compare if the registry object has a tag using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Holder#is&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Tag-holding registry objects contain a method called &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;#is&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; in either their registry object or state-aware class to check whether the object belongs to a certain tag.&lt;br /&gt;
&lt;br /&gt;
As an example: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static final TagKey&amp;lt;Item&amp;gt; myItemTag = ItemTags.create(new ResourceLocation(&amp;quot;mymod&amp;quot;, &amp;quot;myitemgroup&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
public static final TagKey&amp;lt;Potion&amp;gt; myPotionTag = ForgeRegistries.POTIONS.tags().createTagKey(new ResourceLocation(&amp;quot;mymod&amp;quot;, &amp;quot;mypotiongroup&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
public static final TagKey&amp;lt;VillagerType&amp;gt; myVillagerTypeTag = TagKey.create(Registry.VILLAGER_TYPE, new ResourceLocation(&amp;quot;mymod&amp;quot;, &amp;quot;myvillagertypegroup&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
// In some method where stack is an ItemStack&lt;br /&gt;
boolean isInItemGroup = stack.is(myItemTag);&lt;br /&gt;
&lt;br /&gt;
// In some method where potion is a Potion&lt;br /&gt;
boolean isInPotionGroup = ForgeRegistries.POTIONS.tags().getTag(myPotionTag).contains(potion);&lt;br /&gt;
&lt;br /&gt;
// In some method where villagerTypeKey is a ResourceKey&amp;lt;VillagerType&amp;gt;&lt;br /&gt;
boolean isInVillagerTypeGroup = Registry.VILLAGER_TYPE.getHolder(villagerTypeKey).map(holder -&amp;gt; holder.is(myVillagerTypeTag)).orElse(false);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Migration from OreDictionary ==&lt;br /&gt;
* For recipes, tags can be used directly in the vanilla recipe format (see below)&lt;br /&gt;
* For matching items in code, see the section above.&lt;br /&gt;
* If you are declaring a new type of item grouping, follow a couple naming conventions:&lt;br /&gt;
** Use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;domain:type/material&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. When the name is a common one that all modders should adopt, use the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;forge&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; domain.&lt;br /&gt;
** For example, brass ingots should be registered under the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;forge:ingots/brass&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; tag, and cobalt nuggets under the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;forge:nuggets/cobalt&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; tag.&lt;br /&gt;
&lt;br /&gt;
== Using Tags in Recipes and Advancements  ==&lt;br /&gt;
Tags are directly supported by Vanilla, see the respective Vanilla wiki pages for [https://minecraft.gamepedia.com/Recipe#JSON_format recipes] and [https://minecraft.gamepedia.com/Advancements advancements] for usage details.&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
&lt;br /&gt;
There are several conventions that will help facilitate compatibility in the ecosystem: &lt;br /&gt;
   * If there is a Vanilla tag that fits your block or item, add it to that tag. See the [https://minecraft.gamepedia.com/Tag#List_of_tags list of Vanilla tags]. &lt;br /&gt;
   * If there is a Forge tag that fits your block or item, add it to that tag. The list of tags declared by Forge can be seen on [https://github.com/MinecraftForge/MinecraftForge/tree/1.18.x/src/generated/resources/data/forge/tags GitHub]. &lt;br /&gt;
   * If there is a group of something you feel should be shared by the community, consider PR-ing it to Forge instead of making your own tag &lt;br /&gt;
   * Tag naming conventions should follow Vanilla conventions. In particular, item and block groupings are plural instead of singular. E.g. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;minecraft:logs&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;minecraft:saplings&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. &lt;br /&gt;
   * Item tags should be sorted into subdirectories according to the type of item, e.g. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;forge:ingots/iron&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;forge:nuggets/brass&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
=== Forge Tags ===&lt;br /&gt;
&lt;br /&gt;
This is a list of all [https://github.com/MinecraftForge/MinecraftForge/tree/1.18.x/src/generated/resources/data/forge/tags tags] using the &amp;lt;code&amp;gt;forge&amp;lt;/code&amp;gt; namespace that are currently defined by Forge along those that are commonly used by other mods. These can all be found within the [https://github.com/MinecraftForge/MinecraftForge/blob/1.18.x/src/main/java/net/minecraftforge/common/Tags.java &amp;lt;code&amp;gt;Tags&amp;lt;/code&amp;gt;] class.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|Tags that are not officially defined within the Forge codebase will have &amp;lt;code&amp;gt;*&amp;lt;/code&amp;gt; as a suffix. To use those outside the Forge codebase, an &amp;lt;code&amp;gt;IOptionalNamedTag&amp;lt;/code&amp;gt; must be created using &amp;lt;code&amp;gt;*Tags#createOptional&amp;lt;/code&amp;gt; where the asterisk can be replaced by its associated class name.}}&lt;br /&gt;
&lt;br /&gt;
==== Blocks ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Super Tag(s) !! Contains&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:barrels&amp;lt;/code&amp;gt; || None || Barrels&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:barrels/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:barrels&amp;lt;/code&amp;gt; || Wooden barrels&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || None || Chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests/ender&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || Ender chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests/trapped&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || Trapped chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || Wooden chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || None || Cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/normal&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Normal cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/infested&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Infested cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/mossy&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Mossy cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/deepslate&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Deepslate cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:end_stones&amp;lt;/code&amp;gt; || None || End stones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:enderman_place_on_blacklist&amp;lt;/code&amp;gt; || None || Blocks that an enderman cannot place its held block on&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fence_gates&amp;lt;/code&amp;gt; || None || Fence gates&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fence_gates/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:fence_gates&amp;lt;/code&amp;gt; || Wooden fence gates&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fences&amp;lt;/code&amp;gt; || None || Fences&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fences/nether_brick&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:fences&amp;lt;/code&amp;gt; || Nether brick fences&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fences/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:fences&amp;lt;/code&amp;gt; || Wooden fences&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || None || Glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/black&amp;lt;/code&amp;gt; || None || Black glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/blue&amp;lt;/code&amp;gt; || None || Blue glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/brown&amp;lt;/code&amp;gt; || None || Brown glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/colorless&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || Normal glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/cyan&amp;lt;/code&amp;gt; || None || Cyan glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/gray&amp;lt;/code&amp;gt; || None || Gray glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/green&amp;lt;/code&amp;gt; || None || Green glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/light_blue&amp;lt;/code&amp;gt; || None || Light blue glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/light_gray&amp;lt;/code&amp;gt; || None || Light gray glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/lime&amp;lt;/code&amp;gt; || None || Lime glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/magenta&amp;lt;/code&amp;gt; || None || Magenta glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/orange&amp;lt;/code&amp;gt; || None || Orange glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/pink&amp;lt;/code&amp;gt; || None || Pink glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/purple&amp;lt;/code&amp;gt; || None || Purple glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/red&amp;lt;/code&amp;gt; || None || Red glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/silica&amp;lt;/code&amp;gt; || None || Sand-based glass with minor ingredient variation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/tinted&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || Tinted glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/white&amp;lt;/code&amp;gt; || None || White glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/yellow&amp;lt;/code&amp;gt; || None || Yellow glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes&amp;lt;/code&amp;gt; || None || Glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/black&amp;lt;/code&amp;gt; || None || Black glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/blue&amp;lt;/code&amp;gt; || None || Blue glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/brown&amp;lt;/code&amp;gt; || None || Brown glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/colorless&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass_panes&amp;lt;/code&amp;gt; || Normal glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/cyan&amp;lt;/code&amp;gt; || None || Cyan glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/gray&amp;lt;/code&amp;gt; || None || Gray glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/green&amp;lt;/code&amp;gt; || None || Green glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/light_blue&amp;lt;/code&amp;gt; || None || Light blue glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/light_gray&amp;lt;/code&amp;gt; || None || Light gray glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/lime&amp;lt;/code&amp;gt; || None || Lime glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/magenta&amp;lt;/code&amp;gt; || None || Magenta glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/orange&amp;lt;/code&amp;gt; || None || Orange glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/pink&amp;lt;/code&amp;gt; || None || Pink glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/purple&amp;lt;/code&amp;gt; || None || Purple glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/red&amp;lt;/code&amp;gt; || None || Red glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/white&amp;lt;/code&amp;gt; || None || White glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/yellow&amp;lt;/code&amp;gt; || None || Yellow glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gravel&amp;lt;/code&amp;gt; || None || Gravel&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:netherrack&amp;lt;/code&amp;gt; || None || Netherrack&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:obsidian&amp;lt;/code&amp;gt; || None || Obsidian&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_bearing_ground/deepslate&amp;lt;/code&amp;gt; || None || Blocks replaced by deepslate ores during world generation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_bearing_ground/netherrack&amp;lt;/code&amp;gt; || None || Blocks replaced by netherrack ores during world generation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_bearing_ground/stone&amp;lt;/code&amp;gt; || None || Blocks replaced by stone ores during world generation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_rates/dense&amp;lt;/code&amp;gt; || None || Ores which produce numerous resources on average&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_rates/singular&amp;lt;/code&amp;gt; || None || Ores which produce a single resource on average&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_rates/sparse&amp;lt;/code&amp;gt; || None || Ores which produce less than a single resource on average&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || None || Ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/coal&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Coal ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Copper ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/diamond&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Diamond ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/emerald&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Emerald ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Gold ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/lapis&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Lapis ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/netherite_scrap&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Netherite scrap ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/quartz&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Quartz ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/redstone&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Redstone ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores_in_ground/deepslate&amp;lt;/code&amp;gt; || None || Ores which can be found in deepslate&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores_in_ground/netherrack&amp;lt;/code&amp;gt; || None || Ores which can be found in netherrack&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores_in_ground/stone&amp;lt;/code&amp;gt; || None || Ores which can be found in stone&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sand&amp;lt;/code&amp;gt; || None || Sand&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sand/colorless&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:sand&amp;lt;/code&amp;gt; || Normal sand&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sand/red&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:sand&amp;lt;/code&amp;gt; || Red sand&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sandstone&amp;lt;/code&amp;gt; || None || Sandstone&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:stained_glass&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || Stained glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:stained_glass_panes&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass_panes&amp;lt;/code&amp;gt; || Stained glass planes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:stone&amp;lt;/code&amp;gt; || None || Stones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || None || Storage blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/amethyst&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Amethyst blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/coal&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Coal blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Copper blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/diamond&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Diamond blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/emerald&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Emerald blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Gold blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Iron blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/lapis&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Lapis blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/netherite&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Netherite blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/quartz&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Quartz blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/raw_copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Raw copper blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/raw_gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Raw gold blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/raw_iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Raw iron blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/redstone&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Redstone blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:needs_wood_tool&amp;lt;/code&amp;gt; || None || Blocks which need a wooden tool to be mined efficiently&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:needs_gold_tool&amp;lt;/code&amp;gt; || None || Blocks which need a gold tool to be mined efficiently&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:needs_netherite_tool&amp;lt;/code&amp;gt; || None || Blocks which need a netherite tool to be mined efficiently&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Items ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Super Tag(s) !! Contains&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:barrels&amp;lt;/code&amp;gt; || None || Barrels&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:barrels/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:barrels&amp;lt;/code&amp;gt; || Wooden barrels&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:bones&amp;lt;/code&amp;gt; || None || Bones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:bookshelves&amp;lt;/code&amp;gt; || None || Bookshelves&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || None || Chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests/ender&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || Ender chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests/trapped&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || Trapped chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:chests/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:chests&amp;lt;/code&amp;gt; || Wooden chests&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || None || Cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/normal&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Normal cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/infested&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Infested cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/mossy&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Mossy cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:cobblestone/deepslate&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:cobblestone&amp;lt;/code&amp;gt; || Deepslate cobblestones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:crops&amp;lt;/code&amp;gt; || None || Crops&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:crops/beetroot&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:crops&amp;lt;/code&amp;gt; || Beetroot crops&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:crops/carrot&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:crops&amp;lt;/code&amp;gt; || Carrot crops&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:crops/nether_wart&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:crops&amp;lt;/code&amp;gt; || Nether wart crops&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:crops/potato&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:crops&amp;lt;/code&amp;gt;  || Potato crops&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:crops/wheat&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:crops&amp;lt;/code&amp;gt; || Wheat crops&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dusts&amp;lt;/code&amp;gt; || None || Dusts&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dusts/prismarine&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dusts&amp;lt;/code&amp;gt; || Prismarine dusts&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dusts/redstone&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dusts&amp;lt;/code&amp;gt; || Redstone dusts&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dusts/glowstone&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dusts&amp;lt;/code&amp;gt; || Glowstone dusts&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || None || Dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/black&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Black dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/blue&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Blue dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/brown&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Brown dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/cyan&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Cyan dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/gray&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Gray dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/green&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Green dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/light_blue&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt;  || Light blue dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/light_gray&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Light green dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/lime&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt;  || Lime dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/magenta&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Magenta dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/orange&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Orange dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/pink&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Pink dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/purple&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Purple dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/red&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Red dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/white&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || White dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:dyes/yellow&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:dyes&amp;lt;/code&amp;gt; || Yellow dyes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:eggs&amp;lt;/code&amp;gt; || None || Eggs&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:enchanting_fuels&amp;lt;/code&amp;gt; || None || Enchantment table fuels&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:end_stones&amp;lt;/code&amp;gt; || None || End stones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ender_pearls&amp;lt;/code&amp;gt; || None || Ender pearls&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:feathers&amp;lt;/code&amp;gt; || None || Feathers&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fence_gates&amp;lt;/code&amp;gt; || None || Fence gates&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fence_gates/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:fence_gates&amp;lt;/code&amp;gt; || Wooden fence gates&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fences&amp;lt;/code&amp;gt; || None || Fences&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fences/nether_brick&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:fences&amp;lt;/code&amp;gt; || Nether brick fences&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:fences/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:fences&amp;lt;/code&amp;gt; || Wooden fences&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; || None || Gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems/amethyst&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; || Amethyst gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems/diamond&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; || Diamond gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems/emerald&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; || Emerald gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems/lapis&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;forge:enchanting_fuels&amp;lt;/code&amp;gt; || Lapis gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems/prismarine&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; || Prismarine gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gems/quartz&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:gems&amp;lt;/code&amp;gt; || Quartz gems&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || None || Glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/black&amp;lt;/code&amp;gt; || None || Black glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/blue&amp;lt;/code&amp;gt; || None || Blue glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/brown&amp;lt;/code&amp;gt; || None || Brown glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/colorless&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || Normal glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/cyan&amp;lt;/code&amp;gt; || None || Cyan glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/gray&amp;lt;/code&amp;gt; || None || Gray glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/green&amp;lt;/code&amp;gt; || None || Green glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/light_blue&amp;lt;/code&amp;gt; || None || Light blue glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/light_gray&amp;lt;/code&amp;gt; || None || Light gray glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/lime&amp;lt;/code&amp;gt; || None || Lime glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/magenta&amp;lt;/code&amp;gt; || None || Magenta glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/orange&amp;lt;/code&amp;gt; || None || Orange glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/pink&amp;lt;/code&amp;gt; || None || Pink glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/purple&amp;lt;/code&amp;gt; || None || Purple glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/red&amp;lt;/code&amp;gt; || None || Red glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/silica&amp;lt;/code&amp;gt; || None || Sand-based glass with minor ingredient variation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/tinted&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || Tinted glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/white&amp;lt;/code&amp;gt; || None || White glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass/yellow&amp;lt;/code&amp;gt; || None || Yellow glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes&amp;lt;/code&amp;gt; || None || Glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/black&amp;lt;/code&amp;gt; || None || Black glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/blue&amp;lt;/code&amp;gt; || None || Blue glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/brown&amp;lt;/code&amp;gt; || None || Brown glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/colorless&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass_panes&amp;lt;/code&amp;gt; || Normal glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/cyan&amp;lt;/code&amp;gt; || None || Cyan glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/gray&amp;lt;/code&amp;gt; || None || Gray glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/green&amp;lt;/code&amp;gt; || None || Green glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/light_blue&amp;lt;/code&amp;gt; || None || Light blue glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/light_gray&amp;lt;/code&amp;gt; || None || Light gray glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/lime&amp;lt;/code&amp;gt; || None || Lime glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/magenta&amp;lt;/code&amp;gt; || None || Magenta glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/orange&amp;lt;/code&amp;gt; || None || Orange glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/pink&amp;lt;/code&amp;gt; || None || Pink glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/purple&amp;lt;/code&amp;gt; || None || Purple glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/red&amp;lt;/code&amp;gt; || None || Red glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/white&amp;lt;/code&amp;gt; || None || White glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:glass_panes/yellow&amp;lt;/code&amp;gt; || None || Yellow glass panes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gravel&amp;lt;/code&amp;gt; || None || Gravel&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:gunpowder&amp;lt;/code&amp;gt; || None || Gunpowder&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:heads&amp;lt;/code&amp;gt; || None || Heads&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || None || Ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots/brick&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || Brick ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots/copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || Copper ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || Gold ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots/iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || Iron ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots/netherite&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || Netherite ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ingots/nether_brick&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ingots&amp;lt;/code&amp;gt; || Nether brick ingots&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:leather&amp;lt;/code&amp;gt; || None || Leather&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:mushrooms&amp;lt;/code&amp;gt; || None || Mushrooms&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:nether_stars&amp;lt;/code&amp;gt; || None || Nether stars&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:netherrack&amp;lt;/code&amp;gt; || None || Netherrack&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:nuggets&amp;lt;/code&amp;gt; || None || Nuggets&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:nuggets/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:nuggets&amp;lt;/code&amp;gt; || Gold nuggets&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:nuggets/iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:nuggets&amp;lt;/code&amp;gt; || Iron nuggets&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:obsidian&amp;lt;/code&amp;gt; || None || Obsidian&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_bearing_ground/deepslate&amp;lt;/code&amp;gt; || None || Blocks replaced by deepslate ores during world generation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_bearing_ground/netherrack&amp;lt;/code&amp;gt; || None || Blocks replaced by netherrack ores during world generation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_bearing_ground/stone&amp;lt;/code&amp;gt; || None || Blocks replaced by stone ores during world generation&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_rates/dense&amp;lt;/code&amp;gt; || None || Ores which produce numerous resources on average&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_rates/singular&amp;lt;/code&amp;gt; || None || Ores which produce a single resource on average&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ore_rates/sparse&amp;lt;/code&amp;gt; || None || Ores which produce less than a single resource on average&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || None || Ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/coal&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Coal ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Copper ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/diamond&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Diamond ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/emerald&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Emerald ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Gold ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/lapis&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Lapis ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/netherite_scrap&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Netherite scrap ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/quartz&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Quartz ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores/redstone&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:ores&amp;lt;/code&amp;gt; || Redstone ores&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores_in_ground/deepslate&amp;lt;/code&amp;gt; || None || Ores which can be found in deepslate&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores_in_ground/netherrack&amp;lt;/code&amp;gt; || None || Ores which can be found in netherrack&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:ores_in_ground/stone&amp;lt;/code&amp;gt; || None || Ores which can be found in stone&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:raw_materials&amp;lt;/code&amp;gt; || None || Raw materials&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:raw_materials/copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:raw_materials&amp;lt;/code&amp;gt; || Copper raw materials&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:raw_materials/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:raw_materials&amp;lt;/code&amp;gt; || Gold raw materials&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:raw_materials/iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:raw_materials&amp;lt;/code&amp;gt; || Iron raw materials&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:rods&amp;lt;/code&amp;gt; || None || Rods&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:rods/blaze&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:rods&amp;lt;/code&amp;gt; || Blaze rods&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:rods/wooden&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:rods&amp;lt;/code&amp;gt; || Wooden rods&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sand&amp;lt;/code&amp;gt; || None || Sand&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sand/colorless&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:sand&amp;lt;/code&amp;gt; || Normal sand&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sand/red&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:sand&amp;lt;/code&amp;gt; || Red sand&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:sandstone&amp;lt;/code&amp;gt; || None || Sandstone&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:seeds&amp;lt;/code&amp;gt; || None || Seeds&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:seeds/beetroot&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:seeds&amp;lt;/code&amp;gt; || Beetroot seeds&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:seeds/melon&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:seeds&amp;lt;/code&amp;gt; || Melon seeds&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:seeds/pumpkin&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:seeds&amp;lt;/code&amp;gt; || Pumpkin seeds&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:seeds/wheat&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:seeds&amp;lt;/code&amp;gt; || Wheat seeds&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:shears&amp;lt;/code&amp;gt; || None || Shears&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:slimeballs&amp;lt;/code&amp;gt; || None || Slimeballs&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:stained_glass&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass&amp;lt;/code&amp;gt; || Stained glass&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:stained_glass_panes&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:glass_panes&amp;lt;/code&amp;gt; || Stained glass planes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:stone&amp;lt;/code&amp;gt; || None || Stones&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || None || Storage blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/amethyst&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Amethyst blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/coal&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Coal blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Copper blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/diamond&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Diamond blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/emerald&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Emerald blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Gold blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Iron blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/lapis&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Lapis blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/netherite&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Netherite blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/quartz&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Quartz blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/raw_copper&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Raw copper blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/raw_gold&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Raw gold blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/raw_iron&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Raw iron blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:storage_blocks/redstone&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;forge:storage_blocks&amp;lt;/code&amp;gt; || Redstone blocks&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:string&amp;lt;/code&amp;gt; || None || String&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Fluids ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Super Tag(s) !! Contains&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;forge:milk&amp;lt;/code&amp;gt; || None || Milk&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:Resources and Data]]&lt;/div&gt;</summary>
		<author><name>ChampionAsh5357</name></author>
	</entry>
</feed>