<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.2.0">Jekyll</generator><link href="https://fabricmc.net/feed.xml" rel="self" type="application/atom+xml" /><link href="https://fabricmc.net/" rel="alternate" type="text/html" /><updated>2026-06-15T14:05:12+00:00</updated><id>https://fabricmc.net/feed.xml</id><title type="html">Fabric</title><subtitle>The home of the Fabric mod development toolchain.</subtitle><entry><title type="html">Fabric for Minecraft 26.2</title><link href="https://fabricmc.net/2026/06/15/262.html" rel="alternate" type="text/html" title="Fabric for Minecraft 26.2" /><published>2026-06-15T00:00:00+00:00</published><updated>2026-06-15T00:00:00+00:00</updated><id>https://fabricmc.net/2026/06/15/262</id><content type="html" xml:base="https://fabricmc.net/2026/06/15/262.html">&lt;p&gt;A new version of Minecraft is coming soon with some changes that affect most mod makers. As always, &lt;strong&gt;we ask all players to be patient, and give mod developers time to update to this new version&lt;/strong&gt;. We kindly ask everyone not to pester them. &lt;strong&gt;We also recommend all players make backups of their worlds&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;26.2 introduces the ability for the backend to be changed between the default OpenGL backend and an experimental Vulkan backend, with OpenGL planned to be removed once the Vulkan backend is stable. Developers making use of raw OpenGL calls rather than going through the Blaze3D API will need to migrate for their mods to work.&lt;/p&gt;

&lt;p&gt;Here is a list of several major modder-facing changes in this version, using the names provided by the unobfuscated game.&lt;/p&gt;

&lt;h2 id=&quot;fabric-changes&quot;&gt;Fabric changes&lt;/h2&gt;

&lt;p&gt;Developers should use Loom 1.17 and Gradle 9.5.1 (at the time of writing) to develop mods for Minecraft 26.2. Players should install the latest stable version of Fabric Loader (currently 0.19.3).&lt;/p&gt;

&lt;h3 id=&quot;enum-extensions&quot;&gt;Enum extensions&lt;/h3&gt;

&lt;p&gt;Fabric Loader 0.19.0 and Loom 1.17 bring with them a new API for enum extensions, implemented via Fabric Mixin at runtime and classtweaking at compile time. For more information, see the &lt;a href=&quot;https://docs.fabricmc.net/develop/class-tweakers/enum-extension&quot;&gt;dedicated article on the Fabric Docs&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;tag-removal&quot;&gt;Tag removal&lt;/h3&gt;

&lt;p&gt;Fabric API 0.150.1 introduced a new API for removing entries from tags, useful for both mod developers and modpack developers wishing to safely modify tags without replacing them in their entirety.&lt;/p&gt;

&lt;p&gt;As an example, the below will remove &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;minecraft:brick&lt;/code&gt; from the values of this tag. Other entries within &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#c:bricks&lt;/code&gt; will still be added.&lt;/p&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;replace&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;values&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#c:bricks&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;minecraft:snowball&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;fabric:remove&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;minecraft:brick&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;fluid-interaction-api&quot;&gt;Fluid interaction API&lt;/h3&gt;

&lt;p&gt;Fabric API 0.150.1 also introduced the currently experimental Fluid Interaction API, allowing mod developers greater control over how their fluids interact with entities. To use it, register a fluid tag containing your mod’s fluid, and an instance of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FluidBehaviour&lt;/code&gt;, which can either be created directly or via a builder.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;EntityFluidInteractionRegistry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ModTags&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ACID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; 
                                        &lt;span class=&quot;nc&quot;&gt;FluidBehavior&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;simple&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
                                        &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;allowBoats&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                                        &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;allowSwimming&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                                        &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;attended-client-commands&quot;&gt;Attended client commands&lt;/h3&gt;

&lt;p&gt;Fabric API 0.152.0 introduced the ability to set &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.requires(FabricClientCommandSource::attended)&lt;/code&gt; on client commands, allowing mods to ensure that the user has confirmed that they expect to run the given client command. Without this, the server could provide a text component that when clicked runs a client command without the user being able to see the command.&lt;/p&gt;

&lt;h2 id=&quot;minecraft-changes&quot;&gt;Minecraft changes&lt;/h2&gt;

&lt;p&gt;26.2 is a smaller update with more minor changes than 26.1, focused primarily on rendering (as always) and registration. We have only listed a few of the major non-rendering changes here. For a more comprehensive list of changes, please see &lt;a href=&quot;https://github.com/ChampionAsh5357/neoforged-github/blob/port%2F26.2/primers/26.2/index.md&quot;&gt;NeoForged’s upcoming porting “primer”&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;registration-and-data-generation&quot;&gt;Registration and data generation&lt;/h3&gt;

&lt;p&gt;The vanilla game now stores block ids and item ids seperately, in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BlockIds&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BlockItemIds&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemIds&lt;/code&gt;. These keys are used for data generation rather than the raw &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Block&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Item&lt;/code&gt; instances.&lt;/p&gt;

&lt;p&gt;This necessitated the removal of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;valueLookupBuilder&lt;/code&gt;. It’s recommended to match vanilla and seperate your ids from your Blocks as well.&lt;/p&gt;

&lt;h3 id=&quot;gui-reorganization&quot;&gt;Gui reorganization&lt;/h3&gt;

&lt;p&gt;Various GUI and HUD methods have been moved to dedicated classes for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Gui&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Hud&lt;/code&gt;, which included moving the methods for retrieving and setting the current screen out of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Minecraft&lt;/code&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Gui&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Hud&lt;/code&gt; are both available from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Minecraft&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;//&lt;/span&gt; Setting the screen
&lt;span class=&quot;gd&quot;&gt;- Minecraft.getInstance().setScreen()
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ Minecraft.getInstance().gui.setScreen()
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><author><name></name></author><summary type="html">A new version of Minecraft is coming soon with some changes that affect most mod makers. As always, we ask all players to be patient, and give mod developers time to update to this new version. We kindly ask everyone not to pester them. We also recommend all players make backups of their worlds.</summary></entry><entry><title type="html">Fabric for Minecraft 26.1</title><link href="https://fabricmc.net/2026/03/14/261.html" rel="alternate" type="text/html" title="Fabric for Minecraft 26.1" /><published>2026-03-14T00:00:00+00:00</published><updated>2026-03-14T00:00:00+00:00</updated><id>https://fabricmc.net/2026/03/14/261</id><content type="html" xml:base="https://fabricmc.net/2026/03/14/261.html">&lt;p&gt;A new version of Minecraft is coming soon with changes that will affect all mod makers. As always, &lt;strong&gt;we ask all players to be patient, and give mod developers time to update to this new version&lt;/strong&gt;. We kindly ask everyone not to pester them. &lt;strong&gt;We also recommend all players make backups of their worlds, especially due to the major changes to world storage in this version&lt;/strong&gt;.&lt;/p&gt;

&lt;p align=&quot;center&quot;&gt;
  &lt;img src=&quot;/assets/forklift.png&quot; style=&quot;max-width: 400px; height: auto;&quot; alt=&quot;Tiny Potato in a fork lift, by Superkat32&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;Preparing Fabric to support and full embrace the changes in 26.1 has been a major focus for the last several months by many contributors. The changes in the tooling and API are the largest we have ever made for a single release. There are still some rough edges and missing features however the changes put us in a great position to continue to update and improve Fabric for the foreseeable future. We are excited to see what the community will create with the new possibilities that 26.1 opens up.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://fabricmc.net/2025/10/31/obfuscation.html&quot;&gt;26.1 is the first version of Minecraft to not be obfuscated&lt;/a&gt;. Because of that, &lt;strong&gt;no mods from 1.21.11 or before will work without, at a minimum, recompilation.&lt;/strong&gt; If you have not yet &lt;a href=&quot;https://docs.fabricmc.net/develop/migrating-mappings/&quot;&gt;transitioned your mods to Mojang’s mappings&lt;/a&gt;, now is the time to do so, as Yarn is no longer officially supported by Fabric.&lt;/p&gt;

&lt;p&gt;26.1 is also expected to be the last Minecraft release to solely support OpenGL, with 26.2 snapshots expected to allow for &lt;a href=&quot;https://www.minecraft.net/en-us/article/another-step-towards-vibrant-visuals-for-java-edition&quot;&gt;the backend to be changed between OpenGL and Vulkan&lt;/a&gt;, with OpenGL planned to be removed once the Vulkan backend is stable. Developers making use of raw OpenGL calls rather than going through the Blaze3D API will need to migrate for their mods to work.&lt;/p&gt;

&lt;p&gt;Here is a list of several major modder-facing changes in this version. Note that all code references are using Mojang’s official names.&lt;/p&gt;

&lt;h2 id=&quot;fabric-changes&quot;&gt;Fabric changes&lt;/h2&gt;

&lt;p&gt;Developers should use Loom 1.15 and Gradle 9.4.0 (at the time of writing) to develop mods for Minecraft 26.1. Players should install the latest stable version of Fabric Loader (currently 0.18.4).&lt;/p&gt;

&lt;p&gt;Minecraft 26.1 requires &lt;strong&gt;Java 25&lt;/strong&gt; minimum for the Gradle JVM. You can configure this in your IDE’s Gradle Settings. Additionally, if you are using IntelliJ IDEA, version &lt;strong&gt;2025.3&lt;/strong&gt; or above is required for mixins to work correctly.&lt;/p&gt;

&lt;p&gt;Note: The Fabric Model Loading API and Renderer/Indigo modules may not be available for the inital release of 26.1, but we hope to have them updated as soon as they are ready. If you are interested in helping with the development of these modules, please reach out to us on our Discord server.&lt;/p&gt;

&lt;h3 id=&quot;deprecations-and-removals&quot;&gt;Deprecations and removals&lt;/h3&gt;

&lt;p&gt;Fabric API no longer provides the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fabric&lt;/code&gt; mod ID, which was deprecated more than three years ago. If your mod’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fabric.mod.json&lt;/code&gt; depends on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fabric&lt;/code&gt; and not &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fabric-api&lt;/code&gt;, you will need to fix that.&lt;/p&gt;

&lt;p&gt;The following previously deprecated modules have been removed.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fabric-convention-tags-v1&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fabric-loot-api-v2&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition, deprecated conventional tags labeled for removal in 1.22 have finally been removed (&lt;a href=&quot;https://github.com/FabricMC/fabric-api/pull/5056&quot;&gt;#5056&lt;/a&gt;), and the deprecated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HudRenderCallback&lt;/code&gt; event has been removed in favour of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HudElementRegistry&lt;/code&gt;. As always, other APIs have been changed in response to 26.1 refactors, see below for more information.&lt;/p&gt;

&lt;h3 id=&quot;unobfuscated-loom&quot;&gt;Unobfuscated Loom&lt;/h3&gt;

&lt;p&gt;As mappings are not provided for 26.1, developers should switch from the old &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;net.fabricmc.fabric-loom-remap&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fabric-loom&lt;/code&gt; plugins to the new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;net.fabricmc.fabric-loom&lt;/code&gt; plugin, which does not remap Minecraft or mods. Any use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;modImplementation&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;modCompileOnly&lt;/code&gt;, or similar should be switched out for the standard &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;implementation&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;compileOnly&lt;/code&gt;, and any use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;remapJar&lt;/code&gt; should be switched out for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jar&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For further details, see the &lt;a href=&quot;https://docs.fabricmc.net/develop/porting/next#build-script&quot;&gt;buildscript changes&lt;/a&gt; on the Fabric Docs and the new &lt;a href=&quot;https://fabricmc.net/develop/template/&quot;&gt;Fabric example mod&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;fabric-api-renames&quot;&gt;Fabric API renames&lt;/h3&gt;

&lt;p&gt;Previously, Fabric API was built with Yarn mappings in mind, but with the move to official mappings, API names have been updated to match the official names where applicable. These changes are not backwards compatible, so you will need to update your mod to use the new names. As an example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemGroupEvents&lt;/code&gt; became &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CreativeModeTabEvents&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For a full list of changes, as well as an IntelliJ IDEA migration map to automatically make these changes, please see the &lt;a href=&quot;https://docs.fabricmc.net/develop/porting/26.1/fabric-api&quot;&gt;Fabric Docs&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;new-fabric-api-changes&quot;&gt;New Fabric API changes&lt;/h3&gt;

&lt;h4 id=&quot;dimension-events&quot;&gt;Dimension events&lt;/h4&gt;

&lt;p&gt;Rather than use the biome modification API to iterate through and modifying every individual biome within a dimension, Fabric now provides an event that directly interacts with a dimension’s attributes. Datapack and modpack creators still retain granular control, as dimension-level modifications are designed with lower priority than biome-specific definitions during attribute evaluation in vanilla.&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;DimensionEvents&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;MODIFY_ATTRIBUTES&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dimension&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;registries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dimension&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;is&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BuiltinDimensionTypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;OVERWORLD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;EnvironmentAttributes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;CLOUD_COLOR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;PURPLE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;blockitem-events&quot;&gt;Block/Item events&lt;/h4&gt;

&lt;p&gt;Fabric now provides 4 new events which allow for more precise modification of item/block use interactions.
Compared to the existing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UseBlockCallback&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UseItemCallback&lt;/code&gt; events, these new events run only in specific contexts and keep the rest of vanilla logic around the use method calls.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BlockEvents#USE_ITEM_ON&lt;/code&gt; - called before &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Block#useItemOn&lt;/code&gt;, replacing it for non-null returns.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BlockEvents#USE_WITHOUT_ITEM&lt;/code&gt; - called before &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Block#useWithoutItem&lt;/code&gt;, replacing it for non-null returns.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemEvents#USE_ON&lt;/code&gt; - called before &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Item#useOn&lt;/code&gt;, replacing it for non-null returns.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemEvents#USE&lt;/code&gt; - called before &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Item#use&lt;/code&gt;, replacing it for non-null returns.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;block-color-registry&quot;&gt;Block Color Registry&lt;/h4&gt;

&lt;p&gt;As &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ColorProviderRegistry&lt;/code&gt; has solely been used for blocks since 1.21.4, its implementation has been simplified in 26.1 to the new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BlockColorRegistry&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Old code:&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;ColorProviderRegistry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;BLOCK&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tintIndex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[...],&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ModBlocks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;EXAMPLE_BLOCK&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;New code:&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;BlockColorRegistry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BlockTintSource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;o&quot;&gt;[...]&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}),&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ModBlocks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;EXAMPLE_BLOCK&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;minecraft-changes&quot;&gt;Minecraft changes&lt;/h2&gt;

&lt;p&gt;26.1 is a very large update with many changes, especially to the rendering engine. We have only listed a few of the major non-rendering changes here. For a more comprehensive list of changes, please see &lt;a href=&quot;https://docs.neoforged.net/primer/docs/26.1/&quot;&gt;NeoForged’s porting “primer”&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;itemstacktemplate&quot;&gt;ItemStackTemplate&lt;/h3&gt;

&lt;p&gt;An &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemStack&lt;/code&gt; can no longer be created until a world is loaded. As a replacement, the game provides a new class, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemStackTemplate&lt;/code&gt;, an immutable class representing an non-empty &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Item&lt;/code&gt;, a count, and a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DataComponentPatch&lt;/code&gt;. Many methods that used to return an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemStack&lt;/code&gt; now return an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemStackTemplate&lt;/code&gt;. Note that until the world is launched, components on an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemStackTemplate&lt;/code&gt; are not bound and the game will throw if they are accessed too early.&lt;/p&gt;

&lt;h3 id=&quot;recipe-serializers&quot;&gt;Recipe serializers&lt;/h3&gt;

&lt;p&gt;Rather than having every recipe have an inner class than implements &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RecipeSerializer&lt;/code&gt;, recipe serializers have been simplified to just be a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MapCodec&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StreamCodec&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Registry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BuiltInRegistries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;RECIPE_SERIALIZE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;mod_recipe&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RecipeSerializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ModRecipe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;CODEC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ModRecipe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;STREAM_CODEC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;automatically-set-render-layers&quot;&gt;Automatically set render layers&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ChunkSectionLayer&lt;/code&gt; is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RenderType&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RenderLayer&lt;/code&gt;’s replacement for terrain. Whereas before you had to manually register blocks to chunk layers like this…&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Before BlockRenderLayer (Yarn)&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;BlockRenderLayerMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;INSTANCE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;putBlock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;MyModBlocks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TATER_GLASS_BLOCK&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RenderLayer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TRANSLUCENT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// 1.21.6 (Yarn)&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;BlockRenderLayerMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;putBlock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;MyModBlocks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TATER_GLASS_BLOCK&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BlockRenderLayer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TRANSLUCENT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;…Minecraft now automatically sets the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ChunkSectionLayer&lt;/code&gt; for each quad based on the assigned sprite’s properties which are as follows:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Translucency: the sprite has translucent pixels&lt;/li&gt;
  &lt;li&gt;Cutout: the sprite has only solid and transparent pixels&lt;/li&gt;
  &lt;li&gt;Solid: the sprite has no transparency or translucency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This can be overridden with a &lt;a href=&quot;&quot;&gt;block model&lt;/a&gt; or with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MutableQuadView&lt;/code&gt; and Model Loading API.&lt;/p&gt;

