<?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=ShrimpBot</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=ShrimpBot"/>
	<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/wiki/Special:Contributions/ShrimpBot"/>
	<updated>2026-06-02T05:24:24Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.0</generator>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=World_Saved_Data/1.18&amp;diff=3246</id>
		<title>World Saved Data/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=World_Saved_Data/1.18&amp;diff=3246"/>
		<updated>2022-06-10T07:46:34Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy World Saved Data to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Saved Data/1.18|Saved Data]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Version_Checker/1.18&amp;diff=3245</id>
		<title>Version Checker/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Version_Checker/1.18&amp;diff=3245"/>
		<updated>2022-06-10T07:46:32Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Version Checker to MC1.18 archive&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/1.18|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 unmodifiable fields:&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>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Using_Tile_Entity_Renderers/1.18&amp;diff=3244</id>
		<title>Using Tile Entity Renderers/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Using_Tile_Entity_Renderers/1.18&amp;diff=3244"/>
		<updated>2022-06-10T07:46:30Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Using Tile Entity Renderers to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Tile Entity Renderer/1.18|Tile Entity Renderer]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Using_SimpleChannel/1.18&amp;diff=3243</id>
		<title>Using SimpleChannel/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Using_SimpleChannel/1.18&amp;diff=3243"/>
		<updated>2022-06-10T07:46:29Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Using SimpleChannel to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[SimpleChannel/1.18|SimpleChannel]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Using_Resources/1.18&amp;diff=3242</id>
		<title>Using Resources/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Using_Resources/1.18&amp;diff=3242"/>
		<updated>2022-06-10T07:46:27Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Using Resources to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Resources/1.18|Resources]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Resources and Data/1.18|Category:Resources and Data]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Using_PacketBuffer/1.18&amp;diff=3241</id>
		<title>Using PacketBuffer/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Using_PacketBuffer/1.18&amp;diff=3241"/>
		<updated>2022-06-10T07:46:25Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Using PacketBuffer to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Using FriendlyByteBuf/1.18|Using FriendlyByteBuf]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Using_NBT/1.18&amp;diff=3240</id>
		<title>Using NBT/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Using_NBT/1.18&amp;diff=3240"/>
		<updated>2022-06-10T07:46:23Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Using NBT to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Named Binary Tag/1.18|Named Binary Tag]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Using_FriendlyByteBuf/1.18&amp;diff=3239</id>
		<title>Using FriendlyByteBuf/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Using_FriendlyByteBuf/1.18&amp;diff=3239"/>
		<updated>2022-06-10T07:46:22Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Using FriendlyByteBuf to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;FriendlyByteBuf&amp;lt;/code&amp;gt;s are essentially a byte array of zero or more bytes to sync information across a network. It works similarly to a queue: the information is written in to a specific order and read in the order it was written.&lt;br /&gt;
