Fabric for Minecraft 1.21.4
Minecraft 1.21.4, the Garden Awakens drop, releases December 3rd. Like with other updates, this drop contains some significant changes affecting 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.
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.
Fabric changes
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).
Deprecations and removals
The following deprecated module was removed: fabric-rendering-v0
. FabricModelPredicateProviderRegistry
, which was previously deprecated, was also removed.
BuiltinItemRenderer
and BuiltinItemRendererRegistry
from the Rendering v1 module were removed and have been replaced by a transitive access widener to SpecialModelTypes.ID_MAPPER
.
AttachmentRegistry#builder
was deprecated in favor of create
methods. The old method is inconvenient, as it requires explicit type parameters. (See the “Data Attachment Syncing” section for an example.)
BlockPickInteractionAware
was removed, the new pick item events should be used instead.
Breaking change
CustomIngredient#getMatchingStacks
must now return a stream, not a list.
New Fabric API changes
With the help of many contributors, Fabric API has received some new features since the last update blog post:
- Convention Tags: Add more tags (JT122406, TelepathicGrunt, IThundxr)
- Data Attachments: Registration enhancements (forgetmenot13579)
- Data Attachments: Sync API (Syst3ms)
- Lifecycle Events: Add
ServerChunkEvents.Generate
(jpenilla) - Lifecycle Events: Add
AFTER_CLIENT_WORLD_CHANGE
(fishshi) - Transfer API: Add support for Item-containing Items (BasiqueEvangelist)
In addition, a longstanding bug that caused language files to not load after overriding assets/minecraft/lang/en_us.json
in a dedicated server mod was fixed.
Data Attachment Syncing
Fabric API can now sync data attachments. To make a syncable attachment, call syncWith
inside the builder. The passed packet codec is used to serialize the attached data. Here is how a thirst attachment would look like:
public static final AttachmentType<Integer> THIRST = AttachmentRegistry.create(
Identifier.of("modid", "thirst"),
builder -> builder
.initializer(() -> 20) // start with a default value like hunger
.persistent(Codec.INT) // persist across restarts
.syncWith(PacketCodecs.VAR_INT, AttachmentSyncPredicate.targetOnly()) // only the player's own client needs the value for rendering
);
The sync predicate (AttachmentSyncPredicate
) controls who gets the synced data. For example, global data can be synced using all()
. For more granular control, you can also pass a custom predicate.
Pick item events
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 ClientPickBlockApplyCallback
, ClientPickBlockCallback
, and ClientPickBlockGatherCallback
. This change also applies to entities (EntityPickInteractionAware
).
The new events are PlayerPickItemEvents#BLOCK
for picking a block and PlayerPickItemEvents#ENTITY
for picking an entity(‘s spawn egg). Return ItemStack.EMPTY
to stop the picking, and return null
to use the default behavior.
PlayerPickItemEvents.BLOCK.register((player, pos, state, requestIncludeData) -> {
if (state.isIn(MyTags.NOT_PICKABLE)) return ItemStack.EMPTY;
return null; // use default behavior
})
requestIncludeData
is true
if the client requests NBT to be included in the returned item stack (by holding Ctrl
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).
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.
Client Data Generation
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 fabricApi
utility to set up data generation:
fabricApi {
- configureDataGeneration()
+ configureDataGeneration {
+ client = true
+ }
}
If you are using the createSourceSet
option, your datagen
source set will now have access to Minecraft’s client-only classes and classes in your client
source set. Other than updating the data generators themselves, no other changes will be necessary.
If you are using the splitEnvironmentSourceSets
option but not the createSourceSet
option, you should move your DataGeneratorEntrypoint
implementation from the main
source set to the client
source set.
Model Loading API
ModelModifier
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 UnbakedModel
and are baked with settings while block models use GroupableModel
(which no longer extends UnbakedModel
) and are not baked with settings. It also allowed cleaning up the identifier getters and providing the BlockState
directly to ModelModifier.OnLoadBlock
.
However, all BeforeBake
and AfterBake
events were removed. This is because their behavior can now be achieved using the OnLoad
events, by wrapping the given model and overriding the bake
method to replace the unbaked model passed to super.bake
(to replicate BeforeBake
) or replace the result of super.bake
(to replicate AfterBake
). This is possible because 1.21.4 made it so the parent of a JsonUnbakedModel
no longer has to be another JsonUnbakedModel
. To make this easier, the utility classes WrapperUnbakedModel
and WrapperGroupableModel
were added, which forward all method calls to a wrapper
field. There were also some minor fundamental issues with BeforeBake
and AfterBake
events, which prompted their removal.
ModelModifier.OnLoad
can now accept a null
model, which is a model that was requested during resolution but does not have a corresponding JSON file. With this change, ModelResolver
was removed as its behavior could now be achieved with ModelModifier.OnLoad
with OVERRIDE_PHASE
.
DelegatingUnbakedModel
was removed as GroupableModel
no longer extends UnbakedModel
, so BlockModelResolver
s can no longer use it, which was its original purpose.
textureGetter
was removed from ModelModifier
callback contexts as it is now accessible through Baker#getSpriteGetter
.
FRAPI’s WrapperBakedModel
was moved to Model Loading API and was renamed to UnwrappableBakedModel
to avoid conflicts with vanilla’s new WrapperBakedModel
. UnwrappableBakedModel
is also implemented and interface injected on vanilla’s WrapperBakedModel
. A new static UnwrappableBakedModel#unwrap
method was added which accepts a Predicate
saying when to stop unwrapping. See the documentation for more details.
Minecraft changes
Block Models
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:
- @Override
- protected BlockRenderType getRenderType(BlockState state) {
- return BlockRenderType.ENTITYBLOCK_ANIMATED;
- }
While block models were already used to provide particle textures in these cases, mods should still ensure their block entities’ block models are correct.
Item Models
Similar to the blockstate definition json files found in assets/<namespace>/blockstates
, items now utilize new item model definition json files in assets/<namespace>/items
to determine which models to use.
These can be quite simple…
{
"model": {
"type": "minecraft:model",
"model": "modid:item/my_item"
}
}
or more complex…
{
"model": {
"type": "minecraft:condition",
"property": "minecraft:fishing_rod/cast",
"on_false": {
"type": "minecraft:model",
"model": "modid:item/netherite_fishing_rod"
},
"on_true": {
"type": "minecraft:model",
"model": "modid:item/netherite_fishing_rod_cast"
}
}
}
utilising conditions and other logic to determine which model to use.
They also control applying color tints to item textures.
{
"model": {
"type": "minecraft:model",
"model": "minecraft:item/template_spawn_egg",
"tints": [
{
"type": "minecraft:constant",
"value": 6925483
},
{
"type": "minecraft:constant",
"value": 12238402
}
]
}
}
These tints can be constant or based on other factors such as potion contents, map colors, etc.
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,
- {
- "parent": "modid:block/maple_planks"
- }
at assets/modid/models/item/maple_planks.json
can be removed, in favor of
+ {
+ "model": {
+ "type": "minecraft:model",
+ "model": "modid:block/maple_planks"
+ }
+ }
in assets/modid/items/maple_planks.json
.
Additionally, ItemColors
and related APIs for tinting items have been removed, as item color tints are now controlled by these files.
For further information, these jsons are well documented on the vanilla Minecraft wiki here and all the ones used by vanilla items can be easily found in the game files.
For modders using data generation, these can be generated much like any other JSON asset.
Miscellaneous
- Resource Metadata files now use Codec serializers
- Equipment assets were moved from
assets/<namespace>/models/equipment
toassets/<namespace>/equipment
- The
minecraft:tall_flowers
block tag was removed - The
minecraft:flowers
,minecraft:tall_flowers
, andminecraft:trim_templates
item tags were removed - The
minecraft:herobrine
entity was removed - Trim Material jsons no longer specify an item model index, as trimmed items now use separate item models for each material
- Textures for item outlines shown in empty slots in certain GUIs are now located in
assets/<namespace>/textures/gui/sprites/container/slot
Yarn changes
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.
Some notable examples include:
- The
net/minecraft/data/client
package got moved tonet/minecraft/client/data
, to reflect the classes now being client-only - To match this, the
net/minecraft/data/server
package was removed and its contents moved down tonet/minecraft/data
- All references to
xp
got changed toexperience
BlockStateModelGenerator.TintType
was changed toBlockStateModelGenerator.CrossType
CherryLeavesBlock
was changed toParticleLeavesBlock
CherryLeavesParticle
was changed toLeavesParticle
LichenGrower
was changed toMultifaceGrower
EntityModelLoader
was changed toLoadedEntityModels
CocoaBeansTreeDecorator
was changed toCocoaTreeDecorator
BakedQuad#colorIndex
was changed totintIndex