&lt;h3 id=&quot;villager-trading&quot;&gt;Villager trading&lt;/h3&gt;

&lt;p&gt;Villager trading, including Wandering Traders, has been made data-driven in 26.1, removing the need for Fabric’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TradeOfferHelper&lt;/code&gt; API. A &lt;a href=&quot;https://minecraft.wiki/w/Villager_trade_definition&quot;&gt;villager trade&lt;/a&gt; is stored in the new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data/&amp;lt;namespace&amp;gt;/villager_trade&lt;/code&gt; directory, a &lt;a href=&quot;https://minecraft.wiki/w/Trade_set&quot;&gt;set of trades&lt;/a&gt; is defined in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data/&amp;lt;namespace&amp;gt;/trade_set&lt;/code&gt; folder, which uses tags in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data/minecraft/tags/villager_trade/&amp;lt;profession&amp;gt;&lt;/code&gt; folders.&lt;/p&gt;

&lt;p&gt;In general, to add your mod’s trade to an existing profession:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Create a new &lt;a href=&quot;https://minecraft.wiki/w/Villager_trade_definition&quot;&gt;villager trade&lt;/a&gt; in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data/&amp;lt;namespace&amp;gt;/villager_trade&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Add it to the appropriate tag in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data/minecraft/tags/villager_trade/&amp;lt;profession&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;fluid-rendering&quot;&gt;Fluid rendering&lt;/h3&gt;

&lt;p&gt;The new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FluidModel&lt;/code&gt; replaces a lot of functionality previously provided by Fabric API’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FluidRenderHandler&lt;/code&gt;. You can register an unbaked fluid model by creating a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FluidModel.Unbaked&lt;/code&gt;and registering it with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FluidRenderingRegistry.register&lt;/code&gt;. In most cases there is no longer a need to create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FluidRenderHandler&lt;/code&gt; for your mod’s fluids.&lt;/p&gt;

&lt;h2 id=&quot;mcsrcdev&quot;&gt;mcsrc.dev&lt;/h2&gt;

&lt;p&gt;Over the last few months we have been developing &lt;a href=&quot;https://mcsrc.dev&quot;&gt;mcsrc.dev&lt;/a&gt;, a new online tool to view the decompiled source code of Minecraft. It works by downloading the Minecraft jar directly from Mojang’s servers, decompiling it with Vineflower that has been compiled to WASM. mcsrc.dev also provides tools to aid with creating mixins and AccessWideners/ClassTweakers. We have plans to use this as the base for a javadoc editor that will allow users to provide documentation for Minecraft, this is still in the early stages of development.&lt;/p&gt;</content><author><name></name></author><summary type="html">A new version of Minecraft is coming soon with changes that will affect all mod makers. As always, we ask all players to be patient, and give mod developers time to update to this new version. We kindly ask everyone not to pester them. We also recommend all players make backups of their worlds, especially due to the major changes to world storage in this version.</summary></entry><entry><title type="html">Fabric for Minecraft 1.21.11</title><link href="https://fabricmc.net/2025/12/05/12111.html" rel="alternate" type="text/html" title="Fabric for Minecraft 1.21.11" /><published>2025-12-05T00:00:00+00:00</published><updated>2025-12-05T00:00:00+00:00</updated><id>https://fabricmc.net/2025/12/05/12111</id><content type="html" xml:base="https://fabricmc.net/2025/12/05/12111.html">&lt;p&gt;A new version of Minecraft is coming soon with some changes that affect most mod makers. As always, &lt;strong&gt;we ask all players to be patient, and give mod developers time to update to this new version&lt;/strong&gt;. We kindly ask everyone not to pester them. &lt;strong&gt;We also recommend all players make backups of their worlds&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As you may be aware, we expect &lt;a href=&quot;https://www.minecraft.net/en-us/article/removing-obfuscation-in-java-edition&quot;&gt;1.21.11 to be the last version of Minecraft that is obfuscated&lt;/a&gt;. The next snapshot will be the first version of Minecraft that will &lt;strong&gt;not&lt;/strong&gt; be obfuscated.&lt;/p&gt;

&lt;p&gt;Mojang have also recently announced that they will be &lt;a href=&quot;https://www.minecraft.net/en-us/article/minecraft-new-version-numbering-system&quot;&gt;changing how the game is versioned&lt;/a&gt;. The next version will be known as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;26.1&lt;/code&gt;. This new versioning nicely lines up with the unobfuscation process, as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1.21.11&lt;/code&gt; will be the last obfuscated version.&lt;/p&gt;

&lt;p&gt;Here is a list of several major modder-facing changes in this version. Note that all code references are using Mojang’s mappings; modders using alternative mappings, including our previously default Yarn mappings, may need to use different names.&lt;/p&gt;

&lt;h2 id=&quot;fabric-changes&quot;&gt;Fabric changes&lt;/h2&gt;

&lt;p&gt;Developers should use Loom 1.14 (at the time of writing) to develop mods for Minecraft 1.21.11. Players should install the latest stable version of Fabric Loader (currently 0.18.1).&lt;/p&gt;

&lt;h3 id=&quot;world-render-events&quot;&gt;World Render Events&lt;/h3&gt;

&lt;p&gt;The World Render Events were recently reintroduced into Fabric API for 1.21.10. Mods that required them to port can now do so. The new World Render Events are intended to match with recent changes to Minecraft itself, focusing on separating extraction from rendering.&lt;/p&gt;

&lt;p&gt;Rendering in the world has been documented on the &lt;a href=&quot;https://docs.fabricmc.net/develop/rendering/world&quot;&gt;Fabric Docs&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;packet-splitter-and-recipe-sync-api&quot;&gt;Packet Splitter and Recipe Sync API&lt;/h3&gt;

&lt;p&gt;Fabric now offers an opt-in packet splitter, allowing for mods that have packets that would exceed the size of a vanilla one to easily be split between multiple packets.&lt;/p&gt;

&lt;p&gt;Implementing the packet splitter is simple - use the new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;registerLarge&lt;/code&gt; method when registering your packet.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;PayloadTypeRegistry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;playS2C&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;registerLarge&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;YourPayload&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;YourPayload&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;CODEC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DATA_SIZE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Thanks to this API, Fabric also now offers a way for mods to synchronize recipes from the server to the client, comparable to the behavior prior to 1.21.1. This API has already been adopted by recipe viewers like JEI, but means that recipe viewers are required on the server.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;RecipeSynchronization&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;synchronizeRecipeSerializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;YourRecipeSerializers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;RECIPE_TYPE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;minecraft-changes&quot;&gt;Minecraft changes&lt;/h2&gt;

&lt;p&gt;The following section details a few of the more notable changes to Minecraft that affected the Fabric API.&lt;/p&gt;

&lt;h3 id=&quot;game-rules&quot;&gt;Game rules&lt;/h3&gt;

&lt;p&gt;Game rules were refactored to use the Registry system; Mods should now use the new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GameRuleBuilder&lt;/code&gt; API to create and register custom game rules.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GameRule&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Boolean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;EXAMPLE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GameRuleBuilder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;forBoolean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;buildAndRegister&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Identifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fromNamespaceAndPath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;fabric&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;example&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The above snippet creates and registers a new boolean game rule with the default value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GameRuleBuilder&lt;/code&gt; API provides the following factory methods &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forInteger&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forDouble&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forBoolean&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forEnum&lt;/code&gt; to create game rules of different types. The builder also allows for additional configuration such as setting the category, required features and command result suppiler.&lt;/p&gt;

&lt;p&gt;The new version of Fabric API also includes a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GameRuleEvents&lt;/code&gt; class that provides an event for listening to game rule changes. Mods can use this event to perform actions when a game rule is changed.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;GameRuleEvents&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;changeCallback&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;GameRules&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;FIRE_DAMAGE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;c1&quot;&gt;// Your code here&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;environment-attributes&quot;&gt;Environment Attributes&lt;/h3&gt;

&lt;p&gt;The Biome Modification API has been updated to support the new Environment Attributes system. Mods can now modify environment attributes such as temperature, humidity, and altitude for biomes using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BiomeModificationContext#AttributesContext&lt;/code&gt; class. You can access the attributes context by using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getAttributes()&lt;/code&gt; method on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BiomeModificationContext&lt;/code&gt; object.&lt;/p&gt;

&lt;h2 id=&quot;an-update-on-unobfuscation&quot;&gt;An update on unobfuscation&lt;/h2&gt;

&lt;p&gt;Alongside updating to each 1.21.11 snapshot, Fabric has been working towards &lt;a href=&quot;https://fabricmc.net/2025/10/31/obfuscation.html&quot;&gt;making this transition as smooth as possible&lt;/a&gt;. Currently, Mojang has been releasing experimental unobfuscated versions of Minecraft alongside the obfuscated ones, allowing us to test and prepare for the transition.&lt;/p&gt;

&lt;p&gt;With that in mind, this is a good time to begin &lt;a href=&quot;https://docs.fabricmc.net/develop/migrating-mappings/&quot;&gt;remapping your mods to the official Mojang Mappings&lt;/a&gt;, as Yarn will not be available for the version of Minecraft after 1.21.11. The differences between Mojang mappings and the unobfuscated game do not affect compilation, so switching to Mojang mappings now will allow for an easier transition when porting to future snapshots. There is no immediate rush to do this, as we anticipate the first unobfuscated stable release will be a few months into 2026.&lt;/p&gt;

&lt;p&gt;The unobfuscation process has raised many questions. We’ve answered some of the more common ones here, but please reach out in the Fabric Discord if you have any specific questions.&lt;/p&gt;

&lt;h3 id=&quot;is-12111-obfuscated-or-not&quot;&gt;Is 1.21.11 obfuscated or not?&lt;/h3&gt;

&lt;p&gt;Yes, 1.21.11 is still obfuscated. The next version of Minecraft after 1.21.11, &lt;a href=&quot;https://www.minecraft.net/en-us/article/minecraft-new-version-numbering-system&quot;&gt;26.1&lt;/a&gt;, will be the first unobfuscated version.&lt;/p&gt;

&lt;h3 id=&quot;are-yarn-and-intermediary-still-going-to-be-updated-past-12111&quot;&gt;Are Yarn and Intermediary still going to be updated past 1.21.11?&lt;/h3&gt;

&lt;p&gt;No, the plan is to stop updating Yarn and Intermediary after 1.21.11. Modders should begin migrating to Mojang Mappings as soon as possible.&lt;/p&gt;

&lt;h3 id=&quot;what-if-i-want-to-use-custom-mappings&quot;&gt;What if I want to use custom mappings?&lt;/h3&gt;

&lt;p&gt;You can still opt to use custom mappings, we plan to continue to maintain support for remapping in Loom. However, please be aware that using custom mappings may require additional work to ensure compatibility with the unobfuscated game and other mods.&lt;/p&gt;

&lt;h3 id=&quot;will-my-simple-mod-still-work-on-261-without-changes&quot;&gt;Will my simple mod still work on 26.1 without changes?&lt;/h3&gt;

&lt;p&gt;No, all mods that interact with Minecraft code will need to be recompiled to be compatible with the unobfuscated version of Minecraft.&lt;/p&gt;

&lt;h3 id=&quot;my-mod-is-using-yarn-mappings-how-do-i-migrate&quot;&gt;My mod is using Yarn mappings, how do I migrate?&lt;/h3&gt;

&lt;p&gt;We’ve put together an updated article on the &lt;a href=&quot;https://docs.fabricmc.net/develop/migrating-mappings/&quot;&gt;Fabric Docs site&lt;/a&gt; that covers the process of migrating mappings. In short - Loom should be able to handle most mods, and is now able to remap mixins, and third-party tools like Ravel can be used for more complicated projects (like Fabric API itself) or mods using Kotlin.&lt;/p&gt;

&lt;h3 id=&quot;what-is-intermediary&quot;&gt;What is Intermediary?&lt;/h3&gt;

&lt;p&gt;Intermediary is a project we used to create stable names for Minecraft code across versions. This worked by giving each unique class, method, and field an ID that would remain the same across versions. This is not the same as the obfuscated names that Mojang uses as these change completely with each version. Intermediary allowed mods compiled against one version of Minecraft to continue working on future versions, as long as the underlying code did not change significantly.&lt;/p&gt;

&lt;p&gt;Once the game is unobfuscated, there will no longer be a need for Intermediary, as method names should no longer change drastically between releases.&lt;/p&gt;

&lt;h3 id=&quot;what-changes-if-i-am-already-using-mojangs-mappings&quot;&gt;What changes if I am already using Mojang’s mappings?&lt;/h3&gt;

&lt;p&gt;If you are already using Mojang Mappings, the transition to the unobfuscated version of Minecraft should be relatively smooth. You may need to adjust any code that relies on synthetic methods or fields (search for ‘method_’ or ‘field_’ in your project.). Any usage of Fabric Loader’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MappingResolver&lt;/code&gt; can likely be removed. You will need to migrate your build script to the new Loom variant that does not support remapping. We will provide more detailed guidance as we get closer to the release of the unobfuscated version of Minecraft.&lt;/p&gt;

&lt;h3 id=&quot;will-fabric-be-quicker-to-update&quot;&gt;Will Fabric be quicker to update?&lt;/h3&gt;

&lt;p&gt;Yes! With the removal of obfuscation, we no longer need to manually update Yarn and Intermediary for each new version of Minecraft. This means that Fabric Loader and Loom will be able to use new versions as soon as they are released by Mojang. Fabric API will still require updates to accommodate changes to Minecraft itself. For stable releases where Fabric API has already been updated to a release candidate, we expect there will be no delay in fully supporting the new version of Minecraft.&lt;/p&gt;

&lt;h3 id=&quot;so-minecraft-is-open-source-now&quot;&gt;So Minecraft is open source now?&lt;/h3&gt;

&lt;p&gt;No, nothing really changes in that regard. Mojang previously released their obfuscation mappings publicly allowing anyone to see the deobfuscated names of classes, methods, and fields if they remaped the code. This change simply means that the code itself that players use will no longer be obfuscated, making it easier for modders to work with without needing an extra step. The Minecraft &lt;a href=&quot;https://www.minecraft.net/en-us/eula&quot;&gt;EULA&lt;/a&gt; has also not changed.&lt;/p&gt;

&lt;h3 id=&quot;how-much-easier-will-modding-be&quot;&gt;How much easier will modding be?&lt;/h3&gt;

&lt;p&gt;A little bit, as local variable names will now be available in the code, which helps to make debugging and understanding Minecraft’s code easier. Crash reports will no longer require translation. However, developing mods will still require a good understanding of Java, Minecraft’s systems and the modding APIs being used. This will not allow mods to do anything they weren’t able to do before.&lt;/p&gt;</content><author><name></name></author><summary type="html">A new version of Minecraft is coming soon with some changes that affect most mod makers. As always, we ask all players to be patient, and give mod developers time to update to this new version. We kindly ask everyone not to pester them. We also recommend all players make backups of their worlds.</summary></entry><entry><title type="html">Removing Obfuscation from Fabric</title><link href="https://fabricmc.net/2025/10/31/obfuscation.html" rel="alternate" type="text/html" title="Removing Obfuscation from Fabric" /><published>2025-10-31T00:00:00+00:00</published><updated>2025-10-31T00:00:00+00:00</updated><id>https://fabricmc.net/2025/10/31/obfuscation</id><content type="html" xml:base="https://fabricmc.net/2025/10/31/obfuscation.html">&lt;p&gt;Mojang recently published &lt;a href=&quot;https://www.minecraft.net/en-us/article/removing-obfuscation-in-java-edition&quot;&gt;a blog post&lt;/a&gt; announcing that they will be removing obfuscation from Minecraft: Java Edition starting with the first snapshot after the &lt;em&gt;Mounts of Mayhem&lt;/em&gt; launch later this year. There will also be supplementary “experimental” releases starting with next Tuesday’s snapshot to allow us time to prepare and migrate.&lt;/p&gt;

&lt;p&gt;This is a major change that will affect the entire modding community. This blog post will attempt to give a rundown of how the Fabric toolchain will be affected, and what this means for Fabric mod developers.&lt;/p&gt;

&lt;h2 id=&quot;what-is-obfuscation&quot;&gt;What is obfuscation?&lt;/h2&gt;
&lt;p&gt;Obfuscation is a practice by which the names of classes, methods, fields, etc. in the code of the game are hidden by changing them into meaningless sequences of letters that change every version. So, as an example, the class for Creepers may have been changed from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Creeper&lt;/code&gt; to something like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;brc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This has been a practice used for practically the entire time Minecraft has existed, and has meant that people who want to mod the game needed to figure out what each part of the code did, and use tools to apply readable names back to the code.&lt;/p&gt;

&lt;h3 id=&quot;what-has-been-done-about-obfuscation-before&quot;&gt;What has been done about obfuscation before?&lt;/h3&gt;
&lt;p&gt;In the Fabric world, we have had projects called Intermediary and Yarn.
Intermediary would take the obfuscated names and give them stable numbers - so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;brc&lt;/code&gt; might become &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;class_1548&lt;/code&gt;.
Yarn would then apply readable names to those numbers - so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;class_1548&lt;/code&gt; might become &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CreeperEntity&lt;/code&gt;.
These Yarn names were created and determined by our community by analysing the code. (If you’ve seen things in the code named with the Intermediary numbers - those are things we didn’t get around to naming in Yarn!)&lt;/p&gt;