&lt;br /&gt;
== Using &amp;lt;code&amp;gt;FriendlyByteBuf&amp;lt;/code&amp;gt;s ==&lt;br /&gt;
&lt;br /&gt;
In most cases, one will use a premade &amp;lt;code&amp;gt;FriendlyByteBuf&amp;lt;/code&amp;gt; passed in from some network. Most of the time this is a heap buffer of some sort; however, understanding how it works is best left as an explanation of data structures.&lt;br /&gt;
&lt;br /&gt;
When you are '''writing''' to a &amp;lt;code&amp;gt;FriendlyByteBuf&amp;lt;/code&amp;gt;, you are calling one of the many write functions to store information as bytes (e.g. &amp;lt;code&amp;gt;writeBlockPos&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;writeVarInt&amp;lt;/code&amp;gt;). There are a couple of helpers for objects like &amp;lt;code&amp;gt;CompoundTag&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ItemStack&amp;lt;/code&amp;gt;s, etc. if they are needed.&lt;br /&gt;
&lt;br /&gt;
When you are '''reading''' from a &amp;lt;code&amp;gt;FriendlyByteBuf&amp;lt;/code&amp;gt;, you are calling the equivalent read function in the same order. For example, if you call &amp;lt;code&amp;gt;writeBlockPos&amp;lt;/code&amp;gt; and then &amp;lt;code&amp;gt;writeVarInt&amp;lt;/code&amp;gt;, you would call &amp;lt;code&amp;gt;readBlockPos&amp;lt;/code&amp;gt; and then &amp;lt;code&amp;gt;readVarInt&amp;lt;/code&amp;gt; in that order. Each of these method returns the value from the buffer.&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Update_Checker/1.18&amp;diff=3238</id>
		<title>Update Checker/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Update_Checker/1.18&amp;diff=3238"/>
		<updated>2022-06-10T07:46:20Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Update Checker to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Version Checker/1.18|Version Checker]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Beginner Topics/1.18|Category:Beginner Topics]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Understanding_Networking/1.18&amp;diff=3237</id>
		<title>Understanding Networking/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Understanding_Networking/1.18&amp;diff=3237"/>
		<updated>2022-06-10T07:46:18Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Understanding Networking to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Networking/1.18|Networking]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Understanding_Blockstates/1.18&amp;diff=3236</id>
		<title>Understanding Blockstates/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Understanding_Blockstates/1.18&amp;diff=3236"/>
		<updated>2022-06-10T07:46:16Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Understanding Blockstates to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[BlockStates/1.18|BlockStates]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Blocks/1.18|Category:Blocks]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Toolchain:Magic_Constants/1.18&amp;diff=3235</id>
		<title>Toolchain:Magic Constants/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Toolchain:Magic_Constants/1.18&amp;diff=3235"/>
		<updated>2022-06-10T07:46:15Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Toolchain:Magic Constants to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Toolchain/Magic Constants/1.18|Toolchain/Magic Constants]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Toolchain/Retro/2.1/1.18&amp;diff=3234</id>
		<title>Toolchain/Retro/2.1/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Toolchain/Retro/2.1/1.18&amp;diff=3234"/>
		<updated>2022-06-10T07:46:13Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Toolchain/Retro/2.1 to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Deobfuscation Process}}&lt;br /&gt;
{{Under construction}}&lt;br /&gt;
&lt;br /&gt;
The Forge toolchain is designed to clean up, merge, deobfuscate, rename, patch and provide the Minecraft source code for the usage of modders, researchers, or just those curious about how the game works.&lt;br /&gt;
&lt;br /&gt;
This serves as an explanation as to how the development environment sets up your code, and aims to help you troubleshoot in case something goes wrong.&lt;br /&gt;
&lt;br /&gt;
== Overall process ==&lt;br /&gt;
When setting up the environment for the first time, a gradle refresh triggers three things:&lt;br /&gt;
# ForgeGradle downloads the MCPConfig zip for the file you're using, and triggers the SetupMCP task.&lt;br /&gt;
# After that, it processes the jar - applies access transformers, MCPCleanup and others&lt;br /&gt;
# Finally, it patches and finalises the code, ready for modder consumption.&lt;br /&gt;
&lt;br /&gt;
== Needed knowledge ==&lt;br /&gt;
=== Obfuscation ===&lt;br /&gt;
'''Obfuscation''' is the process of renaming all of the fields, methods, and classes of the compiled code into unreadable, machine-generated names (such as &amp;lt;code&amp;gt;aaa&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;bC&amp;lt;/code&amp;gt;), and removing package structures (this makes everything package-local and makes the obfuscated code smaller somewhat. This is commonly used by companies to prevent external entities from easily decompiling their released binaries/executables and retrieving their source code/intellectual property, though it does have size advantages.&lt;br /&gt;
&lt;br /&gt;
Additionally, due to the way the Local Variable Table (LVT) of Java bytecode is stored, every function-local variable name is turned to &amp;lt;code&amp;gt;☃&amp;lt;/code&amp;gt; (that's right, a snowman) in the compiled files. This makes immediate recompilation of the game literally and physically impossible, as every Java compiler currently available requires that local variables have unique names.&lt;br /&gt;
&lt;br /&gt;
Minecraft is a commercial game, which means the source code is unavailable to all except the developers of Mojang. To prevent piracy and the copying of their intellectual property, Mojang applies this obfuscation process to the game before they release it. They use a tool called [https://www.guardsquare.com/en/products/proguard ProGuard], which is both an optimizer&amp;lt;ref&amp;gt;An optimizer is a program that removes redundant/unused instructions and compacts the code to be faster and smaller.&amp;lt;/ref&amp;gt; and an obfuscator.&lt;br /&gt;
&lt;br /&gt;
=== Problematic Naming ===&lt;br /&gt;
There are a few big problems with using these obfuscated names directly for modding.&lt;br /&gt;
&lt;br /&gt;
# It is incredibly difficult to create mods using these obfuscated names. It requires immense patience to reverse-engineer the meanings behind each and every name, and to keep relating those names to what was already reverse-engineered. Although, tools do exist to make this process easier, such as IntelliJ IDEA plugins that provide naming hints automatically.&lt;br /&gt;
# Because the obfuscation process takes place after compilation (the obfuscator operates on the compiled classes), the obfuscated names are not handled by the compiler. Thus, obfuscated classes may contain member&amp;lt;ref&amp;gt;'''member''' refers to class fields and methods.&amp;lt;/ref&amp;gt; names that are invalid in the Java source language, but valid in compiled bytecode (like ☃ discussed earlier); this means that the decompiled source of the game is not immediately recompilable.&lt;br /&gt;
# These obfuscated names are automatically generated by the obfuscator for each independent release. This means that the obfuscated names may change signficantly between any two versions, making it harder for mod developers to update mods between releases.&lt;br /&gt;
&lt;br /&gt;
=== SRGification ===&lt;br /&gt;
Some background on what SRG is and how it works:&lt;br /&gt;
&lt;br /&gt;
'''SRG''' stands for '''S'''earge's '''R'''etro '''G'''uard; RetroGuard being an early attempt to reverse the ProGuard obfuscation, and Searge being co-author of the Mod Coder Pack or MCP&amp;lt;ref&amp;gt;This was previously called the ''Minecraft Coder Pack''&amp;lt;/ref&amp;gt;, who created this process.&lt;br /&gt;
Each obfuscated class, method, and field is assigned a unique number by the [[Toolchain:MCPConfig/1.18|backend]], via a sequential counter. This unique number is called the '''SRG ID''' of that class/method/field (henceforth called member).&lt;br /&gt;
&lt;br /&gt;
The SRG name of the member is then derived from its SRG ID, its type (function {given the prefix &amp;lt;code&amp;gt;func_&amp;lt;/code&amp;gt;}, field {given the prefix &amp;lt;code&amp;gt;field_&amp;lt;/code&amp;gt;}, or parameter {given the prefix &amp;lt;code&amp;gt;p_&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;p_i&amp;lt;/code&amp;gt; if this is the parameter of a constructor}), and (optionally) the obfuscated name of the object at the time it was given its SRG name&amp;lt;ref&amp;gt;The SRG name for a given member is only created once, when it first appears in the code. Therefore, the SRG postfix may be different from the current obf name.&amp;lt;/ref&amp;gt;. This inclusion of the SRG ID into the name guarantees that the SRG name for all members are unique, and is the reason the ID is generated.&lt;br /&gt;
&lt;br /&gt;
The actual conversion of obf names to SRG names is done by a tool called [[Toolchain:SpecialSource/1.18|SpecialSource]]. More information on how it works can be found on that page.&lt;br /&gt;
&lt;br /&gt;
== The Setup ==&lt;br /&gt;
The process can be broken up into 3 steps; MCPConfig, patch and provide.&lt;br /&gt;
The MCPConfig step is, understandably, the biggest and most prone to failure.&lt;br /&gt;
An explanation of MCPConfig itself, how it works, what it's for (but NOT how to use it) can be found [[Toolchain:MCPConfig/1.18|here]]. For the purpose of this guide, you need only know that its' goal is to get the game decompiled, and into a state where it can immediately be recompiled. Due to certain flaws in the rest of the toolchain, this means it needs to fix and patch the source code before passing it onto Forge.&lt;br /&gt;
&lt;br /&gt;
In this way, MCPConfig can be thought of the vanilla side of the setup. It does not modify the game.&lt;br /&gt;
&lt;br /&gt;
The following steps are all executed in order of appearance.&lt;br /&gt;
&lt;br /&gt;
=== Download and parsing MCPConfig ===&lt;br /&gt;
The first thing that ForgeGradle does upon initialising a first-time setup, is starting the [https://github.com/MinecraftForge/ForgeGradle/blob/e2ed49546abced95650635f81be071441ec60995/src/mcp/java/net/minecraftforge/gradle/mcp/task/SetupMCPTask.java#L91 SetupMCP] task. &lt;br /&gt;
&lt;br /&gt;
This task then seeks to [https://github.com/MinecraftForge/ForgeGradle/blob/e2ed49546abced95650635f81be071441ec60995/src/mcp/java/net/minecraftforge/gradle/mcp/task/DownloadMCPConfigTask.java#L78 download the MCPConfig.zip jar] for the version you're setting up.&lt;br /&gt;
Once it is acquired, it &lt;br /&gt;
[https://github.com/MinecraftForge/ForgeGradle/blob/e2ed49546abced95650635f81be071441ec60995/src/mcp/java/net/minecraftforge/gradle/mcp/util/MCPRuntime.java#L74 parses the steps contained within the config.json]. It does this by interpreting the file with the following rules:&lt;br /&gt;
* Every key, except for libraries, is interpreted as the name of a step.&lt;br /&gt;
* Steps are executed in order.&lt;br /&gt;
* The version value is interpreted as a maven coordinate of a file to download.&lt;br /&gt;
* If there is a repo value, it is used instead of the maven repositories defined in the buildscript, to retrieve the version.&lt;br /&gt;
* The args array is parsed, and {values} like this are interpreted as inputs, which can be substituted accordingly.&lt;br /&gt;
* Once the step is all parsed in, it is executed:&lt;br /&gt;
** java -jar &amp;amp;lt;version&amp;amp;gt; &amp;amp;lt;args&amp;amp;gt; &amp;amp;lt;jvmArgs&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
An example config.json can be found [https://github.com/MinecraftForge/MCPConfig/blob/master/versions/release/1.16.4/config.json here].&lt;br /&gt;
&lt;br /&gt;
It defines the steps:&lt;br /&gt;
* [[Toolchain:MCinjector/1.18|mcinjector]]&lt;br /&gt;
** version: de.oceanlabs.mcp:mcinjector:3.8.0:fatjar&lt;br /&gt;
** args: --in {input} --out {output} --log {log} --level=INFO --lvt=LVT --exc {exceptions} --acc {access} --ctr {constructors}&lt;br /&gt;
* [[Toolchain:ForgeFlower/1.18|fernflower]]&lt;br /&gt;
** version: net.minecraftforge:forgeflower:1.5.478.16&lt;br /&gt;
** args: -din=1 -rbr=1 -dgs=1 -asc=1 -rsy=1 -iec=1 -jvn=1 -isl=0 -iib=1 -log=TRACE -cfg {libraries} {input} {output}&lt;br /&gt;
** jvmargs: -Xmx4G&lt;br /&gt;
* [[Toolchain:Mergetool/1.18|merge]]&lt;br /&gt;
** version: net.minecraftforge:mergetool:1.1.1:fatjar&lt;br /&gt;
** args: --client {client} --server {server} --ann {version} --output {output} --inject false&amp;quot;&lt;br /&gt;
* [[Toolchain:MCInjector/1.18|rename]]&lt;br /&gt;
** version: net.md-5:SpecialSource:1.8.3:shaded&lt;br /&gt;
** args: --in-jar {input} --out-jar {output} --srg-in {mappings}&lt;br /&gt;
** repo: https://repo1.maven.org/maven2/&lt;br /&gt;
&lt;br /&gt;
More information about each of these tools can be found at the link provided, as well as what each of these arguments do. A brief description is provided.&lt;br /&gt;
&lt;br /&gt;
=== MCInjector ===&lt;br /&gt;
[https://github.com/ModCoderPack/MCInjector MCInjector] is the tool we use to apply various fixes to the code, while it is still in bytecode form. That meaning, it works on compiled code, not sourcecode. It does this because it's easier to rename LVT entries (from the snowman) to readable names while you can search for every other code path that references that specific entry; ergo renaming all accesses at once. This is impossible in sourcecode, where every name is identical and string matching is impossible.&lt;br /&gt;
&lt;br /&gt;
It:&lt;br /&gt;
* Removes synthetic parameters from constructors&lt;br /&gt;
** In bytecode, inner classes have the outer class as their first constructor parameter, but Java source code does not.&lt;br /&gt;
* Handles adding annotations for parameters that have synthetic data&lt;br /&gt;
** In bytecode, these Nonnull (or whatever) annotations are attached to the parameters, not to the function that contains them.&lt;br /&gt;
* Adds constructors for inner classes&lt;br /&gt;
** These are removed by Proguard sometimes, as they are not required in the bytecode if the parent has a default constructor.&lt;br /&gt;
* Adds synthetic (invisible) constructors for classes without them&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It also applies fixes for things like EXC;&lt;br /&gt;
* Renaming parameters inside constructors, such that subclasses retain the ID of their parent.&lt;br /&gt;
* Fixing access for select functions, where it is required for the proper recompilation.&lt;br /&gt;
* Applying proper typing to constructor parameters&lt;br /&gt;
* Applying proper external (LWJGL) exception data to functions and classes.&lt;br /&gt;
&lt;br /&gt;
Note that it does NOT rename to SRG. LVT (Local Variables) are renamed to lvt_&amp;amp;lt;index&amp;amp;gt;_&amp;amp;lt;version&amp;amp;gt;&amp;lt;ref&amp;gt;Index means: the place where this item was found. If it is the 4th entry in the table, it is index 3.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ForgeFlower === &lt;br /&gt;
After the code has been cleaned up by MCInjector, to a state where it no longer conflicts with itself, it can be passed to the decompiler. &lt;br /&gt;
&lt;br /&gt;
The decompiler used by ForgeGradle is a custom fork of [https://github.com/JetBrains/intellij-community/tree/master/plugins/java-decompiler/engine Jetbrains' FernFlower], called [https://github.com/MinecraftForge/ForgeFlower ForgeFlower].&lt;br /&gt;
&lt;br /&gt;
It simply searches the jar for files, converts the bytecode into a reasonable best-guess interpretation.&lt;br /&gt;
&lt;br /&gt;
As you can see by the repository, a lot of work has gone into tuning it for Minecraft's needs, but it is still a far way from perfect. This is why the patches are needed.&lt;br /&gt;
&lt;br /&gt;
If you [https://github.com/MinecraftForge/MCPConfig/blob/master/versions/release/1.16.4/patches/ look at the patches] for 1.16.4, they are mostly incredibly simple changes. Adding generics, making types more strict. &lt;br /&gt;
&lt;br /&gt;
This is all stuff that should be done by the decompiler, and PRs are always welcome at the ForgeFlower repository for changes and fixes that would reduce the amount of MCPConfig patches required to get the game to compile.&lt;br /&gt;
&lt;br /&gt;
For now, it is a necessity.&lt;br /&gt;
&lt;br /&gt;
=== Mergetool ===&lt;br /&gt;
The game is split into two distributions; server and client.&lt;br /&gt;
&lt;br /&gt;
Because the server contains no rendering code, and the client contains none of the server-specific code (like the UI), this means there are differences between what can run on one side or the other.&lt;br /&gt;
&lt;br /&gt;
To get around this, we have a tool called Mergetool, which can search for the differences between two files (down to the function level) and merge them into one large (referred to as joined) jar file.&lt;br /&gt;
&lt;br /&gt;
It is a simple program, but it works.&lt;br /&gt;
&lt;br /&gt;
=== SpecialSource ===&lt;br /&gt;
SpecialSource is where SRG starts to come into play. It serves the role of our deobfuscator, performing deobfuscation.&lt;br /&gt;
&lt;br /&gt;
This process is done with the help of a '''deobfusation map''', a file generated by the original obfuscator (in this case, ProGuard) that contains a map of the obfuscated names to original, non-obfuscated names. This is commonly used on debofuscating stack traces outputted by an obfuscated program, for debugging purposes.&amp;lt;ref name=&amp;quot;retrace&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have three sets of deobfuscation maps available to us; the obf-&amp;gt;SRG mappings distributed with the MCPConfig system, the Yarn intermediary system, or the offical mappings.&amp;lt;ref name=&amp;quot;mojmappings&amp;quot;/&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rectify this problem, Forge has it's own process to create deobfuscation mappings for the game, using community-sourced human-readable names. This process is split into two separate parts: the '''SRG renaming''', and the '''MCP mapping'''. During the SetupMCP task, only the SRG renaming is performed.&lt;br /&gt;
&lt;br /&gt;
SpecialSource itself operates on the source jar, as can be gathered by the name, and takes in a .tsrg file, like that [https://github.com/MinecraftForge/MCPConfig/blob/master/versions/release/1.16.4/joined.tsrg contained in the MCPConfig zip].&lt;br /&gt;
&lt;br /&gt;
It first renames classes, straight into MCP names.&lt;br /&gt;
Then, iterating the members of the class, it renames fields, methods, parameters and inner classes.&lt;br /&gt;
&lt;br /&gt;
A recap from earlier:&lt;br /&gt;
* For classes -&amp;gt; &amp;lt;code&amp;gt;c_###_&amp;lt;/code&amp;gt; (but it is immediately changed without the c_ being written to disk)&lt;br /&gt;
* For functions/methods -&amp;gt; &amp;lt;code&amp;gt;func_&amp;amp;lt;ID&amp;amp;gt;_&amp;amp;lt;obf-name&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* For fields -&amp;gt; &amp;lt;code&amp;gt;field_&amp;amp;lt;ID&amp;amp;gt;_&amp;amp;lt;obf-name&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* For function/method parameters -&amp;gt; &amp;lt;code&amp;gt;p_###_#_&amp;lt;/code&amp;gt; for normal methods, &amp;lt;code&amp;gt;p_i###_#&amp;lt;/code&amp;gt; for constructors; the second number is the index&amp;lt;ref&amp;gt;The index is the position of the argument. 0 on the left, 1 after that, 2 after that. Note that double and long arguments increase their index by two, rather than one.&amp;lt;/ref&amp;gt; of the parameter.&lt;br /&gt;
&lt;br /&gt;
For example, &amp;lt;code&amp;gt;func_71410_x&amp;lt;/code&amp;gt; refers to a function with SRG ID 71410 and original obfuscated name of &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt;.&amp;lt;ref&amp;gt;For version 1.16.2, &amp;lt;code&amp;gt;func_71410_x&amp;lt;/code&amp;gt; refers to &amp;lt;code&amp;gt;Minecraft.getInstance()&amp;lt;/code&amp;gt;, with real obfuscated name of &amp;lt;code&amp;gt;B&amp;lt;/code&amp;gt;, but when the getInstance() function was first discovered in code, it was called x.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, combined with the MCInjector step from earlier, we have a completely SRGed-up source jar.&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
Once we have the source code ready to go, the final step in the setup is to apply patches.&lt;br /&gt;
These are done trivially, using diffs and [https://github.com/CadixDev/gitpatcher gitpatcher].&lt;br /&gt;
&lt;br /&gt;
=== Clean-up ===&lt;br /&gt;
Because of the way Proguard (or whatever obfuscator) and ForgeFlower mangle the source code, we need to take some steps to clean it up before we can proceed.&lt;br /&gt;
&lt;br /&gt;
Assorted cleanup fixes are performed by the [https://github.com/MinecraftForge/MCPCleanup/ MCPCleanup] utility. These include:&lt;br /&gt;
* removing trailing whitespace at the end of lines&lt;br /&gt;
* removing extra newlines at the start and end of files&lt;br /&gt;
* removing extra newlines between every line of code (every set of concurrent newlines is replaced with a single)&lt;br /&gt;
* removing comments (// hello, /* hello */)&lt;br /&gt;
** the purpose of this step is unclear - it seems to be a preventative measure to ensure that Java changes do not interfere with the patch alignment in the future. Comments from the decompiler are still sometimes present in the source code.&lt;br /&gt;
* removing imports from the package a class is in&lt;br /&gt;
* removing comments that include the phrase &amp;lt;code&amp;gt;GL_[^*]+&amp;lt;/code&amp;gt;&lt;br /&gt;
* replacing [[Toolchain:Magic Constants/1.18|magic constants]] with their code substitutions&lt;br /&gt;
* replacing &amp;lt;code&amp;gt;Character.valueOf(&amp;amp;lt;character&amp;amp;gt;)&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;&amp;amp;lt;character&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* replacing OpenGL integer constants with their code representation&lt;br /&gt;
* converting unicode character constants back into integer representation&lt;br /&gt;
* formatting the code with JAStyle&lt;br /&gt;
&lt;br /&gt;
It also adjusts abstract functions in some way - after running the program on a jar, the parameters of a default abstract function get renamed, but it is unclear exactly what part of the source code does this.&lt;br /&gt;
&lt;br /&gt;
== The Forge Side ==&lt;br /&gt;
&lt;br /&gt;
After the MCPConfig/SetupMCP tasks are finished, ForgeGradle will print '''MCP Environment Setup is complete''' and wait for the user input.&lt;br /&gt;
&lt;br /&gt;
The next step is to run the &amp;lt;code&amp;gt;gradlew setup&amp;lt;/code&amp;gt; task, which does what it implies: Applying the Forge system to the processed vanilla code.&lt;br /&gt;
&lt;br /&gt;
First, it applies ATs. After that, patches. Finally, MCP/Crowdsourced mappings are applied.&lt;br /&gt;
&lt;br /&gt;
All in all, compared to the MCPConfig setup, this is a string of extremely basic tasks - mostly just one-line commands.&lt;br /&gt;
&lt;br /&gt;
=== Applying Access Transformers ===&lt;br /&gt;
&lt;br /&gt;
[[Access Transformers/1.18|Access Transformers]] are a way of changing the visibility and finality of classes and class members. A full explanation of how it works, what the specification is, and what exactly they're used for, can be found at that page.&lt;br /&gt;
&lt;br /&gt;
They are applied by passing the AT Config (nowadays called accesstransformer.cfg) into SpecialSource:&lt;br /&gt;
* &amp;lt;code&amp;gt;SpecialSource.jar --in-jar {input} --out-jar {output} --access-transformer {at.cfg}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/MinecraftForge/MinecraftForge/blob/c3e84646db70f518dd0b37a8fcfc42cb814d7ba8/src/main/resources/META-INF/accesstransformer.cfg The current AT cfg can be found here.]&lt;br /&gt;
&lt;br /&gt;
=== Applying Patches ===&lt;br /&gt;
&lt;br /&gt;
The patches used for Forge itself are different from those used by MCPConfig, which means there are two separate patching stages performed.&lt;br /&gt;
&lt;br /&gt;
As opposed to the minimal MCPConfig patching, with the goal to make the code recompileable, the Forge patching is done to apply the API and modloader to the code.&lt;br /&gt;
&lt;br /&gt;
It does this in a very similar way, with the [https://github.com/CadixDev/gitpatcher gitpatcher] utility.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Applying Mappings ===&lt;br /&gt;
This step isn't strictly necessary, and it can be ommitted. However, working with exclusively SRG names is confusing for most people, so we have an extra step to apply human names to the SRG.&lt;br /&gt;
&lt;br /&gt;
These renames can come from any source; as mentioned earlier, the MCP/Crowdsourced naming, the Yarn naming, or the Mojang Obf-map naming. ForgeGradle does not care, as long as there is a valid SRG-&amp;gt;names map.&lt;br /&gt;
&lt;br /&gt;
How ForgeGradle retrieves these mappings is covered in the [[ForgeGradle/mappings/1.18|appropriate article]].&lt;br /&gt;
&lt;br /&gt;
The process of renaming itself is a simple regex substitution, performed by [https://github.com/MinecraftForge/ForgeGradle/blob/e2ed49546abced95650635f81be071441ec60995/src/common/java/net/minecraftforge/gradle/common/util/McpNames.java#L104 ForgeGradle itself]. This is made possible by the assured uniqueness of SRG names.&lt;br /&gt;
&lt;br /&gt;
=== Post-processing ===&lt;br /&gt;
&lt;br /&gt;
At this point, the files are ready to go. We have processed the Minecraft jar such that it can be recompiled, we have applied appropriate access transformers and the Forge patches, and optionally renamed every applicable SRG name to whatever chosen distribution of mappings.&lt;br /&gt;
&lt;br /&gt;
There is not much left to do but package the code into a jar file, and place it into the gradle cache (so that this process does not occur every single time the project is opened). It calculates this name based on many factors, and this is covered in the [[ForgeGradle#naming/1.18|naming]] article.&lt;br /&gt;
&lt;br /&gt;
== Some additional Infos ==&lt;br /&gt;
# You will never see c_XXX_ for classes, because the class names are picked beforehand&lt;br /&gt;
#* this is still crowdsourced, but before a new version is ready for Forge, all classes are given an &amp;lt;code&amp;gt;MCP&amp;lt;/code&amp;gt; name&lt;br /&gt;
#* this &amp;lt;code&amp;gt;MCP&amp;lt;/code&amp;gt; name stays constant throughout the game version it was picked for; it can change between versions, but it usually wont for already-named classes (except for misspells, typos, and misnames)&lt;br /&gt;
# If you look into the JAR, you won't see any packages for the obfuscated classes, but the deobfuscated classes do have the packages, this is because the same process that names the classes, also decides what package they belong to&lt;br /&gt;
# parameters have special names&lt;br /&gt;
#* there are two types of parameter names: &amp;lt;code&amp;gt;p_XXX_X_&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;p_iXXX_X_&amp;lt;/code&amp;gt;&lt;br /&gt;
#* the one with the i means that it's a parameter for a constructor&lt;br /&gt;
#* the first set of numbers are the SRG ID of their parent method, and the second number denotes the index of the parameter&lt;br /&gt;
#* the index of the parameter is a bit more involved, but this will not be explained here&lt;br /&gt;
# If you look into the source, you'll see that parameters for lambdas don't have mapped names&lt;br /&gt;
#* This is because of a complication in how the lambdas are compiled/decompiled; it's a more advanced topic which involves how the compiler compiles lambdas which we will not explain here.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Obfuscation_(software) Obfuscation]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;retrace&amp;quot;&amp;gt;For ProGuard users (such as Mojang), this is done using [https://www.guardsquare.com/en/products/proguard/manual/retrace ReTrace].&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;mojmappings&amp;quot;&amp;gt;Mojang recently released their deobfuscation mappings for Minecraft (colloquially named &amp;lt;code&amp;gt;mojmappings&amp;lt;/code&amp;gt;), but the licensing for its uses is a bit ambiguous. [https://cpw.github.io/MinecraftMappingData See this post by cpw] for more information.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Toolchain/Magic_Constants/1.18&amp;diff=3233</id>
		<title>Toolchain/Magic Constants/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Toolchain/Magic_Constants/1.18&amp;diff=3233"/>
		<updated>2022-06-10T07:46:11Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Toolchain/Magic Constants to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The [[Toolchain:MCPCleanup/1.18|Toolchain:MCPCleanup]] utility has many functions, one among them is to convert known constants into code representation for easier visualisation.&lt;br /&gt;
&lt;br /&gt;
== Constants ==&lt;br /&gt;
&lt;br /&gt;
The known substitutions are:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;1.7976[0-9]*[Ee]+308[Dd]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Double.MAX_VALUE&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;3.1415[0-9]*[Dd]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;Math.PI&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;3.1415[0-9]*[Ff]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;(float)Math.PI&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;6.2831[0-9]*[Dd]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;(Math.PI * 2D)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;6.2831[0-9]*[Ff]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;((float)Math.PI * 2F)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;4.7123[0-9]*[Dd]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;(Math.PI * 3D / 2D)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;4.7123[0-9]*[Ff]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;((float)Math.PI * 3F / 2F)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;0.7853[0-9]*[Dd]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;(Math.PI / 4D)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;0.7853[0-9]*[Ff]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;((float)Math.PI / 4F)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;6.2831[0-9]*[Ff]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;((float)Math.PI * 2F)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;0.6283[0-9]*[Dd]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;(Math.PI / 5D)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;0.6283[0-9]*[Ff]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;((float)Math.PI / 5F)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;57.295[0-9]*[Dd]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;(180D / Math.PI)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;57.295[0-9]*[Ff]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;(180F / (float)Math.PI)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;0.6981[0-9]*[Dd]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;(Math.PI * 2D / 9D)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;0.6981[0-9]*[Ff]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;((float)Math.PI * 2F / 9F)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;0.3141[0-9]*[Dd]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;(Math.PI / 10D)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;0.3141[0-9]*[Ff]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;((float)Math.PI / 10F)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;1.2566[0-9]*[Dd]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;(Math.PI * 2D / 5D)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;1.2566[0-9]*[Ff]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;((float)Math.PI 2F / 5F)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;0.21991[0-9]*[Dd]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;(Math.PI * 7D / 100D)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;0.21991[0-9]*[Ff]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;((float)Math.PI * 7F / 100F)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;5.8119[0-9]*[Dd]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;(Math.PI * 185D / 100D)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;0.8119[0-9]*[Ff]&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;((float)Math.PI * 185F / 100F)&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Toolchain/1.18&amp;diff=3232</id>
		<title>Toolchain/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Toolchain/1.18&amp;diff=3232"/>
		<updated>2022-06-10T07:46:09Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Toolchain to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Deobfuscation Process}}&lt;br /&gt;
{{Under construction}}&lt;br /&gt;
&lt;br /&gt;
The Forge toolchain is designed to clean up, merge, deobfuscate, rename, patch and provide the Minecraft source code for the usage of modders, researchers, or just those curious about how the game works.&lt;br /&gt;
&lt;br /&gt;
This serves as an explanation as to how the development environment sets up your code, and aims to help you troubleshoot in case something goes wrong.&lt;br /&gt;
&lt;br /&gt;
== Overall process ==&lt;br /&gt;
Whenever a gradle refresh is triggered, a few things occur:&lt;br /&gt;
# ForgeGradle downloads the jar and MCPConfig zip and triggers the extractSrg/createSrgToMcp task.&lt;br /&gt;
# After that, it processes the jar - applies access transformers from forge/userdev, SAS from forge, and decompiles.&lt;br /&gt;
# Finally, it patches and finalizes the code, ready for modder consumption.&lt;br /&gt;
&lt;br /&gt;
This is triggered whenever the &amp;lt;code&amp;gt;setup&amp;lt;/code&amp;gt; task is ran.&lt;br /&gt;
&lt;br /&gt;
== Needed knowledge ==&lt;br /&gt;
=== Obfuscation ===&lt;br /&gt;
'''Obfuscation''' is the process of renaming all of the fields, methods, and classes of the compiled code into unreadable, machine-generated names (such as &amp;lt;code&amp;gt;aaa&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;bC&amp;lt;/code&amp;gt;), and removing package structures (this makes everything package-local and makes the obfuscated code smaller somewhat. This is commonly used by companies to prevent external entities from easily decompiling their released binaries/executables and retrieving their source code/intellectual property.&lt;br /&gt;
&lt;br /&gt;
Additionally, due to the way the Local Variable Table (LVT) of Java bytecode is stored, every function-local variable name is turned to &amp;lt;code&amp;gt;☃&amp;lt;/code&amp;gt; (that's right, a snowman) in the compiled files. This makes immediate recompilation of the game literally and physically impossible, as every Java compiler currently available requires that local variables have unique names.&lt;br /&gt;
&lt;br /&gt;
Minecraft is a commercial game, which means the source code is unavailable to all except the developers of Mojang. To prevent piracy and the copying of their intellectual property, Mojang applies this obfuscation process to the game before they release it. They use a tool called [https://www.guardsquare.com/en/products/proguard ProGuard], which is both an optimizer&amp;lt;ref&amp;gt;An optimizer is a program that removes redundant/unused instructions and compacts the code to be faster and smaller.&amp;lt;/ref&amp;gt; and an obfuscator.&lt;br /&gt;
&lt;br /&gt;
=== Problematic Naming ===&lt;br /&gt;
There are a few big problems with using these obfuscated names directly for modding.&lt;br /&gt;
&lt;br /&gt;
# It is incredibly difficult to create mods using these obfuscated names. It requires immense patience to reverse-engineer the meanings behind each and every name, and to keep relating those names to what was already reverse-engineered. Although, tools do exist to make this process easier, such as IntelliJ IDEA plugins that provide naming hints automatically.&lt;br /&gt;
# Because the obfuscation process takes place after compilation (the obfuscator operates on the compiled classes), the obfuscated names are not handled by the compiler. Thus, obfuscated classes may contain member&amp;lt;ref&amp;gt;'''member''' refers to class fields and methods.&amp;lt;/ref&amp;gt; names that are invalid in the Java source language, but valid in compiled bytecode (like ☃ discussed earlier); this means that the decompiled source of the game is not immediately recompilable.&lt;br /&gt;
# These obfuscated names are automatically generated by the obfuscator for each independent release. This means that the obfuscated names may change significantly between any two versions, making it harder for mod developers to update mods between releases.&lt;br /&gt;
&lt;br /&gt;
=== SRGification ===&lt;br /&gt;
Some background on what SRG is and how it works:&lt;br /&gt;
&lt;br /&gt;
'''SRG''' stands for '''S'''earge's '''R'''etro '''G'''uard; RetroGuard being an early attempt to reverse the ProGuard obfuscation, and Searge being co-author of the Mod Coder Pack or MCP&amp;lt;ref&amp;gt;This was previously called the ''Minecraft Coder Pack''&amp;lt;/ref&amp;gt;, who created this process.&lt;br /&gt;
Each obfuscated class, method, and field is assigned a unique number by the [[Toolchain:MCPConfig/1.18|backend]], via a sequential counter. This unique number is called the '''SRG ID''' of that class/method/field (henceforth called member).&lt;br /&gt;
&lt;br /&gt;
The SRG name of the member is then derived from its SRG ID and its type (method {given the prefix &amp;lt;code&amp;gt;m_&amp;lt;/code&amp;gt;}, field {given the prefix &amp;lt;code&amp;gt;f_&amp;lt;/code&amp;gt;}, or parameter {given the prefix &amp;lt;code&amp;gt;p_&amp;lt;/code&amp;gt;}). &amp;lt;ref&amp;gt;The SRG name for a given member is only created once, when it first appears in the code.&amp;lt;/ref&amp;gt;. This inclusion of the SRG ID into the name guarantees that the SRG name for all members are unique, and is the reason the ID is generated.&lt;br /&gt;
&lt;br /&gt;
The actual conversion of obf names to SRG names is done by a tool called [[Toolchain#Vignette/1.18|Vignette]]. More information on how it works can be found on that page.&lt;br /&gt;
&lt;br /&gt;
== The Setup ==&lt;br /&gt;
The process can be broken up into 3 steps; MCPConfig, patch and provide.&lt;br /&gt;
The MCPConfig step is, understandably, the biggest and most prone to failure.&lt;br /&gt;
An explanation of MCPConfig itself, how it works, what it's for (but NOT how to use it) can be found [[Toolchain:MCPConfig/1.18|here]]. For the purpose of this guide, you need only know that its' goal is to get the game decompiled, and into a state where it can immediately be recompiled. This means it needs to fix and patch the source code before passing it onto Forge.&lt;br /&gt;
&lt;br /&gt;
In this way, MCPConfig can be thought of the vanilla side of the setup. It does not modify the game.&lt;br /&gt;
&lt;br /&gt;
The following steps are all executed in order of appearance.&lt;br /&gt;
&lt;br /&gt;
=== Download and parsing MCPConfig ===&lt;br /&gt;
The first thing that ForgeGradle does upon initializing a first-time setup, is starting the [https://github.com/MinecraftForge/ForgeGradle/blob/a0d2d1f488b3285ef7c75367feeebbe1a38aa19b/src/mcp/java/net/minecraftforge/gradle/mcp/tasks/SetupMCP.java#L74 SetupMCP] task.&lt;br /&gt;
&lt;br /&gt;
This task then seeks to [https://github.com/MinecraftForge/ForgeGradle/blob/a0d2d1f488b3285ef7c75367feeebbe1a38aa19b/src/mcp/java/net/minecraftforge/gradle/mcp/tasks/DownloadMCPConfig.java#L68 download the MCPConfig.zip jar] for the version you're setting up&lt;br /&gt;
Once it is acquired, it &lt;br /&gt;
[https://github.com/MinecraftForge/ForgeGradle/blob/a0d2d1f488b3285ef7c75367feeebbe1a38aa19b/src/mcp/java/net/minecraftforge/gradle/mcp/util/MCPRuntime.java#L75 parses the steps contained within the config.json]. It does this by interpreting the file with the following rules:&lt;br /&gt;
* Every key, except for libraries, is interpreted as the name of a step.&lt;br /&gt;
* Steps are executed in order.&lt;br /&gt;
* The version value is interpreted as a maven coordinate of a file to download.&lt;br /&gt;
* If there is a repo value, it is used instead of the maven repositories defined in the buildscript, to retrieve the version.&lt;br /&gt;
* The args array is parsed, and {values} like this are interpreted as inputs, which can be substituted accordingly.&lt;br /&gt;
* Once the step is all parsed in, it is executed:&lt;br /&gt;
** java -jar &amp;amp;lt;version&amp;amp;gt; &amp;amp;lt;args&amp;amp;gt; &amp;amp;lt;jvmArgs&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Tip|content=A config.json can be found [https://github.com/MinecraftForge/MCPConfig/blob/master/versions/release/1.17.1/config.json here] which defines the following steps:&lt;br /&gt;
* [[Toolchain:ForgeFlower/1.18|fernflower]]&lt;br /&gt;
** version: net.minecraftforge:forgeflower:1.5.498.12&lt;br /&gt;
** args: -din=1 -rbr=1 -dgs=1 -asc=1 -rsy=1 -iec=1 -jvn=1 -isl=0 -iib=1 -log=TRACE -cfg {libraries} {input} {output}&lt;br /&gt;
** jvmargs: -Xmx4G&lt;br /&gt;
* [[Toolchain:Mergetool/1.18|merge]]&lt;br /&gt;
** version: net.minecraftforge:mergetool:1.1.3:fatjar&lt;br /&gt;
** args: --client {client} --server {server} --ann {version} --output {output} --inject false&lt;br /&gt;
* [[Toolchain:MCInjector/1.18|rename]]&lt;br /&gt;
** version: net.minecraftforge.lex:vignette:0.2.0.10&lt;br /&gt;
** args: --jar-in {input} --jar-out {output} --mapping-format tsrg2 --mappings {mappings} --fernflower-meta --cfg {libraries} --create-inits --fix-param-annotations&lt;br /&gt;
&lt;br /&gt;
More information about each of these tools can be found at the link provided, as well as what each of these arguments do. A brief description is provided.}}&lt;br /&gt;
&lt;br /&gt;
=== ForgeFlower === &lt;br /&gt;
The decompiler used by ForgeGradle is a custom fork of [https://github.com/JetBrains/intellij-community/tree/master/plugins/java-decompiler/engine Jetbrains' FernFlower], called [https://github.com/MinecraftForge/ForgeFlower ForgeFlower] which searches the jar for files, cleans up the bytecode, and then converts it into a reasonable best-guess interpretation.&lt;br /&gt;
&lt;br /&gt;
It also produces the following side effects:&lt;br /&gt;
* Removes synthetic parameters from constructors&lt;br /&gt;
** In bytecode, inner classes have the outer class as their first constructor parameter, but Java source code does not.&lt;br /&gt;
* Adds constructors for inner classes&lt;br /&gt;
** These are removed by Proguard sometimes, as they are not required in the bytecode if the parent has a default constructor.&lt;br /&gt;
* Hides bridge methods&lt;br /&gt;
* Decompiles generic signatures&lt;br /&gt;
* Encodes non-ASCII characters in string and character literals as Unicode escaped characters&lt;br /&gt;
* Hides synthetic class members&lt;br /&gt;
* Prevents simple lambdas from being inlined&lt;br /&gt;
&lt;br /&gt;
As you can see by the repository, a lot of work has gone into tuning it for Minecraft's needs, but it is still a far way from perfect. This is why the patches are needed.&lt;br /&gt;
&lt;br /&gt;
If you [https://github.com/MinecraftForge/MCPConfig/tree/master/versions/release/1.17.1/patches look at the patches] for 1.17.1, they are mostly incredibly simple changes. Adding generics, making types more strict. &lt;br /&gt;
&lt;br /&gt;
This is all stuff that should be done by the decompiler, and PRs are always welcome at the ForgeFlower repository for changes and fixes that would reduce the amount of MCPConfig patches required to get the game to compile.&lt;br /&gt;
&lt;br /&gt;
For now, it is a necessity.&lt;br /&gt;
&lt;br /&gt;
=== Mergetool ===&lt;br /&gt;
The game is split into two distributions; server and client. Since the server is just a subset of the client, the client contains the server-only classes as well.&lt;br /&gt;
&lt;br /&gt;
To get around this, we have a tool called Mergetool, which can search for the differences between two files (down to the function level) and merge them into one large (referred to as joined) jar file. It also can also annotate those files as necessary.&lt;br /&gt;
&lt;br /&gt;
It is a simple program, but it works.&lt;br /&gt;
&lt;br /&gt;
=== Vignette ===&lt;br /&gt;
Vignette is where SRG starts to come into play. It serves the role of our deobfuscator, performing deobfuscation.&lt;br /&gt;
&lt;br /&gt;
This process is done with the help of a '''deobfusation map''', a file generated by the original obfuscator (in this case, ProGuard) that contains a map of the obfuscated names to original, non-obfuscated names. This is commonly used on deobfuscating stack traces outputted by an obfuscated program, for debugging purposes.&amp;lt;ref name=&amp;quot;retrace&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have three sets of deobfuscation maps available to us; the obf-&amp;gt;SRG mappings distributed with the MCPConfig system, the Yarn intermediary system, or the official mappings.&amp;lt;ref name=&amp;quot;mojmappings&amp;quot;/&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To rectify this problem, Forge has it's own process to create deobfuscation mappings for the game, using the official mappings. This process is split into two separate parts: the '''SRG renaming''', and the '''official mapping'''. During the SetupMCP task, only the SRG renaming is performed.&lt;br /&gt;
&lt;br /&gt;
Vignette itself operates on the compiled jar and takes in a .tsrg file, like that [https://github.com/MinecraftForge/MCPConfig/blob/master/versions/release/1.17.1/joined.tsrg contained in the MCPConfig zip]. It does this because it's easier to rename LVT entries (from the snowman) to readable names while you can search for every other code path that references that specific entry; ergo renaming all accesses at once. This is impossible in source code, where every name is identical and string matching is impossible.&lt;br /&gt;
&lt;br /&gt;
It also:&lt;br /&gt;
* Handles adding annotations for parameters that have synthetic data&lt;br /&gt;
** In bytecode, these Nonnull (or whatever) annotations are attached to the parameters, not to the function that contains them.&lt;br /&gt;
* Adds synthetic (invisible) constructors for classes without them&lt;br /&gt;
&lt;br /&gt;
LVT (Local Variables) are initially renamed to lvt_&amp;amp;lt;index&amp;amp;gt;_&amp;amp;lt;version&amp;amp;gt;&amp;lt;ref&amp;gt;Index means: the place where this item was found. If it is the 4th entry in the table, it is index 3.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First, the class names are renamed from their obfuscated target to the specified mapping output.&lt;br /&gt;
Then, iterating the members of the class, it renames fields, methods, parameters, and inner classes.&lt;br /&gt;
&lt;br /&gt;
A recap from earlier:&lt;br /&gt;
* For classes -&amp;gt; &amp;lt;code&amp;gt;C_###_&amp;lt;/code&amp;gt; (but it is transparently remapped without the C_ being written to disk)&lt;br /&gt;
* For functions/methods -&amp;gt; &amp;lt;code&amp;gt;m_&amp;amp;lt;ID&amp;amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
* For fields -&amp;gt; &amp;lt;code&amp;gt;f_&amp;amp;lt;ID&amp;amp;gt;_&amp;lt;/code&amp;gt;&lt;br /&gt;
* For function/method parameters -&amp;gt; &amp;lt;code&amp;gt;p_###_&amp;lt;/code&amp;gt;&amp;lt;ref&amp;gt;The index is the position of the argument. 0 on the left, 1 after that, 2 after that. Note that double and long arguments increase their index by two, rather than one of the parameter&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For example, &amp;lt;code&amp;gt;m_91087_&amp;lt;/code&amp;gt; refers to a function with SRG ID 91087.&amp;lt;ref&amp;gt;For version 1.17.1, &amp;lt;code&amp;gt;m_91087_&amp;lt;/code&amp;gt; refers to &amp;lt;code&amp;gt;Minecraft#getInstance&amp;lt;/code&amp;gt; with an obfuscated name of &amp;lt;code&amp;gt;dvp$C&amp;lt;/code&amp;gt;.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, we have a completely remapped jar.&lt;br /&gt;
&lt;br /&gt;
=== Patches ===&lt;br /&gt;
Once we have the source code ready to go, the final step in the setup is to apply patches.&lt;br /&gt;
These are done trivially using [https://github.com/MinecraftForge/DiffPatch DiffPatch].&lt;br /&gt;
&lt;br /&gt;
== The Forge Side ==&lt;br /&gt;
&lt;br /&gt;
When Forge is first loaded by gradle, it prepares the files for setting up the workspace.&lt;br /&gt;
&lt;br /&gt;
The initial setup is done through the &amp;lt;code&amp;gt;gradlew setup&amp;lt;/code&amp;gt; task. It will run the SetupMCP tasks and then start applying the Forge system to the processed vanilla code. After the MCPConfig/SetupMCP tasks are finished, ForgeGradle will print '''MCP Environment Setup is complete''' and continue. The text '''pausing after requested step''' is also printed twice during this task such that some necessary data can be extracted.&lt;br /&gt;
&lt;br /&gt;
First, it applies ATs. After that, patches. Finally, the official mappings, or some other mappings from a provider like Parchment, are applied.&lt;br /&gt;
&lt;br /&gt;
All in all, compared to the MCPConfig setup, this is a string of extremely basic tasks - mostly just one-line commands.&lt;br /&gt;
&lt;br /&gt;
=== Applying Access Transformers ===&lt;br /&gt;
&lt;br /&gt;
[[Access Transformers/1.18|Access Transformers]] are a way of changing the visibility and finality of classes and class members. A full explanation of how it works, what the specification is, and what exactly they're used for, can be found at that page.&lt;br /&gt;
&lt;br /&gt;
They are applied by passing the AT Config (nowadays called accesstransformer.cfg) into AccessTransformers:&lt;br /&gt;
* &amp;lt;code&amp;gt;AccessTransformers.jar --inJar {input} --outJar {output} --logFile accesstransform.log --atFile {at.cfg}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[https://github.com/MinecraftForge/MinecraftForge/blob/1.17.x/src/main/resources/META-INF/accesstransformer.cfg The AT cfg for Forge can be found here.]&lt;br /&gt;
&lt;br /&gt;
=== Applying Patches ===&lt;br /&gt;
&lt;br /&gt;
The patches used for Forge itself are different from those used by MCPConfig, which means there are two separate patching stages performed.&lt;br /&gt;
&lt;br /&gt;
As opposed to the minimal MCPConfig patching, with the goal to make the code recompilable, the Forge patching is done to apply the API and mod loader to the code.&lt;br /&gt;
&lt;br /&gt;
It does this in a very similar way, with the [https://github.com/MinecraftForge/BinaryPatcher BinaryPatcher] utility used at install time/during a CI build or [https://github.com/MinecraftForge/DiffPatch DiffPatch] in all other situations.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Applying Mappings ===&lt;br /&gt;
This step isn't strictly necessary, and it can be omitted. However, working with exclusively SRG names is confusing for most people, so we have an extra step to apply human names to the SRG.&lt;br /&gt;
&lt;br /&gt;
These renames can come from any source; as mentioned earlier, the Yarn naming or the Mojang Obf-map naming. ForgeGradle does not care, as long as there is a valid SRG-&amp;gt;names map.&lt;br /&gt;
&lt;br /&gt;
How ForgeGradle retrieves these mappings is covered in the [[ForgeGradle/mappings/1.18|appropriate article]].&lt;br /&gt;
&lt;br /&gt;
The process of renaming itself is a simple regex substitution, performed by [https://github.com/MinecraftForge/ForgeGradle/blob/a0d2d1f488b3285ef7c75367feeebbe1a38aa19b/src/common/java/net/minecraftforge/gradle/common/util/McpNames.java#L105 ForgeGradle itself]. This is made possible by the assured uniqueness of SRG names.&lt;br /&gt;
&lt;br /&gt;
=== Post-processing ===&lt;br /&gt;
&lt;br /&gt;
At this point, the files are ready to go. We have processed the Minecraft jar such that it can be recompiled, we have applied appropriate access transformers and the Forge patches, and optionally renamed every applicable SRG name to whatever chosen distribution of mappings.&lt;br /&gt;
&lt;br /&gt;
There is not much left to do but package the code into a jar file, and place it into the gradle cache (so that this process does not occur every single time the project is opened). It calculates this name based on many factors, and this is covered in the [[ForgeGradle#naming/1.18|naming]] article.&lt;br /&gt;
&lt;br /&gt;
== Some Additional Info ==&lt;br /&gt;
# You will never see C_XXX_ for classes, because the class names are picked beforehand using the official mapping class names&lt;br /&gt;
# If you look into the JAR, you won't see any packages for the obfuscated classes, but the deobfuscated classes do have the packages, this is because the same process that names the classes, also decides what package they belong to&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Obfuscation_(software) Obfuscation]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;retrace&amp;quot;&amp;gt;For ProGuard users (such as Mojang), this is done using [https://www.guardsquare.com/en/products/proguard/manual/retrace ReTrace].&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;mojmappings&amp;quot;&amp;gt;Mojang recently released their deobfuscation mappings for Minecraft (colloquially named &amp;lt;code&amp;gt;mojmappings&amp;lt;/code&amp;gt;), but the licensing for its uses is a bit ambiguous. [https://cpw.github.io/MinecraftMappingData See this post by cpw] for more information.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;/references&amp;gt;&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Tinted_Textures/1.18&amp;diff=3231</id>
		<title>Tinted Textures/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Tinted_Textures/1.18&amp;diff=3231"/>
		<updated>2022-06-10T07:46:07Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Tinted Textures to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Many blocks and items in vanilla change their texture color depending on where they are, such as grass. Models support specifying “tint indices” on faces, which are integers that can then be handled by &amp;lt;code&amp;gt;BlockColor&amp;lt;/code&amp;gt;s and &amp;lt;code&amp;gt;IItemColor&amp;lt;/code&amp;gt;s. See the wiki for information on how tint indices are defined in vanilla models.&lt;br /&gt;
&lt;br /&gt;
=== BlockColor / ItemColor ===&lt;br /&gt;
Both of these are single-method interfaces. &amp;lt;code&amp;gt;BlockColor&amp;lt;/code&amp;gt; takes a &amp;lt;code&amp;gt;BlockState&amp;lt;/code&amp;gt;, a (&amp;lt;code&amp;gt;nullable&amp;lt;/code&amp;gt;) &amp;lt;code&amp;gt;BlockAndTintGetter&amp;lt;/code&amp;gt;, and a (&amp;lt;code&amp;gt;nullable&amp;lt;/code&amp;gt;) &amp;lt;code&amp;gt;BlockPos&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;ItemColor&amp;lt;/code&amp;gt; takes an &amp;lt;code&amp;gt;ItemStack&amp;lt;/code&amp;gt;. Both of them take a parameter &amp;lt;code&amp;gt;tintIndex&amp;lt;/code&amp;gt;, which is the tint index of the face being colored. Both of them return an &amp;lt;code&amp;gt;int&amp;lt;/code&amp;gt;, a color multiplier. This int is treated as four unsigned bytes, alpha, red, green, and blue, in that order, from most significant byte to least. For each pixel in the tinted face, the value of each color channel is &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;(int)((float)base * multiplier / 255)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, where &amp;lt;code&amp;gt;base&amp;lt;/code&amp;gt; is the original value for the channel, and &amp;lt;code&amp;gt;multiplier&amp;lt;/code&amp;gt; is the associated byte from the color multiplier. Note that blocks do not use the alpha channel. For example, the grass texture, untinted, looks white and gray. The &amp;lt;code&amp;gt;BlockColor&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ItemColor&amp;lt;/code&amp;gt; for grass return color multipliers with low red and blue components, but high alpha and green components, (at least in warm biomes) so when the multiplication is performed, the green is brought out and the red/blue diminished.&lt;br /&gt;
&lt;br /&gt;
If an item inherits from the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;builtin/generated&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; model, each layer (“layer0”, “layer1”, etc.) has a tint index corresponding to its layer index. For blocks, the “particle” layer is index 0.&lt;br /&gt;
&lt;br /&gt;
=== Creating Color Handlers ===&lt;br /&gt;
&amp;lt;code&amp;gt;BlockColor&amp;lt;/code&amp;gt;s need to be registered to the &amp;lt;code&amp;gt;BlockColors&amp;lt;/code&amp;gt; instance of the game. &amp;lt;code&amp;gt;BlockColors&amp;lt;/code&amp;gt; can be acquired through &amp;lt;code&amp;gt;ColorHandlerEvent$Block&amp;lt;/code&amp;gt;, and an &amp;lt;code&amp;gt;BlockColor&amp;lt;/code&amp;gt; can be registered by &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockColors#register&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Note that this does not cause the &amp;lt;code&amp;gt;BlockItem&amp;lt;/code&amp;gt; for the given block to be colored. &amp;lt;code&amp;gt;BlockItem&amp;lt;/code&amp;gt; are items and need to colored with an &amp;lt;code&amp;gt;ItemColor&amp;lt;/code&amp;gt;.&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public void registerBlockColors(final ColorHandlerEvent.Block event) {&lt;br /&gt;
    event.getBlockColors().register(myBlockColor, coloredBlock1, coloredBlock2, ...);&lt;br /&gt;
}&lt;br /&gt;
|groovy=void registerBlockColors(final ColorHandlerEvent.Block event) {&lt;br /&gt;
    event.blockColors.register(myBlockColor, coloredBlock1, coloredBlock2, ...);&lt;br /&gt;
}&lt;br /&gt;
|}}&lt;br /&gt;
&amp;lt;code&amp;gt;ItemColor&amp;lt;/code&amp;gt;s need to be registered to the &amp;lt;code&amp;gt;ItemColors&amp;lt;/code&amp;gt; instance of the game. &amp;lt;code&amp;gt;ItemColors&amp;lt;/code&amp;gt; can be acquired through &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ColorHandlerEvent$Item&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, and an &amp;lt;code&amp;gt;ItemColor&amp;lt;/code&amp;gt; can be registered by &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ItemColors#register&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. This method is overloaded to also take &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt;s, which simply registers the color handler for the item &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block#asItem&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; (i.e. the block’s &amp;lt;code&amp;gt;BlockItem&amp;lt;/code&amp;gt;).&lt;br /&gt;
{{Template:Tabs/Code_Snippets&lt;br /&gt;
|java=public void registerItemColors(final ColorHandlerEvent.Item event) {&lt;br /&gt;
    event.getItemColors().register(myItemColor, coloredItem1, coloredItem2, ...);&lt;br /&gt;
}&lt;br /&gt;
|groovy=void registerBlockColors(final ColorHandlerEvent.Item event) {&lt;br /&gt;
    event.itemColors.register(myItemColor, coloredItem1, coloredItem2, ...);&lt;br /&gt;
}&lt;br /&gt;
|}}&lt;br /&gt;
This registration must be done client-side, in the initialization phase.&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Tile_Entity_Renderer/1.18&amp;diff=3230</id>
		<title>Tile Entity Renderer/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Tile_Entity_Renderer/1.18&amp;diff=3230"/>
		<updated>2022-06-10T07:46:05Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Tile Entity Renderer to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Block Entity Renderer/1.18|Block Entity Renderer]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Tile_Entity/1.18&amp;diff=3229</id>
		<title>Tile Entity/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Tile_Entity/1.18&amp;diff=3229"/>
		<updated>2022-06-10T07:46:04Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Tile Entity to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Tile Entities/1.18|Tile Entities]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Tile_Entities/1.18&amp;diff=3228</id>
		<title>Tile Entities/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Tile_Entities/1.18&amp;diff=3228"/>
		<updated>2022-06-10T07:46:02Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Tile Entities to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Block Entities/1.18|Block Entities]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Text_Components/1.18&amp;diff=3227</id>
		<title>Text Components/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Text_Components/1.18&amp;diff=3227"/>
		<updated>2022-06-10T07:46:00Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Text Components to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Components/1.18|Components]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Tags/1.18&amp;diff=3226</id>
		<title>Tags/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Tags/1.18&amp;diff=3226"/>
		<updated>2022-06-10T07:45:58Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Tags to MC1.18 archive&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/1.18|Category:Resources and Data]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Structures/1.18&amp;diff=3225</id>
		<title>Structures/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Structures/1.18&amp;diff=3225"/>
		<updated>2022-06-10T07:45:57Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Structures to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;https://github.com/TelepathicGrunt/StructureTutorialMod&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Stages_of_Modloading/1.18&amp;diff=3224</id>
		<title>Stages of Modloading/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Stages_of_Modloading/1.18&amp;diff=3224"/>
		<updated>2022-06-10T07:45:55Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Stages of Modloading to MC1.18 archive&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;RegistryEvent.NewRegistry&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;RegistryEvent.Register&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;   ||   (inlined in &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ModStateProvider&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;)   ||   ?   ||   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>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Sounds/1.18&amp;diff=3223</id>
		<title>Sounds/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Sounds/1.18&amp;diff=3223"/>
		<updated>2022-06-10T07:45:53Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Sounds to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Although not essential, sounds bring a greater immersion into the Minecraft world. Their usages within and outside the development environment gives a bit more polish to an already existing mod from background music to a single block break.&lt;br /&gt;
&lt;br /&gt;
== Creating a Sound ==&lt;br /&gt;
&lt;br /&gt;
Sounds in Minecraft are comprised of two things: an audio file and a reference pointer to that audio file.&lt;br /&gt;
&lt;br /&gt;
The reference pointer is known as &amp;lt;code&amp;gt;sounds.json&amp;lt;/code&amp;gt; which should be created at &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;assets/&amp;lt;modid&amp;gt;/sounds.json&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. This JSON defines resource names to point to the audio files added by a specific mod. The only thing necessary to define a sound is by creating an object, naming it, and then defining the location of the sound within a list.&lt;br /&gt;
&lt;br /&gt;
By default, the only supported audio format is [https://xiph.org/vorbis/ Ogg Vorbis] represented by the extension &amp;lt;code&amp;gt;.ogg&amp;lt;/code&amp;gt;. The file &amp;lt;code&amp;gt;namespace:path&amp;lt;/code&amp;gt; when referenced in the JSON will be located within &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;assets/&amp;lt;namespace&amp;gt;/sounds/&amp;lt;path&amp;gt;.ogg&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&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;example_sound&amp;quot;: {&lt;br /&gt;
    &amp;quot;sounds&amp;quot;: [ &amp;quot;examplemod:example_sound_file&amp;quot; ]&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using the example above, it creates a sound called &amp;lt;code&amp;gt;example_sound&amp;lt;/code&amp;gt; and references the file &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;assets/&amp;lt;modid&amp;gt;/sounds/example_sound_file.ogg&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Tip/Danger | Due to [https://bugs.mojang.com/browse/MC-146721 the way OpenAL (Minecraft's sound engine) works], for your sound to have attenuation - that is, for it to get quieter as the player walks away, it absolutely MUST be mono (have one audio channel).  &lt;br /&gt;
&lt;br /&gt;
Stereo sounds are always played at the '''player's''' location, making them ideal for ambient sounds and background music.&lt;br /&gt;
&lt;br /&gt;
}}  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Instead of being constructed as a list of strings, each entry could also be an object which allows a greater control over what and how it is played.&lt;br /&gt;
&lt;br /&gt;
Here are some variables that could be defined:&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; border=1&lt;br /&gt;
!Parameter !!Description &lt;br /&gt;
|-&lt;br /&gt;
|   name   ||  Sets the path to the sound file excluding the &amp;lt;code&amp;gt;.ogg&amp;lt;/code&amp;gt; extension. &lt;br /&gt;
|-&lt;br /&gt;
|   stream   ||  Determines whether the sound should be streamed from the file. When true, it reduces the amount of lag from loading a large file; however, it only allows four instances of the sound to be played at once. &lt;br /&gt;
|-&lt;br /&gt;
|   volume   ||  A value between 0 and 1 to determine the volume of the sound played. &lt;br /&gt;
|-&lt;br /&gt;
|}&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;example_sound&amp;quot;: {&lt;br /&gt;
    &amp;quot;sounds&amp;quot;: [ &amp;quot;examplemod:example_sound_file&amp;quot; ]&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;example_sound_complex&amp;quot;: {&lt;br /&gt;
    &amp;quot;sounds&amp;quot;:&lt;br /&gt;
    [&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;name&amp;quot;: &amp;quot;examplemod:complex/example_complex&amp;quot;,&lt;br /&gt;
        &amp;quot;pitch&amp;quot;: 0.6,&lt;br /&gt;
        &amp;quot;stream&amp;quot;: true&lt;br /&gt;
      }&lt;br /&gt;
    ]&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now there is a new sound within our JSON called &amp;lt;code&amp;gt;example_sound_complex&amp;lt;/code&amp;gt;. This points to the audio file at &amp;lt;code&amp;gt;assets/examplemod/sounds/complex/example_complex.json&amp;lt;/code&amp;gt;. The sound's pitch is lowered to 0.6 of its original value. The &amp;lt;code&amp;gt;stream&amp;lt;/code&amp;gt; parameter is also set to true.&lt;br /&gt;
&lt;br /&gt;
There are many more parameters that can give greater control on how sounds are played. However, this is left as an exercise to the reader to try and construct with the [https://minecraft.gamepedia.com/Sounds.json wiki].&lt;br /&gt;
&lt;br /&gt;
== Creating &amp;lt;code&amp;gt;SoundEvent&amp;lt;/code&amp;gt;s ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;sounds.json&amp;lt;/code&amp;gt; left in its current state would only be defined in-game. There is currently no way to reference the sound within a mod. To do this, we utilize the &amp;lt;code&amp;gt;SoundEvent&amp;lt;/code&amp;gt; class. Each &amp;lt;code&amp;gt;SoundEvent&amp;lt;/code&amp;gt; class holds a &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; to reference a sound pointer defined in the &amp;lt;code&amp;gt;sounds.json&amp;lt;/code&amp;gt; file. The &amp;lt;code&amp;gt;sounds.json&amp;lt;/code&amp;gt; file used is determined by the namespace or the resource location passed into the class.&lt;br /&gt;
&lt;br /&gt;
For example, to reference &amp;lt;code&amp;gt;example_complex.ogg&amp;lt;/code&amp;gt;, you would store the reference name (e.g. &amp;lt;code&amp;gt;example_sound_complex&amp;lt;/code&amp;gt;) within a &amp;lt;code&amp;gt;new SoundEvent(new ResourceLocation(&amp;quot;examplemod&amp;quot;, &amp;quot;example_sound_complex&amp;quot;))&amp;lt;/code&amp;gt;. This will locate &amp;lt;code&amp;gt;assets/examplemod/sounds.json&amp;lt;/code&amp;gt; and try to find an &amp;lt;code&amp;gt;example_sound_complex&amp;lt;/code&amp;gt; object nested within it.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Warning|&amp;lt;code&amp;gt;SoundEvent&amp;lt;/code&amp;gt;s must be [[Registration/1.16/1.18|registered]] on the &amp;lt;code&amp;gt;ModEventBus&amp;lt;/code&amp;gt; to properly reference a sound on a server. However, &amp;lt;code&amp;gt;SoundEvent&amp;lt;/code&amp;gt;s or referencing a sound by name will still work on the client when the sound is not registered as long as the sound exists in &amp;lt;code&amp;gt;sounds.json&amp;lt;/code&amp;gt;!}}&lt;br /&gt;
&lt;br /&gt;
== Playing Sounds ==&lt;br /&gt;
&lt;br /&gt;
Vanilla has lots of methods for playing sounds that can be used in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;Level&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;playSound(Player, BlockPos, SoundEvent, SoundCategory, volume, pitch)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
#*Simply forwards to overload (2), adding 0.5 to each coordinate of the BlockPos given.&lt;br /&gt;
# &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;playSound(Player, double x, double y, double z, SoundEvent, SoundCategory, volume, pitch)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Client Behavior&amp;lt;/code&amp;gt;: If the passed in player is the client player, plays the sound event to the client player.&lt;br /&gt;
#* &amp;lt;code&amp;gt;Server Behavior&amp;lt;/code&amp;gt;: Plays the sound event to everyone nearby except the passed in player. Player can be &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;.&lt;br /&gt;
#* &amp;lt;code&amp;gt;Usage&amp;lt;/code&amp;gt;: The correspondence between the behaviors implies that these two methods are to be called from some player-initiated code that will be run on both logical sides at the same time - the logical client handles playing it to the user and the logical server handles everyone else hearing it without re-playing it to the original user. They can also be used to play any sound in general at any position server-side by calling it on the logical server and passing in a &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; player, thus letting everyone hear it.&lt;br /&gt;
# &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;playSound(double x, double y, double z, SoundEvent, SoundCategory, volume, pitch, distanceDelay)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
#* &amp;lt;code&amp;gt;Client Behavior&amp;lt;/code&amp;gt;: Just plays the sound event in the client level. If distanceDelay is true, then delays the sound based on how far it is from the player.&lt;br /&gt;
#* &amp;lt;code&amp;gt;Server Behavior&amp;lt;/code&amp;gt;: Does nothing.&lt;br /&gt;
#* &amp;lt;code&amp;gt;Usage&amp;lt;/code&amp;gt;: This method only works client-side, and thus is useful for sounds sent in custom packets, or other client-only effect-type sounds. Used for thunder.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;ClientLevel&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;playSound(BlockPos, SoundEvent, SoundCategory, volume, pitch, distanceDelay)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
#* Simply forwards to &amp;lt;code&amp;gt;Level&amp;lt;/code&amp;gt;‘s overload (3), adding 0.5 to each coordinate of the &amp;lt;code&amp;gt;BlockPos&amp;lt;/code&amp;gt; given.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;Entity&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;playSound(SoundEvent, volume, pitch)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
#* Forwards to &amp;lt;code&amp;gt;LEvel&amp;lt;/code&amp;gt;‘s overload (2), passing in &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; as the player.&lt;br /&gt;
#* &amp;lt;code&amp;gt;Client Behavior&amp;lt;/code&amp;gt;: Does nothing.&lt;br /&gt;
#* &amp;lt;code&amp;gt;Server Behavior&amp;lt;/code&amp;gt;: Plays the sound event to everyone at this entity’s position.&lt;br /&gt;
#* &amp;lt;code&amp;gt;Usage&amp;lt;/code&amp;gt;: Emitting any sound from any non-player entity server-side.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;Player&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;playSound(SoundEvent, volume, pitch)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; (overriding the one in &amp;lt;code&amp;gt;[[Sounds#Entity/1.18|Entity]]&amp;lt;/code&amp;gt;)&lt;br /&gt;
#* Forwards to &amp;lt;code&amp;gt;Level&amp;lt;/code&amp;gt;‘s overload (2), passing in &amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt; as the player.&lt;br /&gt;
#* &amp;lt;code&amp;gt;Client Behavior&amp;lt;/code&amp;gt;: Does nothing, see override in &amp;lt;code&amp;gt;[[Sounds#localplayer/1.18|LocalPlayer]]&amp;lt;/code&amp;gt;.&lt;br /&gt;
#* &amp;lt;code&amp;gt;Server Behavior&amp;lt;/code&amp;gt;: Plays the sound to everyone nearby &amp;lt;code&amp;gt;except&amp;lt;/code&amp;gt; this player.&lt;br /&gt;
#* &amp;lt;code&amp;gt;Usage&amp;lt;/code&amp;gt;: See &amp;lt;code&amp;gt;[[Sounds#localplayer/1.18|LocalPlayer]]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;LocalPlayer&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;playSound(SoundEvent, volume, pitch)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; (overriding the one in &amp;lt;code&amp;gt;[[Sounds#player|Player]&amp;lt;/code&amp;gt;)&lt;br /&gt;
#* Forwards to &amp;lt;code&amp;gt;Level&amp;lt;/code&amp;gt;‘s overload (2), passing in &amp;lt;code&amp;gt;this&amp;lt;/code&amp;gt; as the player.&lt;br /&gt;
#* &amp;lt;code&amp;gt;Client Behavior&amp;lt;/code&amp;gt;: Just plays the Sound Event.&lt;br /&gt;
#* &amp;lt;code&amp;gt;Server Behavior&amp;lt;/code&amp;gt;: Method is client-only.&lt;br /&gt;
#* &amp;lt;code&amp;gt;Usage&amp;lt;/code&amp;gt;: Just like the ones in &amp;lt;code&amp;gt;Level&amp;lt;/code&amp;gt;, these two overrides in the player classes seem to be for code that runs together on both sides. The client handles playing the sound to the user, while the server handles everyone else hearing it without re-playing to the original user.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Game Effects/1.18|Category:Game Effects]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=SimpleChannel/1.18&amp;diff=3222</id>
		<title>SimpleChannel/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=SimpleChannel/1.18&amp;diff=3222"/>
		<updated>2022-06-10T07:45:51Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy SimpleChannel to MC1.18 archive&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>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Sides/1.18&amp;diff=3221</id>
		<title>Sides/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Sides/1.18&amp;diff=3221"/>
		<updated>2022-06-10T07:45:49Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Sides to MC1.18 archive&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/1.18|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/1.18|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/1.18|&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, but the server menu will display the server as being incompatible (with a red &amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt; at the side). Therefore, you should register an &amp;lt;code&amp;gt;IExtensionPoint$DisplayTest&amp;lt;/code&amp;gt; extension point to make sure that Forge does not think your mod is required on the server: (this is usually done in the mod constructor)&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/1.18|Category:Common Concepts]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Sending_Packets/1.18&amp;diff=3220</id>
		<title>Sending Packets/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Sending_Packets/1.18&amp;diff=3220"/>
		<updated>2022-06-10T07:45:47Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Sending Packets to MC1.18 archive&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;
