NeoForge 21.6 for Minecraft 1.21.6

The first beta release of NeoForge 21.6 for Minecraft 1.21.6 is now available: 21.6.0-beta. This post covers a small subset of the vanilla changes, to get you started with the update!

ValueInput/ValueOutput

Many serialization methods were migrated from operating on a CompoundTag directly to a new abstraction: either ValueInput when loading data, or ValueOutput when saving it.

For example, the saveAdditional and loadAdditional methods of BlockEntity were changed as follows:

     @Override
-    protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) {
+    protected void saveAdditional(ValueOutput output) {
         // ...
     }

     @Override
-    protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) {
+    protected void loadAdditional(ValueInput input) {
         // ...
     }

Migration from CompoundTag to these classes should be quite straightforward. Reading the ValueInput and ValueOutput classes to learn which methods are available is recommended.

Here is one example (saving and loading a lit boolean):

- lit = tag.getBooleanOr("lit", false);
+ lit = valueInput.getBooleanOr("lit", false);

- tag.putBoolean("lit", lit);
+ valueOutput.putBoolean("lit", lit);

To create a value input or output, use TagValueInput.create and TagValueOutput.createWithContext/createWithoutContext.

Note that NeoForge offers a ValueIOSerializable interface for objects that can serialize to a ValueOutput and deserialize from a ValueInput, in case that is useful. It should be preferred to the old INBTSerializable interface.

GUI rendering changes

There continue to be significant refactors of Minecraft’s rendering internals. In particular, GUI rendering was changed a lot in this release.

You must specify an alpha value when drawing a string with GuiGraphics, otherwise text will appear invisible (alpha = 0). For example:

- graphics.drawCenteredString(font, /* other parameters */, 0xffffff);
+ graphics.drawCenteredString(font, /* other parameters */, 0xffffffff);

Blitting sprites now uses RenderPipelines.GUI_TEXTURE:

- guiGraphics.blitSprite(RenderType::guiTextured, ...);
+ guiGraphics.blitSprite(RenderPipelines.GUI_TEXTURE, ...);

There were other very large changes to GUI rendering, that we won’t cover in this blog post.

Finding out what needs to be migrated

A good strategy to migrate your mod is to have a working Minecraft 1.21.5 workspace alongside your in-progress Minecraft 1.21.6 workspace. This allows you to quickly find out how to update specific pieces of code. The workflow is as follows:

  1. Find a function call that doesn’t compile anymore in 1.21.6.
  2. Find the same function call in the 1.21.5 workspace that still compiles.
  3. Right click the function call, and go to a vanilla usage of the method. Note: In IntelliJ, this requires the Minecraft sources to be attached, and the scope for the search needs to be set to All Places!
  4. Go to the same vanilla usage in 1.21.6, and compare to see how vanilla updated their code.
  5. In many cases it is enough to make the same change to your code.

This can also be applied on a larger scale than a function call, for example to learn how tag data generation changed between 1.21.5 and 1.21.6.

Porting Primer

A porting primer covering a lot more of Minecraft’s changes is available here (courtesy of @ChampionAsh5357).

Happy porting!