&lt;p&gt;Since 2019, while the code of the game itself has still used the scrambled letters, Mojang has released their own official set of readable names, colloquially known as ‘Mojmap’, which are the names they themselves use when developing the game.
This set of names was different from Yarn, and many developers embraced them, though some continued using Yarn names out of preference.
Fabric has supported the option to use either set of names.&lt;/p&gt;

&lt;h3 id=&quot;what-does-it-mean-that-obfuscation-is-being-removed&quot;&gt;What does it mean that obfuscation is being removed?&lt;/h3&gt;
&lt;p&gt;Now, the names in the actual code of the game will match those that Mojang has been releasing since 2019. What’s more, for the first time, mod developers will now be able to see official names for method parameters and local variables, which were previously missing from those names.&lt;/p&gt;

&lt;p&gt;However, as the Fabric toolchain has been built around the need to apply our own names, this means a lot of work will have to go into supporting this change.&lt;/p&gt;

&lt;h2 id=&quot;what-is-fabric-going-to-do&quot;&gt;What is Fabric going to do?&lt;/h2&gt;
&lt;p&gt;We have plans in place to update our toolchain, but there’s a lot to do, and this may take some time.&lt;/p&gt;

&lt;h3 id=&quot;the-future-of-fabric-api&quot;&gt;The future of Fabric API&lt;/h3&gt;
&lt;p&gt;Fabric API will &lt;strong&gt;not&lt;/strong&gt; undergo major rewrites as a result of this, and all of your favourite APIs will stay on course.
However, the naming of the APIs and their associated methods and javadoc will change to accurately reflect the official Mojang names.&lt;/p&gt;

&lt;p&gt;The first stage of this will be to migrate Fabric API to use the official Mojang names in a non API-breaking way. This will happen fairly quickly as it can be done with no impact to modders and players.&lt;/p&gt;

&lt;p&gt;When the new fully deobfuscated version is released, we will rename Fabric’s own API functions to match those of the official names.&lt;/p&gt;

&lt;h3 id=&quot;loom&quot;&gt;Loom&lt;/h3&gt;
&lt;p&gt;Development of a new Loom version has begun. The initial goal is to provide a solution for mod developers to begin using the new experimental releases for testing. This will likely take the form of Loom 1.13.&lt;/p&gt;

&lt;p&gt;In the long run we may look into making a totally new version of Loom that is more modular. Loom 2.0 may provide a slim version that contains no support for remapping. This will likely take some time, and is still in the design phase so please be patient.&lt;/p&gt;

&lt;p&gt;Support for modding older game versions with the latest Loom is a very high priority and something that we wish to continue to provide as we have done previously. We also understand that not everyone wishes to use the new official names, we hope to provide a remapping solution for those advanced users who wish to use their own names.&lt;/p&gt;

&lt;h3 id=&quot;the-future-of-yarn&quot;&gt;The future of Yarn&lt;/h3&gt;

&lt;p align=&quot;center&quot;&gt;
  &lt;img src=&quot;/assets/rip_yarn.png&quot; alt=&quot;Example Image&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;The Fabric community as a whole thanks all 261 Yarn contributors for their 9 years, 2 months, and 17 days of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Identifier&lt;/code&gt; glory. Your contributions have been and continue to be greatly appreciated.&lt;/p&gt;

&lt;p&gt;Unfortunately, given the current circumstances we can’t see a way to justify maintaining Yarn in its current state.&lt;/p&gt;

&lt;p&gt;Yarn for existing Minecraft versions will continue to welcome contributions.&lt;/p&gt;

&lt;p&gt;If you are a mod developer using Yarn mappings, you will likely need to migrate to Mojang’s names. See the ‘For mod developers’ section below.&lt;/p&gt;

&lt;h2 id=&quot;what-do-i-need-to-do&quot;&gt;What do I need to do?&lt;/h2&gt;
&lt;h3 id=&quot;for-players&quot;&gt;For players&lt;/h3&gt;
&lt;p&gt;Very little! This is largely only going to affect developers. We aim to keep supporting all existing launchers.&lt;/p&gt;

&lt;p&gt;In good news, this also means once all this is sorted, updates for some things like Fabric API will likely be quicker in the future, and crash logs might be slightly easier to read. Rejoice!&lt;/p&gt;

&lt;p&gt;And as always, we ask all players to be patient, and give mod developers time to update. We kindly ask everyone not to pester them. We also recommend all players make backups of their worlds before updating to any new version.&lt;/p&gt;

&lt;h3 id=&quot;for-mod-developers&quot;&gt;For mod developers&lt;/h3&gt;

&lt;p&gt;This is going to be a large change, especially for those that are using Yarn. There is no expectation to update your mods right away, but you may wish to prepare. Nothing will change until after the &lt;em&gt;Mounts of Mayhem&lt;/em&gt; (1.21.11) drop.&lt;/p&gt;

&lt;p&gt;We recommend that all new mods should be created using the official Mojang mappings, this will provide an easier upgrade path in the future.&lt;/p&gt;

&lt;p&gt;If you have a mod using Yarn, don’t worry! Loom has existing automated tooling that will help you to rename your code. We are actively looking at ways to improve this tooling and plan to provide some resources in the future to help you.&lt;/p&gt;

&lt;p&gt;Once you have upgraded, you will benefit from a much simpler and faster toolchain, improved logs/crash reports and new debugging options.&lt;/p&gt;

&lt;h2 id=&quot;tldr-what-will-affect-you&quot;&gt;TL;DR: What will affect you&lt;/h2&gt;

&lt;h3 id=&quot;players&quot;&gt;Players&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Be patient while mods update.&lt;/li&gt;
  &lt;li&gt;Crash logs may be slightly easier to read.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;modders&quot;&gt;Modders&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Don’t worry! There is no rush.&lt;/li&gt;
  &lt;li&gt;Most Yarn users will need to migrate to the official names.&lt;/li&gt;
  &lt;li&gt;Your build script will require some changes.&lt;/li&gt;
  &lt;li&gt;Production crash logs may be slightly easier to debug.&lt;/li&gt;
  &lt;li&gt;Intermediary will no longer exist; the game will use Mojang’s names at runtime.&lt;/li&gt;
&lt;/ul&gt;</content><author><name></name></author><summary type="html">Mojang recently published a blog post announcing that they will be removing obfuscation from Minecraft: Java Edition starting with the first snapshot after the Mounts of Mayhem launch later this year. There will also be supplementary “experimental” releases starting with next Tuesday’s snapshot to allow us time to prepare and migrate.</summary></entry><entry><title type="html">Fabric for Minecraft 1.21.9 &amp;amp; 1.21.10</title><link href="https://fabricmc.net/2025/09/23/1219.html" rel="alternate" type="text/html" title="Fabric for Minecraft 1.21.9 &amp;amp; 1.21.10" /><published>2025-09-23T00:00:00+00:00</published><updated>2025-09-23T00:00:00+00:00</updated><id>https://fabricmc.net/2025/09/23/1219</id><content type="html" xml:base="https://fabricmc.net/2025/09/23/1219.html">&lt;p&gt;A new version of Minecraft is coming soon with some changes that affect most mod makers. As always, &lt;strong&gt;we ask all players to be patient, and give mod developers time to update to this new version.&lt;/strong&gt; We kindly ask everyone not to pester them. &lt;strong&gt;We also recommend all players make backups of their worlds.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is a list of several major modder-facing changes in this version. Note that all code references are using Yarn mappings; modders using alternative mappings may need to use different names.&lt;/p&gt;

&lt;h2 id=&quot;fabric-changes&quot;&gt;Fabric changes&lt;/h2&gt;
&lt;p&gt;Developers should use Loom 1.11 (at the time of writing) to develop mods for Minecraft 1.21.9.
Players should install the latest stable version of Fabric Loader (currently 0.17.2).&lt;/p&gt;

&lt;h3 id=&quot;yarn-mappings&quot;&gt;Yarn Mappings&lt;/h3&gt;
&lt;p&gt;In this update, several mapping name changes were forced by changes in the vanilla class hierarchy. While a full diff may be found &lt;a href=&quot;https://github.com/FabricMC/yarn/compare/d9167974e1fc83c980cf3be9fb567b1ab67d1153..6f9f183d2908d05e67a89aa3558caf9fee207dc0&quot;&gt;here&lt;/a&gt;, there is one major change affecting almost all mods: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Entity#getWorld&lt;/code&gt; was renamed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Entity#getEntityWorld&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;world-render-events&quot;&gt;World Render Events&lt;/h3&gt;
&lt;p&gt;The current event suite for rendering in the world has been removed. A suitable replacement is planned asap, but not ready yet. In the meantime, please use mixins to implement what your mod needs.&lt;/p&gt;

&lt;h3 id=&quot;resource-loader-api-v1&quot;&gt;Resource Loader API v1&lt;/h3&gt;

&lt;p&gt;A major rework of the resource loader API is present in the 1.21.9 version of Fabric API. This will make current functionality easier to acomplish, as well as opening doors for features like runtime resource generation in the future.&lt;/p&gt;

&lt;p&gt;The first part of this rework has just landed with the focus being on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ResourceReloader&lt;/code&gt;.
Historically this API based itself on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IdentifiableResourceReloadListener&lt;/code&gt; interface which allowed &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ResourceReloader&lt;/code&gt; to both be identifiable and specify dependencies.
However this API had limits, which prevented to run before another &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ResourceReloader&lt;/code&gt; or was difficult to use in multiloader environments.
This has been fixed with this new iteration of the API.&lt;/p&gt;

&lt;p&gt;From now on, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ResourceReloader&lt;/code&gt; do not need to implement a Fabric-provided interface, instead they can be registered with an identifier directly:&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gd&quot;&gt;- ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(new CustomResourceReloader())
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ ResourceLoader.get(ResourceType.SERVER_DATA).registerReloader(Identifier.of(&quot;modid&quot;, &quot;custom_resource_reloader&quot;), new CustomResourceReloader());
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Ordering is now specified akin to events:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;ResourceLoader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ResourceType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;SERVER_DATA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;addReloaderOrdering&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Identifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;other&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;other_reloader_to_depend&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Triggers first&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Identifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modid&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;custom_resource_reloader&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Triggers second&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can also order based on Vanilla reloaders thanks to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ResourceReloaderKeys&lt;/code&gt;, which provides both per-resource-reloader an identifier, and two global keys: before and after vanilla.&lt;/p&gt;

&lt;p&gt;Thanks to 1.21.9 Vanilla changes the way to register reloaders which need registry access has been simplified, instead of using a specialized registration method, now you can get registries and feature flags in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ResourceType.SERVER_DATA&lt;/code&gt; reloaders via the shared state &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Store&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DataReloader&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ResourceReloader&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CompletableFuture&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Void&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;reload&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Store&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;store&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Executor&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prepareExecutor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Synchronizer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reloadSynchronizer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Executor&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;applyExecutor&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;RegistryWrapper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;WrapperLookup&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;registries&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;store&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getOrThrow&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ResourceLoader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;RELOADER_REGISTRY_LOOKUP_KEY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;FeatureSet&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;featureSet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;store&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getOrThrow&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ResourceLoader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;RELOADER_FEATURE_SET_KEY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Code&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This change also allows for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ResourceReloader&lt;/code&gt;s to communicate data between them.&lt;/p&gt;

&lt;p&gt;See &lt;a href=&quot;https://github.com/FabricMC/fabric/issues/4574&quot;&gt;#4574&lt;/a&gt; for more details about what else is planned and the current progress.&lt;/p&gt;

&lt;h3 id=&quot;enchantments&quot;&gt;Enchantments&lt;/h3&gt;
&lt;p&gt;Transitive access wideners have been added for all of the utility methods in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EnchantmentHelper&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Enchantment&lt;/code&gt;. We hope that this will make it easier for developers to implement custom enchantment effect components.
See &lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4819&quot;&gt;#4819&lt;/a&gt; for more details.&lt;/p&gt;

&lt;h3 id=&quot;serialization&quot;&gt;Serialization&lt;/h3&gt;
&lt;p&gt;We have added a new module for utilities related to serialization. Currently, this module includes additional methods in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ReadView&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WriteView&lt;/code&gt;, and provides &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Codec&lt;/code&gt;s for some types that base vanilla doesn’t. Please feel free to suggest anything else that may be useful in this area.
See &lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4745&quot;&gt;#4745&lt;/a&gt; for more details.&lt;/p&gt;

&lt;h3 id=&quot;block-conversions&quot;&gt;Block Conversions&lt;/h3&gt;
&lt;p&gt;To closer align with vanilla code flow, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OxidizableBlocksRegistry&lt;/code&gt; now supports registering a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CopperBlockSet&lt;/code&gt; direclty. Simply call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OxidizableBlocksRegistry.registerCopperBlockSet(set)&lt;/code&gt; to register. The prior methods for block pairs are still avalible for those that prefer them.
See &lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4807&quot;&gt;#4807&lt;/a&gt; for more details.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StrippableBlockRegistry&lt;/code&gt; now provides multiple overloads to satisfy all your stripping needs. As before, simple conversions can be registered by calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StrippableBlockRegistry.register(Block, Block)&lt;/code&gt;.  You may also call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StrippableBlockRegistry.registerCopyState(Block, Block)&lt;/code&gt; to register a stripping conversion that automatically copies all properties from the previous state, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;register(Block, Block, StrippingTransformer)&lt;/code&gt; to have full control over the stripping process.
See &lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4829&quot;&gt;#4829&lt;/a&gt; for more details.&lt;/p&gt;

&lt;h3 id=&quot;gui-rendering&quot;&gt;GUI Rendering&lt;/h3&gt;
&lt;p&gt;When using a custom &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RenderPipeline&lt;/code&gt; to render in the GUI, vanilla may assume that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VertexFormat&lt;/code&gt; being used is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;QUADS&lt;/code&gt;. Fabric now provides a way to override this behavior with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RenderPipeline.Builder.withUsePipelineDrawModeForGui&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pipeline&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RenderPipeline&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;snippet1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; 
        &lt;span class=&quot;n&quot;&gt;snippet1&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;withUsePipelineDrawModeForGui&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;fictionalRenderInGuiInNonGuads&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pipeline&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// will respect the VertexFormat set in the pipeline&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;See &lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4824&quot;&gt;#4824&lt;/a&gt; for more details.&lt;/p&gt;

&lt;h3 id=&quot;mixin--mixinextras&quot;&gt;Mixin &amp;amp; MixinExtras&lt;/h3&gt;
&lt;p&gt;With version 0.17.0 of Fabric Loader, MixinExtras 5.0.0 and Fabric Mixin 0.16.3+mixin.0.8.7 are now bundled.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;MixinExtras 5.0.0 brings expressions, a new way to discribe mixins to java code in a syntax that mirrors the target, leading to mixins that are easier to maintain, more expressive, and potentially even more compatible with other mixins. See the &lt;a href=&quot;https://github.com/LlamaLad7/MixinExtras/releases/tag/0.5.0&quot;&gt;release notes&lt;/a&gt; and &lt;a href=&quot;https://github.com/LlamaLad7/MixinExtras/wiki/Expressions&quot;&gt;wiki pages&lt;/a&gt; for more details.&lt;/li&gt;
  &lt;li&gt;Fabric Mixin 0.16.3 brings many bug fixes, along with scaffolding in mixin for potential widespread performance increases.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;screen-key-events&quot;&gt;Screen Key Events&lt;/h3&gt;

&lt;p&gt;With many breaking changes from mojang regarding keybindings, we’ve taken the opportunity to improve our events. Most parameters in the event have been consolidated into a context object known as a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;KeyInput&lt;/code&gt;. The &lt;em&gt;afterMouseX&lt;/em&gt; style events now also take and return a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;boolean&lt;/code&gt; representing whether the event has been consumed. Returning &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt; from these events will prevent further vanilla handling.&lt;/p&gt;

&lt;p&gt;See &lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4846/&quot;&gt;#4846&lt;/a&gt; and &lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4620&quot;&gt;#4620&lt;/a&gt; for more details.&lt;/p&gt;

&lt;h2 id=&quot;minecraft-changes&quot;&gt;Minecraft Changes&lt;/h2&gt;

&lt;h3 id=&quot;rendering&quot;&gt;Rendering&lt;/h3&gt;
&lt;p&gt;Almost all world rendering has been reworked to group objects with similar rendering requirements together. Most places now use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OrderedRenderCommandQueue&lt;/code&gt; to submit things to be drawn later, when all objects of a similar type have been rendered.&lt;/p&gt;