Here is a list of distributors available:&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Semantic_Versioning/1.18&amp;diff=3219</id>
		<title>Semantic Versioning/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Semantic_Versioning/1.18&amp;diff=3219"/>
		<updated>2022-06-10T07:45:45Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Semantic Versioning to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://semver.org/ Semantic Versioning] is a versioning system where three variable are used to represent the version, in the format of &amp;lt;code&amp;gt;MAJOR.MINOR.PATCH&amp;lt;/code&amp;gt;. However, in the case of modding, it may be beneficial to add additional variable such as the Minecraft version, to allow distinction between mods that work for which Minecraft versions.&lt;br /&gt;
&lt;br /&gt;
{{Tip|The information presented here is purely informative. You are free to use any versioning system you wish.}}&lt;br /&gt;
&lt;br /&gt;
When incrementing any variable, all lesser variables should reset to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. For instance, if &amp;lt;code&amp;gt;MINOR&amp;lt;/code&amp;gt; would increment, &amp;lt;code&amp;gt;PATCH&amp;lt;/code&amp;gt; would become &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. If &amp;lt;code&amp;gt;MAJORMOD&amp;lt;/code&amp;gt; would increment, all other variables would become &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Hybrid Versioning ==&lt;br /&gt;
&lt;br /&gt;
A good hybrid of Semantic Versioning for Minecraft mods is the format: &amp;lt;code&amp;gt;MCVERSION-MAJORMOD.MAJORAPI.MINOR.PATCH&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Variable !! Description &lt;br /&gt;
! When to Change&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;MCVERSION&amp;lt;/code&amp;gt; || The Minecraft version being targeted. &lt;br /&gt;
| The target Minecraft version is updated. &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;MAJORMOD&amp;lt;/code&amp;gt; || The major version of the mod. &lt;br /&gt;
| Exising mod objects - such as items, blocks, tile entities - are removed or fundamental mechanics are modified. &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;MAJORAPI&amp;lt;/code&amp;gt; || The major version of the mod's API. &lt;br /&gt;
| Any part of the mod's public-facing API is changed, such as reordered enums, method signature changes, or removal of public methods. &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;MINOR&amp;lt;/code&amp;gt; || The minor version of the mod. &lt;br /&gt;
| Mod objects or non-fundamental mechanics are added, or elements of the API are deprecated (but not removed). &lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;PATCH&amp;lt;/code&amp;gt; || The patch version of the mod release. &lt;br /&gt;
| Bugs are fixed or the changes are unnoticable. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Classifiers ==&lt;br /&gt;
&lt;br /&gt;
A classifer can be appended to the build version to denote it is a special build of some note. These classifiers are appended after the version variables are incremented and reset.&lt;br /&gt;
&lt;br /&gt;
=== Pre-releases ===&lt;br /&gt;
&lt;br /&gt;
It is also possible to pre-release work-in-progress features, which means new features are released that are not quite done yet. These can be seen as a sort of &amp;quot;beta&amp;quot;. These versions should be appended with &amp;lt;code&amp;gt;-betaX&amp;lt;/code&amp;gt;, where &amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt; is the number of the pre-release. Already released versions before the initial release can not go into pre-release; a variable must be incremented (e.g. the &amp;lt;code&amp;gt;MINOR&amp;lt;/code&amp;gt; variable) and others updated before applying this classifier.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|This guide does not use the &amp;lt;code&amp;gt;-preX&amp;lt;/code&amp;gt; classifier for pre-releases, because the library used to compare versions does not accept it as an alias for &amp;lt;code&amp;gt;-betaX&amp;lt;/code&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
=== Release Candidates ===&lt;br /&gt;
&lt;br /&gt;
If you are confident enough that a build is ready to be a release but a bit more testing is required, you may make it a ''release candidate''. These release candidates may receive the &amp;lt;code&amp;gt;-rcX&amp;lt;/code&amp;gt; classifier, where &amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt; is the number of the release candidate, incremented for every new release candidate build. Already released versions before the initial release can not go into pre-release; a variable must be incremented (e.g. the &amp;lt;code&amp;gt;MINOR&amp;lt;/code&amp;gt; variable) and others updated before applying this classifier.&lt;br /&gt;
&lt;br /&gt;
The final released build will have the same version as the release candidate with the classifier omitted, and will usually be exactly the same or have a few unnoticable bugfixes included.&lt;br /&gt;
&lt;br /&gt;
=== Final Release ===&lt;br /&gt;
&lt;br /&gt;
When dropping support for a Minecraft version, the ''final build'' for that Minecraft version may receive the &amp;lt;code&amp;gt;-final&amp;lt;/code&amp;gt; classifer. This denotes that the mod will no longer be supported for the denoted &amp;lt;code&amp;gt;MCVERSION&amp;lt;/code&amp;gt; and players should upgrade their Minecraft version to continue receiving updates and fixes.&lt;br /&gt;
&lt;br /&gt;
== During Development ==&lt;br /&gt;
&lt;br /&gt;
If you are in the initial development stage of your mod (before any official releases), the &amp;lt;code&amp;gt;MAJORMOD&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;MAJORAPI&amp;lt;/code&amp;gt; should be kept at &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. Only &amp;lt;code&amp;gt;MINOR.PATCH&amp;lt;/code&amp;gt; should be updated every time you build your mod. During this development stage, you are free to change or restructure your mod's API, objects, and mechanics as you wish without updating the major version variables. Once you build an official public release, you should increment the &amp;lt;code&amp;gt;MAJORMOD&amp;lt;/code&amp;gt; version, reset the others to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;, and follow your versioning strictly.&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Saved_Data/1.18&amp;diff=3218</id>
		<title>Saved Data/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Saved_Data/1.18&amp;diff=3218"/>
		<updated>2022-06-10T07:45:44Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Saved Data to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code&amp;gt;SavedData&amp;lt;/code&amp;gt; is an alternative to capabilities that stores data per dimension or globally depending on how the context is passed.&lt;br /&gt;