&lt;h4 id=&quot;block-entities&quot;&gt;Block Entities&lt;/h4&gt;
&lt;p&gt;Block entities now use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OrderedRenderCommandQueue&lt;/code&gt;. The following example shows rendering text on the block using the queue.&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TestBlockEntityRenderer&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BlockEntityRenderer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TestBlockEntity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BlockEntityRenderState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TestBlockEntityRenderer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BlockEntityRendererFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Context&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BlockEntityRenderState&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;createRenderState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;BlockEntityRenderState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BlockEntityRenderState&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MatrixStack&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;matrices&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;OrderedRenderCommandQueue&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CameraRenderState&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cameraRenderState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;submitText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;matrices&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;nc&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;literal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello, world!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;asOrderedText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt;
                &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;nc&quot;&gt;TextRenderer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TextLayerType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;NORMAL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;lightmapCoordinates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;nc&quot;&gt;Colors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;WHITE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;nc&quot;&gt;Colors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;BLACK&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;!-- this looks like the old way of doing this, should probably mention that --&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TestBlockEntityRenderer&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BlockEntityRenderer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TestBlockEntity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TestBlockEntityRenderer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BlockEntityRendererFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Context&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TestBlockEntity&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tickProgress&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MatrixStack&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;matrices&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;VertexConsumerProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vertexConsumers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;light&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;overlay&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Vec3d&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cameraPos&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;MinecraftClient&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;textRenderer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;drawWithOutline&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;nc&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;literal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello, world!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;asOrderedText&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt;
                &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;nc&quot;&gt;Colors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;WHITE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;nc&quot;&gt;Colors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;BLACK&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;matrices&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;peek&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getPositionMatrix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;vertexConsumers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;light&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;particles&quot;&gt;Particles&lt;/h4&gt;
&lt;p&gt;Particle rendering has been changed to use the same queue system as above. Many good examples for implementing custom rendering via the queue can be found in the vanilla particle classes.
&lt;!-- no examples, I'm not awake enough to be trusted with a buffer. --&gt;&lt;/p&gt;

&lt;h4 id=&quot;entities&quot;&gt;Entities&lt;/h4&gt;
&lt;p&gt;Entity rendering has changed to use the same queue as shown above. Changes will be similar.&lt;/p&gt;

&lt;h3 id=&quot;keybinding-changes&quot;&gt;Keybinding Changes&lt;/h3&gt;
&lt;p&gt;Keybinding categories have become more structured. You could do the following before:&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ModKeybindings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;KeyBinding&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;RANDOM_KEYBIND&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;KeyBinding&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;key.test.random_keybind&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;InputUtil&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;KEYSYM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;InputUtil&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;UNKNOWN_KEY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getCode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;key.category.test.main&quot;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;tickKeybindings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;MinecraftClient&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;RANDOM_KEYBIND&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;wasPressed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Random keybind pressed!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;ClientTickEvents&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;END_CLIENT_TICK&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;ModKeybindings:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tickKeybindings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Now you could do:&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ModKeybindings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;KeyBinding&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Category&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;TEST_CATEGORY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;KeyBinding&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Category&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Identifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;KeyBinding&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;RANDOM_KEYBIND&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;KeyBinding&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;key.test.random_keybind&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;InputUtil&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;KEYSYM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;InputUtil&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;UNKNOWN_KEY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getCode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;TEST_CATEGORY&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Each category may only be registered once; Registering a category twice, or two categories with the same id will lead to an exception.&lt;/p&gt;

&lt;p&gt;When Fabric API is installed, mod-provided categories will be sorted by alphabetically according to their identifiers, first by namespace, and then by path. All vanilla categories will remain in their natural order.&lt;/p&gt;