&lt;br /&gt;
==Class Structure==&lt;br /&gt;
&lt;br /&gt;
The class can be broken down into two important methods:&lt;br /&gt;
 - &amp;lt;code&amp;gt;save&amp;lt;/code&amp;gt;: Write the data to nbt.&lt;br /&gt;
 - &amp;lt;code&amp;gt;setDirty&amp;lt;/code&amp;gt;: Tell the game that the data has changed and needs to be saved to file.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;save&amp;lt;/code&amp;gt; method need to be implemented while &amp;lt;code&amp;gt;setDirty&amp;lt;/code&amp;gt; should be called whenever the data is going to be manipulated. As the class is abstract, it should be subclassed with these three methods implemented.&lt;br /&gt;
&lt;br /&gt;
==Attaching to a Level ==&lt;br /&gt;
&lt;br /&gt;
To attach a Saved Data to a particular level, you must have access to an instance of &amp;lt;code&amp;gt;ServerLevel&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;ServerChunkCache&amp;lt;/code&amp;gt;. From there, you can call the method &amp;lt;code&amp;gt;#getSavedData&amp;lt;/code&amp;gt; which will give you an instance of the &amp;lt;code&amp;gt;DimensionDataStorage&amp;lt;/code&amp;gt;: the class that stores all saved data for that particular dimension. You can attach an instance or get the current instance of the data using &amp;lt;code&amp;gt;DimensionDataStorage#computeIfAbsent&amp;lt;/code&amp;gt;. This takes in three arguments: the first to construct a saved data with data already existing in some &amp;lt;code&amp;gt;CompoundTag&amp;lt;/code&amp;gt;, the second to construct a saved data with no existing data, and the third to specify the name of the file to save the data to within the &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; folder in the overworld or in the specific dimension of the save.&lt;br /&gt;
&lt;br /&gt;
Global attachments are the same except that they should only be attached to the overworld as that level will always persist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Data Storage/1.18|Category:Data Storage]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Saplings/1.18&amp;diff=3217</id>
		<title>Saplings/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Saplings/1.18&amp;diff=3217"/>
		<updated>2022-06-10T07:45:42Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Saplings to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Let's start with a basic example by extending SaplingBlock.First create a class that extends SaplingBlock.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;public class ExampleSapling extends SaplingBlock{}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After that you can insert the constructor. It must call super with the Parameters : &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=1&lt;br /&gt;
!Name !! Type !!Description &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;treeIn&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;net.minecraft.block.trees.Tree&amp;lt;/code&amp;gt;   || &amp;lt;code&amp;gt;The Tree your Sapling is related to&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;properties&amp;lt;/code&amp;gt;   ||   &amp;lt;code&amp;gt;net.minecraft.block.AbstractBlock.Properties&amp;lt;/code&amp;gt;   ||  &amp;lt;code&amp;gt;The Block Properties of the Sapling&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
That means we need to make a Tree for ourselves, but more on that in a bit.&lt;br /&gt;
If you want to have the Sapling be placeable on your own Mods Block, you need to override &amp;lt;code&amp;gt;isValidGround&amp;lt;/code&amp;gt; and make your own additions to the vanilla provided Blocks. I recommend making a &lt;br /&gt;
&amp;lt;code&amp;gt;private static final List&amp;lt;Block&amp;gt; validBlocks = ImmutableList.of(Blocks block...)&amp;lt;/code&amp;gt; to add Blocks to the List of possible Blocks.&lt;br /&gt;
If you have that, your function could look like :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
protected boolean isValidGround(@Nonnull BlockState state,@Nonnull IBlockReader worldIn,@Nonnull BlockPos pos) {&lt;br /&gt;
return validBlocks.stream().anyMatch(state::isIn) || super.isValidGround(state, worldIn, pos);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now onto making the Tree for your Sapling.&lt;br /&gt;
&lt;br /&gt;
Start by making a &amp;lt;code&amp;gt;class&amp;lt;/code&amp;gt; that extends &amp;lt;code&amp;gt;Tree&amp;lt;/code&amp;gt; : &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;public class ExampleTree extends Tree &amp;lt;/code&amp;gt;&lt;br /&gt;
This &amp;lt;code&amp;gt;class&amp;lt;/code&amp;gt; will only contain one &amp;lt;code&amp;gt;function&amp;lt;/code&amp;gt; which is : &lt;br /&gt;
&amp;lt;code&amp;gt;protected ConfiguredFeature&amp;lt;BaseTreeFeatureConfig, ?&amp;gt; getTreeFeature(Random randomIn, boolean largeHive)&amp;lt;/code&amp;gt;&lt;br /&gt;
As you can see, this function requires to return a ConfiguredFeature&amp;lt;BaseTreeFeatureConfig, ?&amp;gt;. This will be the Tree that is Placed in the World.&lt;br /&gt;
The &amp;lt;code&amp;gt;ConfiguredFeature&amp;lt;BaseTreeFeatureConfig, ?&amp;gt;&amp;lt;/code&amp;gt; will look sth like this :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static final ConfiguredFeature&amp;lt;BaseTreeFeatureConfig, ?&amp;gt; EXAMPLETREEFEATURE = &lt;br /&gt;
 Feature.TREE.withConfiguration(&lt;br /&gt;
            new BaseTreeFeatureConfig.Builder(&lt;br /&gt;
                    new SimpleBlockStateProvider(BlockInit.EXAMPLE_WOOD.get().getDefaultState()),&lt;br /&gt;
                    new SimpleBlockStateProvider(BlockInit.EXAMPLE_LEAVES.get().getDefaultState()),&lt;br /&gt;
                    new BlobFoliagePlacer(FeatureSpread.func_242252_a(2), FeatureSpread.func_242252_a(0), 3),&lt;br /&gt;
                    new StraightTrunkPlacer(4, 2, 0),&lt;br /&gt;
                    new TwoLayerFeature(1, 0, 1)&lt;br /&gt;
            ).setIgnoreVines().build());&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
After we have our ExampleTree we need to register it. This is done via 2 functions :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public static void registerTrees() {&lt;br /&gt;
        register(&amp;quot;example_tree&amp;quot;, EXAMPLETREE);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
and also the function &amp;lt;code&amp;gt;register&amp;lt;/code&amp;gt; : &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public void register(String key, ConfiguredFeature&amp;lt;FC, ?&amp;gt; configuredFeature){&lt;br /&gt;
Registry.register(WorldGenRegistries.CONFIGURED_FEATURE, key, configuredFeature);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight &amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have everything setup, call registerTrees() in FMLCommonSetupEvent.&amp;lt;br&amp;gt;&lt;br /&gt;
Back to the Sapling. Your constructor can now be completed by putting the Tree we just registered as the first super parameter and the Properties as the second parameter : &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public ExampleSapling() {&lt;br /&gt;
        super(new ExampleTree(), AbstractBlock.Properties.create(Material.PLANTS).doesNotBlockMovement().tickRandomly().zeroHardnessAndResistance().sound(SoundType.PLANT));&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight &amp;gt;&lt;br /&gt;
Also in your ExampleTree class, instead of null, the function now should return your TreeFeature : &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
protected ConfiguredFeature&amp;lt;BaseTreeFeatureConfig, ?&amp;gt; getTreeFeature(@Nonnull Random randomIn, boolean largeHive) {&lt;br /&gt;
        return EXAMPLETREEFEATURE;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight &amp;gt;&lt;br /&gt;
Now register the Sapling like any other Block and it should be able to be placed and grow with the correct Tree.&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Resources/1.18&amp;diff=3216</id>
		<title>Resources/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Resources/1.18&amp;diff=3216"/>
		<updated>2022-06-10T07:45:40Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Resources to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A resource is extra data used by the game, and is stored in a data file, instead of being in the code. Minecraft has two primary resource systems active: one on the client used for visuals such as models, textures, and localization called &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;assets&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, the other used for gameplay such as recipes and loot tables called &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;data&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Resource packs control the former, while data packs control the latter.&lt;br /&gt;
&lt;br /&gt;
When multiple resource packs or data packs are enabled, they are merged. Generally, files from packs at the top of the stack override those below; however, for certain files, such as localization files and tags, data is actually merged contentwise. Mods actually define resource and data packs too, in their &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;resources&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; directories, but they are seen as subsets of the “Default” pack. Mod resource packs cannot be disabled, but they can be overridden by other resource packs. Mod datapacks can be disabled with the vanilla &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;/datapack&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
All resources should have '''snake case''' paths and filenames (lowercase, using “_” for word boundaries).&lt;br /&gt;
&lt;br /&gt;
== ResourceLocation ==&lt;br /&gt;
&lt;br /&gt;
Minecraft identifies resources using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ResourceLocation&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s. A &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ResourceLocation&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; contains two parts: a namespace and a path. It generally points to the resource at &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;assets|data&amp;gt;/&amp;lt;namespace&amp;gt;/&amp;lt;ctx&amp;gt;/&amp;lt;path&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, where &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ctx&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; is a context-specific path fragment that depends on how the ResourceLocation is being used. When a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ResourceLocation&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; is written from/read as a string, it is seen as &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;namespace&amp;gt;:&amp;lt;path&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. If the namespace and the colon are left out, then when the string is read into an ResourceLocation the namespace will almost always default to &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;minecraft&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. A mod should put its resources into a namespace with the same name as its modid (E.g. a mod with id &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;examplemod&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; should place its resources in &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;assets|data&amp;gt;/examplemod&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ResourceLocation&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s pointing to those files would look like &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;examplemod:&amp;lt;path&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;). This is not a requirement, and in some cases it can be desirable to use a different (or even more than one) namespace. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ResourceLocation&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;s are used outside the resource system, too, as they happen to be a great way to uniquely identify objects (e.g. [[Registration/1.18|registries]]).&lt;br /&gt;
&lt;br /&gt;
== Important Directories ==&lt;br /&gt;
&lt;br /&gt;
Minecraft expects certain parts of your project to be in certain locations, such as textures and JSONs.&lt;br /&gt;
&lt;br /&gt;
All locations and items covered in this page are relative to your &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;./src/main/resources/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; directory.&lt;br /&gt;
&lt;br /&gt;
== General Files ==&lt;br /&gt;
&lt;br /&gt;
=== mods.toml ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;mods.toml&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; file is in the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;./META-INF/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; directory. This holds the basic information relating to your mod.&lt;br /&gt;
&lt;br /&gt;
=== pack.mcmeta ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;pack.mcmeta&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; file is in the current directory. This allows Minecraft to notice the assets provided by your mod.&lt;br /&gt;
&lt;br /&gt;
== Assets ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;./assets&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; folder holds all client related files for a specific user. These files are only specific to the computer they're on.&lt;br /&gt;
&lt;br /&gt;
=== Blockstates ===&lt;br /&gt;
&lt;br /&gt;
Blockstate definition files are in the JSON format and are in the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;./assets/&amp;lt;modid&amp;gt;/blockstates/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; folder.&lt;br /&gt;
&lt;br /&gt;
=== Localizations ===&lt;br /&gt;
&lt;br /&gt;
Localizations are plain-text files with the file extension &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;.json&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and the name being their [https://docs.microsoft.com/en-us/previous-versions/commerce-server/ee825488(v=cs.20)?redirectedfrom=MSDN language code] in lowercase such as &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;en_us&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
They are located in the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;./assets/&amp;lt;modid&amp;gt;/lang/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; folder.&lt;br /&gt;
&lt;br /&gt;
=== Models ===&lt;br /&gt;
&lt;br /&gt;
Model files are in JSON format and are located in &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;./assets/&amp;lt;modid&amp;gt;/models/block/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;./assets/&amp;lt;modid&amp;gt;/models/item/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; depending on whether they are for a block or an item, respectively.&lt;br /&gt;
&lt;br /&gt;
=== Textures ===&lt;br /&gt;
&lt;br /&gt;
Textures are in the PNG format and are located in &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;./assets/&amp;lt;modid&amp;gt;/textures/block/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;./assets/&amp;lt;modid&amp;gt;/textures/item/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; depending on whether they are for a block or an item, respectively. For other entries, they will be placed in their specified location within &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;./assets/&amp;lt;modid&amp;gt;/textures/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Data ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;./data&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; folder holds all server related files for a specific game file. These files are synced across the network from the hosting server location.&lt;br /&gt;
&lt;br /&gt;
=== Advancements ===&lt;br /&gt;
&lt;br /&gt;
Advancements are in JSON format and are located in &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;./data/&amp;lt;modid&amp;gt;/advancements/&amp;lt;group&amp;gt;/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; where &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;group&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; is the tab the advancement is part of.&lt;br /&gt;
&lt;br /&gt;
=== Loot Tables ===&lt;br /&gt;
&lt;br /&gt;
Loot tables are in JSON format and are located in &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;./data/&amp;lt;modid&amp;gt;/loot_tables/&amp;lt;group&amp;gt;/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; where &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;group&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; is the general object where the loot table drops from (e.g. a block's loot table is in &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;blocks&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
=== Recipes ===&lt;br /&gt;
&lt;br /&gt;
Recipes are in JSON format and are located in &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;./data/&amp;lt;modid&amp;gt;/recipes/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Tags ===&lt;br /&gt;
&lt;br /&gt;
Tags are in JSON format and are located in &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;./data/&amp;lt;modid&amp;gt;/tags/&amp;lt;group&amp;gt;/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; where &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;group&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; is the registry object to create the tags for (e.g. an entity tag would be in &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;entity_types&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;).&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Registration/1.18&amp;diff=3215</id>
		<title>Registration/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Registration/1.18&amp;diff=3215"/>
		<updated>2022-06-10T07:45:38Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Registration to MC1.18 archive&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/1.18|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/1.18|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/1.18|&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 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 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;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(ExampleRegistry.class, 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(ExampleRegistry::class.java, ::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(classOf[ExampleRegistry], () =&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;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/1.18|Category:Common Concepts]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Recipes/1.18&amp;diff=3214</id>
		<title>Recipes/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Recipes/1.18&amp;diff=3214"/>
		<updated>2022-06-10T07:45:36Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Recipes to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;With the update to Minecraft 1.12, Mojang introduced a new data-driven recipe system based on JSON files. Since then, it has been adopted by Forge as well and was expanded in Minecraft 1.13 into [[datapacks/1.18|datapacks]].&lt;br /&gt;
&lt;br /&gt;
== Loading Recipes ==&lt;br /&gt;
Forge will load all recipes found within the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;./resources/data/&amp;lt;modid&amp;gt;/recipes/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; folder of your mod. You can call these files whatever you want, though the vanilla convention is to name them after the output item. For multiple recipes from different sources (smelting, crafting, etc) one vanilla convention is to use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;item_name_from_smelting.json&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. This name is also used as the registration key but does not affect the operation of the recipe.&lt;br /&gt;
&lt;br /&gt;
== The Recipe File ==&lt;br /&gt;
A basic recipe file might look like the following example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;minecraft:crafting_shaped&amp;quot;,&lt;br /&gt;
    &amp;quot;pattern&amp;quot;:&lt;br /&gt;
    [&lt;br /&gt;
        &amp;quot;XXX&amp;quot;,&lt;br /&gt;
        &amp;quot;XAX&amp;quot;,&lt;br /&gt;
        &amp;quot;XXX&amp;quot;&lt;br /&gt;
    ],&lt;br /&gt;
    &amp;quot;key&amp;quot;:&lt;br /&gt;
    {&lt;br /&gt;
        &amp;quot;X&amp;quot;:&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;tag&amp;quot;: &amp;quot;forge:gems/diamond&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;A&amp;quot;:&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;item&amp;quot;: &amp;quot;mymod:myfirstitem&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;result&amp;quot;:&lt;br /&gt;
    {&lt;br /&gt;
        &amp;quot;item&amp;quot;: &amp;quot;mymod:myseconditem&amp;quot;,&lt;br /&gt;
        &amp;quot;count&amp;quot;: 9&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{Colored box|title=Tip|content=When you first obtain an ingredient to a vanilla recipe, it will automatically unlock the recipe in the recipe book. To achieve the same effect, you have to use the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Advancement&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; system and create a new &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Advancement&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for each of your ingredients.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
The advancement has to exist. This doesn’t mean it has to be visible in the advancement tree.}}&lt;br /&gt;
&lt;br /&gt;
=== Groups ===&lt;br /&gt;
Optionally, you can add a group to your recipes to be displayed within the recipe helper interface. All recipes with the same group String will be shown in the same group. For example, this can be used to have all door recipes shown in the recipe helper interface as a single entry, even though there are different types of doors.&lt;br /&gt;
&lt;br /&gt;
=== Type ===&lt;br /&gt;
The type of the recipe. You can think of this as the definition of which crafting layout is to be used. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;minecraft:crafting_shaped&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;minecraft:crafting_shapeless&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; are the two options.&lt;br /&gt;
&lt;br /&gt;
== Types of Crafting Recipes ==&lt;br /&gt;
In this section, we will take a closer look at the differences between defining a shaped and a shapeless crafting recipe.&lt;br /&gt;
&lt;br /&gt;
=== Shaped Crafting ===&lt;br /&gt;
Shaped recipes require the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;pattern&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;key&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; keywords.&lt;br /&gt;
The '''Pattern''' keyword defines the slot an item must appear in using placeholder characters. You can choose whatever character you want to be a placeholder for an item.&lt;br /&gt;
'''Keys''' define what items the placeholders stand for. A key is defined by a placeholder character and the item or tag it stands for (in the correct format).&lt;br /&gt;
&lt;br /&gt;
=== Shapeless Crafting ===&lt;br /&gt;
A shapeless recipe doesn’t use the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;pattern&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;key&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; keywords.&lt;br /&gt;
&lt;br /&gt;
To define a shapeless recipe, you have to use the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ingredients&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; list. It defines which items have to be used for the crafting process. There are many more of these types that can be used here, and you can even register your own. It is even possible to define multiple instances of the same item which means multiple of these items have to be in place for the crafting recipe to take place.&lt;br /&gt;
&lt;br /&gt;
{{Colored box|title=Tip|content=While there is no limit on how many ingredients your recipe requires, the vanilla crafting table only allows 9 items for each crafting recipe.}}&lt;br /&gt;
Below is an example of an ingredient list:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;quot;ingredients&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;tag&amp;quot;: &amp;quot;forge:gems/diamond&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;item&amp;quot;: &amp;quot;minecraft:nether_star&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
    ],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Recipe Elements ==&lt;br /&gt;
&lt;br /&gt;
=== Patterns ===&lt;br /&gt;
A pattern will be defined with the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;pattern&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; list. Each string represents one row in the crafting grid and each placeholder character within the string represents a column. As shown in the example above, a space means that no item needs to be inserted at that position.&lt;br /&gt;
&lt;br /&gt;
=== Keys ===&lt;br /&gt;
A key set is used in combination with a pattern set. It contains keys whose name is the same as the placeholder character in the pattern list which it represents. One key may be defined to represent multiple items, as is the case for the wooden button. This means that the player can use one of the defined items for the crafting recipe, for example, different types of wood.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;quot;key&amp;quot;: {&lt;br /&gt;
     &amp;quot;#&amp;quot;: [&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;item&amp;quot;: &amp;quot;minecraft:oak_planks&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      {&lt;br /&gt;
        &amp;quot;item&amp;quot;: &amp;quot;minecraft:spruce_planks&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;
=== Results ===&lt;br /&gt;
&lt;br /&gt;
Every &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;recipe&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; must have a result tag to define the output item.&lt;br /&gt;
&lt;br /&gt;
When crafting something, you can get more than one item. This is achieved by defining the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;count&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; value. If this is left out, meaning it doesn’t exist within the result block, it defaults to 1. Negative values are not allowed here as an itemstack cannot be smaller than 0. There is no option to use the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;count&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; number anywhere else than the result.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Resources and Data/1.18|Category:Resources and Data]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Proper_Mod_Structuring/1.18&amp;diff=3213</id>
		<title>Proper Mod Structuring/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Proper_Mod_Structuring/1.18&amp;diff=3213"/>
		<updated>2022-06-10T07:45:34Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Proper Mod Structuring to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
The structure of your mod is important in keeping your mod organized, for both your benefit and the benefit of anyone who wishes to make a feature or an &lt;br /&gt;
add-on for your mod. A disorganized mod structure may cause headaches when someone is trying to update it to a higher version, especially if they cannot modify the package structure, due to i.e. licensing.&lt;br /&gt;
&lt;br /&gt;
{{Tip|Note that this page is only a recommendation for your mod structure; you may structure your mod in any way you see fit.}}&lt;br /&gt;
&lt;br /&gt;
== Packaging ==&lt;br /&gt;
&lt;br /&gt;
Pick a unique package name for your mod. If you own a URL associated with your project, you can use it as your top level package. For example if you own &amp;quot;example.com&amp;quot;, you may use &amp;lt;code&amp;gt;com.example&amp;lt;/code&amp;gt; as your top level package. &lt;br /&gt;
The next level package is usually your mod's ID: if your mod ID is &amp;lt;code&amp;gt;examplemod&amp;lt;/code&amp;gt;, your mod's package will be &amp;lt;code&amp;gt;com.example.examplemod&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|Do not use a domain for your top level package if you do not own that domain. It is perfectly acceptable to have your top level package be named with anything, such as your name/nickname, or the name of the mod (&amp;lt;code&amp;gt;me.exampledude.examplemod&amp;lt;/code&amp;gt;).}}&lt;br /&gt;
&lt;br /&gt;
=== Using Subpackages ===&lt;br /&gt;
&lt;br /&gt;
Rather than clutter up a single class and package with everything, it is recommended you break your mod into subpackages. Below are a few possible methods for laying out your folder structure though you may as well come up with your own layout too.&lt;br /&gt;
&lt;br /&gt;
* '''Group by Logic''': One possible strategy is to make subpackages for logical units of your mod. For example, if you have a block called Super Furnace you would put its block, its block entity and its item all under &amp;lt;code&amp;gt;feature/superfurnace&amp;lt;/code&amp;gt;.&lt;br /&gt;
* '''Group by Function''': Another common strategy is to make subpackages for grouping classes that have a common purpose. For example, your blocks classes can be under &amp;lt;code&amp;gt;blocks&amp;lt;/code&amp;gt;, your entities classes can be under &amp;lt;code&amp;gt;entities&amp;lt;/code&amp;gt;, your helper utilities can be under &amp;lt;code&amp;gt;helpers&amp;lt;/code&amp;gt;, etc.&lt;br /&gt;
&lt;br /&gt;
No matter how your final structure looks like it is highly recommended to add a &amp;lt;code&amp;gt;client&amp;lt;/code&amp;gt; subpackage under your main package. This helps to isolate your [[Sides/1.18|client-only code]] from the rest, such as your Screens and renderers.&lt;br /&gt;
&lt;br /&gt;
By keeping your code in clean subpackages, you can grow your mod much more organically.&lt;br /&gt;
&lt;br /&gt;
{{Tip|If you are unsure on how exactly you want to structure your mod it can be a good idea to look at the source of others to see how they did it.}}&lt;br /&gt;
&lt;br /&gt;
== Class Naming Schemes ==&lt;br /&gt;
&lt;br /&gt;
A common class naming scheme allows easier deciphering of the purpose of the class, and makes it easier for someone developing for your mod to find specific classes.&lt;br /&gt;
&lt;br /&gt;
The usual style is to use suffixes for your classes, for example:&lt;br /&gt;
&lt;br /&gt;
* An &amp;lt;code&amp;gt;Item&amp;lt;/code&amp;gt; called &amp;lt;code&amp;gt;PowerRing&amp;lt;/code&amp;gt; would have a class name of &amp;lt;code&amp;gt;PowerRingItem&amp;lt;/code&amp;gt;.&lt;br /&gt;
* A &amp;lt;code&amp;gt;Block&amp;lt;/code&amp;gt; called &amp;lt;code&amp;gt;NotDirt&amp;lt;/code&amp;gt; would have a class name of &amp;lt;code&amp;gt;NotDirtBlock&amp;lt;/code&amp;gt;.&lt;br /&gt;
* A &amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt; for a block called &amp;lt;code&amp;gt;SuperChewer&amp;lt;/code&amp;gt; would have a class name of &amp;lt;code&amp;gt;SuperChewerBlockEntity&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== The Mod File ==&lt;br /&gt;
&lt;br /&gt;
The main mod class - the class that is annotated with &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt; - is usually put into the main package of your mod, and not placed into a subpackage. This allows an easier time to access this, as your main mod class is the entrypoint of your mod.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt; annotation indicates to the mod loader that this class is the entry point of your mod. Each &amp;lt;code&amp;gt;@Mod&amp;lt;/code&amp;gt; annotation and their value should be paired with a mod id entry in your &amp;lt;code&amp;gt;mods.toml&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
== mods.toml file ==&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;
More information about the structure of this file and the possible configuration options available to you can be found on the [[Mods.toml file/1.18|dedicated page]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Getting Started/1.18|Category:Getting Started]]&lt;br /&gt;
[[Category:Beginner Topics/1.18|Category:Beginner Topics]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Potions/1.18&amp;diff=3212</id>
		<title>Potions/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Potions/1.18&amp;diff=3212"/>
		<updated>2022-06-10T07:45:31Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Potions to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A &amp;lt;code&amp;gt;Potion&amp;lt;/code&amp;gt; is simply a list of &amp;lt;code&amp;gt;MobEffectInstance&amp;lt;/code&amp;gt;s to be applied when used. Each &amp;lt;code&amp;gt;Potion&amp;lt;/code&amp;gt; gets applied to every &amp;lt;code&amp;gt;Items#POTION&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Items#SPLASH_POTION&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Items#LINGERING_POTION&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;Items#TIPPED_ARROW&amp;lt;/code&amp;gt;. Like mob effects, potions need to be [[Registration/1.18|registered]].&lt;br /&gt;
&lt;br /&gt;
== Creating a &amp;lt;code&amp;gt;Potion&amp;lt;/code&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;Potion&amp;lt;/code&amp;gt; requires a passed in list of &amp;lt;code&amp;gt;MobEffectInstance&amp;lt;/code&amp;gt;s to apply to the player when the potion is &amp;quot;consumed&amp;quot;. There is also a nullable parameter called &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; that can be set if you would like to use the same name for multiple potions (e.g. &amp;lt;code&amp;gt;SWIFTNESS&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;LONG_SWIFTNESS&amp;lt;/code&amp;gt; can be both &amp;lt;code&amp;gt;swiftness&amp;lt;/code&amp;gt; potions).&lt;br /&gt;
&lt;br /&gt;
== Adding a Brewing Recipe ==&lt;br /&gt;
&lt;br /&gt;
Brewing Recipes can be added using &amp;lt;code&amp;gt;BrewingRecipeRegistry::addRecipe&amp;lt;/code&amp;gt;. The most common constructor takes in an &amp;lt;code&amp;gt;Ingredient&amp;lt;/code&amp;gt; input, an &amp;lt;code&amp;gt;Ingredient&amp;lt;/code&amp;gt; reactant, and an &amp;lt;code&amp;gt;ItemStack&amp;lt;/code&amp;gt; output. This can be registered during &amp;lt;code&amp;gt;FMLCommonSetupEvent&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|If you want to use NBT information in your inputs (e.g. create a potion from another potion), you need to pass in an &amp;lt;code&amp;gt;NBTIngredient&amp;lt;/code&amp;gt; instead.}}&lt;br /&gt;
&lt;br /&gt;
{{Colored box|title=Alert|content=&amp;lt;code&amp;gt;BrewingRecipeRegistry&amp;lt;/code&amp;gt; is '''not''' thread-safe. It should be called within &amp;lt;code&amp;gt;enqueueWork&amp;lt;/code&amp;gt; in the specified parallel dispatch event.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Game Effects/1.18|Category:Game Effects]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Particles/1.18&amp;diff=3211</id>
		<title>Particles/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Particles/1.18&amp;diff=3211"/>
		<updated>2022-06-10T07:45:30Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Particles to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Particles are one of the few effects within the game that are used as polish to better improve immersion. Their usefulness also requires great caution due to how they are created and referenced in the game.&lt;br /&gt;
&lt;br /&gt;
== Sided Issues ==&lt;br /&gt;
Particles are problematic due to their presence only on the [[Sides/1.18|physical client]]. They have no existence on a server whatsoever. This means that if specific data from a server is needed, it needs to be synced from the server to create the particle on the client.&lt;br /&gt;
&lt;br /&gt;
== Creating a Particle ==&lt;br /&gt;
A particle can be broken up into four distinct classes. On the server, a &amp;lt;code&amp;gt;ParticleType&amp;lt;?&amp;gt;&amp;lt;/code&amp;gt; holds a &amp;lt;code&amp;gt;ParticleOptions&amp;lt;/code&amp;gt; to sync the information. On the client, a &amp;lt;code&amp;gt;ParticleProvider&amp;lt;/code&amp;gt; is used to generate a &amp;lt;code&amp;gt;Particle&amp;lt;/code&amp;gt; from the synced &amp;lt;code&amp;gt;ParticleOptions&amp;lt;/code&amp;gt;. To be more specific, a &amp;lt;code&amp;gt;ParticleType&amp;lt;?&amp;gt;&amp;lt;/code&amp;gt; holds the registry reference of the particle itself. A &amp;lt;code&amp;gt;ParticleOptions&amp;lt;/code&amp;gt; hooks into a &amp;lt;code&amp;gt;ParticleType&amp;lt;?&amp;gt;&amp;lt;/code&amp;gt; to send information to the &amp;lt;code&amp;gt;ParticleProvider&amp;lt;/code&amp;gt;. A &amp;lt;code&amp;gt;ParticleProvider&amp;lt;/code&amp;gt; creates the specified particle in some place within the level. Then, the &amp;lt;code&amp;gt;Particle&amp;lt;/code&amp;gt; goes and handles the rendering logic to make it appear in game.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;ParticleType&amp;lt;/code&amp;gt;s ===&lt;br /&gt;
&lt;br /&gt;
While there are a lot of different particles in vanilla, in almost all cases vanilla uses &amp;lt;code&amp;gt;SimpleParticleType&amp;lt;/code&amp;gt;, a basic implementation of &amp;lt;code&amp;gt;ParticleType&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ParticleOptions&amp;lt;/code&amp;gt;. This is used whenever server data is not necessary to spawn the particle. The only vanilla particles that do not use &amp;lt;code&amp;gt;SimpleParticleType&amp;lt;/code&amp;gt; are redstone dust and block/item texture dependent particles. When requiring server data, a direct implementation of &amp;lt;code&amp;gt;ParticleOptions&amp;lt;/code&amp;gt; is needed. A good way is to extend &amp;lt;code&amp;gt;ParticleType&amp;lt;?&amp;gt;&amp;lt;/code&amp;gt; and implement &amp;lt;code&amp;gt;ParticleOptions&amp;lt;/code&amp;gt; on the same class. In the case of a more generic solution, an implementation of &amp;lt;code&amp;gt;ParticleOptions&amp;lt;/code&amp;gt; can be referenced while the standard &amp;lt;code&amp;gt;ParticleType&amp;lt;?&amp;gt;&amp;lt;/code&amp;gt; class is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ParticleType&amp;lt;/code&amp;gt;s must be [[Registration#registering-things/1.18|registered]]. &lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;ParticleOptions&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Beside the standard reference to a &amp;lt;code&amp;gt;ParticleType&amp;lt;?&amp;gt;&amp;lt;/code&amp;gt;, a &amp;lt;code&amp;gt;ParticleOptions&amp;lt;/code&amp;gt; is made up of two main methods and two accessory methods for compatibility across Minecraft usage.&lt;br /&gt;
&lt;br /&gt;
First there are the sync methods:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
ParticleOptions#writeToNetwork(FriendlyByteBuf)&lt;br /&gt;
&lt;br /&gt;
ParticleOptions$Deserializer#fromNetwork(ParticleType, FriendlyByteBuf)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two are used to sync information across the network. All information from the server should be synced in this fashion.&lt;br /&gt;
&lt;br /&gt;
The other two are for compatibility with other Minecraft systems:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
ParticleOptions#writeToString&lt;br /&gt;
&lt;br /&gt;
ParticleOptions$Deserializer#fromCommand(ParticleType, StringReader)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two are used to read/write data to NBT as well as get information to spawn the particle in the level using a command.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;Particle&amp;lt;/code&amp;gt;s === &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Particle&amp;lt;/code&amp;gt;s will be left as an exercise to the reader as it is mainly about deciding what the reader wants to render to the screen. One of the most common classes to subclass, however, is &amp;lt;code&amp;gt;TextureSheetParticle&amp;lt;/code&amp;gt;. This abstract class renders a texture specified by the user as the particle to go according to the logic rendered.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;ParticleProvider&amp;lt;/code&amp;gt;s ===&lt;br /&gt;
Finally, a particle must be created using a &amp;lt;code&amp;gt;ParticleProvider&amp;lt;/code&amp;gt;. This simply just decides where the particle should be placed in the level at some speed in most cases. Since a &amp;lt;code&amp;gt;Particle&amp;lt;/code&amp;gt; is not beholden to any particular &amp;lt;code&amp;gt;ParticleType&amp;lt;?&amp;gt;&amp;lt;/code&amp;gt;, it can be reused over and over again in different factories if necessary.&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;code&amp;gt;ParticleProvider&amp;lt;/code&amp;gt; must be attached to a &amp;lt;code&amp;gt;ParticleType&amp;lt;/code&amp;gt; using &amp;lt;code&amp;gt;ParticleEngine#register&amp;lt;/code&amp;gt;. If a particle has a json defined sprite location, then the &amp;lt;code&amp;gt;ParticleEngine$SpriteParticleRegistration&amp;lt;/code&amp;gt; variant must be used instead as otherwise an exception will be thrown. This should be called during &amp;lt;code&amp;gt;ParticleFactoryRegisterEvent&amp;lt;/code&amp;gt; on the mod event bus.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|&amp;lt;code&amp;gt;ParticleProvider&amp;lt;/code&amp;gt; is only present on the client, so the event needs to be isolated via &amp;lt;code&amp;gt;DistExecutor&amp;lt;/code&amp;gt; or some other method.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Spawning Particles ==&lt;br /&gt;
Particles can be spawned from a level instance. Each side, however, has a specific way of calling them. The &amp;lt;code&amp;gt;ClientLevel&amp;lt;/code&amp;gt; can call either &amp;lt;code&amp;gt;addParticle&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;addAlwaysVisibleParticle&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;ServerLevel&amp;lt;/code&amp;gt; must call &amp;lt;code&amp;gt;sendParticles&amp;lt;/code&amp;gt; as it sends a packet to the client level to call one of the other two methods. Calling the two &amp;lt;code&amp;gt;ClientLevel&amp;lt;/code&amp;gt; methods on the server will result in nothing happening.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Game Effects/1.18|Category:Game Effects]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Networking_with_Entities/1.18&amp;diff=3210</id>
		<title>Networking with Entities/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Networking_with_Entities/1.18&amp;diff=3210"/>
		<updated>2022-06-10T07:45:28Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Networking with Entities to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In addition to regular network messages, there are various other systems provided to handle synchronizing entity data.&lt;br /&gt;
&lt;br /&gt;
== Spawn Data ==&lt;br /&gt;
&lt;br /&gt;
In general, the spawning of modded entities is handled seperately, by Forge.&lt;br /&gt;
&lt;br /&gt;
{{Colored box|title=Info|content=This means that simply extending a vanilla entity class may not inherit all its behaviour here. You may need to implement certain vanilla behaviours yourself.}}&lt;br /&gt;
&lt;br /&gt;
You can add extra data to the spawn packet Forge sends by implementing the following interface.&lt;br /&gt;
&lt;br /&gt;
===IEntityAdditionalSpawnData===&lt;br /&gt;
If your entity has data that is needed on the client, but doesn't change over time, then it can be added to the entity spawn packet using this interface. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;writeSpawnData()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;readSpawnData()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; control how the data should be en/decoded to/from the network buffer. Also override &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;getAddEntityPacket()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; to return &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;NetworkHooks.getEntitySpawningPacket(...)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for the data to be send.&lt;br /&gt;
&lt;br /&gt;
== Dynamic Data ==&lt;br /&gt;
&lt;br /&gt;
=== Data Parameters ===&lt;br /&gt;
&lt;br /&gt;
This is the main vanilla system for synchronizing entity data from the server to the client. As such, a number of vanilla examples are available to refer to.&lt;br /&gt;
&lt;br /&gt;
Firstly you need a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;EntityDataAccessor&amp;lt;T&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for the data you wish to keep synchronized. This should be stored as a static final field in your entity class, obtained by calling &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;SynchedEntityData.defineId()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and passing the entity class and a serializer for that type of data. The available serializer implementations can be found as static constants within the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;EntityDataSerializers&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
{{Colored box|title=Alert|content=You should '''only''' create data parameters for your own entities, ''within that entity's class''. Adding parameters to entities you do not control can cause the IDs used to send that data over the network to become desynchronized, causing difficult to debug crashes.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then, override &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Entity#defineSynchedData()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and call &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;this.entityData.define(...)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for each of your data parameters, passing the parameter and an initial value to use. Remember to always call &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;super.defineSynchedData()&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; first!&lt;br /&gt;
&lt;br /&gt;
You can then get and set these values via your entity's &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;entityData&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; instance. Changes made will be synchronized to the client automatically.&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Networking/1.18&amp;diff=3209</id>
		<title>Networking/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Networking/1.18&amp;diff=3209"/>
		<updated>2022-06-10T07:45:26Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Networking to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Communication between servers and clients is the backbone of a successful mod implementation.&lt;br /&gt;
&lt;br /&gt;
Read an [[Understanding Networking#overview/1.18|overview]] of why networking matters and the basic strategies in thinking about networking.&lt;br /&gt;
&lt;br /&gt;
There are a variety of techniques provided by Forge to facilitate communication - mostly built on top of [https://netty.io netty].&lt;br /&gt;
&lt;br /&gt;
The simplest, for a new mod, would be [[Using SimpleChannel/1.18|SimpleImpl]], where most of the complexity of the netty system is&lt;br /&gt;
abstracted away. It uses a message and handler style system.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
There are two primary goals in network communication:&lt;br /&gt;
&lt;br /&gt;
# Making sure the client view is &amp;quot;in sync&amp;quot; with the server view&lt;br /&gt;
#* The flower at coordinates X, Y, Z just grew&lt;br /&gt;
# Giving the client a way to tell the server that something has changed about the player&lt;br /&gt;
#* the player pressed a key&lt;br /&gt;
&lt;br /&gt;
The most common way to accomplish these goals is to pass messages between the client and the server. These messages will&lt;br /&gt;
usually be structured, containing data in a particular arrangement, for easy sending and receiving.&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Named_Binary_Tag/1.18&amp;diff=3208</id>
		<title>Named Binary Tag/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Named_Binary_Tag/1.18&amp;diff=3208"/>
		<updated>2022-06-10T07:45:24Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Named Binary Tag to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Information between two points are passed in many different ways in Minecraft. The most common of them is known as NBTs. NBTs are a structured binary file used to store information on the disk. They are also used as intermediaries to hold information that will be sent across a network. Understanding and utilizing NBTs properly is a good start to understanding disk storage in general.&lt;br /&gt;
&lt;br /&gt;
== NBT Types ==&lt;br /&gt;
There are a total of fourteen different nbt data types that can be parsed. The most common one to use is &amp;lt;code&amp;gt;CompoundTag&amp;lt;/code&amp;gt;s within a &amp;lt;code&amp;gt;BlockEntity&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Entity&amp;lt;/code&amp;gt; when it comes to writing to the disk. However, on capabilities, other types can be specified to reduce the space it takes on a file.&lt;br /&gt;
&lt;br /&gt;
All types implement &amp;lt;code&amp;gt;Tag&amp;lt;/code&amp;gt; in some fashion. This interface holds basic methods for writing to a file and copying itself. It also holds basic methods to determine the output to a chat line.&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; border=1&lt;br /&gt;
!Id !!Name !!Description &lt;br /&gt;
|-&lt;br /&gt;
|   0   ||   &amp;lt;code&amp;gt;EndTag&amp;lt;/code&amp;gt;   ||  Specifies the end of an nbt file. &lt;br /&gt;
|-&lt;br /&gt;
|   1   ||   &amp;lt;code&amp;gt;ByteTag&amp;lt;/code&amp;gt;   ||  Holds a byte. Also used to store a boolean value. &lt;br /&gt;
|-&lt;br /&gt;
|   2   ||   &amp;lt;code&amp;gt;ShortTag&amp;lt;/code&amp;gt;   ||  Holds a short. &lt;br /&gt;
|-&lt;br /&gt;
|   3   ||   &amp;lt;code&amp;gt;IntTag&amp;lt;/code&amp;gt;   ||  Holds an integer. &lt;br /&gt;
|-&lt;br /&gt;
|   4   ||   &amp;lt;code&amp;gt;LongTag&amp;lt;/code&amp;gt;   ||  Holds a long. &lt;br /&gt;
|-&lt;br /&gt;
|   5   ||   &amp;lt;code&amp;gt;FloatTag&amp;lt;/code&amp;gt;   ||  Holds a float. &lt;br /&gt;
|-&lt;br /&gt;
|   6   ||   &amp;lt;code&amp;gt;DoubleTag&amp;lt;/code&amp;gt;   ||  Holds a double. &lt;br /&gt;
|-&lt;br /&gt;
|   7   ||   &amp;lt;code&amp;gt;ByteArrayTag&amp;lt;/code&amp;gt;   ||  Holds a byte array. Can be parsed from an array of primitive bytes or a list of byte objects. &lt;br /&gt;
|-&lt;br /&gt;
|   8   ||   &amp;lt;code&amp;gt;StringTag&amp;lt;/code&amp;gt;   ||  Holds a string. &lt;br /&gt;
|-&lt;br /&gt;
|   9   ||   &amp;lt;code&amp;gt;ListTag&amp;lt;/code&amp;gt;   ||  Holds a list of a specific &amp;lt;code&amp;gt;Tag&amp;lt;/code&amp;gt;. &lt;br /&gt;
|-&lt;br /&gt;
|   10   ||   &amp;lt;code&amp;gt;CompoundTag&amp;lt;/code&amp;gt;   ||  Holds an object comprised of &amp;lt;code&amp;gt;Tag&amp;lt;/code&amp;gt;s. It works similarly to a java object where it can store other primitives, objects, or itself inside. &lt;br /&gt;
|-&lt;br /&gt;
|   11   ||   &amp;lt;code&amp;gt;IntArrayTag&amp;lt;/code&amp;gt;   ||  Holds an integer array. Can be parsed from an array of primitive integers or a list of integer objects. &lt;br /&gt;
|-&lt;br /&gt;
|   12   ||   &amp;lt;code&amp;gt;LongArrayTag&amp;lt;/code&amp;gt;   ||  Holds an long array. Can be parsed from an array of primitive long, a list of long objects, or a &amp;lt;code&amp;gt;LongSet&amp;lt;/code&amp;gt;. &lt;br /&gt;
|-&lt;br /&gt;
|   99   ||   &amp;lt;code&amp;gt;NumericTag&amp;lt;/code&amp;gt;   ||  Holds a generic number. Used when the specific &amp;lt;code&amp;gt;Tag&amp;lt;/code&amp;gt; for a number is not specified. All numbers can be converted to each other. &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In most cases, you will only have to deal with &amp;lt;code&amp;gt;CompoundTag&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ListTag&amp;lt;/code&amp;gt;. The others are usually handled internally by whichever type uses them.&lt;br /&gt;
&lt;br /&gt;
== Common Usages ==&lt;br /&gt;
&amp;lt;code&amp;gt;CompoundTag&amp;lt;/code&amp;gt;s are used similar to objects. You can &amp;lt;code&amp;gt;put&amp;lt;/code&amp;gt; and value within them using a key. You can then retrieve the value once again with that same key. It has specific methods for putting and getting most of the different types of data (e.g. an integer using &amp;lt;code&amp;gt;putInt&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;getInt&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ListTag&amp;lt;/code&amp;gt;s are functionally the same as &amp;lt;code&amp;gt;ArrayList&amp;lt;/code&amp;gt;s. You can &amp;lt;code&amp;gt;add&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;remove&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;set&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;get&amp;lt;/code&amp;gt; a specific NBT type.&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=NBT/1.18&amp;diff=3207</id>
		<title>NBT/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=NBT/1.18&amp;diff=3207"/>
		<updated>2022-06-10T07:45:22Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy NBT to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Named Binary Tag/1.18|Named Binary Tag]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Mods.toml_file/1.18&amp;diff=3206</id>
		<title>Mods.toml file/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Mods.toml_file/1.18&amp;diff=3206"/>
		<updated>2022-06-10T07:45:20Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Mods.toml file to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Mods.toml/1.18|Mods.toml]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Mods.toml/1.18&amp;diff=3205</id>
		<title>Mods.toml/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Mods.toml/1.18&amp;diff=3205"/>
		<updated>2022-06-10T07:45:18Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Mods.toml to MC1.18 archive&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.18.2 is version 40&lt;br /&gt;
loaderVersion=&amp;quot;[40,)&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/1.18|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/1.18|dependencies.examplemod]]&lt;br /&gt;
    modId=&amp;quot;forge&amp;quot;&lt;br /&gt;
    mandatory=true&lt;br /&gt;
    versionRange=&amp;quot;[40,)&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/1.18|dependencies.examplemod]]&lt;br /&gt;
    modId=&amp;quot;minecraft&amp;quot;&lt;br /&gt;
    mandatory=true&lt;br /&gt;
    versionRange=&amp;quot;[1.18.2,1.19)&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;[40,)&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/1.18|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/1.18|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/1.18|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/1.18|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/1.18|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/1.18|Category:Getting Started]]&lt;br /&gt;
[[Category:Beginner Topics/1.18|Category:Beginner Topics]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Model_JSONs/1.18&amp;diff=3204</id>
		<title>Model JSONs/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Model_JSONs/1.18&amp;diff=3204"/>
		<updated>2022-06-10T07:45:17Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Model JSONs to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A “model” is simply a shape. It can be a simple cube, it can be several cubes, it can be a truncated icosidodecahedron, or anything in between. Most models you’ll see will be in the vanilla JSON format. Models in other formats are loaded into an &amp;lt;code&amp;gt;IModelGeometry&amp;lt;/code&amp;gt; by an &amp;lt;code&amp;gt;IModelLoader&amp;lt;/code&amp;gt; at runtime. Forge provides default implementations for WaveFront OBJ files, buckets, composite models, models in different render layers, and a reimplementation of Vanilla's &amp;lt;code&amp;gt;builtin/generated&amp;lt;/code&amp;gt; item model. Most things do not care about what loaded the model or what format it’s in as they all &amp;quot;bake&amp;quot; into an &amp;lt;code&amp;gt;BakedModel&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; refers to a model, the path is normally relative to &amp;lt;code&amp;gt;models&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;examplemod:block/block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;assets/examplemod/models/block/block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Block and item models differ in a few ways, the major one being [[Item Overrides/1.18|item property overrides]].&lt;br /&gt;
&lt;br /&gt;
== Textures ==&lt;br /&gt;
Textures, like models, are contained within resource packs and are referred to with &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt;s. When &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt;s refer to textures in models, the paths are taken to be relative to &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;textures/&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; (e.g. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;examplemod:blocks/test&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; → &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;assets/examplemod/textures/blocks/test.png&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;). Additionally, in Minecraft, the [https://en.wikipedia.org/wiki/UV_mapping UV coordinates] (0,0) are taken to mean the ''&amp;lt;code&amp;gt;top-left&amp;lt;/code&amp;gt;'' corner. UVs are &amp;lt;code&amp;gt;always&amp;lt;/code&amp;gt; from 0 to 16. If a texture is larger or smaller, the coordinates are scaled to fit. A texture should also be square, and the side length of a texture should be a power of two, as doing otherwise breaks mipmapping. (E.g. 1x1, 2x2, 8x8, 16x16, and 128x128 are good. 5x5 and 30x30 are not recommended because they are not powers of 2. 5x10 and 4x8 are completely broken as they are not square.) If there is an &amp;lt;code&amp;gt;mcmeta&amp;lt;/code&amp;gt; file associated with the texture, and an animation is defined, the image can be rectangular and is interpreted as a vertical sequence of square regions from top to bottom, where each square is a frame of the animation.&lt;br /&gt;
&lt;br /&gt;
== JSON Models ==&lt;br /&gt;
Vanilla Minecraft’s JSON model format is rather simple. It defines cuboid (cube/rectangular prism) elements, and assigns textures to their faces. On the [https://minecraft.fandom.com/wiki/Model#Block_models wiki], there is a definition of its format.&lt;br /&gt;
&lt;br /&gt;
{{Colored box|title=Tip|content=JSON models only support cuboid elements; there is no way to express a triangular wedge or anything like it. To have more complicated models, another format must be used.}}&lt;br /&gt;
&lt;br /&gt;
When a &amp;lt;code&amp;gt;ResourceLocation&amp;lt;/code&amp;gt; refers to the location of a JSON model, it is not suffixed with &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;.json&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, unlike OBJ (e.g. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;minecraft:block/cube_all&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, not &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;minecraft:block/cube_all.json&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== WaveFront OBJ Models ==&lt;br /&gt;
Forge adds a loader for the &amp;lt;code&amp;gt;.obj&amp;lt;/code&amp;gt; file format. To use these models, the JSON must reference the &amp;lt;code&amp;gt;forge:obj&amp;lt;/code&amp;gt; loader. This loader accepts any model location that is in a registered namespace and whose path ends in &amp;lt;code&amp;gt;.obj&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;.mtl&amp;lt;/code&amp;gt; file should be placed in the same location with the same name as the &amp;lt;code&amp;gt;.obj&amp;lt;/code&amp;gt; to be used automatically. The &amp;lt;code&amp;gt;.mtl&amp;lt;/code&amp;gt; file will probably have to be manually edited to change the paths pointing to textures defined within the JSON. Additionally, the V axis for textures may be flipped depending on the external program that created the model (i.e. V = 0 may be the bottom edge, not the top). This may be rectified in the modelling program itself or done in the model JSON like so:&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;__comment&amp;quot;: &amp;quot;Add the following line on the same level as a 'model' declaration.&amp;quot;,&lt;br /&gt;
  &amp;quot;loader&amp;quot;: &amp;quot;forge:obj&amp;quot;,&lt;br /&gt;
  &amp;quot;flip-v&amp;quot;: true,&lt;br /&gt;
  &amp;quot;model&amp;quot;: &amp;quot;examplemod:models/block/model.obj&amp;quot;,&lt;br /&gt;
  &amp;quot;textures&amp;quot;: {&lt;br /&gt;
    &amp;quot;_comment&amp;quot;: &amp;quot;Can refer to in .mtl using #texture0&amp;quot;,&lt;br /&gt;
    &amp;quot;texture0&amp;quot;: &amp;quot;minecraft:block/dirt&amp;quot;,&lt;br /&gt;
    &amp;quot;particle&amp;quot;: &amp;quot;minecraft:block/dirt&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Models/1.18|Category:Models]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Mob_Effects/1.18&amp;diff=3203</id>
		<title>Mob Effects/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Mob_Effects/1.18&amp;diff=3203"/>
		<updated>2022-06-10T07:45:15Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Mob Effects to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A &amp;lt;code&amp;gt;MobEffect&amp;lt;/code&amp;gt; is what handles the specific logic on the entity it is on. For example, &amp;lt;code&amp;gt;MobEffects#MOVEMENT_SPEED&amp;lt;/code&amp;gt; adds an attribute modifier that affects the movement speed while &amp;lt;code&amp;gt;MobEffects#WITHER&amp;lt;/code&amp;gt; attacks the entity from a &amp;lt;code&amp;gt;DamageSource&amp;lt;/code&amp;gt; whenever the mob effect is ready to be applied.&lt;br /&gt;
&lt;br /&gt;
== Creating a &amp;lt;code&amp;gt;MobEffect&amp;lt;/code&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
You can create a &amp;lt;code&amp;gt;MobEffect&amp;lt;/code&amp;gt; using two methods. The first creates a regular &amp;lt;code&amp;gt;MobEffect&amp;lt;/code&amp;gt; and applies the logic in some event method. The other method involves extending the &amp;lt;code&amp;gt;MobEffect&amp;lt;/code&amp;gt; class and overriding specific methods when needed. This documentation will focus on the second method.&lt;br /&gt;
&lt;br /&gt;
There are four methods that are important depending on the type of mob effect you are creating. In each scenario, you should take into account whether you should extend &amp;lt;code&amp;gt;MobEffect&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;InstantenousMobEffect&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Here are the classes and methods to review:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; border=1&lt;br /&gt;
!Class !!Usage &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;MobEffect&amp;lt;/code&amp;gt;   ||  The basic mob effect class. Should be used if the mob effect happens over time. &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;InstantenousMobEffect&amp;lt;/code&amp;gt;   ||  An extended version of the mob effect class. Should be used if the mob effect happens only once and instantly. &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; border=1&lt;br /&gt;
!Method !!Description &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;isDurationEffectTick&amp;lt;/code&amp;gt;   ||  Determines how fast a mob effect should call &amp;lt;code&amp;gt;applyEffectTick&amp;lt;/code&amp;gt; while applied. This is overridden by &amp;lt;code&amp;gt;InstantenousMobEffect&amp;lt;/code&amp;gt; to occur after one tick. If too fast, the server will not have enough time to execute the damage on the entity. &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;applyEffectTick&amp;lt;/code&amp;gt;   ||  Executes the logic on the entity when called. &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;isInstantenous&amp;lt;/code&amp;gt;   ||  Determines if the mob effect is instant. Returns true in &amp;lt;code&amp;gt;InstantenousMobEffect&amp;lt;/code&amp;gt;. &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;applyInstantenousEffect&amp;lt;/code&amp;gt;   ||  Executes the logic on the entity when called. &amp;lt;code&amp;gt;isInstantenous&amp;lt;/code&amp;gt; must return true for this to be called. &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If you are only modifying an entity &amp;lt;code&amp;gt;Attribute&amp;lt;/code&amp;gt;, then there is no need to extend the class. When constructing the mob effect instance, chain &amp;lt;code&amp;gt;addAttributeModifier&amp;lt;/code&amp;gt; and select the specific attribute, it's unique id, the amount to affect by, and the operation to apply the amount with.&lt;br /&gt;
&lt;br /&gt;
Mob Effects need to be [[Registration/1.18|registered]].&lt;br /&gt;
&lt;br /&gt;
== &amp;lt;code&amp;gt;MobEffectInstance&amp;lt;/code&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
To allow greater customization, each mob effect is passed in as a &amp;lt;code&amp;gt;MobEffectInstance&amp;lt;/code&amp;gt; which allows the user to specify additional information for what the mob effect should do.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Game Effects/1.18|Category:Game Effects]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Making_Tools/1.18&amp;diff=3202</id>
		<title>Making Tools/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Making_Tools/1.18&amp;diff=3202"/>
		<updated>2022-06-10T07:45:13Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Making Tools to MC1.18 archive&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;Tag&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/1.18|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/1.18|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/1.18|Category:Items]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Making_Items/1.18&amp;diff=3201</id>
		<title>Making Items/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Making_Items/1.18&amp;diff=3201"/>
		<updated>2022-06-10T07:45:11Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Making Items to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Under construction}}&lt;br /&gt;
&lt;br /&gt;
Along with blocks, items are a key component of most mods. While blocks make up the world around you, items are what let you change it.&lt;br /&gt;
&lt;br /&gt;
== Creating an Item ==&lt;br /&gt;
=== Basic Items ===&lt;br /&gt;
Basic items that need no special functionality (think sticks or sugar) don’t need custom classes. You can create an item by instantiating the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Item&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; class with an &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Item$Properties&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; object. This &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Item$Properties&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; object can be made by calling the constructor and can be customised by calling its methods. For instance:&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; border=1&lt;br /&gt;
!Method                   !!Description   &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;tab&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;           ||  Sets which &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;CreativeModeTab&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; (previously called creative tab) this item is under. Must be called if this item is meant to be shown on the creative menu. Vanilla tabs can be found in the class &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;CreativeModeTab&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;durability&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;       ||  Sets the maximum damage value for this item. If it is greater than ''0'', the properties ''damaged'' and ''damage'' are added to keep track of the current ''ItemStack'' damage. &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;stacksTo&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;    ||  Sets the maximum stack size. You cannot have an item that is both damagable and stackable. &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;setNoRepair&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;     ||  Makes this item impossible to repair, even if it is damageable. &lt;br /&gt;
|-&lt;br /&gt;
|   &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;craftRemainder&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;   ||  Sets this item’s container item. For example, milk buckets give you back an empty bucket when they are crafted. &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The above methods are chainable, meaning they &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;return this&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; to facilitate calling them in series.&lt;br /&gt;
&lt;br /&gt;
=== Advanced Items ===&lt;br /&gt;
Setting the properties of an item as above only works for simple items. If you want more complicated items, you should subclass ''Item'' and override its methods.&lt;br /&gt;
&lt;br /&gt;
== Registering an Item ==&lt;br /&gt;
Items must be [[Registration/1.18|registered]] to function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Items/1.18|Category:Items]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Making_Blocks/1.18&amp;diff=3200</id>
		<title>Making Blocks/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Making_Blocks/1.18&amp;diff=3200"/>
		<updated>2022-06-10T07:45:09Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Making Blocks to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Blocks are, obviously, essential to the Minecraft world. They make up all of the terrain, structures, and machines. Chances are if you are interested in making a mod, then you will want to add some blocks. This page will guide you through the creation of blocks, and some of the things you can do with them.&lt;br /&gt;
==Creating a Block==&lt;br /&gt;
===Basic Blocks===&lt;br /&gt;
For simple blocks, which need no special functionality (think cobblestone, wooden planks, etc.), a custom class is not necessary. You can create a block by instantiating the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; class with a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockBehaviour$Properties&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; object. This &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockBehaviour$Properties&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; object can be made using &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockBehaviour$Properties::of&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and it can be customised by calling its methods. For instance:&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;strength&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; - The hardness controls the time it takes to break the block. It is an arbitrary value. For reference, stone has a hardness of 1.5, and dirt 0.5. If the block should be unbreakable a hardness of -1.0 should be used, see the definition of &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Blocks#BEDROCK&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; as an example. The resistance controls the explosion resistance of the block. For reference, stone has a resistance of 6.0, and dirt 0.5.&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;sound&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; - Controls the sound the block makes when it is punched, broken, or placed. Requires a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;SoundType&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; argument, see the [[Sounds/1.18|sounds]] page for more details.&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;lightLevel&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; - Controls the light emission of the block. Takes a function with a ''BlockState'' parameter that returns an integer value from zero to fifteen.&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;friction&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; - Controls how slippery the block is. For reference, ice has a slipperiness of 0.98.&lt;br /&gt;
&lt;br /&gt;
All these methods are ''chainable'' which means you can call them in series. See the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Blocks&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; class for examples of this.&lt;br /&gt;
&lt;br /&gt;
{{Colored box|title=Tip|content=Blocks have no setter for their &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;CreativeModeTab&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. This has been moved to the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockItem&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and is now its responsibility.}}&lt;br /&gt;
&lt;br /&gt;
===Advanced Blocks===&lt;br /&gt;
Of course, the above only allows for extremely basic blocks. If you want to add functionality, like player interaction, a custom class is required. However, the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; class has many methods and unfortunately not every single one can be documented here. See the rest of the pages in this section for things you can do with blocks.&lt;br /&gt;
==Registering a Block==&lt;br /&gt;
Blocks must be [[Registration/1.18|registered]] to function.&lt;br /&gt;
&lt;br /&gt;
{{Tip/Important|A block in the level and a &amp;quot;block&amp;quot; in an inventory are very different things. A block in the level is represented by a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockState&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, and its behavior defined by an instance of &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. Meanwhile, an item in an inventory is an &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;ItemStack&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, controlled by an &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Item&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. As a bridge between the different worlds of &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Item&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, there exists the class &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockItem&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockItem&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; is a subclass of &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Item&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; that has a field &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; that holds a reference to the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; it represents. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockItem&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; defines some of the behavior of a &amp;quot;block&amp;quot; as an item, like how a right click places the block. It's possible to have a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; without an &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockItem&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. (E.g. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;minecraft:water&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; exists as a block, but not an item. It is therefore impossible to hold it in an inventory as one.)&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
When a block is registered, ''only'' a block is registered. The block does not automatically have an &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockItem&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;. To create a basic &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockItem&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for a block, one should use &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;new BlockItem(block)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and match the registry name between the two objects. Custom subclasses of &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockItem&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; may be used as well. Once a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockItem&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; has been registered for a block, &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block#asItem&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; can be used to retrieve it. &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block#asItem&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; will default to &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Items#AIR&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; if there is no &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockItem&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;, so if you are not certain that there is a &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;BlockItem&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; for the &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Block&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; you are using, check for &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;Items#AIR&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Optionally Registering Blocks====&lt;br /&gt;
Since there is no limit on the amount of blocks that can be register, register all blocks in your mod! If you want a block to be disabled through a configuration file, you should disable the crafting recipe and/or remove the block from the creative menu (&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;CreativeModeTab&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;).&lt;br /&gt;
==Further Reading==&lt;br /&gt;
For information about block properties, such as those used for vanilla blocks like fences, walls, and many more, see the section on [[Understanding Blockstates/1.18|blockstates]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Blocks/1.18|Category:Blocks]]&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Main_Page/styles.css/1.18&amp;diff=3199</id>
		<title>Main Page/styles.css/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Main_Page/styles.css/1.18&amp;diff=3199"/>
		<updated>2022-06-10T07:45:07Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Main Page/styles.css to MC1.18 archive&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;.center {&lt;br /&gt;
  text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.title {&lt;br /&gt;
  font-weight: 900;&lt;br /&gt;
  font-size: 3em;&lt;br /&gt;
  line-height: 1.2em;&lt;br /&gt;
  color: #e0a969;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.round_warning {&lt;br /&gt;
  font-weight: 700;&lt;br /&gt;
  width: 60%;&lt;br /&gt;
  border-radius: 1em;&lt;br /&gt;
  margin: auto;&lt;br /&gt;
  margin-top: 1em;&lt;br /&gt;
  background-color: #fefefe;&lt;br /&gt;
  color: #222;&lt;br /&gt;
  height: 2em;&lt;br /&gt;
  display: flex;&lt;br /&gt;
  justify-content: center;&lt;br /&gt;
  align-items: center;&lt;br /&gt;
  padding: 0.25em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.round_warning p {&lt;br /&gt;
  margin-top: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.box_container {&lt;br /&gt;
  display: flex;&lt;br /&gt;
  flex-flow: row wrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.box {&lt;br /&gt;
  flex: 1 1 12em;&lt;br /&gt;
  padding: 1em;&lt;br /&gt;
  border: solid;&lt;br /&gt;
  border-radius: 1em;&lt;br /&gt;
  margin: 0.5em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.box h1, .box h2, .box h3 {&lt;br /&gt;
  margin-top: 0&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.box ul {&lt;br /&gt;
  list-style-type: none;&lt;br /&gt;
  margin-left: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.box ul li {&lt;br /&gt;
  line-height: 1.3em;&lt;br /&gt;
  margin-top: 0.45em;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Main_Page/1.18&amp;diff=3198</id>
		<title>Main Page/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Main_Page/1.18&amp;diff=3198"/>
		<updated>2022-06-10T07:45:05Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Main Page to MC1.18 archive&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/1.18|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/1.18|Getting Started]]&lt;br /&gt;
* [[Proper Mod Structuring/1.18|Proper Mod Structuring]]&lt;br /&gt;
* [[Mods.toml file/1.18|Mods.toml file]]&lt;br /&gt;
* [[Debug Profiler/1.18|The Debug Profiler]]&lt;br /&gt;
* [[Version Checker/1.18|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/1.18|Understanding Sides]]&lt;br /&gt;
* [[Events/1.18|Understanding Events]]&lt;br /&gt;
* [[Registration/1.18|Registration]]&lt;br /&gt;
* [[Internationalization/1.18|Internationalization]]&lt;br /&gt;
* [[Configs/1.18|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/1.18|Semantic Versioning]]&lt;br /&gt;
* [[Stages of Modloading/1.18|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/1.18|Introduction]]&lt;br /&gt;
* [[Recipes/1.18|Recipes]]&lt;br /&gt;
* [[Tags/1.18|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/1.18|Creating Blocks]]&lt;br /&gt;
* [[Understanding Blockstates/1.18|Understanding Blockstates]] &lt;br /&gt;
* [[Interacting With Blocks/1.18|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/1.18|Making Items]]&lt;br /&gt;
* [[Making Tools/1.18|Making Tools]]&lt;br /&gt;
* [[BlockEntityWithoutLevelRenderer/1.18|&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/1.18|Introduction]]&lt;br /&gt;
* [[Datageneration/Recipes/1.18|Recipes]]&lt;br /&gt;
* [[Datageneration/Tags/1.18|Tags]]&lt;br /&gt;
* [[Datageneration/Loot Tables/1.18|Loot Tables]]&lt;br /&gt;
* [[Datageneration/I18n/1.18|Localization]]&lt;br /&gt;
* [[Datageneration/States and Models/1.18|&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/1.18|Introduction]]&lt;br /&gt;
* [[Block Entity Renderer/1.18|&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/1.18|Introduction]]&lt;br /&gt;
* [[Model JSONs/1.18|Model JSONs]]&lt;br /&gt;
* [[BlockState JSONs/1.18|BlockState JSONs]]&lt;br /&gt;
* [[Coloring textures dynamically/1.18|Dynamically Colored Textures]]&lt;br /&gt;
* [[Item Properties/1.18|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/1.18|Introduction]]&lt;br /&gt;
* [[Using NBT/1.18|Named Binary Tag (NBT)]]&lt;br /&gt;
* [[Using FriendlyByteBuf/1.18|Using &amp;lt;tt&amp;gt;FriendlyByteBuf&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
* [[Sending Packets/1.18|Sending and Receiving Packets]]&lt;br /&gt;
* [[Using SimpleChannel/1.18|Using &amp;lt;tt&amp;gt;SimpleChannel&amp;lt;/tt&amp;gt;]]&lt;br /&gt;
* [[Networking with Entities/1.18|Networking with Entities]]&lt;br /&gt;
* [[DynamicOps/1.18|Using DynamicOps]]&lt;br /&gt;
* [[Codecs/1.18|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/1.18|Understanding Capabilities]] &lt;br /&gt;
* [[Capabilities/Attaching/1.18|Attaching Capabilities]]&lt;br /&gt;
* [[Saved Data/1.18|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/1.18|Mob Effects]]&lt;br /&gt;
* [[Potions/1.18|Potions]]&lt;br /&gt;
* [[Particles/1.18|Particles]]&lt;br /&gt;
* [[Sounds/1.18|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/1.18|Understanding Events]]&lt;br /&gt;
* [[Entity Events/1.18|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/1.18|Dependencies]]&lt;br /&gt;
* [[Dynamic Loot Modification/1.18|Dynamic Loot Modification]]&lt;br /&gt;
* [[Components/1.18|Components and Translation Keys]]&lt;br /&gt;
* [[Key Mappings/1.18|Key Mappings]]&lt;br /&gt;
* [[Access Transformers/1.18|Access Transformers]]&lt;br /&gt;
* [[Toolchain/1.18|Toolchain]]&lt;br /&gt;
* [[Game Tests/1.18|Game Tests]]&lt;br /&gt;
* [[Biome Modifiers/1.18|Biome Modifiers]]&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/1.18|Recipes]]&lt;br /&gt;
* [[Custom Recipes/1.18|Custom Recipe Types]]&lt;br /&gt;
* [[Datageneration/Recipes/1.18|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>ShrimpBot</name></author>
	</entry>
	<entry>
		<id>https://forge.gemwire.uk/index.php?title=Key_Mappings/1.18&amp;diff=3197</id>
		<title>Key Mappings/1.18</title>
		<link rel="alternate" type="text/html" href="https://forge.gemwire.uk/index.php?title=Key_Mappings/1.18&amp;diff=3197"/>
		<updated>2022-06-10T07:45:03Z</updated>

		<summary type="html">&lt;p&gt;ShrimpBot: Copy Key Mappings to MC1.18 archive&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/1.18|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;KeyMapping#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>ShrimpBot</name></author>
	</entry>
</feed>