&lt;h3 id=&quot;debug-text-api&quot;&gt;Debug Text API&lt;/h3&gt;
&lt;p&gt;It is now possible to register debug HUD entries to be added to the debug (F3) overlay. The debug overlay is now also available outside of a world. Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DebugHudEntries&lt;/code&gt; to register entries to be rendered as follows:&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;DebugHudEntries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;Identifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;example&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; 
  &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DebugHudEntry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;nc&quot;&gt;DebugHudLines&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; 
      &lt;span class=&quot;nd&quot;&gt;@Nullable&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;World&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; 
      &lt;span class=&quot;nd&quot;&gt;@Nullable&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;WorldChunk&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;clientChunk&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; 
      &lt;span class=&quot;nd&quot;&gt;@Nullable&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;WorldChunk&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chunk&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;world&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;addLine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Example in-world line :)&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;addLine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Example out-of-world line :(&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;canShow&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reducedDebugInfo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;// return false if your debug text &lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;// is not applicable with reduced debug info&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;misc&quot;&gt;Misc&lt;/h3&gt;
&lt;h4 id=&quot;macos&quot;&gt;MacOS&lt;/h4&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MinecraftClient.IS_SYSTEM_MAC&lt;/code&gt; has been replaced by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SystemKeycodes.IS_MAC_OS&lt;/code&gt;.&lt;/p&gt;</content><author><name></name></author><summary type="html">A new version of Minecraft is coming soon with some changes that affect most mod makers. As always, we ask all players to be patient, and give mod developers time to update to this new version. We kindly ask everyone not to pester them. We also recommend all players make backups of their worlds.</summary></entry><entry><title type="html">Fabric for Minecraft 1.21.6, 1.21.7 &amp;amp; 1.21.8</title><link href="https://fabricmc.net/2025/06/15/1216.html" rel="alternate" type="text/html" title="Fabric for Minecraft 1.21.6, 1.21.7 &amp;amp; 1.21.8" /><published>2025-06-15T00:00:00+00:00</published><updated>2025-06-15T00:00:00+00:00</updated><id>https://fabricmc.net/2025/06/15/1216</id><content type="html" xml:base="https://fabricmc.net/2025/06/15/1216.html">&lt;p&gt;A new version of Minecraft is coming soon with some changes that affect most mod makers. As always, &lt;strong&gt;we ask all players to be patient, and give mod developers time to update to this new version.&lt;/strong&gt; We kindly ask everyone not to pester them. &lt;strong&gt;We also recommend all players make backups of their worlds.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is a list of several major modder-facing changes in this version. Note that all code references are using Yarn mappings; modders using alternative mappings may need to use different names.&lt;/p&gt;

&lt;h2 id=&quot;fabric-changes&quot;&gt;Fabric changes&lt;/h2&gt;
&lt;p&gt;Developers should use Loom 1.10 (at the time of writing) to develop mods for Minecraft 1.21.6.
Players should install the latest stable version of Fabric Loader (currently 0.16.14).&lt;/p&gt;

&lt;h3 id=&quot;deprecations-and-removals&quot;&gt;Deprecations and removals&lt;/h3&gt;
&lt;p&gt;The following previously deprecated modules have been removed (&lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4651&quot;&gt;#4651&lt;/a&gt;):&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fabric-command-api-v1&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fabric-commands-v0&lt;/code&gt; (Deprecated almost 5 years ago!)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fabric-keybindings-v0&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fabric-rendering-data-attachment-v1&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following modules have been merged into other modules for simplicity:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fabric-client-tags-api-v1&lt;/code&gt; was merged into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fabric-tag-api-v1&lt;/code&gt; (&lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4647&quot;&gt;#4647&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fabric-blockrenderlayer-v1&lt;/code&gt; was merged into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fabric-rendering-v1&lt;/code&gt; (&lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4675&quot;&gt;#4675&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tag API changes are technically breaking for some developers who explicitly depend on these modules. The removal and merging of these modules has been done to help improve peformance when setting up a new development environment.&lt;/p&gt;

&lt;p&gt;The Fabric Rendering API previously provided a Material API, to allow modders more control of the way their models rendered. This has been removed.&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Materials were removed … because they were deemed to be an unnecessary part of the API design, and the breaking change induced by changes in 1.21.6 was related to materials, which made this the perfect time to remove them - PepperCode1&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;See (&lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4675&quot;&gt;#4675&lt;/a&gt;) for more info.&lt;/p&gt;

&lt;p&gt;In addition to being relocated, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BlockRenderLayerMap&lt;/code&gt; API was also updated to be more consistent out current API style:&lt;/p&gt;
&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gd&quot;&gt;- import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ import net.fabricmc.fabric.api.client.rendering.v1.BlockRenderLayerMap;
&lt;/span&gt; ...
&lt;span class=&quot;gd&quot;&gt;- BlockRenderLayerMap.INSTANCE.putBlock(ModBlocks.MY_EPIC_BLOCK, BlockRenderLayer.CUTOUT)
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ BlockRenderLayerMap.putBlock(ModBlocks.MY_EPIC_BLOCK, BlockRenderLayer.CUTOUT)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;See (&lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4664&quot;&gt;#4664&lt;/a&gt;) for more info.&lt;/p&gt;
&lt;h3 id=&quot;breaking-changes&quot;&gt;Breaking changes&lt;/h3&gt;

&lt;p&gt;Fabric’s brand new HUD API had to be totally rewritten in 1.21.6. The new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HudElementRegistry&lt;/code&gt; provides all of the functionality provided by the old API. The following basic example shows how you can draw text after all of the vanilla HUD layers:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;HudElementRegistry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;addLast&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Identifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;example&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;hud&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tickCounter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;drawTextWithShadow&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;MinecraftClient&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;textRenderer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;This is an example&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Colors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;WHITE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you wish to render your custom hud element before the vanilla chat you can do the following:&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;HudElementRegistry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;attachElementBefore&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;VanillaHudElements&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;CHAT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Identifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;example&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;ud&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tickCounter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;new-fabric-api-features&quot;&gt;New Fabric API features&lt;/h3&gt;

&lt;p&gt;Since &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Item#appendTooltip&lt;/code&gt; has become deprecated, Fabric API now provides the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ComponentTooltipAppenderRegistry&lt;/code&gt;. This registry provides &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addAfter&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addBefore&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addFirst&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addLast&lt;/code&gt; to allow you to position your tooltips relative to vanilla and other mods.&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MyAmazingComponent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TooltipAppender&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;appendTooltip&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TooltipContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Consumer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;textConsumer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TooltipType&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ComponentsAccess&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;components&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;textConsumer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;accept&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;literal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Amazingness Awaits!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;ComponentType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;MyAmazingComponent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myAmazingComponentComponentType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/*...*/&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;ComponentTooltipAppenderRegistry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;addAfter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;nc&quot;&gt;DataComponentTypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;DAMAGE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;myAmazingComponentComponentType&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Any &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemStack&lt;/code&gt; that has your component applied will call your component’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;appendTooltip&lt;/code&gt; method, allowing you to append as you wish. (&lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4587&quot;&gt;#4587&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The LootTable API has been expanded to make certain extreme usages more convenient. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LootTableEvents.MODIFY_DROPS&lt;/code&gt; event allows modders to customize the collective output of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LootTable&lt;/code&gt;s. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LootTableEvents.MODIFY&lt;/code&gt; event should still be preferred when possible, for mod compatibility reasons. This event may also recurse if you generate loot from within a listener. (&lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4643&quot;&gt;#4643&lt;/a&gt;)&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;matchGetter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ServerRecipeManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;createCachedMatchGetter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;RecipeType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;SMELTING&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// smelt any smeltable drops from blocks broken with a diamond pickaxe&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;LootTableEvents&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;MODIFY_DROPS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;drops&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;hasParameter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;LootContextParameters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TOOL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;hasParameter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;LootContextParameters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;BLOCK_STATE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;nc&quot;&gt;ItemStack&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;LootContextParameters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TOOL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tool&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Items&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;DIAMOND_PICKAXE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getWorld&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lookup&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getRegistryManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;drops&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;replaceAll&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;drop&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;matchGetter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getFirstMatch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SingleStackRecipeInput&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;drop&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;RecipeEntry:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recipe&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;recipe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;craft&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
			&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;orElse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;drop&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Continuing with our conventional tag API, we added new biome tags, allowing modders to differentiate biomes based on their primary wood type.
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ServerChunkEvents.CHUNK_LEVEL_TYPE_CHANGE&lt;/code&gt; event was added to allow more control over the timing of chunk events. This event fires for changes in chunk loading level, to react to changes not previously possible without mixins. (&lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4541&quot;&gt;#4541&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;An event was added for attachment changes, allowing reaction to an attachment value changing. This event can be recursive in nature, as if you set an attachment value from within a listener, the event will be invoked again. Modders should use proper recursion techniques to prevent infinite recursion. (&lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4606&quot;&gt;#4606&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Two more events were added for players joining and leaving the game:&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;AttachmentType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Instant&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;JOINED_TIME&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/*...*/&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;ServerPlayerEvents&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;JOIN&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// runs on the main thread, no need to use player.getServer().execute(() -&amp;gt; ...);&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setAttached&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;JOINED_TIME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Instant&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ServerPlayerEntity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;activePlayers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/*...*/&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;ServerPlayerEvents&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;LEAVE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;activePlayers:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;These events are designed for initializing and de-initializing state related to players, and run along vanilla code with the same purpose on the main thread, unlike the current events. (&lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4642&quot;&gt;#4642&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FabricSoundsProvider&lt;/code&gt; class was added to allow convenient creation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sounds.json&lt;/code&gt; from within datagen. (&lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4560&quot;&gt;#4560&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The Client Game Test API has been tweaked to support filtering tests run by model, allowing more precise and efficient testing. (&lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4597&quot;&gt;#4597&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The Model Loading API now supports registering extra unbound models (&lt;a href=&quot;https://github.com/FabricMC/fabric/pull/4565&quot;&gt;#4565&lt;/a&gt;)&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// A ModelKey is a unique identifier for a model you want to bake.&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ModelKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;BlockStateModel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;HALF_RED_SAND_MODEL_KEY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ModelKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Identifier&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;HALF_RED_SAND_MODEL_ID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;half_red_sand&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;nc&quot;&gt;ModelLoadingPlugin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pluginContext&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;pluginContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;addModel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HALF_RED_SAND_MODEL_KEY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;HALF_RED_SAND_MODEL_ID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;nc&quot;&gt;ModelTextures&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;textures&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getTextures&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SimpleBlockStateModel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GeometryBakedModel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
				&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;bakeGeometry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;textures&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ModelRotation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;X0_Y0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
				&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getAmbientOcclusion&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt;
				&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getParticleTexture&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;textures&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
		&lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BlockStateModel&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getModel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MinecraftClient&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getBakedModelManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getModel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HALF_RED_SAND_MODEL_KEY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FabricTrackedDataRegistry&lt;/code&gt; has been added to allow registering tracked data handlers for entities. This removes conflicts between mods registering tracked data handlers and ensures that the order is consistent between the client and server. If you previously used the vanilla API the following 1 line change is all you need to take advantage of this new API:&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gd&quot;&gt;- TrackedDataHandlerRegistry.register(TRACKED_DATA_HANDLER);
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ FabricTrackedDataRegistry.registerHandler(TRACKED_DATA_HANDLER_ID, TRACKED_DATA_HANDLER);
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;bug-fixes&quot;&gt;Bug Fixes&lt;/h3&gt;
&lt;p&gt;Thanks to the diligent developers and players, many bugs in Fabric API were reported and patched during this update cycle. See &lt;a href=&quot;https://github.com/FabricMC/fabric/pulls?q=is%3Apr+is%3Aclosed+label%3Abug&quot;&gt;The Fabric Github&lt;/a&gt; for more info.&lt;/p&gt;
&lt;h2 id=&quot;minecraft-changes&quot;&gt;Minecraft changes&lt;/h2&gt;
&lt;h3 id=&quot;rendering&quot;&gt;Rendering&lt;/h3&gt;
&lt;p&gt;Mojang is currently working on separating Minecraft’s rendering pipeline into two stages:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;The extraction stage, where all renderable data is seperated from the game&lt;/li&gt;
  &lt;li&gt;The render phase, where the previously extracted data is rendered.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This process began in 1.21.2, and is still incomplete as of this update. Chunk, GUI and HUD rendering have all been converted to use the new separate rendering style. The ultimate goal of this separation is to enable the game to render one frame while the next is being extracted.&lt;/p&gt;

&lt;p&gt;Many methods in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RenderSystem&lt;/code&gt; have been removed without direct replacement. In most cases, there isn’t a one-to-one translation from the old code to the new, but the same capabilities exist by combining the new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RenderPipeline&lt;/code&gt;s with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RenderLayer&lt;/code&gt;s.&lt;/p&gt;

&lt;h3 id=&quot;nbt&quot;&gt;NBT&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BlockEntity&lt;/code&gt;s now abstract saving to NBT through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ReadView&lt;/code&gt;s and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WriteView&lt;/code&gt;s. These views are responsible for storing errors from encoding / decoding, and keeping track of registries throughout the serialization process. You can read from a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ReadView&lt;/code&gt; using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;read&lt;/code&gt; method, passing in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Codec&lt;/code&gt; for the desired type. Likewise, you can write to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WriteView&lt;/code&gt; by using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;put&lt;/code&gt; method, passing in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Codec&lt;/code&gt; for the type, and the value in question. there are also methods for primitives, under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get(Int, Short, Boolean, ...)&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;put(Int, Short, Boolean, ...)&lt;/code&gt;. The View also provides methods for working with lists, nullable types, and nested objects.&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BE&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BlockEntity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Extra&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extra&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// Ctor excluded for brevity&lt;/span&gt;
	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NbtCompound&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;toInitialChunkDataNbt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;RegistryWrapper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;WrapperLookup&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;registries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;createNbt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;registries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// createNbt takes care of adapting to / from WriteView&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;writeData&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;WriteView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;writeData&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;putNullable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;extra&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Extra&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;CODEC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;extra&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// putString will eventually throw if we pass null&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;putString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;aString&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;putInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;anInt&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
	&lt;span class=&quot;kd&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;readData&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReadView&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;readData&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;extra&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Extra&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;CODEC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ifPresent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extra&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;extra&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extra&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getOptionalString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;aString&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ifPresent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;aString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getOptionalInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;anInt&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ifPresent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;anInt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;anInt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;anInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;n&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Extra&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Codec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Extra&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CODEC&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RecordCodecBuilder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Codec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;INT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fieldOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;i&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;forGetter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extra&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extra&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Codec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;INT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fieldOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;j&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;forGetter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extra&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extra&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;instance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;Extra:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
	&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;data-generation&quot;&gt;Data Generation&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getOrCreateTagBuilder&lt;/code&gt; should be replaced with the new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;valueLookupBuilder&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;</content><author><name></name></author><summary type="html">A new version of Minecraft is coming soon with some changes that affect most mod makers. As always, we ask all players to be patient, and give mod developers time to update to this new version. We kindly ask everyone not to pester them. We also recommend all players make backups of their worlds.</summary></entry><entry><title type="html">Fabric for Minecraft 1.21.5</title><link href="https://fabricmc.net/2025/03/24/1215.html" rel="alternate" type="text/html" title="Fabric for Minecraft 1.21.5" /><published>2025-03-24T00:00:00+00:00</published><updated>2025-03-24T00:00:00+00:00</updated><id>https://fabricmc.net/2025/03/24/1215</id><content type="html" xml:base="https://fabricmc.net/2025/03/24/1215.html">&lt;p&gt;A new version of Minecraft is coming soon with some changes that affect most mod makers. As always, &lt;strong&gt;we ask all players to be patient, and give mod developers time to update to this new version.&lt;/strong&gt; We kindly ask everyone not to pester them. &lt;strong&gt;We also recommend all players make backups of their worlds.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is a list of several major modder-facing changes in this version. Note that all code references are using Yarn mappings; modders using alternative mappings may need to use different names.&lt;/p&gt;

&lt;h2 id=&quot;fabric-changes&quot;&gt;Fabric changes&lt;/h2&gt;
&lt;p&gt;Developers should use Loom 1.10 (at the time of writing) to develop mods for Minecraft 1.21.5. Players should install the latest stable version of Fabric Loader (currently 0.16.10).&lt;/p&gt;

&lt;h3 id=&quot;loom-110&quot;&gt;Loom 1.10&lt;/h3&gt;
&lt;p&gt;Loom 1.10 requires Gradle 8.12, and comes with performance improvements and enhanced testing setup support. You can checkout the new Loom documentation &lt;a href=&quot;https://docs.fabricmc.net/develop/loom/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;deprecations-and-removals&quot;&gt;Deprecations and removals&lt;/h3&gt;
&lt;p&gt;In Content Registries, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VillagerInteractionsRegistries#registerGiftLootTable&lt;/code&gt; overload that takes an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Identifier&lt;/code&gt; was removed. This method was previously deprecated.&lt;/p&gt;

&lt;p&gt;In Object Builder, two deprecated classes, namely &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VillagerProfessionBuilder&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VillagerTypeHelper&lt;/code&gt;, have been removed. Use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VillagerProfession&lt;/code&gt; constructor and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VillagerType#create&lt;/code&gt; instead. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TradeOfferHelper#refreshOffers&lt;/code&gt;, which had been deprecated and did nothing, was also removed.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HudRenderCallback&lt;/code&gt; has been deprecated in favor of newly added &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HudLayerRegistrationCallback&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;breaking-changes&quot;&gt;Breaking changes&lt;/h3&gt;
&lt;p&gt;When a mod creates a new dynamic registry, the data pack JSON files for the registry must now be placed inside namespaced directories. For example, if the new registry is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;example:potato_variant&lt;/code&gt;, the file for variant &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test:tiny&lt;/code&gt; will be placed in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data/test/example/potato_variant/tiny.json&lt;/code&gt;.&lt;!-- https://github.com/FabricMC/fabric/pull/4180 --&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BiomeModificationContext#addSpawn&lt;/code&gt; has a new parameter, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;weight&lt;/code&gt;. This was previously part of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SpawnEntry&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TradeOfferHelper&lt;/code&gt; now takes a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RegistryKey&lt;/code&gt; of the profession instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VillagerProfession&lt;/code&gt;. Wandering trader trades must now be added via the builder, which was previously used for the Rebalance experiment. (The rebalanced trades are now used in all worlds.)&lt;/p&gt;

&lt;h3 id=&quot;new-fabric-api-changes&quot;&gt;New Fabric API changes&lt;/h3&gt;
&lt;p&gt;With the help of many contributors, Fabric API has received some new features since the last update blog post:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;New module: Client Game Test API, which can be used to automatically test client rendering and GUI (Earthcomputer)&lt;/li&gt;
  &lt;li&gt;New module: Fabric Tag API, which currently handles tag aliases (Juxxel)&lt;/li&gt;
  &lt;li&gt;Convention Tags: Sync remaining &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c&lt;/code&gt; tags with NeoForge (TelepathicGrunt)&lt;/li&gt;
  &lt;li&gt;Convention Tags: Add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c:flowers&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c:flowers/tall&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c:flowers/small&lt;/code&gt; block and item tags (TelepathicGrunt)&lt;/li&gt;
  &lt;li&gt;Convention Tags: Add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TagKey&lt;/code&gt; for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c:tools/wrench&lt;/code&gt; (TelepathicGrunt)&lt;/li&gt;
  &lt;li&gt;Convention Tags: Convention Drink Tags (TheDeathlyCow)&lt;/li&gt;
  &lt;li&gt;Convention Tags: Add Pumpkin Block and Item Tags (JT122406)&lt;/li&gt;
  &lt;li&gt;Data Generation: Add vararg helper methods for multi-tag support in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FabricTagBuilder&lt;/code&gt; (Starexify)&lt;/li&gt;
  &lt;li&gt;Data Generation: Add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FabricEntityLootTableProvider&lt;/code&gt; (Antikyth)&lt;/li&gt;
  &lt;li&gt;Item API: Add a method for overriding modelId in item settings (Patbox)&lt;/li&gt;
  &lt;li&gt;Item API: Add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;contains&lt;/code&gt; method to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FabricComponentMapBuilder&lt;/code&gt; (TheDeathlyCow)&lt;/li&gt;
  &lt;li&gt;Item Group API: Change Creative Buttons Texture (matthewperiut)&lt;/li&gt;
  &lt;li&gt;Item Group API: Use page up/down to change creative inventory pages (modmuss50)&lt;/li&gt;
  &lt;li&gt;Model Loading API: Allow retrieving model loading plugins (PepperCode1)&lt;/li&gt;
  &lt;li&gt;Networking API: Add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ServerPlayNetworking.reconfigure&lt;/code&gt; (modmuss50)&lt;/li&gt;
  &lt;li&gt;Object Builder: Allow setting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canPotentiallyExecuteCommands&lt;/code&gt; in builders (PepperCode1)&lt;/li&gt;
  &lt;li&gt;Recipe API: Add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getAllMatches&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getAllOfType&lt;/code&gt; methods to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ServerRecipeManager&lt;/code&gt; (Patbox)&lt;/li&gt;
  &lt;li&gt;Registry Sync: Add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RegistryAttribute#OPTIONAL&lt;/code&gt; that can be used to not disconnect clients lacking an entire registry; note that optional registry values are still unsupported (modmuss50)&lt;/li&gt;
  &lt;li&gt;Registry Sync: Registry aliasing (Syst3ms)&lt;/li&gt;
  &lt;li&gt;Rendering: Add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SpecialBlockRendererRegistry&lt;/code&gt; (PepperCode1)&lt;/li&gt;
  &lt;li&gt;Rendering: Add HUD Render Events (kevinthegreat1)&lt;/li&gt;
  &lt;li&gt;Resource Loader: Implement builtin mod resource/data pack sorting (Apollo)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;tag-and-registry-aliases&quot;&gt;Tag and registry aliases&lt;/h3&gt;
&lt;p&gt;The new tag and registry alias APIs allow for mods to seemlessly migrate their tags and registry aliases to new names. Thanks to Juuxel and Syst3ms respectively for implementing these new APIs.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Registries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;BLOCK&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;addAlias&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Identifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;my_mod&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;old&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Registries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;BLOCK&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Identifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;my_mod&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;new&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Registry aliases are really simple; with the code above, any access to the old ID in the registry is redirected to the new ID. This allows worlds to be upgraded to use the new ID; for example, a block with the old ID becomes the one with the new ID.&lt;/p&gt;

&lt;p&gt;Tag aliases are defined in data packs like tags. For example, a block tag alias group for fences would be located at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data/my_mod/fabric/tag_aliases/block/fences.json&lt;/code&gt; with the contents:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;tags&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;minecraft:fences&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;c:fences&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;client-gametest&quot;&gt;Client GameTest&lt;/h3&gt;
&lt;p&gt;For a long time, Fabric has had an internal client test framework that was used for testing that Fabric API was working correctly on the client. In a series of PRs, Earthcomputer has worked to expand and expose this framework to mod developers. The new experimental API has the following features:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;World creation API, for specifying options used to generate the test world.&lt;/li&gt;
  &lt;li&gt;Screenshot API, with support for comparing against golden images.&lt;/li&gt;
  &lt;li&gt;Input API, to simulate a user interacting with the game.&lt;/li&gt;
  &lt;li&gt;Advanced threading setup, to make the tests more repoducible.&lt;/li&gt;
  &lt;li&gt;Network synchronization, to ensure packets are handled consistently.&lt;/li&gt;
  &lt;li&gt;Herobrine removal, to bring peace to the Kingdom of Tiny Potato.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more information checkout the full documentation &lt;a href=&quot;https://maven.fabricmc.net/docs/fabric-api-0.119.2+1.21.5/net/fabricmc/fabric/api/client/gametest/v1/package-summary.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;hud-render-events&quot;&gt;HUD Render Events&lt;/h3&gt;
&lt;p&gt;Fabric API 0.116.0 added &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HudLayerRegistrationCallback&lt;/code&gt; event, providing full control over the HUD rendering process. The new API assigns idenftifiers to each layer that can be used to specify where things will be rendered. The new API also allows replacing or removing existing layers. A big thanks to kevinthegreat1 and many other people for making this happen!&lt;/p&gt;

&lt;h2 id=&quot;minecraft-changes&quot;&gt;Minecraft changes&lt;/h2&gt;
&lt;h3 id=&quot;nbt&quot;&gt;NBT&lt;/h3&gt;
&lt;p&gt;Significant changes to NBT handling code have been made.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NbtCompound&lt;/code&gt; methods now return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Optional&lt;/code&gt; instead of the value. If the key is not in the compound or if the value is not of the correct type, an empty optional is now returned instead of that type’s default value.&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gd&quot;&gt;- int value = nbt.getInt(&quot;value&quot;);
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ Optional&amp;lt;Integer&amp;gt; value = nbt.getInt(&quot;value&quot;); // not OptionalInt
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For primitives (numbers and strings), instead of checking for the existence of a key and handling a fallback, the fallback can now be passed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;get&lt;/code&gt; methods:&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gd&quot;&gt;- int value;
- if (nbt.contains(&quot;value&quot;, NbtElement.NUMBER_TYPE)) {
-   value = nbt.getInt(&quot;value&quot;);
- } else {
-   value = 1000;
- }
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ int value = nbt.getInt(&quot;value&quot;, 1000);
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Also note that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NbtElement#NUMBER_TYPE&lt;/code&gt; and type-aware &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;contains&lt;/code&gt; have been removed. There is no fallback method for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getIntArray&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getLongArray&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getByteArray&lt;/code&gt;. (Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Optional#orElse&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;For &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getCompound&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getList&lt;/code&gt; methods, methods with the previous behavior (returning empty objects) are provided with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OrEmpty&lt;/code&gt; suffix.&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gd&quot;&gt;- NbtCompound config = nbt.getCompound(&quot;config&quot;);
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ NbtCompound config = nbt.getCompoundOrEmpty(&quot;config&quot;);
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally, for those who want to encode/decode codec-based values (such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Identifier&lt;/code&gt;) stored in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NbtCompound&lt;/code&gt; field, new methods simplify the process:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-java=&quot;&gt;NbtCompound nbt = new NbtCompound();
nbt.put(&quot;Id&quot;, Identifier.CODEC, id);
// for reading
Optional&amp;lt;Identifier&amp;gt; id = nbt.get(&quot;Id&quot;, Identifier.CODEC);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And if there is a codec for the whole object:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-java=&quot;&gt;NbtCompound nbt = new NbtCompound();
// have to use the RegistryOps since an item is a registry entry
nbt.copyFromCodec(ItemStack.MAP_CODEC, wrapperLookup.getOps(NbtOps.INSTANCE), stack);
// for reading
Optional&amp;lt;ItemStack&amp;gt; stack = nbt.decode(ItemStack.MAP_CODEC, wrapperLookup.getOps(NbtOps.INSTANCE));
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Typed arrays (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ByteArray&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IntArray&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LongArray&lt;/code&gt;) are no longer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;List&lt;/code&gt;s. They can be converted to a list using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.stream().toList()&lt;/code&gt;, but this is usually not necessary. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NbtList&lt;/code&gt; can now contain values of differing types, but this should be a transparent change unless you work with binary data.&lt;/p&gt;

&lt;h3 id=&quot;gametest&quot;&gt;GameTest&lt;/h3&gt;

&lt;p&gt;In Minecraft &lt;a href=&quot;https://www.minecraft.net/en-us/article/minecraft-snapshot-25w03a&quot;&gt;25w03a&lt;/a&gt;, Mojang totally refactored the vanilla testing framework, exposing it to datapack developers. Unfortunately, the new API is a little bit cumbersome for mod developers. Fabric API now provides its own &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@GameTest&lt;/code&gt; annotation that functions similarly to the old one. The options in the new Fabric-provided &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@GameTest&lt;/code&gt; annotation directly map the vanilla data-driven options, removing the need to have a JSON file for each test function. Data driven tests will still work if you wish to use the vanilla system.&lt;/p&gt;

&lt;h3 id=&quot;miscellaneous&quot;&gt;Miscellaneous&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DataPool&lt;/code&gt; has been replaced with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pool&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbstractBlock#onStateReplaced&lt;/code&gt; has been significantly changed, the state provided is the old state and it now runs after block entities get removed. Block entities should use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BlockEntity#onBlockReplaced&lt;/code&gt; instead.&lt;/li&gt;
&lt;/ul&gt;</content><author><name></name></author><summary type="html">A new version of Minecraft is coming soon with some changes that affect most mod makers. As always, we ask all players to be patient, and give mod developers time to update to this new version. We kindly ask everyone not to pester them. We also recommend all players make backups of their worlds.</summary></entry><entry><title type="html">Fabric for Minecraft 1.21.4</title><link href="https://fabricmc.net/2024/12/02/1214.html" rel="alternate" type="text/html" title="Fabric for Minecraft 1.21.4" /><published>2024-12-02T00:00:00+00:00</published><updated>2024-12-02T00:00:00+00:00</updated><id>https://fabricmc.net/2024/12/02/1214</id><content type="html" xml:base="https://fabricmc.net/2024/12/02/1214.html">&lt;p&gt;Minecraft 1.21.4, the Garden Awakens drop, releases December 3rd. Like with other updates, this drop contains some significant changes affecting mod makers.&lt;/p&gt;

&lt;p&gt;As always, &lt;strong&gt;we ask all players to be patient, and give mod developers time to update to this new version.&lt;/strong&gt; We kindly ask everyone not to pester them. &lt;strong&gt;We also recommend all players make backups of their worlds.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is a list of several major modder-facing changes in this version. Note that all code references are using Yarn mappings; modders using alternative mappings may need to use different names.&lt;/p&gt;

&lt;h2 id=&quot;fabric-changes&quot;&gt;Fabric changes&lt;/h2&gt;

&lt;p&gt;Developers should use Loom 1.9 (at the time of writing) to develop mods for Minecraft 1.21.4. Players should install the latest stable version of Fabric Loader (currently 0.16.9).&lt;/p&gt;

&lt;h3 id=&quot;deprecations-and-removals&quot;&gt;Deprecations and removals&lt;/h3&gt;
&lt;p&gt;The following deprecated module was removed: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fabric-rendering-v0&lt;/code&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FabricModelPredicateProviderRegistry&lt;/code&gt;, which was previously deprecated, was also removed.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BuiltinItemRenderer&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BuiltinItemRendererRegistry&lt;/code&gt; from the Rendering v1 module were removed and have been replaced by a transitive access widener to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SpecialModelTypes.ID_MAPPER&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AttachmentRegistry#builder&lt;/code&gt; was deprecated in favor of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;create&lt;/code&gt; methods. The old method is inconvenient, as it requires explicit type parameters. (See the “Data Attachment Syncing” section for an example.)&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BlockPickInteractionAware&lt;/code&gt; was removed, the new pick item events should be used instead.&lt;/p&gt;

&lt;h3 id=&quot;breaking-change&quot;&gt;Breaking change&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CustomIngredient#getMatchingStacks&lt;/code&gt; must now return a stream, not a list.&lt;/p&gt;

&lt;!-- NOTE: despite what the semver suggests, Biome API DID NOT receive a breaking change in 24w44a. --&gt;

&lt;h3 id=&quot;new-fabric-api-changes&quot;&gt;New Fabric API changes&lt;/h3&gt;

&lt;p&gt;With the help of many contributors, Fabric API has received some new features since the last update blog post:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Convention Tags: Add more tags (JT122406, TelepathicGrunt, IThundxr)&lt;/li&gt;
  &lt;li&gt;Data Attachments: Registration enhancements (forgetmenot13579)&lt;/li&gt;
  &lt;li&gt;Data Attachments: Sync API (Syst3ms)&lt;/li&gt;
  &lt;li&gt;Lifecycle Events: Add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ServerChunkEvents.Generate&lt;/code&gt; (jpenilla)&lt;/li&gt;
  &lt;li&gt;Lifecycle Events: Add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AFTER_CLIENT_WORLD_CHANGE&lt;/code&gt; (fishshi)&lt;/li&gt;
  &lt;li&gt;Transfer API: Add support for Item-containing Items (BasiqueEvangelist)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition, a longstanding bug that caused language files to not load after overriding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;assets/minecraft/lang/en_us.json&lt;/code&gt; in a dedicated server mod was fixed.&lt;/p&gt;

&lt;h4 id=&quot;data-attachment-syncing&quot;&gt;Data Attachment Syncing&lt;/h4&gt;
&lt;p&gt;Fabric API can now sync data attachments. To make a syncable attachment, call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;syncWith&lt;/code&gt; inside the builder. The passed packet codec is used to serialize the attached data. Here is how a thirst attachment would look like:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AttachmentType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;THIRST&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AttachmentRegistry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;Identifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;modid&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;thirst&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt; 
        &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;initializer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// start with a default value like hunger&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;persistent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Codec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;INT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// persist across restarts&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;syncWith&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;PacketCodecs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;VAR_INT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AttachmentSyncPredicate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;targetOnly&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// only the player's own client needs the value for rendering&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The sync predicate (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AttachmentSyncPredicate&lt;/code&gt;) controls who gets the synced data. For example, global data can be synced using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;all()&lt;/code&gt;. For more granular control, you can also pass a custom predicate.&lt;/p&gt;

&lt;h4 id=&quot;pick-item-events&quot;&gt;Pick item events&lt;/h4&gt;

&lt;p&gt;Minecraft 1.21.4 moves the ‘Pick Block’ functionality from the client to the logical server. As such, the existing client events have been replaced with new, server-side ones. This replaces &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ClientPickBlockApplyCallback&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ClientPickBlockCallback&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ClientPickBlockGatherCallback&lt;/code&gt;. This change also applies to entities (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EntityPickInteractionAware&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The new events are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PlayerPickItemEvents#BLOCK&lt;/code&gt; for picking a block and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PlayerPickItemEvents#ENTITY&lt;/code&gt; for picking an entity(‘s spawn egg). Return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemStack.EMPTY&lt;/code&gt; to stop the picking, and return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt; to use the default behavior.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;PlayerPickItemEvents&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;BLOCK&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requestIncludeData&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isIn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;MyTags&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;NOT_PICKABLE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ItemStack&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;EMPTY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// use default behavior&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;requestIncludeData&lt;/code&gt; is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt; if the client requests NBT to be included in the returned item stack (by holding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl&lt;/code&gt; while picking block). This parameter is also available to the entity pick item event, even though vanilla does not use this functionality (spawn eggs do not include the picked entity’s NBT).&lt;/p&gt;

&lt;p&gt;Note that this only checks if the client is asking NBT data, and does not check game mode or permission level. In vanilla, NBT data is only included for Creative mode players.&lt;/p&gt;

&lt;h4 id=&quot;client-data-generation&quot;&gt;Client Data Generation&lt;/h4&gt;

&lt;p&gt;Starting with Minecraft 1.21.4, Mojang has moved a number of data generation classes to the client. Loom 1.9 adds a new option that allows you to run your data generation against the client. See the following example if you are using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fabricApi&lt;/code&gt; utility to set up data generation:&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  fabricApi {
&lt;span class=&quot;gd&quot;&gt;-     configureDataGeneration()
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+     configureDataGeneration {
+       client = true
+     }
&lt;/span&gt;  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you are using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;createSourceSet&lt;/code&gt; option, your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;datagen&lt;/code&gt; source set will now have access to Minecraft’s client-only classes and classes in your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;client&lt;/code&gt; source set. Other than updating the data generators themselves, no other changes will be necessary.&lt;/p&gt;

&lt;p&gt;If you are using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;splitEnvironmentSourceSets&lt;/code&gt; option but not the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;createSourceSet&lt;/code&gt; option, you should move your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DataGeneratorEntrypoint&lt;/code&gt; implementation from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; source set to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;client&lt;/code&gt; source set.&lt;/p&gt;

&lt;h4 id=&quot;model-loading-api&quot;&gt;Model Loading API&lt;/h4&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ModelModifier&lt;/code&gt; events and callbacks have been split; there is now one set for static models and one set for block models. This was necessary because static models use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UnbakedModel&lt;/code&gt; and are baked with settings while block models use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GroupableModel&lt;/code&gt; (which no longer extends &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UnbakedModel&lt;/code&gt;) and are not baked with settings. It also allowed cleaning up the identifier getters and providing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BlockState&lt;/code&gt; directly to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ModelModifier.OnLoadBlock&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;However, all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BeforeBake&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AfterBake&lt;/code&gt; events were removed. This is because their behavior can now be achieved using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OnLoad&lt;/code&gt; events, by wrapping the given model and overriding the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bake&lt;/code&gt; method to replace the unbaked model passed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;super.bake&lt;/code&gt; (to replicate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BeforeBake&lt;/code&gt;) or replace the result of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;super.bake&lt;/code&gt; (to replicate &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AfterBake&lt;/code&gt;). This is possible because 1.21.4 made it so the parent of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JsonUnbakedModel&lt;/code&gt; no longer has to be another &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JsonUnbakedModel&lt;/code&gt;. To make this easier, the utility classes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WrapperUnbakedModel&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WrapperGroupableModel&lt;/code&gt; were added, which forward all method calls to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wrapper&lt;/code&gt; field. There were also some minor fundamental issues with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BeforeBake&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AfterBake&lt;/code&gt; events, which prompted their removal.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ModelModifier.OnLoad&lt;/code&gt; can now accept a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;null&lt;/code&gt; model, which is a model that was requested during resolution but does not have a corresponding JSON file. With this change, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ModelResolver&lt;/code&gt; was removed as its behavior could now be achieved with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ModelModifier.OnLoad&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OVERRIDE_PHASE&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DelegatingUnbakedModel&lt;/code&gt; was removed as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GroupableModel&lt;/code&gt; no longer extends &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UnbakedModel&lt;/code&gt;, so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BlockModelResolver&lt;/code&gt;s can no longer use it, which was its original purpose.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;textureGetter&lt;/code&gt; was removed from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ModelModifier&lt;/code&gt; callback contexts as it is now accessible through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Baker#getSpriteGetter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;FRAPI’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WrapperBakedModel&lt;/code&gt; was moved to Model Loading API and was renamed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UnwrappableBakedModel&lt;/code&gt; to avoid conflicts with vanilla’s new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WrapperBakedModel&lt;/code&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UnwrappableBakedModel&lt;/code&gt; is also implemented and interface injected on vanilla’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WrapperBakedModel&lt;/code&gt;. A new static &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UnwrappableBakedModel#unwrap&lt;/code&gt; method was added which accepts a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Predicate&lt;/code&gt; saying when to stop unwrapping. See the documentation for more details.&lt;/p&gt;

&lt;h2 id=&quot;minecraft-changes&quot;&gt;Minecraft changes&lt;/h2&gt;

&lt;h3 id=&quot;block-models&quot;&gt;Block Models&lt;/h3&gt;

&lt;p&gt;Previously, block entities could choose whether they rendered their block model in addition to any custom block entity rendering. This method has been removed, as now all block entities render their block models:&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gd&quot;&gt;- @Override
- protected BlockRenderType getRenderType(BlockState state) {
-     return BlockRenderType.ENTITYBLOCK_ANIMATED;
- }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;While block models were already used to provide particle textures in these cases, mods should still ensure their block entities’ block models are correct.&lt;/p&gt;

&lt;h3 id=&quot;item-models&quot;&gt;Item Models&lt;/h3&gt;

&lt;p&gt;Similar to the blockstate definition json files found in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;assets/&amp;lt;namespace&amp;gt;/blockstates&lt;/code&gt;, items now utilize new item model definition json files in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;assets/&amp;lt;namespace&amp;gt;/items&lt;/code&gt; to determine which models to use.&lt;/p&gt;

&lt;p&gt;These can be quite simple…&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;model&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;minecraft:model&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;model&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;modid:item/my_item&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;or more complex…&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;model&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;minecraft:condition&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;property&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;minecraft:fishing_rod/cast&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;on_false&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;minecraft:model&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;model&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;modid:item/netherite_fishing_rod&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;on_true&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;minecraft:model&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;model&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;modid:item/netherite_fishing_rod_cast&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;utilising conditions and other logic to determine which model to use.&lt;/p&gt;

&lt;p&gt;They also control applying color tints to item textures.&lt;/p&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;model&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;minecraft:model&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;model&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;minecraft:item/template_spawn_egg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;tints&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;minecraft:constant&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6925483&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;minecraft:constant&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12238402&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;These tints can be constant or based on other factors such as potion contents, map colors, etc.&lt;/p&gt;

&lt;p&gt;As a result of these files being introduced, blocks whose item models previously simply referred to their block model no longer require a separate item model file, as the block model is referred to in the model definition file instead. For example,&lt;/p&gt;
&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gd&quot;&gt;- {
-  &quot;parent&quot;: &quot;modid:block/maple_planks&quot;
- }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;assets/modid/models/item/maple_planks.json&lt;/code&gt; can be removed, in favor of&lt;/p&gt;
&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gi&quot;&gt;+ {
+  &quot;model&quot;: {
+    &quot;type&quot;: &quot;minecraft:model&quot;,
+    &quot;model&quot;: &quot;modid:block/maple_planks&quot;
+  }
+ }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;assets/modid/items/maple_planks.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Additionally, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemColors&lt;/code&gt; and related APIs for tinting items have been removed, as item color tints are now controlled by these files.&lt;/p&gt;

&lt;p&gt;For further information, these jsons are well documented on &lt;a href=&quot;https://minecraft.wiki/w/Items_model_definition&quot;&gt;the vanilla Minecraft wiki here&lt;/a&gt; and all the ones used by vanilla items can be easily found in the game files.&lt;/p&gt;

&lt;p&gt;For modders using data generation, these can be generated much like any other JSON asset.&lt;/p&gt;

&lt;h3 id=&quot;miscellaneous&quot;&gt;Miscellaneous&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Resource Metadata files now use Codec serializers&lt;/li&gt;
  &lt;li&gt;Equipment assets were moved from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;assets/&amp;lt;namespace&amp;gt;/models/equipment&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;assets/&amp;lt;namespace&amp;gt;/equipment&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;minecraft:tall_flowers&lt;/code&gt; block tag was removed&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;minecraft:flowers&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;minecraft:tall_flowers&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;minecraft:trim_templates&lt;/code&gt; item tags were removed&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;minecraft:herobrine&lt;/code&gt; entity was removed&lt;/li&gt;
  &lt;li&gt;Trim Material jsons no longer specify an item model index, as trimmed items now use separate item models for each material&lt;/li&gt;
  &lt;li&gt;Textures for item outlines shown in empty slots in certain GUIs are now located in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;assets/&amp;lt;namespace&amp;gt;/textures/gui/sprites/container/slot&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;yarn-changes&quot;&gt;Yarn changes&lt;/h2&gt;

&lt;p&gt;There have been many changes to Yarn mappings to reflect refactors to the vanilla game, fix issues with the mappings, or to otherwise improve them.&lt;/p&gt;

&lt;p&gt;Some notable examples include:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;net/minecraft/data/client&lt;/code&gt; package got moved to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;net/minecraft/client/data&lt;/code&gt;, to reflect the classes now being client-only&lt;/li&gt;
  &lt;li&gt;To match this, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;net/minecraft/data/server&lt;/code&gt; package was removed and its contents moved down to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;net/minecraft/data&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;All references to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xp&lt;/code&gt; got changed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;experience&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BlockStateModelGenerator.TintType&lt;/code&gt; was changed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BlockStateModelGenerator.CrossType&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CherryLeavesBlock&lt;/code&gt; was changed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ParticleLeavesBlock&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CherryLeavesParticle&lt;/code&gt; was changed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LeavesParticle&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LichenGrower&lt;/code&gt; was changed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MultifaceGrower&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EntityModelLoader&lt;/code&gt; was changed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadedEntityModels&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CocoaBeansTreeDecorator&lt;/code&gt; was changed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CocoaTreeDecorator&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BakedQuad#colorIndex&lt;/code&gt; was changed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tintIndex&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name></name></author><summary type="html">Minecraft 1.21.4, the Garden Awakens drop, releases December 3rd. Like with other updates, this drop contains some significant changes affecting mod makers.</summary></entry><entry><title type="html">Fabric for Minecraft 1.21.2 &amp;amp; 1.21.3</title><link href="https://fabricmc.net/2024/10/14/1212.html" rel="alternate" type="text/html" title="Fabric for Minecraft 1.21.2 &amp;amp; 1.21.3" /><published>2024-10-14T00:00:00+00:00</published><updated>2024-10-14T00:00:00+00:00</updated><id>https://fabricmc.net/2024/10/14/1212</id><content type="html" xml:base="https://fabricmc.net/2024/10/14/1212.html">&lt;p&gt;Minecraft 1.21.2, the “Bundles of Bravery” drop, is expected to release soon. Mojang has recently &lt;a href=&quot;https://www.minecraft.net/en-us/article/the-future-of-minecrafts-development&quot;&gt;announced&lt;/a&gt; that they will release these “drops” throughout the year. Like with other updates, this drop contains some significant changes affecting mod makers.&lt;/p&gt;

&lt;p&gt;As always, &lt;strong&gt;we ask all players to be patient, and give mod developers time to update to this new version.&lt;/strong&gt; We ask everyone kindly not to pester them. &lt;strong&gt;We also recommend all players to make a backup of their worlds.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is a list of all major modder-facing changes in this version. Note that all code references are using Yarn mappings; modders using alternative mappings may need to use different names.&lt;/p&gt;

&lt;h2 id=&quot;fabric-changes&quot;&gt;Fabric changes&lt;/h2&gt;

&lt;p&gt;Developers should use Loom 1.8 (at the time of writing) to develop mods for Minecraft 1.21.2. Players should install the latest stable version of Fabric Loader (currently 0.16.7).&lt;/p&gt;

&lt;h3 id=&quot;fabric-loader-changes&quot;&gt;Fabric Loader changes&lt;/h3&gt;

&lt;p&gt;Fabric Loader 0.16.0 was released some time ago.  Most notably, this release updates the bundled MixinExtras to 0.4.0.&lt;/p&gt;

&lt;p&gt;In addition, Fabric Loader 0.16.7 added support for Java 23. However, you should continue to use Java 21 for mod development and gameplay.&lt;/p&gt;

&lt;h4 id=&quot;mixinextras-additions&quot;&gt;MixinExtras additions&lt;/h4&gt;

&lt;p&gt;The following new features have been added:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/LlamaLad7/MixinExtras/wiki/WrapMethod&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@WrapMethod&lt;/code&gt;&lt;/a&gt;, which allows wrapping the entire method&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/LlamaLad7/MixinExtras/wiki/Cancellable&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@Cancellable&lt;/code&gt;&lt;/a&gt;, which allows cancellation from all injectors.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;namespace&lt;/code&gt; parameter in &lt;a href=&quot;https://github.com/LlamaLad7/MixinExtras/wiki/Share&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@Share&lt;/code&gt;&lt;/a&gt; to share values between Mixins&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;loom-18&quot;&gt;Loom 1.8&lt;/h3&gt;

&lt;p&gt;Loom 1.8 adds support for configuration caches, Gradle 8.10, and other changes and fixes.&lt;/p&gt;

&lt;p&gt;Configuration cache is an opt-in Gradle performance enhancement feature that will be enabled by default in Gradle 9. Because this may break existing setup, we only recommend using this if you are familiar with Gradle buildscripts. To support this change, multi-project optimization has been removed.&lt;/p&gt;

&lt;h3 id=&quot;new-fabric-api-changes&quot;&gt;New Fabric API changes&lt;/h3&gt;

&lt;p&gt;With the help of many contributors, Fabric API has received some new features since the last update blog post:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Convention Tags: Add more tags (TelepathicGrunt, Juuz)&lt;/li&gt;
  &lt;li&gt;Crash Report Info: Print the full stack trace from the dedicated server watchdog (TelepathicGrunt)&lt;/li&gt;
  &lt;li&gt;Entity Events: Add after damage event (TheDeathlyCow)&lt;/li&gt;
  &lt;li&gt;Item API: Modify enchantment and add component map builder extensions (TheDeathlyCow)&lt;/li&gt;
  &lt;li&gt;Item Group API: Add API to control creative inventory screen (modmuss50)&lt;/li&gt;
  &lt;li&gt;Loot API: Loot API v3 (modmuss50)&lt;/li&gt;
  &lt;li&gt;Networking: Add MinecraftClient/Server instances to networking contexts (modmuss50)&lt;/li&gt;
  &lt;li&gt;Networking: Add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ClientConfigurationConnectionEvents#START&lt;/code&gt; (modmuss50)&lt;/li&gt;
  &lt;li&gt;Networking: Add access to ClientConfigurationNetworkHandler in context (Earthcomputer)&lt;/li&gt;
  &lt;li&gt;Object Builder: Add an API to add additional supported blocks to block entity types (modmuss50)&lt;/li&gt;
  &lt;li&gt;Renderer API: Add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ShadeMode&lt;/code&gt; (PepperCode1)&lt;/li&gt;
  &lt;li&gt;Renderer API: Quads overloads for joml interfaces (SHsuperCM)&lt;/li&gt;
  &lt;li&gt;Resource Conditions: Allow conditions inside pack overlays (Apollo)&lt;/li&gt;
  &lt;li&gt;Resource Loader: Add API to create reload listeners with a registry lookup (modmuss50)&lt;/li&gt;
  &lt;li&gt;Removed Herobrine (Tiny Potato)&lt;/li&gt;
  &lt;li&gt;Transfer API: Crafter support (modmuss50)&lt;/li&gt;
  &lt;li&gt;Transfer API: Add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemVariant#withComponentChanges&lt;/code&gt; (BasiqueEvangelist)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;breaking-changes-and-deprecations&quot;&gt;Breaking changes and deprecations&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Note: breaking changes related to vanilla changes are addressed separately below.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One deprecated module was removed: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fabric-renderer-registries-v1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In Resource Condition, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test&lt;/code&gt; method now takes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RegistryOps.RegistryInfoGetter&lt;/code&gt;. Tags can no longer have resource conditions. Similarly, in Resource Loader, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ResourceReloadListenerKeys#TAGS&lt;/code&gt; was removed.&lt;/p&gt;

&lt;p&gt;The following deprecations were made since the last blogpost:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Content Registries: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VillagerInteractionRegistries#registerCollectable&lt;/code&gt; was deprecated. Use the vanilla tag, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;minecraft:villager_picks_up&lt;/code&gt;, instead.&lt;/li&gt;
  &lt;li&gt;Loot API: Loot API v2 was deprecated. Use Loot API v3, which passes registry contexts, instead.&lt;/li&gt;
  &lt;li&gt;Networking:&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ClientConfigurationConnectionEvents#READY&lt;/code&gt; was renamed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;COMPLETE&lt;/code&gt;. (This was done during the 1.21 update cycle, but after we published the last blogpost.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;minecraft-changes&quot;&gt;Minecraft changes&lt;/h2&gt;

&lt;h3 id=&quot;serverworld-parameters&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ServerWorld&lt;/code&gt; parameters&lt;/h3&gt;

&lt;p&gt;Many methods that must be executed on the server side only now require &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ServerWorld&lt;/code&gt; to be passed explicitly. &lt;strong&gt;Do not cast just to fix a type error;&lt;/strong&gt; many events and overridden method are still called on both the client side and the server side.&lt;/p&gt;

&lt;p&gt;Instead, wrap all logic that must be run only on the server side with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if (world instanceof ServerWorld serverWorld)&lt;/code&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;serverWorld&lt;/code&gt; can be passed to those methods.&lt;/p&gt;

&lt;p&gt;For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Entity#damage&lt;/code&gt; now requires &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ServerWorld&lt;/code&gt;, and is therefore only called on the server side. There is an additional method, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clientDamage&lt;/code&gt;, which is called only on the client side.&lt;/p&gt;

&lt;h3 id=&quot;block-and-item-settings&quot;&gt;Block and item settings&lt;/h3&gt;

&lt;p&gt;Minecraft 1.21.2 uses registry keys to pre-compute certain block or item settings. This allows referencing them in default item components. For example, rather than computing a default name based on an item’s registry key inside &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getName&lt;/code&gt; method if the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;minecraft:item_name&lt;/code&gt; component is not present, every item now contains the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;minecraft:item_name&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;Because of this, you must &lt;strong&gt;manually set registry keys in the settings of every block and item&lt;/strong&gt;. Failure to do so will result in crashes such as:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NullPointerException: Block id not set&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NullPointerException: Item id not set&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both settings classes provide a simple method which should be called for every item or block with their respective registry key:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Identifier&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Identifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;mymod&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;test_item&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;RegistryKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RegistryKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;RegistryKeys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ITEM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Settings&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;settings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Settings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// If your item is based on a block&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;useBlockPrefixedTranslationKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;registryKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;Registry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Registries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ITEM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Identifier&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Identifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;mymod&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;test_block&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;RegistryKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Block&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RegistryKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;RegistryKeys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;BLOCK&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;Block&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Settings&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;settings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Block&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Settings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;registryKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;Registry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Registries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;BLOCK&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Block&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Make sure to call the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Item.Settings#useBlockPrefixedTranslationKey&lt;/code&gt; method for block items so that they use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;block.&amp;lt;namespace&amp;gt;.&amp;lt;path&amp;gt;&lt;/code&gt; translation key format.&lt;/p&gt;

&lt;p&gt;This change affects the following traits:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Item names (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;minecraft:item_name&lt;/code&gt; component)&lt;/li&gt;
  &lt;li&gt;Item models (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;minecraft:item_model&lt;/code&gt; component)&lt;/li&gt;
  &lt;li&gt;Block models&lt;/li&gt;
  &lt;li&gt;Block loot table key&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some traits, such as the cooldown group of items with cooldowns, still dynamically look up a registry key, but this pattern should be avoided as much as possible.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Block#getLootTableKey&lt;/code&gt; now returns &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Optional&amp;lt;RegistryKey&amp;gt;&lt;/code&gt;. A block without a corresponding loot table now returns an empty optional instead of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;minecraft:empty&lt;/code&gt; loot table registry key.&lt;/p&gt;

&lt;p&gt;In Fabric API, the previously-deprecated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FabricBlockSettings&lt;/code&gt; class was removed. Use the vanilla &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbstractBlock.Settings&lt;/code&gt; class instead.&lt;/p&gt;

&lt;h3 id=&quot;furnace-fuels&quot;&gt;Furnace fuels&lt;/h3&gt;

&lt;p&gt;Furnace fuels are now registered through an event, which allows access to new parameters:&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gd&quot;&gt;- FuelRegistry.INSTANCE.add(ModItems.TEST_ITEM, 50);
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ FuelRegistryEvents.BUILD.register((builder, context) -&amp;gt; {
+     builder.add(ModItems.TEST_ITEM, context.baseSmeltTime() / 4);
+ });
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The base smelt time can be used to express a fuel’s smelt time in terms of a ratio. The default base smelt time is 200 ticks, or 10 seconds.&lt;/p&gt;

&lt;h3 id=&quot;entities&quot;&gt;Entities&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EntityType&lt;/code&gt; received a registry key change similar to the block and item one described above. When building an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EntityType&lt;/code&gt;, pass a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RegistryKey&lt;/code&gt; for the entity type. The no-argument version of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EntityType.Builder#build&lt;/code&gt; method, injected by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FabricEntityTypeBuilder&lt;/code&gt;, has been removed. For example:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Identifier&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Identifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;mymod&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;test_entity_type&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;RegistryKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;EntityType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RegistryKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;RegistryKeys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ENTITY_TYPE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;EntityType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TestEntity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entityType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EntityType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TestEntity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;TestEntity:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SpawnGroup&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;MISC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nc&quot;&gt;Registry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Registries&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ENTITY_TYPE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entityType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Mob conversion (such as zombie villager curing or slimes splitting on death) was overhauled. The exact behavior of conversion is now handled by methods implemented by values of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EntityConversionType&lt;/code&gt; enum. When using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MobEntity#convertTo&lt;/code&gt; method to convert a mob, an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EntityConversionContext&lt;/code&gt; is now required. This context is also now passed to Fabric API’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ServerLivingEntityEvents#MOB_CONVERSION&lt;/code&gt; event.&lt;/p&gt;

&lt;p&gt;When creating an entity, a spawn reason is now required:&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gd&quot;&gt;- Entity pig = EntityType.PIG.create(overworld);
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ Entity pig = EntityType.PIG.create(overworld, SpawnReason.SPAWN_ITEM_USE);
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The prefixes of attributes in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EntityAttributes&lt;/code&gt;, like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GENERIC&lt;/code&gt;, have been dropped. This matches a change in the identifiers of attributes:&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gd&quot;&gt;- public static final RegistryEntry&amp;lt;EntityAttribute&amp;gt; GENERIC_ATTACK_KNOCKBACK = register(
-    &quot;generic.attack_knockback&quot;,
-    new ClampedEntityAttribute(&quot;attribute.name.generic.attack_knockback&quot;, 0, 0, 5)
&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;);&lt;/span&gt;
+ public static final RegistryEntry&amp;lt;EntityAttribute&amp;gt; ATTACK_KNOCKBACK = register(
    &quot;attack_knockback&quot;,
    new ClampedEntityAttribute(&quot;attribute.name.attack_knockback&quot;, 0, 0, 5)
&lt;span class=&quot;err&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;data-generation&quot;&gt;Data generation&lt;/h3&gt;

&lt;p&gt;A recipe provider must now override &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getRecipeGenerator&lt;/code&gt; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;generate&lt;/code&gt;. The new method takes the registries and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exporter&lt;/code&gt;, and returns a new instance of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RecipeGenerator&lt;/code&gt; that actually generates the recipes.&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gd&quot;&gt;- public void generate(RecipeExporter exporter) {
-    offerPlanksRecipe2(exporter, SIMPLE_BLOCK, ItemTags.ACACIA_LOGS, 1);
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ protected RecipeGenerator getRecipeGenerator(RegistryWrapper.WrapperLookup registries, RecipeExporter exporter) {
+    return new RecipeGenerator(registries, exporter) {
+        @Override
+        public void generate() {
+            offerPlanksRecipe2(SIMPLE_BLOCK, ItemTags.ACACIA_LOGS, 1);
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;actionresult&quot;&gt;ActionResult&lt;/h3&gt;

&lt;p&gt;Previously, action results have been represented in several ways, including the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ActionResult&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemActionResult&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TypedActionResult&lt;/code&gt; classes. In Minecraft 1.21.2, these classes have been merged into a single &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ActionResult&lt;/code&gt; class, which provides direct replacements for the previous methods for all three classes:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Old&lt;/th&gt;
      &lt;th&gt;New&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ActionResult.success(world.isClient())&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ActionResult.SUCCESS&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TypedActionResult.pass(stack)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ActionResult.PASS&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TypedActionResult.fail(stack)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ActionResult.FAIL&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TypedActionResult.success(stack, world.isClient())&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ActionResult.SUCCESS&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TypedActionResult.consume(stack)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ActionResult.CONSUME&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;If an action replaces the hand stack with another instance of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemStack&lt;/code&gt;, then it should be marked with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ActionResult#withNewHandStack&lt;/code&gt; method. For example, an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Item#use&lt;/code&gt; implementation that replaces the hand stack might be:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ActionResult&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;World&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PlayerEntity&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Hand&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hand&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;ItemStack&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stack&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getStackInHand&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hand&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stack&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getCount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;ItemStack&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newStack&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ItemStack&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Items&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;BLAZE_ROD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ActionResult&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;SUCCESS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;withNewHandStack&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newStack&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ActionResult&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;PASS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;On the other hand, if the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemStack&lt;/code&gt; instance for the hand stack is the same as the one provided to an interaction method such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Item#use&lt;/code&gt;, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ActionResult#withNewHandStack&lt;/code&gt; method should not be called.&lt;/p&gt;

&lt;p&gt;This change affects all places where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TypedActionResult&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemActionResult&lt;/code&gt; were previously used in Minecraft’s code. In Fabric API, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UseItemCallback&lt;/code&gt; event in the Events Interaction module now returns &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ActionResult&lt;/code&gt; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TypedActionResult&amp;lt;ItemStack&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;item-components&quot;&gt;Item components&lt;/h3&gt;
&lt;p&gt;Because elytra behavior is now controlled by a new item component, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;minecraft:glider&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FabricElytraItem&lt;/code&gt; was removed. Add the component to your elytra item instead.&lt;/p&gt;

&lt;h3 id=&quot;block-entities&quot;&gt;Block entities&lt;/h3&gt;

&lt;p&gt;In Minecraft 1.21.1 (released in August), a change was made that required mods to add all supported blocks to block entities. For example, a mod with a new sign block must add the block to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BlockEntityType#SIGN&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;BlockEntityType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;SIGN&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;addSupportedBlock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ModBlocks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;TEAL_SIGN&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In Minecraft 1.21.2, block entity types are no longer constructed using builders. Therefore, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FabricBlockEntityType.Builder&lt;/code&gt; was removed, while &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FabricBlockEntityTypeBuilder&lt;/code&gt; is no longer deprecated.&lt;/p&gt;

&lt;h3 id=&quot;registries&quot;&gt;Registries&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Registry&lt;/code&gt; now implements &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RegistryEntryLookup&lt;/code&gt;. This resulted in several name changes. To query a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RegistryEntry&lt;/code&gt; from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RegistryKey&lt;/code&gt;, use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getOptional&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getOrThrow&lt;/code&gt;. (Same applies to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RegistryEntryList&lt;/code&gt; from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TagKey&lt;/code&gt;.) If you want to query the registry value, use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getValueOrThrow&lt;/code&gt;. See the table below for all changes.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Old&lt;/th&gt;
      &lt;th&gt;New&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getEntry&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getOptional&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;entryOf&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getOrThrow&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getOrThrow&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getValueOrThrow&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getOrEmpty&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getOptionalValue&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getEntryList&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getOptional&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Similarly, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DynamicRegistryManager#get&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RegistryWrapper.WrapperLookup#getWrapperOrThrow&lt;/code&gt; has been renamed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getOrThrow&lt;/code&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getOptionalWrapper&lt;/code&gt; was renamed tp &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getOptional&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;rendering&quot;&gt;Rendering&lt;/h3&gt;
&lt;h4 id=&quot;entity-rendering&quot;&gt;Entity rendering&lt;/h4&gt;
&lt;p&gt;Entity rendering has received a large refactor that decouples the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Entity&lt;/code&gt; instance from its respective rendering calls. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EntityRenderer&lt;/code&gt; now has an additional type parameter, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;S extends EntityRenderState&lt;/code&gt;, which represents a ‘render state’, which is a mutable class containing only the parameters of the entity that are used in rendering.&lt;/p&gt;

&lt;p&gt;Previously, renderer methods accessed the entity instance directly. However, accessing entity information now happens in three steps.&lt;/p&gt;

&lt;p&gt;First, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EntityRenderer#createRenderState&lt;/code&gt; method is called to construct an instance of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;S&lt;/code&gt; for the given entity with placeholder values:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;createRenderState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EntityRenderer#updateRenderState&lt;/code&gt; method performs the operation of copying information from the entity to its render state:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;updateRenderState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;S&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tickDelta&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;updateRenderState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tickDelta&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Example: entity has an 'is saddled' field&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isSaddled&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isSaddled&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EntityRenderer#render&lt;/code&gt; method (as well as other renderer methods) accesses information from the entity’s render state:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;S&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MatrixStack&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;matrices&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;VertexConsumerProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vertexConsumers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;light&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;matrices&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vertexConsumers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;light&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isSaddled&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Render the saddle&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;shaders&quot;&gt;Shaders&lt;/h4&gt;
&lt;p&gt;In Fabric Rendering API, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoreShaderRegistrationCallback&lt;/code&gt; was removed. Vanilla resource pack now allows loading modded core shaders.&lt;/p&gt;

&lt;h4 id=&quot;other-changes&quot;&gt;Other changes&lt;/h4&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WorldRenderer&lt;/code&gt; methods for rendering certain vertices (like a box) were transferred to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VertexRendering&lt;/code&gt;.&lt;/p&gt;

&lt;!-- TODO Shader changes. Models. --&gt;

&lt;h3 id=&quot;recipes&quot;&gt;Recipes&lt;/h3&gt;
&lt;p&gt;The recipe system was reworked. To summarize:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Recipes are now identified using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RegistryKey&amp;lt;? extends Recipe&amp;gt;&lt;/code&gt;, not &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Identifier&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Recipe&lt;/code&gt; and the recipe ID is now server-side only. It cannot be accessed from the client.&lt;/li&gt;
  &lt;li&gt;Instead, clients receive &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RecipeDisplayEntry&lt;/code&gt;. It contains all information needed to display and run the recipe book. Recipes are identified using an integer (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NetworkRecipeId&lt;/code&gt;) on the client. A recipe can have multiple display entries.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IngredientPlacement&lt;/code&gt; controls the placement of ingredients on the crafting table, while &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RecipeMatcher&lt;/code&gt; handles recipe matching.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ingredient&lt;/code&gt; is now internally a list of items, not item stacks.&lt;/p&gt;

&lt;p&gt;In Fabric API, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CustomIngredientSerializer#getCodec&lt;/code&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;allowEmpty&lt;/code&gt; param removed, empty now always disallowed.&lt;/p&gt;

&lt;h3 id=&quot;biome&quot;&gt;Biome&lt;/h3&gt;

&lt;p&gt;Water cave carvers (which, before 1.18, were seen in seabeds) were removed, along with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GenerationStep.Carver&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In Fabric Biome API, biome modification methods like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addCarver&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;removeCarver&lt;/code&gt; no longer takes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GenerationStep.Carver&lt;/code&gt; argument.&lt;/p&gt;

&lt;h3 id=&quot;profiler&quot;&gt;Profiler&lt;/h3&gt;
&lt;p&gt;The shared profiler is now accessed using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Profilers#get&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gd&quot;&gt;- world.getProfiler().push(&quot;tinyPotato&quot;);
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ Profilers.get().push(&quot;tinyPotato&quot;);
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;loot-tables&quot;&gt;Loot tables&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LootTables#EMPTY&lt;/code&gt; was removed. The game uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Optional&lt;/code&gt; to mark the lack of loot tables.&lt;/p&gt;

&lt;p&gt;Some loot context-related logics are now shared with recipes, resulting in name changes. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LootContextParameter&lt;/code&gt; is now &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContextParameter&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LootContextType&lt;/code&gt; is now &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContextType&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;yarn-renames&quot;&gt;Yarn renames&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;This section only affects those using the Yarn mapping.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As part of regular Yarn maintainace, the following changes were made. These should be a simple replacement:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ModelTransformationMode&lt;/code&gt; is transferred to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;net.minecraft.item&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RealmsLoadingWidget&lt;/code&gt; is renamed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LoadingWidget&lt;/code&gt; and transferred to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;client.gui.widget&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Several &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Brain&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Task&lt;/code&gt;-related names: see &lt;a href=&quot;https://github.com/FabricMC/yarn/pull/3992&quot;&gt;the pull request&lt;/a&gt; for details.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;registryLookupFuture&lt;/code&gt; is renamed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;registriesFuture&lt;/code&gt; in several locations.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Codecs#NONNEGATIVE_INT&lt;/code&gt; is renamed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NON_NEGATIVE_INT&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;QUATERNIONF&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VECTOR3F&lt;/code&gt; are renamed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;QUATERNION_F&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VECTOR_3F&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Screen#initTabNavigation&lt;/code&gt; is renamed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;refreshWidgetPositions&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ComponentMapImpl&lt;/code&gt; is renamed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MergedComponentMap&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContainerComponentModifier#create&lt;/code&gt; is renamed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apply&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ItemStack#encode&lt;/code&gt; is renamed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toNbt&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;</content><author><name></name></author><summary type="html">Minecraft 1.21.2, the “Bundles of Bravery” drop, is expected to release soon. Mojang has recently announced that they will release these “drops” throughout the year. Like with other updates, this drop contains some significant changes affecting mod makers.</summary></entry><entry><title type="html">Fabric for Minecraft 1.21 &amp;amp; 1.21.1</title><link href="https://fabricmc.net/2024/05/31/121.html" rel="alternate" type="text/html" title="Fabric for Minecraft 1.21 &amp;amp; 1.21.1" /><published>2024-05-31T00:00:00+00:00</published><updated>2024-05-31T00:00:00+00:00</updated><id>https://fabricmc.net/2024/05/31/121</id><content type="html" xml:base="https://fabricmc.net/2024/05/31/121.html">&lt;p&gt;Minecraft 1.21 is expected to be released on June 13, with some significant changes affecting mod makers.&lt;/p&gt;

&lt;p&gt;It’s been only a month and a half since we last released a blogpost. Yet, this update is nothing small - some changes are likely to affect most, if not all, mods.&lt;/p&gt;

&lt;p&gt;As always, &lt;strong&gt;we ask all players to be patient, and give mod developers time to update to this new version.&lt;/strong&gt; We ask everyone kindly not to pester them. &lt;strong&gt;We also recommend all players to make a backup of their worlds.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is a list of all major modder-facing changes in this version. Note that all code references are using Yarn mappings; modders using alternative mappings may need to use different names.&lt;/p&gt;

&lt;h2 id=&quot;fabric-changes&quot;&gt;Fabric changes&lt;/h2&gt;
&lt;p&gt;Developers should use Loom 1.6 (at the time of writing) to develop mods for Minecraft 1.21. Players should install the latest stable version of Fabric Loader (currently 0.15.11).&lt;/p&gt;
&lt;h3 id=&quot;new-fabric-api-changes&quot;&gt;New Fabric API changes&lt;/h3&gt;
&lt;p&gt;With the help of many contributors, Fabric API has received some new features since the last update blog post:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Conventional Tags: Default English Translations for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c&lt;/code&gt; namespaced tags (TelepathicGrunt)&lt;/li&gt;
  &lt;li&gt;Data Generation: Support extending dynamic registries in datagen (SquidDev)&lt;/li&gt;
  &lt;li&gt;Item API: Add API to modify default item components (modmuss50)&lt;/li&gt;
  &lt;li&gt;Resource Conditions: Support loading a single resource condition instead of array (Apollo)&lt;/li&gt;
  &lt;li&gt;Resource Conditions: Registry resource conditions (SquidDev)&lt;/li&gt;
  &lt;li&gt;Removed Herobrine (Tiny Potato)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;tag-translation&quot;&gt;Tag translation&lt;/h4&gt;
&lt;p&gt;Mods are now strongly encouraged to provide an English translation for item tags it provides. For example, the translation for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test:potatoes&lt;/code&gt; should be declared like this:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;tag.item.test.potatoes&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Potatoes&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Although these are not used by the API itself, other mods (such as recipe viewers) rely on them for proper display.&lt;/p&gt;

&lt;h3 id=&quot;breaking-changes&quot;&gt;Breaking Changes&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Note: breaking changes related to vanilla changes are addressed separately below.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One deprecated module was removed: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fabric-models-v0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In Item API, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EquipmentSlotProvider#getPreferredEquipmentSlot&lt;/code&gt; is now passed a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LivingEntity&lt;/code&gt;. Implementations are expected to check themselves whether the slot is available, using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;entity.canUseSlot(EquipmentSlot)&lt;/code&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FabricItem#getAttributeModifiers&lt;/code&gt; was removed; use Default Components API instead.&lt;/p&gt;

&lt;p&gt;Registry Sync now freezes the registry at an earlier point. This does not affect mods that register things in their &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ModInitializer&lt;/code&gt;s, but might affect more complex mods. Make sure to register everything during &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ModInitializer&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;minecraft-changes&quot;&gt;Minecraft changes&lt;/h2&gt;
&lt;p&gt;This version brought many breaking changes, including data-driven Enchantments. Data pack structures also changed, using singular nouns (instead of plurals) in many places.&lt;/p&gt;

&lt;h3 id=&quot;identifier&quot;&gt;Identifier&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Identifier&lt;/code&gt; constructor is now &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;protected&lt;/code&gt;. Use the static method &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;of&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ofVanilla&lt;/code&gt; to construct &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Identifier&lt;/code&gt;. Replacing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new Identifier&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Identifier.of&lt;/code&gt; using text editors or IDEs should be sufficient.&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gd&quot;&gt;- var id = new Identifier(&quot;example&quot;, &quot;foo_bar&quot;);
- var id2 = new Identifier(&quot;test:single_argument&quot;);
- var creeper = new Identifier(&quot;minecraft&quot;, &quot;creeper&quot;);
- @Nullable var customId = Identifier.of(&quot;namespace&quot;, unsanitizedInput);
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ var id = Identifier.of(&quot;example&quot;, &quot;foo_bar&quot;);
+ var id2 = Identifier.of(&quot;test:single_argument&quot;);
+ var creeper = Identifier.ofVanilla(&quot;creeper&quot;); // very slightly improved performance
+ @Nullable var customId = Identifier.tryParse(&quot;namespace&quot;, unsanitizedInput);
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Pro tip: make a method to construct &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Identifier&lt;/code&gt; for your mod’s namespace; this can be imported later using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;import static&lt;/code&gt; to shorten your code.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Identifier&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Identifier&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;mod_namespace&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;enchantments&quot;&gt;Enchantments&lt;/h3&gt;
&lt;p&gt;Enchantments are now data-driven. This means that they are no longer hardcoded - instead, they’re part of data packs. Consequentially, there are several important changes in how mods handle enchantments.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Generally, enchantments either “do something” (like causing an explosion), or “modify a value” (like attack damage).
Example: Instead of checking if the player has Thorns and applying damage to the attacker, a mod should now call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EnchantmentHelper#onTargetDamaged&lt;/code&gt; which should automatically handle this.
Example 2: Instead of checking the level of Knockback, a mod should now call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EnchantmentHelper#modifyKnockback&lt;/code&gt; with the original knockback.&lt;/li&gt;
  &lt;li&gt;Sometimes, a code needs to check if an item has certain enchantments. Because enchantments are no longer hard-coded, this is done using enchantment tags.
Example 3: Breaking a beehive with Silk Touch prevents bees from getting released. Previously, this was done by checking for the Silk Touch enchantment. Now, this is done by calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EnchantmentHelper#hasAnyEnchantmentsIn(stack, EnchantmentTags#PREVENTS_BEE_SPAWNS_WHEN_MINING)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;enchantment-code-structures&quot;&gt;Enchantment Code Structures&lt;/h3&gt;
&lt;p&gt;An &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Enchantment&lt;/code&gt; is, well, an enchantment. Because it is now defined by a dynamic registry, it is often handled as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RegistryEntry&amp;lt;Enchantment&amp;gt;&lt;/code&gt;. These can be obtained from the dynamic registry, i.e. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;world.getRegistryManager()&lt;/code&gt; or the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;registryLookup&lt;/code&gt; passed to various methods.&lt;/p&gt;

&lt;p&gt;An enchantment has effect components, which is a map of effect types to list of effects. Effect types are pre-defined keys that enchantments can define behaviors for. For example, an enchantment may want to add “multiply by 2” behavior for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DAMAGE&lt;/code&gt; effect type, or “explode” behavior for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;POST_ATTACK&lt;/code&gt; effect type. These are defined in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EnchantmentEffectComponentTypes&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The values of effect components are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EnchantmentEffectEntry&lt;/code&gt;. This is a pair of the effect and an optional condition. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LootCondition&lt;/code&gt; is reused for this purpose.&lt;/p&gt;

&lt;p&gt;Enchantment effects can be categorized into three categories:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EnchantmentValueEffect&lt;/code&gt;. When given a value, the effect calculates the modified value. Examples include Protection (which modifies &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DAMAGE_PROTECTION&lt;/code&gt;), Lure (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FISHING_LUCK_BONUS&lt;/code&gt;), Unbreaking (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ITEM_DAMAGE&lt;/code&gt;), and Multishot (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PROJECTILE_COUNT&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EnchantmentEntityEffect&lt;/code&gt;. This effect does something when triggered. Examples include Thorns and Channeling (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;POST_ATTACK&lt;/code&gt;) and Flame (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PROJECTILE_SPAWNED&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AttributeEnchantmentEffect&lt;/code&gt;, which adds an attribute to the entity. Unlike entity effects, attributes persist until the enchantment becomes inapplicable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EnchantmentLocationBasedEffect&lt;/code&gt; is an interface implemented by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EnchantmentEntityEffect&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AttributeEnchantmentEffect&lt;/code&gt;. In addition, some enchantment effect types simply require effective values to be specified directly - like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CROSSBOW_CHARGING_SOUNDS&lt;/code&gt;, which is a list of sounds. Some effects, like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PREVENT_ARMOR_CHANGE&lt;/code&gt;, cannot be configured further.&lt;/p&gt;

&lt;h3 id=&quot;using-vanilla-enchantments&quot;&gt;Using Vanilla Enchantments&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EnchantmentHelper&lt;/code&gt; methods can be used to handle vanilla enchantments.&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Example of modifying a value&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newDamage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EnchantmentHelper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getDamage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;stack&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;attackTarget&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;damageSource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;baseDamage&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// For values with no base value (such as Protection)&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;protection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EnchantmentHelper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getProtectionAmount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;damageSource&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Entity-based effect&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;EnchantmentHelper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;onTargetDamaged&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;world&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;attackTarget&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;damageSource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;weapon&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Checking if an ItemStack is enchanted with certain enchantments&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;EnchantmentHelper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;hasAnyEnchantmentsIn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;stack&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;EnchantmentTags&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;PREVENTS_BEE_SPAWNS_WHEN_MINING&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Checking for nonconfigurable effects&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// e.g. checking for Curse of Binding&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;EnchantmentHelper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;hasAnyEnchantmentsWith&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;stack&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nc&quot;&gt;EnchantmentEffectComponentTypes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;PREVENT_ARMOR_CHANGE&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;adding-a-new-enchantment&quot;&gt;Adding a new Enchantment&lt;/h3&gt;
&lt;p&gt;Adding a new enchantment is now done by writing JSON files. You can use Data Generation to generate enchantments easily.&lt;/p&gt;

&lt;p&gt;An enchantment can perform many tasks, like applying attributes, replacing blocks or summoning an entity. However, not all things are possible. To add a custom &lt;strong&gt;effect type&lt;/strong&gt;, a new effect class must be created and its codec registered. &lt;strong&gt;An effect type must exist in both the client and the server.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enchantment tags are used to specify exclusive enchantments (e.g. Fortune and Silk Touch) and where the enchantments can be obtained. Make sure to add your enchantments to those tags.&lt;/p&gt;

&lt;h3 id=&quot;enchantment-related-fabric-api-changes&quot;&gt;Enchantment-related Fabric API changes&lt;/h3&gt;
&lt;p&gt;The following event callbacks now pass &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RegistryEntry&amp;lt;Enchantment&amp;gt;&lt;/code&gt; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Enchantment&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EnchantmentEvents.AllowEnchanting#allowEnchanting&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FabricItem#canBeEnchantedWith&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FabricItemStack#canBeEnchantedWith&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EnchantmentContext&lt;/code&gt; was reworked. Previously, a context was one of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RANDOM_ENCHANTMENT&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ANVIL&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ENCHANT_COMMAND&lt;/code&gt;, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LOOT_RANDOM_ENCHANTMENT&lt;/code&gt;. To clarify its purpose, they are now one of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ACCEPTABLE&lt;/code&gt; (e.g. anvils) or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PRIMARY&lt;/code&gt; (e.g. enchanting tables). For example, a helmet can be enchanted with Thorns using anvils but not in enchanting tables, because only chestplates are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PRIMARY&lt;/code&gt; in case of Thorns.&lt;/p&gt;

&lt;h3 id=&quot;teleportation&quot;&gt;Teleportation&lt;/h3&gt;
&lt;p&gt;Both intra-dimensional and cross-dimensional teleportation can now be performed using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Entity#teleportTo&lt;/code&gt; (previously known as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;moveToWorld&lt;/code&gt;). &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TeleportTarget&lt;/code&gt; now contains the destination world and position.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FabricDimensions&lt;/code&gt; was removed, because its only API, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;teleport&lt;/code&gt;, is effectively superseded with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Entity#teleportTo&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;data-pack-paths&quot;&gt;Data Pack Paths&lt;/h3&gt;
&lt;p&gt;Data packs now use singular nouns in the following paths:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Tag subdirectories such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tags/blocks&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tags/entity_types&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tags/functions&lt;/code&gt;. They are now &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tags/block&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tags/entity_type&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tags/function&lt;/code&gt;, respectively. &lt;strong&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tags&lt;/code&gt; directory itself remains plural.&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Advancements (previously &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;advancements&lt;/code&gt;, now &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;advancement&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;Functions (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;functions&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;function&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;Item modifiers/loot functions (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;item_modifiers&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;item_modifier&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;Loot tables (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;loot_tables&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;loot_table&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;Predicates/loot conditions (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;predicates&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;predicate&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;Recipes (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;recipes&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;recipe&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;Structures (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;structures&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;structure&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In Fabric API news, GameTest structure directories are now singular as well; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gametest/structures&lt;/code&gt;, they are now placed in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gametest/structure&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;rendering-changes&quot;&gt;Rendering Changes&lt;/h3&gt;
&lt;p&gt;In the Fabric Rendering API, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HudRenderCallback&lt;/code&gt; now passes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RenderTickCounter&lt;/code&gt; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tickDelta&lt;/code&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tickDelta&lt;/code&gt; can be obtained from the counter. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WorldRenderContext&lt;/code&gt;’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tickDelta&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;limitTime&lt;/code&gt; methods are also replaced with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tickCounter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There are some other, significant internal refactors to rendering. For example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BufferBuilder#next()&lt;/code&gt; was removed, and the methods for beginning or ending the building process has changed:&lt;/p&gt;

&lt;div class=&quot;language-diff highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gd&quot;&gt;- BufferBuilder builder = tessellator.getBuffer();
- builder.begin(...);
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ BufferBuilder builder = tessellator.begin(...);
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;- builder.vertex(...).texture(...).color(...).next();
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ builder.vertex(...).texture(...).color(...)
&lt;/span&gt;&lt;span class=&quot;gd&quot;&gt;- tessellator.draw();
&lt;/span&gt;&lt;span class=&quot;gi&quot;&gt;+ BufferRenderer.drawWithGlobalProgram(builder.end());
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;miscellaneous&quot;&gt;Miscellaneous&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FabricCodecProvider&lt;/code&gt; now has a new constructor that takes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RegistryKey&lt;/code&gt; instead of directory name. This can be used with, for example, item modifier providers. The old constructor can still be used for non-registered codecs.&lt;/li&gt;
&lt;/ul&gt;</content><author><name></name></author><summary type="html">Minecraft 1.21 is expected to be released on June 13, with some significant changes affecting mod makers.</summary></entry></feed>