Minecraft 1.21.11 -> 26.1 Mod Migration Primer
This is a high level, non-exhaustive overview on how to migrate your mod from 1.21.11 to 26.1. This does not look at any specific mod loader, just the changes to the vanilla classes.
This primer is licensed under the Creative Commons Attribution 4.0 International, so feel free to use it as a reference and leave a link so that other readers can consume the primer.
If there’s any incorrect or missing information, please file an issue on this repository or ping @ChampionAsh5357 in the Neoforged Discord server.
Thank you to:
- @Shnupbups for some grammatical fixes
- @cassiancc for information about Java 25 IDE support
- @boq for information regarding IME support
- @lolothepro for a typo
Pack Changes
There are a number of user-facing changes that are part of vanilla which are not discussed below that may be relevant to modders. You can find a list of them on Misode’s version changelog.
Java 25 and Deobfuscation
26.1 introduces two new changes into the general pipeline.
First, the Java Development Kit has been upgraded from 21 to 25. Vanilla makes use of these new features, such as JEP 447, which allows statements before super within constructors. For users within the modding scene, please make sure to update accordingly, or take advantage of your IDE or build tool features. Microsoft’s OpenJDK can be found here.
You may need to update your IDE to support Java 25. If using Eclipse, you will need at least either 2025-12, or 2025-09 with the Java 25 Support marketplace plugin. If using IntelliJ IDEA, you will need at least 2025.2.
Vanilla has also returned to being deobfuscated, meaning that all value types now have the official names provided by Mojang. There are still some things that are not captured due to the Java compilation process, such as inlining primitive and string constants, but the majority are now provided. This will only have a change for users or mod loaders who used a different value type mapping set from the official mappings.
Loot Type Unrolling
Loot pool entries, item functions, item conditions, nbt providers, number providers, score providers, int providers, and float providers no longer use a wrapping object type to act as the registered instance. Now, the registries directly take in the MapCodec used for the serialization and deserialization process. As such, the *Type classes or records that held the codec have been removed. Additionally, getType is now renamed to codec, taking in the registered MapCodec.
// The following is an example with LootItemFunctions, but can roughly apply to the other instances as well
public record NoopItemFunction() implements LootItemFunction {
public static final NoopItemFunction INSTANCE = new NoopItemFunction();
// The map codec used as the registry object
public static final MapCodec<NoopItemFunction> MAP_CODEC = MapCodec.unit(INSTANCE);
// Replaces getType
@Override
public MapCodec<NoopItemFunction> codec() {
// Return the registry object
return MAP_CODEC;
}
}
// Register the map codec to the appropriate registry
Registry.register(BuiltInRegistries.LOOT_FUNCTION_TYPE, Identifier.fromNamespaceAndPath("examplemod", "noop"), NoopItemFunction.MAP_CODEC);
net.minecraft.core.registries.BuiltInRegistries,RegistriesLOOT_POOL_ENTRY_TYPEnow holds aLootPoolEntryContainermap codec instead of aLootPoolEntryTypeLOOT_FUNCTION_TYPEnow holds aLootItemFunctionmap codec instead of aLootItemFunctionTypeLOOT_CONDITION_TYPEnow holds aLootItemConditionmap codec instead of aLootItemConditionTypeLOOT_NUMBER_PROVIDER_TYPEnow holds aNumberProvidermap codec instead of aLootNumberProviderTypeLOOT_NBT_PROVIDER_TYPEnow holds aNbtProvidermap codec instead of aLootNbtProviderTypeLOOT_SCORE_PROVIDER_TYPEnow holds aScoreboardNameProvidermap codec instead of aLootScoreProviderTypeFLOAT_PROVIDER_TYPEnow holds aFloatProvidermap codec instead of aFloatProviderTypeINT_PROVIDER_TYPEnow holds aIntProvidermap codec instead of aIntProviderType
net.minecraft.util.valueprovidersnow renamesCODECfields toMAP_CODECFloatProvidersubtypes are now all recordsIntProvidersubtypes, except forWeightedListInt, are now all recordsFloatProvideris now aninterfacefrom aclassCODEC->FloatProviders#CODECcodec->FloatProviders#codecgetType->codec, not one-to-onegetMinValue->mingetMaxValue->max
FloatProviders- All vanilla float providers to register.FloatProviderTypeinterface is removed- Singleton fields have all been removed, use map codecs in each class instead
codec->FloatProvider#codec
IntProvideris now aninterfacefrom aclassCODEC->IntProviders#CODECNON_NEGATIVE_CODEC->IntProviders#NON_NEGATIVE_CODECPOSITIVE_CODEC->IntProviders#POSITIVE_CODECcodec->IntProviders#codecvalidateCodec->IntProviders#validateCodecgetMinValue->minInclusivegetMaxValue->maxInclusivegetType->codec, not one-to-one
IntProviders- All vanilla int providers to register.IntProviderTypeinterface is removed- Singleton fields have all been removed, use map codecs in each class instead
codec->IntProvider#codec
net.minecraft.world.level.storage.loot.entriesnow renamesCODECfields toMAP_CODECLootPoolEntriessingleton fields have all been removed- The map codecs in each class should be used instead
bootstrap- Registers the loot pool entries.
LootPoolEntryContainer#getType->codec, not one-to-oneLootPoolEntryTyperecord is removed
net.minecraft.world.level.storage.loot.functionsnow renamesCODECfields toMAP_CODECLootItemFunction#getType->codec, not one-to-oneLootItemFunctionssingleton fields have all been removed- The map codecs in each class should be used instead
bootstrap- Registers the loot item functions.
LootItemFunctionTyperecord is removed
net.minecraft.world.level.storage.loot.predicatesnow renamesCODECfields toMAP_CODECLootItemCondition#getType->codec, not one-to-oneLootItemConditionssingleton fields have all been removed- The map codecs in each class should be used instead
bootstrap- Registers the loot item conditions.
LootItemConditionTyperecord is removed
net.minecraft.world.level.storage.loot.providers.nbtnow renamesCODECfields toMAP_CODECLootNbtProviderTyperecord is removedNbtProvidernow implementsLootContextUsergetType->codec, not one-to-one
NbtProviderssingleton fields have all been removed- The map codecs in each class should be used instead
bootstrap- Registers the nbt providers.
LootItemConditionTyperecord is removed
net.minecraft.world.level.storage.loot.providers.numbernow renamesCODECfields toMAP_CODECLootNumberProviderTyperecord is removedNumberProvider#getType->codec, not one-to-oneNumberProviderssingleton fields have all been removed- The map codecs in each class should be used instead
bootstrap- Registers the number providers.
net.minecraft.world.level.storage.loot.providers.scorenow renamesCODECfields toMAP_CODECLootScoreProviderTyperecord is removedScoreProvidernow implementsLootContextUsergetType->codec, not one-to-one
ScoreProviderssingleton fields have all been removed- The map codecs in each class should be used instead
bootstrap- Registers the score providers.
Validation Overhaul
The validation handler used to collect and then report problems with data-generated content has been overhauled. This is not, and has never been a replacement for field validation. The validation handler is specifically for more easily handling validation between multiple pieces of information that may not be exposed to a single field, such as whether a loot provider can be used for the given context params.
All validated objects implement either Validatable, or CriterionTriggerInstance specifically for advancement criteria. Both of these methods provide one method: validate, which is used to check the validity of an object. validate takes in a ValidationContext, which essentially holds the ProblemReporter used to collect issues, the current context params, and a reference resolver. CriterionTriggerInstance provides a ValidationContextSource, but this can be transformed to a ValidationContext using one of the context methods, providing the context params to check against. If the specific object cannot be validated, then ValidationContext#reportProblem is called, detailing the specific issue.
// For some object that implements Validatable
@Override
public void validate(ValidationContext ctx) {
// Check if a specific condition is validated.
if (this.foo() != this.bar()) {
// If not, report that there is an issue.
ctx.reportProblem(() -> "'Foo' does not equal 'bar'.");
}
}
If the object itself does not have any issues, but rather the specific fields, then the reporter can follow the stack trace while checking the individual elements using one of the ValidationContext#for* methods, performing something similar.
// For some object that implements Validatable
// Let's assume it has a list of children objects.
@Override
public void validate(ValidationContext ctx) {
for (int i = 0; i < this.children.size(); i++) {
// Get specific context for child in list
var childCtx = ctx.forIndexedField("children", i);
// Check if a specific condition is validated.
if (this.foo() != this.bar()) {
// If not, report that there is an issue.
childCtx.reportProblem(() -> "'Foo' does not equal 'bar'.");
}
}
}
Validatable also provides some static utilities for checking other Validatable fields.
// For some object that implements Validatable
// Assume some child object also implements Validatable
@Override
public void validate(ValidationContext ctx) {
Validatable.validate(ctx, "child", this.child);
}
After Validatable is implemented on all required objects, the validation can then be called depending on where it is used (typically after deserialization or before serialization). The call stack for these is typically the following:
// For some Validatable validatable
// Let's assume we have access to the HolderGetter.Provider provider.
// The parameter itself is optional if not available.
// Create the problem collector and validation context.
// The context params should only include the ones that are being provided.
ProblemReporter reporter = new ProblemCollector.Collector();
ValidationContext ctx = new ValidationContext(reporter, LootContextParamSets.ALL_PARAMS, provider);
// Call the validator
validatable.validate(ctx);
This can also be appended to the end of codecs via Codec#validate:
public record ExampleObject() implements Validatable {
public static final Codec<ExampleObject> CODEC = MapCodec.unitCodec(
ExampleObject::new
).validate(
// Supply the validator along with the context params to check against.
// This method does not have access to the registry provider.
Validatable.validatorForContext(LootContextParamSets.ALL_PARAMS)
);
@Override
public void validate(ValidationContext ctx) {
// ...
}
}
net.minecraft.advancements.CriterionTriggerInstance#validatenow takes in aValidationContextSourceinstead of aCriterionValidatornet.minecraft.advancements.criterionContextAwarePredicatenow implementsValidatableCriterionValidator->ValidationContextSourceandValidatableValidatablecontains thevalidate*methodsValidationContextSourceholds the context and reporters
net.minecraft.world.item.enchantmentConditionalEffectnow implementsValidatableconditionCodecis replaced by callingvalidateafter load
TargetedConditionalEffectnow implementsValidatable
net.minecraft.world.level.storage.lootIntRangenow implementsLootContextUsergetReferencedContextParamsreplaced byvalidate
LootContext$VisitedEntrygeneric must now extendValidatableLootContextUsernow implementsValidatableLootDataTypegeneric must now extendValidatable- The constructor now takes in a
$ContextGetterinstead of a$Validator runValidationnow takes in theValidationContextSourceinstead of aValidationContext- Also has an overload taking in a
HolderLookupinstead of a key-value pair
- Also has an overload taking in a
createSimpleValidator,createLootTableValidator,$Validatorreplaced byValidatable$ContextGetter- Gets theContextKeySetfor some value.
- The constructor now takes in a
LootPoolnow implementsValidatableLootTablenow implementsValidatableValidatable- An interface which handles the validation of its instance within the given context.ValidationContextforField- Creates a context for a given field.forIndexedField- Creates a context for a given entry in a list.forMapField- Creates a context for a given key in a map.setContextKeySetis removed
ValidationContextSource- The source for the defined context where the validation is taking place.
net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainernow implementsValidatablenet.minecraft.world.level.storage.loot.functionsSetAttributesFunction$Modifiernow implementsLootContextUserSetStewEffectFunction$EffectEntrynow implementsLootContextUser
Datapack Villager Trades
Villager trades has now become a data-generated registry from its original map-based setup. While basic impressions make it seem like that system is more limited, it is actually just as extensible, though in a rather convoluted way because the trades are functionally a loot table itself to determine what MerchantOffers a trader can provide. For the purposes of understanding, this section will go over the basics of the trade rewrite, along with how each previous item listing can be converted to a VillagerTrade.
Understanding the Trade Format
All trades are expressed as VillagerTrades, which at its core determines what a trader wants and what it gives in return. Each trade can also provide modifiers to the item itself or its cost, or whether the specific trade can be made at all with the given condition. Each trade also specifies the number of trades that can be made, how much xp to give, or the price multiple that is multiplied with the user’s reputation. A VillagerTrade is then turned into a MerchantOffer via getOffer, taking in the LootContext, typically with a context param of LootContextParamSets#VILLAGER_TRADE, providing the trader itself (THIS_ENTITY) and its position (ORIGIN).
The trades themselves are within data/<namespace>/villager_trade/<path>. Typically the path contains the profession and level the trade is for, such as examplemod:example_profession/1/example_trade
// For some villager trade 'examplemod:example_profession/1/example_trade'
// JSON at 'data/examplemod/villager_trade/example_profession/1/example_trade.json'
{
// The stack the trader wants.
"wants": {
// The item of the stack.
"id": "minecraft:apple",
// A number provider used to determine how much
// of the item that it wants. Once the count is
// determined, any additional cost on the `gives`
// stack (via `ADDITIONAL_TRADE_COST` component)
// is added to the count before being clamped to
// the max stack size.
// If not specified, defaults to 1.
"count": {
"type": "minecraft:uniform",
"min": 1,
"max": 5
},
// Any components that stack should have. The stack
// must have the exact components specified.
// If not specified, then no components will be
// checked, meaning that this is ignored.
"components": {
// Map of registry key to component value.
"minecraft:custom_name": "Apple...?"
}
},
// An additional stack the trader wants.
// If not specified, the trader only checks `wants`.
"additional_wants": {
"id": "minecraft:emerald"
},
// The stack template the trader gives in return.
"gives": {
// The item of the stack.
"id": "minecraft:golden_apple",
// A number [1, 99].
// If not specified, defaults to 1.
"count": 1,
// The components to apply to the stack.
// If not specified, just applies the default
// item components.
"components": {
"minecraft:custom_name": "Not an Apple"
}
},
// A number provider to determine how many times
// the trade can be performed by the player before
// the trader restocks. The value will always be at
// least 1.
// If not specified, defaults to 4.
"max_uses": {
"type": "minecraft:uniform",
"min": 1,
"max": 20
},
// A number provider to determine the price multiplier
// to apply to the cost of the item based on the player's
// reputation with the trader and the item demand,
// calculated from how many times the player has performed
// the trade. This should generally be a small number as
// the maximum reputation a user can have per trader is 150,
// though it's more likely to have a reputation of 25 at most.
// However, the trade must always have a minimum of one item,
// even if the reputation discount multiplied with the reputation
// indicates 100% or more off.
// If not specified, defaults to 0.
"reputation_discount": {
"type": "minecraft:uniform",
"min": 0,
"max": 0.05
},
// A number provider to determine the amount of experience
// the player obtains from performing the trade with the trader.
// This is typically around 5-30 xp for vanilla trades.
// If not specified, defaults to 1.
"xp": {
"type": "minecraft:uniform",
"min": 10,
"max": 20
},
// A loot item condition that determines whether the
// trader can provide the trade to the player.
// If not specified, defaults to always true.
"merchant_predicate": {
// This trade can only be performed by villagers
// from a desert or snow village.
"condition": "minecraft:entity_properties",
"entity": "this",
"predicate": {
"predicates": {
"minecraft:villager/variant": [
"minecraft:desert",
"minecraft:snow"
]
}
}
},
// A list of loot item functions that modify the item
// offered from `gives` to the player.
// If not specified, `gives` is not modified.
"given_item_modifiers": [
{
// Chooses a random enchantment from the provided tag
"function": "minecraft:enchant_randomly",
// If this is true, the trade cost increases the
// number of `wants` items required.
"include_additional_cost_component": true,
"only_compatible": false,
"options": "#minecraft:trades/desert_common"
}
],
// Can either be an enchantment id, such as "minecraft:protection",
// or a list of enchantment ids, such as ["minecraft:protection", "minecraft:smite", ...],
// or an enchantment tag, such as "#minecraft:trades/desert_common".
// When provided, if the `gives` item after modifiers contains an
// enchantment in this list, then the number of `wants` items required
// is multiplied by 2.
// If not specified, does nothing.
"double_trade_price_enchantments": "#minecraft:trades/desert_common"
}
The Trades of a Trader
Every trader can make many trades, typically choosing from a specified pool known as a TradeSet. Trade sets themselves are a separate datapack registry that consumes VillagerTrades. Each set of trades determines how many trades can be offered and if the same trade can be chosen more than once. The trades that are offered are computed within AbstractVillager#addOffersFromTradeSet, first calling TradeSet#calculateNumberOfTrades to get the number of offers, and then using either AbstractVillager#addOffersFromItemListings or AbstractVillager#addOffersFromItemListingsWithoutDuplicates to choose the offers to use.
Note that if duplicate trades are allowed, there is a potential race condition where if all trades’ merchant_predicates fail, then the offers will loop forever. This is because the method always assumes that there will be one trade that can be made.
The trade sets are within data/<namespace>/trade_set/<path>. Typically the path contains the profession and level the trade is for, such as examplemod:example_profession/level_1.json
// For some trade set 'examplemod:example_profession/level_1'
// JSON at 'data/examplemod/villager_trade/trade_set/level_1.json'
{
// Can either be a villager trade id, such as "examplemod:example_profession/1/example_trade",
// or a list of trade ids, such as ["examplemod:example_profession/1/example_trade", "minecraft:farmer/1/wheat_emerald", ...],
// or an trade tag, such as "#examplemod:example_profession/level_1".
// This is the set of trades that can be offered by the trader.
// This should always be a villager trade tag so allow other users
// to easily add their own trades to a trader.
"trades": "#examplemod:example_profession/level_1",
// A number provider that determines the number of offers that can be
// made by the trader.
"amount": {
"type": "minecraft:uniform",
"min": 1,
"max": 5
},
// Whether the same trade can be used to make multiple offers.
// If not specified, defaults to false.
"allow_duplicates": true,
// An identifier that determines the unique random instance to
// user when determining the offers.
// If not specified, uses the level random.
"random_sequence": "examplemod:example_profession/level_1"
}
Where the villager trade tag could be:
// For some tag 'examplemod:example_profession/level_1'
// JSON at 'data/examplemod/tags/villager_trade/example_profession/level_1.json'
{
"values": [
"examplemod:example_profession/1/example_trade"
]
}
This also means trades can be easily added to existing trade sets by adding to the associated tag:
// For some tag 'minecraft:farmer/level_1'
// JSON at 'data/minecraft/tags/villager_trade/farmer/level_1.json'
{
"values": [
"examplemod:example_profession/1/example_trade"
]
}
Meanwhile, adding to a new VillagerProfession is done by mapping the level int to the trade set key in tradeSetsByLevel:
public static final VillagerProfession EXAMPLE = Registry.register(
BuiltInRegistries.VILLAGER_PROFESSION,
Identifier.fromNamespaceAndPath("examplemod", "example_profession"),
new VillagerProfession(
Component.literal(""),
p -> true,
p -> true,
ImmutableSet.of(),
ImmutableSet.of(),
null,
// A map of profession level to trade set keys
Int2ObjectMap.ofEntries(
Int2ObjectMap.entry(
// The profession level
1,
// The trade set id
ResourceKey.create(Registries.TRADE_SET, Identifier.fromNamespaceAndPath("examplemod", "example_profession/level_1"))
)
)
)
);
Item Listing Conversions
With all this in mind, we can now convert item listings to their new data-generated villager trades.
Emeralds <-> Items
For the following trades:
public static final VillagerTrades.ItemListing ITEM_TO_EMERALD = new VillagerTrades.EmeraldForItems(
// The item the trader wants.
Items.WHEAT,
// The number of items the trader wants.
20,
// The maximum number of times the trade can be made
// before restock.
16,
// The amount of experience given for the trade.
2,
// The number of emeralds given in return.
1
);
public static final VillagerTrades.ItemListing EMERALD_TO_ITEM = new VillagerTrades.ItemsForEmeralds(
// The item the trader will give in return.
Items.BREAD,
// The number of emeralds the trader wants.
1,
// The number of items the trader will give.
6,
// The maximum number of times the trade can be made
// before restock.
16,
// The amount of experience given for the trade.
1,
// The price multiplier to apply to the offer, given
// reputation and demand.
0.05f
);
Their equivalent would be:
// For some villager trade 'examplemod:item_to_emerald'
// JSON at 'data/examplemod/villager_trade/item_to_emerald.json'
{
"gives": {
// The number of emeralds given in return.
"count": 1,
"id": "minecraft:emerald"
},
// The maximum number of times the trade can be made
// before restock.
"max_uses": 16,
// The price multiplier to apply to the offer, given
// reputation and demand.
// `EmeraldForItems` hardcoded this to 0.05
"reputation_discount": 0.05,
"wants": {
// The number of items the trader wants.
"count": 20,
// The item the trader wants.
"id": "minecraft:wheat"
},
// The amount of experience given for the trade.
"xp": 2
}
// For some villager trade 'examplemod:emerald_to_item'
// JSON at 'data/examplemod/villager_trade/emerald_to_item.json'
{
"gives": {
// The number of items the trader will give.
"count": 6,
// The item the trader will give in return.
"id": "minecraft:bread"
},
// The maximum number of times the trade can be made
// before restock.
"max_uses": 16,
// The price multiplier to apply to the offer, given
// reputation and demand.
"reputation_discount": 0.05,
"wants": {
"id": "minecraft:emerald",
// The number of emeralds the trader wants.
"count": 1
},
// The amount of experience given for the trade.
"xp": 1
}
Items and Emeralds -> Items
For the following trade:
public static final VillagerTrades.ItemListing ITEM_EMERALD_TO_ITEM = new VillagerTrades.ItemsAndEmeraldsToItems(
// The item the trader wants.
Items.COD,
// The number of items the trader wants.
6,
// The number of emeralds the trader additionally wants.
1,
// The item the trader will give in return.
Items.COOKED_COD,
// The number of items the trader will give.
6,
// The maximum number of times the trade can be made
// before restock.
16,
// The amount of experience given for the trade.
1,
// The price multiplier to apply to the offer, given
// reputation and demand.
0.05f
);
The equivalent would be:
// For some villager trade 'examplemod:item_emerald_to_item'
// JSON at 'data/examplemod/villager_trade/item_emerald_to_item.json'
{
// The emeralds the trader additionally wants.
"additional_wants": {
"id": "minecraft:emerald",
},
"gives": {
// The number of items the trader will give.
"count": 6,
// The item the trader will give in return.
"id": "minecraft:cooked_cod"
},
// The maximum number of times the trade can be made
// before restock.
"max_uses": 16,
// The price multiplier to apply to the offer, given
// reputation and demand.
"reputation_discount": 0.05,
"wants": {
// The number of items the trader wants.
"count": 6,
// The item the trader wants.
"id": "minecraft:cod"
},
// The amount of experience given for the trade.
"xp": 1
}
Emeralds -> Dyed Armor
For the following trade:
public static final VillagerTrades.ItemListing EMERALD_TO_DYED_ARMOR = new VillagerTrades.DyedArmorForEmeralds(
// The item the trader will give in return and dye.
Items.LEATHER_HELMET,
// The number of emeralds the trader wants.
5,
// The maximum number of times the trade can be made
// before restock.
12,
// The amount of experience given for the trade.
5
);
The equivalent would be:
// For some villager trade 'examplemod:emerald_to_dyed_armor'
// JSON at 'data/examplemod/villager_trade/emerald_to_dyed_armor.json'
{
"given_item_modifiers": [
{
// Sets the random dye(s) on the armor.
"function": "minecraft:set_random_dyes",
"number_of_dyes": {
"type": "minecraft:sum",
"summands": [
1.0,
{
"type": "minecraft:binomial",
"n": 2.0,
"p": 0.75
}
]
}
},
{
// Checks that the dye was successfully applied
// to the item.
"function": "minecraft:filtered",
"item_filter": {
"items": "minecraft:leather_helmet",
"predicates": {
"minecraft:dyed_color": {}
}
},
// If it fails, discards the offer.
"on_fail": {
"function": "minecraft:discard"
}
}
],
"gives": {
"count": 1,
// The item the trader will give in return and dye.
"id": "minecraft:leather_helmet"
},
// The maximum number of times the trade can be made
// before restock.
"max_uses": 12,
// The price multiplier to apply to the offer, given
// reputation and demand.
"reputation_discount": 0.05,
"wants": {
// The number of emeralds the trader wants.
"count": 5,
"id": "minecraft:emerald"
},
// The amount of experience given for the trade.
"xp": 5
}
Emeralds -> Enchanted Item
For the following trade:
public static final VillagerTrades.ItemListing EMERALD_TO_ENCHANTED_BOOK = new VillagerTrades.EnchantBookForEmeralds(
// The amount of experience given for the trade.
30,
// The minimum level used when selecting the stored enchantments on the book.
3,
// The maximum level used when selecting the stored enchantments on the book.
3,
// A tag containing the list of available enchantments to select from for the book.
EnchantmentTags.TRADES_DESERT_SPECIAL
);
public static final VillagerTrades.ItemListing EMERALD_TO_ENCHANTED_ITEM = new VillagerTrades.EnchantedItemForEmeralds(
// The item the trader will give in return and try to enchant.
Items.FISHING_ROD,
// The base number of emeralds the trader wants.
3,
// The maximum number of times the trade can be made
// before restock.
3,
// The amount of experience given for the trade.
10,
// The price multiplier to apply to the offer, given
// reputation and demand.
0.2f
);
The equivalent would be:
// For some villager trade 'examplemod:emerald_to_enchanted_book'
// JSON at 'data/examplemod/villager_trade/emerald_to_enchanted_book.json'
{
// The trader expects a book to write the enchantment to.
"additional_wants": {
"id": "minecraft:book"
},
// Trade cost for emeralds increased when in the double trade price
// tag.
"double_trade_price_enchantments": "#minecraft:double_trade_price",
"given_item_modifiers": [
{
"function": "minecraft:enchant_with_levels",
"include_additional_cost_component": true,
"levels": {
"type": "minecraft:uniform",
// The minimum level used when selecting the stored enchantments on the book.
"min": 3,
// The maximum level used when selecting the stored enchantments on the book.
"max": 3
},
// The list of available enchantments to select from for the book.
"options": [
"minecraft:efficiency"
]
},
{
// Make sure the enchantment was added successfully with the given level.
"function": "minecraft:filtered",
"item_filter": {
"items": "minecraft:enchanted_book",
"predicates": {
"minecraft:stored_enchantments": [
{
"levels": {
// The minimum level used when selecting the stored enchantments on the book.
"min": 3,
// The maximum level used when selecting the stored enchantments on the book.
"max": 3
}
}
]
}
},
// Discard on failure
"on_fail": {
"function": "minecraft:discard"
}
}
],
// The trader gives the enchanted book.
"gives": {
"count": 1,
"id": "minecraft:enchanted_book"
},
// The maximum number of times the trade can be made
// before restock was hardcoded to 12.
"max_uses": 12,
// The price multiplier to apply to the offer, given
// reputation and demand, hardcoded to 0.2.
"reputation_discount": 0.2,
"wants": {
"count": {
"type": "minecraft:sum",
"summands": [
// A hardcoded computation based on the min and max
// level of the enchantment.
11.0,
{
"type": "minecraft:uniform",
"max": 35.0,
"min": 0.0
}
]
},
"id": "minecraft:emerald"
},
// The amount of experience given for the trade.
"xp": 30
}
// For some villager trade 'examplemod:emerald_to_enchanted_item'
// JSON at 'data/examplemod/villager_trade/emerald_to_enchanted_item.json'
{
"given_item_modifiers": [
{
// Applies the enchantment to the given equipment.
"function": "minecraft:enchant_with_levels",
"include_additional_cost_component": true,
"levels": {
"type": "minecraft:uniform",
"max": 20,
"min": 5
},
"options": "#minecraft:on_traded_equipment"
},
{
// Checks to make sure the enchantment was applied.
"function": "minecraft:filtered",
"item_filter": {
"items": "minecraft:fishing_rod",
"predicates": {
"minecraft:enchantments": [
{}
]
}
},
// On fail, give nothing.
"on_fail": {
"function": "minecraft:discard"
}
}
],
"gives": {
"count": 1,
// The item the trader will give in return and try to enchant.
"id": "minecraft:fishing_rod"
},
// The maximum number of times the trade can be made
// before restock.
"max_uses": 3,
// The price multiplier to apply to the offer, given
// reputation and demand.
"reputation_discount": 0.2,
"wants": {
"count": {
"type": "minecraft:sum",
"summands": [
// The base number of emeralds the trader wants.
3,
{
// The variation based on the enchantment level.
// Originally, this would be the value used in the
// item function, but since they are now isolated,
// these values could differ.
"type": "minecraft:uniform",
"max": 20,
"min": 5
}
]
},
"id": "minecraft:emerald"
},
// The amount of experience given for the trade.
"xp": 10
}
Items and Emeralds -> Potion Effect Item
For the following trade:
public static final VillagerTrades.ItemListing EMERALD_TO_SUSPICIOUS_STEW = new VillagerTrades.SuspiciousStewForEmerald(
// The effect applied by the suspicious stew.
MobEffects.NIGHT_VISION,
// The number of ticks the effect should be active for.
100,
// The amount of experience given for the trade.
15
);
public static final VillagerTrades.ItemListing ITEM_EMERALD_TO_TIPPED_ARROW = new VillagerTrades.TippedArrowForItemsAndEmeralds(
// The item the trader additionally wants.
Items.ARROW,
// The number of items the trader additionally wants.
5,
// The item the trader will give in return.
Items.TIPPED_ARROW,
// The number of items the trader will give.
5,
// The number of emeralds the trader wants.
2,
// The maximum number of times the trade can be made
// before restock.
12,
// The amount of experience given for the trade.
30
);
The equivalent would be:
// For some villager trade 'examplemod:emerald_to_suspicious_stew'
// JSON at 'data/examplemod/villager_trade/emerald_to_suspicious_stew.json'
{
"given_item_modifiers": [
{
"effects": [
{
// The effect applied by the suspicious stew.
"type": "minecraft:night_vision",
// The number of ticks the effect should be active for.
"duration": 100
}
// Vanilla merges all suspicious stew offers
// into one since this function picks one
// stew effect at random.
],
"function": "minecraft:set_stew_effect"
}
],
"gives": {
"count": 1,
"id": "minecraft:suspicious_stew"
},
// The maximum number of times the trade can be made
// before restock, hardcoded to 12.
"max_uses": 12,
// The price multiplier to apply to the offer, given
// reputation and demand, hardcoded to 0.05.
"reputation_discount": 0.05,
"wants": {
"id": "minecraft:emerald"
},
// The amount of experience given for the trade.
"xp": 15
}
// For some villager trade 'examplemod:item_emerald_to_tipped_arrow'
// JSON at 'data/examplemod/villager_trade/item_emerald_to_tipped_arrow.json'
{
"additional_wants": {
// The number of items the trader additionally wants.
"count": 5,
// The item the trader additionally wants.
"id": "minecraft:arrow"
},
"given_item_modifiers": [
{
// Applies a random potion effect from the tradable potions.
// Original implementation just picked any potion at random.
"function": "minecraft:set_random_potion",
"options": "#minecraft:tradeable"
}
],
"gives": {
// The number of items the trader will give.
"count": 5,
// The item the trader will give in return.
"id": "minecraft:tipped_arrow"
},
// The maximum number of times the trade can be made
// before restock.
"max_uses": 12,
// The price multiplier to apply to the offer, given
// reputation and demand, hardcoded to 0.05.
"reputation_discount": 0.05,
"wants": {
// The number of emeralds the trader wants.
"count": 2,
"id": "minecraft:emerald"
},
// The amount of experience given for the trade.
"xp": 30
}
Emeralds -> Treasure Map
For the following trade:
public static final VillagerTrades.ItemListing EMERALD_TO_TREASURE_MAP = new VillagerTrades.TreasureMapForEmeralds(
// The number of emeralds the trader wants.
8,
// A tag containing a list of treasure structures to find the nearest of.
StructureTags.ON_TAIGA_VILLAGE_MAPS,
// The translation key of the map name.
"filled_map.village_taiga",
// The icon used to decorate the treasure location found on the map.
MapDecorationTypes.TAIGA_VILLAGE,
// The maximum number of times the trade can be made
// before restock.
12,
// The amount of experience given for the trade.
5
);
The equivalent would be:
// For some villager trade 'examplemod:emerald_to_treasure_map'
// JSON at 'data/examplemod/villager_trade/emerald_to_treasure_map.json'
{
"additional_wants": {
// An item the trader additionally wants, hardcoded to compass.
"id": "minecraft:compass"
},
"given_item_modifiers": [
{
// Finds a treasure structure to display on the map.
// The icon used to decorate the treasure location found on the map.
"decoration": "minecraft:village_taiga",
// A tag containing a list of treasure structures to find the nearest of.
"destination": "minecraft:on_taiga_village_maps",
"function": "minecraft:exploration_map",
"search_radius": 100
},
{
// Sets the name of the map.
"function": "minecraft:set_name",
"name": {
// The translation key of the map name.
"translate": "filled_map.village_taiga"
},
"target": "item_name"
},
{
// Check to make sure a structure was found.
"function": "minecraft:filtered",
"item_filter": {
"items": "minecraft:filled_map",
"predicates": {
"minecraft:map_id": {}
}
},
"on_fail": {
"function": "minecraft:discard"
}
}
],
"gives": {
"count": 1,
// Returns a map filled with the treasure location.
"id": "minecraft:map"
},
// The maximum number of times the trade can be made
// before restock.
"max_uses": 12,
// The price multiplier to apply to the offer, given
// reputation and demand, hardcoded to 0.05.
"reputation_discount": 0.05,
"wants": {
// The number of emeralds the trader wants.
"count": 8,
"id": "minecraft:emerald"
},
// The amount of experience given for the trade.
"xp": 5
}
Villager Variants
Some traders would provide different options depending on the villager type it was as one giant map of item listings. Now, each type has its own individual villager trade, using a merchant_predicate to check whether the offer can be made to the specific villager type:
// For some villager trade 'examplemod:villager_type_item'
// JSON at 'data/examplemod/villager_trade/villager_type_item.json'
{
// ...
"merchant_predicate": {
// Check the entity.
"condition": "minecraft:entity_properties",
"entity": "this",
"predicate": {
"predicates": {
// Villager type must be desert for this trade to be chosen.
"minecraft:villager/variant": "minecraft:desert"
}
}
},
// ...
}
net.minecraft.core.registries.RegistriesTRADE_SET- A key to the registry holding a list of trades.VILLAGER_TRADE- A key to the registry holding a single trade.
net.minecraft.tags.VillagerTradeTags- Tags for villager trades.net.minecraft.world.entity.npc.villagerAbstractVillager#addOffersFromItemListings->addOffersFromTradeSet, taking in a key for the trade set rather than the$ItemListings and number of offers; not one-to-oneVillagerProfessionnow takes in a map of trader level toTradeSetgetTrades- Returns the trades set key for the given level.
VillagerTradeshas been split into many different classes and implementationsTRADES,EXPERIMENTAL_TRADES,WANDERING_TRADER_TRADESis now represented by theVillagerProfession#tradeSetsByLevel- As they are now datapack entries, they are stored in their respective datapacks
TRADES,EXPERIMENTAL_TRADESare represented bydata/minecraft/trade_set/<profession>/*WANDERING_TRADER_TRADESare represented bydata/minecraft/trade_set/wandering_trader/*
$DyedArmorForEmeralds->VillagerTrades#dyedItem,addRandomDye; not one-to-one$EmeraldForItems->VillagerTrade, not one-to-one$EmeraldsForVillagerTypeItem->VillagerTrades#registerBoatTrades, see usage, not one-to-one$EnchantBookForEmeralds->VillagerTrades#enchantedBook, not one-to-one$EnchantedItemForEmeralds->VillagerTrades#enchantedItem, not one-to-one$ItemListing->VillagerTrade$ItemsAndEmeraldsToItems->VillagerTradewithadditionalWants$ItemsForEmeralds->VillagerTrade, not one-to-one$SuspiciousStewForEmerald->VillagerTradewithSetStewEffectFunction$TippedArrowForItemsAndEmeralds->VillagerTradewithSetRandomPotionFunction$TreasureMapForEmeralds->VillagerTrades$VillagerExplorerMapEntry, see usage, not one-to-one$TypeSpecificTrade->VillagerTrades#villagerTypeRestriction,villagerTypeHolderSet; not one-to-one
net.minecraft.world.item.enchantment.providers.TradeRebalanceEnchantmentProvidersinterface is removed- Replaced by
TradeRebalanceVillagerTrades,TradeRebalanceRegistries
- Replaced by
net.minecraft.world.item.tradingTradeCost- AnItemStackthat is being traded to some trader.TradeRebalanceVillagerTrades- All trades part of the trade rebalance datapack.TradeSet- A set of trades that can be performed by a trader at some level.TradeSets- All vanilla trades sets for some trader at some level.VillagerTrade- A trade between the trader and the player.VillagerTrades- All vanilla trades.
net.minecraft.world.level.storage.loot.parameters.LootContextParamSets#VILLAGER_TRADE- A loot context when a villager trade is taking place, containing the trade origin and the trading entity.
Level#random field now protected
The Level#random field is now protected instead of public. As such, uses should transition to using the public getRandom method.
// For some Level level
RandomSource random = level.getRandom();
net.minecraft.world.level.Level#randomfield is nowprotectedinstead ofpublic- Use
getRandommethod instead
- Use
Data Component Initializers
Data components have begun their transition from being moved off the raw object and onto the Holder itself. This is to properly handle objects that are not available during construction, such as datapack registry objects for items. Currently, this is only implemented for Items, but the system allows for any registry object, given its wrapped-holder, to store some defined data components.
Data components are attached to their holders through the DataComponentInitializers. During object construction, DataComponentInitializers#add is called, providing the ResourceKey identifier of the registry object, along with a DataComponentInitializers$Initializer. The initializer takes in three parameters: the builder for the component map, the full registries HolderLookup$Provider, and the key passed to DataComponentInitializers#add. The initializer functions like a consumer, also allowing for additional initializers to be chained via $Initializer#andThen or to easily add a component via $Initializer#add.
// For some custom registry object
public ExampleObject(ResourceKey<ExampleObject> id) {
// Register the data component initializer
BuiltInRegistries.DATA_COMPONENT_INITIALIZERS.add(
// The identifier for the registry object
id,
// The initializer function, taking in a component builder,
// the registries context, and the id
(components, context, key) -> components
.set(DataComponents.MAX_DAMAGE, 1)
.set(DataComponents.DAMAGE_TYPE, context.getOrThrow(DamageTypes.SPEAR))
);
}
From there, the data components are initialized or reinitialized whenever ReloadableServerResources#loadResources is called (on datapack reload). The datapack objects are loaded first, then the components are set on the Holder$References. From there, the components can be gathered via Holder#components.
// For some Holder<ExampleObject> EXAMPLE_HOLDER
DataComponentMap components = EXAMPLE_HOLDER.components();
Items
Since components are now initialized during resource reload, Item$Properties provides two methods to properly delay component initialization until such data components are loaded: delayedComponent and delayedHolderComponent. delayedComponent takes in the component type and a function that takes in the HolderLookup$Provider and returns the component value. delayedHolderCOmponent delegates to delayedComponent, taking in a ResourceKey and setting the registry object as the component value.
public static final Item EXAMPLE_ITEM = new Item(
new Item.Properties()
.delayedComponent(
// The component type whose construction
// should be lazily initialized.
DataComponents.JUKEBOX_PLAYABLE,
// A function that takes in the registries
// and returns the component value.
context -> new JukeboxPlayable(context.getOrThrow(
JukeboxSongs.THIRTEEN
))
)
.delayedHolderComponent(
// The component type which has a
// holder value type.
DataComponents.DAMAGE_TYPE
// The resource key for a registry
// object of the associated holder
// generic type.
DamageTypes.SPEAR
)
// ...
);
Recipes
Since data components now hold the true values from being lazily initialized after resource reload, Recipe#assemble no longer takes in the HolderLookup$Provider. Instead, it assumes that the recipe has all the required data stored passed into the recipe, either on a stack or directly.
net.minecraft.coreHolderareComponentsBound- Whether the components have been bound to the holder.components- The components of the object stored on the holder.direct,$Directnow can take in theDataComponentMap$Reference#bindComponents- Stores the components on the holder reference.
Registry#componentLookup- Gets the lookup of component to holders.WritableRegistry#bindTag->bindTags, now taking in a map of keys to holder lists instead of one mapping
net.minecraft.core.componentDataComponentInitializers- A class that handles initializing the data components for component-attached objects.DataComponentLookup- A lookup that maps the component type to the holders that use it.DataComponentMap$Builder#addValidator- Adds a validator for the components on the object.DataComponentPatchgetnow takes in aDataComponentGetterand returns the raw component value$Builder#setnow has an overload that takes in an iterable ofTypedDataComponents
DataComponentsDAMAGE_TYPEnow is a holder-wrappedDamageTypeinstead ofEitherHolder-wrappedPROVIDES_TRIM_MATERIALnow is a holder-wrappedTrimMaterialinstead ofProvidesTrimMaterialCHICKEN_VARIANTnow is a holder-wrappedChickenVariantinstead ofEitherHolder-wrappedZOMBIE_NAUTILUS_VARIANTnow is a holder-wrappedZombieNautilusVariantinstead ofEitherHolder-wrappedPROVIDES_BANNER_PATTERNSis now aHolderSetinstead of aTagKey
net.minecraft.core.registriesBuiltInRegistries#DATA_COMPONENT_INITIALIZERS- A list of data components attached to registry entries.Registries#componentsDirPath- The path directory for the components in a registry.
net.minecraft.data.PackOutput#createRegistryComponentPathProvider- The path provider for the components registry report.net.minecraft.data.info.ItemListReport->RegistryComponentsReport, not one-to-onenet.minecraft.resourcesNetworkRegistryLoadTask- A load task that handles registering registry objects and tags from the network, or else from a resource.RegistryDataLoader$PendingRegistration->RegistryLoadTask$PendingRegistration$RegistryDatanow takes in aRegistryValidatorinstead of aboolean$RegistryLoadTask->RegistryLoadTask, not one-to-one
RegistryValidator- An interface that validates the entries in a registry, storing all errors in a map.ResourceManagerRegistryLoadTask- A load task that handles registering registry objects and tags from the local resource manager.
net.minecraft.server.ReloadableServerResources#updateStaticRegistryTags->updateComponentsAndStaticRegistryTags, not one-to-onenet.minecraft.world.itemEitherHolderclass is removedItemCODEC_WITH_BOUND_COMPONENTS- An item codec that validates that the components are bound.$PropertiesdelayedComponent- Sets the component lazily, providing theHolderLookup$Providerto get any dynamic elements.delayedHolderComponent- Sets the component lazily for some holder-wrapped registry object.
ItemStack#validateComponentsis nowprivatefrompublicJukeboxPlayablenow holds a holder-wrappedJukeboxSonginstead of anEitherHolder-wrapped variantJukeboxSong#fromStackno longer takes in theHolderLookup$ProviderSpawnEggItemspawnEntityis nowstaticbyIdnow returns an optional holder-wrappedIteminstead of aSpawnEggItemeggsis removedgetTypeis nowstaticspawnOffspringFromSpawnEggis nowstatic
net.minecraft.world.item.componentBlocksAttacksnow holds an optional holder set-wrappedDamageTypeinstead of aTagKeyDamageResistantnow holds a holder setDamageTypeinstead of aTagKeyInstrumentComponentnow holds a holder-wrappedInstrumentinstead of anEitherHolder-wrapped variantunwrapis removed
ProvidesTrimMaterialnow holds a holder-wrappedTrimMaterialinstead of anEitherHolder-wrapped variant
net.minecraft.world.item.craftingRecipe#assembleno longer takes in theHolderLookup$ProviderSmithingTrimRecipe#applyTrimno longer takes in theHolderLookup$Provider
net.minecraft.world.item.equipment.trim.TrimMaterials#getFromIngredientis removednet.minecraft.world.level.storage.loot.functions.SetInstrumentFunction,#setInstrumentOptionsnow takes in a holder set-wrappedInstrumentinstead of aTagKeynet.minecraft.world.timeline.Timeline#validateRegistry- Validates that each time marker was only defined once.
Item Instances and Stack Templates
ItemStacks now have an immutable instance known as an ItemStackTemplate. Similar to the ItemStack, it contains the holder-wrapped Item, the number of items it represents, and a DataComponentPatch of the components to apply to the stack. The template can be transformed to a stack via create, or apply if adding additional data components. An ItemStack can likewise be turned into a template via ItemStackTemplate#fromNonEmptyStack. Templates are now used in place of ItemStacks were immutability is required (e.g., advancements, recipes, etc.). They provide a regular CODEC, a MAP_CODEC, and a STREAM_CODEC for network communication.
ItemStackTemplate apple = new ItemStackTemplate(
// The item of the stack
Items.APPLE.builtInRegistryHolder(),
// The number of items held
5,
// The components applied to the stack
DataComponentPatch.builder()
.set(DataComponents.ITEM_NAME, Component.literal("Apple?"))
.build()
);
// Turn the template into a stack
ItemStack stack = apple.create();
// Creating a template from a non-empty stack
ItemStackTemplate fromStack = ItemStackTemplate.fromNonEmptyStack(stack);
To help standardize accessing the general components between the two, both the template and the stack implement ItemInstance, which provides access to the standard holder method checks, the count, and the DataComponentGetter. The common interface also means that if it doesn’t matter whether the stack is mutable or not, then the ItemInstance can be used as the type.
// Both are item instances
ItemInstance stack = new ItemStack(Items.APPLE);
ItemInstance template = new ItemStackTemplate(Items.APPLE);
// Get the holder or check something
Holder<Item> item = stack.typeHolder();
template.is(Items.APPLE);
// Get the number of items in the stack or template
int stackCount = stack.count();
int templateCount = template.count();
// Get the component values
Identifier stackModel = stack.get(DataComponents.ITEM_MODEL);
Identifier templateModel = template.get(DataComponents.ITEM_MODEL);
Recipe Builders
Due to the addition of ItemStackTemplates, RecipeBuilders have changed slightly in their implementation. First, the builder no longer stores an Item for the result, instead defining the defaultId as the resource key recipe. As such, this allows for a more clear method of defining custom recipes that do not export an Item.
Of course, the change to this new format just has defaultId return RecipeBuilder#getDefaultRecipeId with the ItemInstance (either a stack or template), like so:
public class ExampleRecipeBuilder implements RecipeBuilder {
// The result of the recipe
private final ItemStackTemplate result;
public ExampleRecipeBuilder(ItemStackTemplate result) {
this.result = result;
}
@Override
public ResourceKey<Recipe<?>> defaultId() {
// Get the default recipe id from the result
return RecipeBuilder.getDefaultRecipeId(this.result);
}
// Implement everything else below
// ...
}
net.minecraft.advancementsAdvancement$Builder#displaynow takes in anItemStackTemplateinstead of anItemStackDisplayInfonow takes in anItemStackTemplateinstead of anItemStackgetIconnow returns anItemStackTemplateinstead of anItemStack
net.minecraft.advancements.criterionAnyBlockInteractionTrigger#triggernow takes in anItemInstanceinstead of anItemStackItemPredicatenow implements a predicate ofItemInstanceinstead ofItemStackItemUsedOnLocationTrigger#triggernow takes in anItemInstanceinstead of anItemStack
net.minecraft.client.particle.BreakingItemParticle$ItemParticleProvider#getSpritenow takes in anItemStackTemplateinstead of anItemStacknet.minecraft.commands.arguments.itemItemInputis now a recordserializeis removedcreateItemStackno longer takes in thebooleanto check the size
ItemParser#parsenow returns anItemResultinstead of anItemParser$ItemResult$ItemResultmerged intoItemInput
net.minecraft.core.component.predicatesBundlePredicatenow deals with an iterable ofItemInstances rather thanItemStacksContainerPredicatenow deals with an iterable ofItemInstances rather thanItemStacks
net.minecraft.core.particles.ItemParticleOptionnow takes in anItemStackTemplateinstead of anItemStack- There is also an overload for a regular
Item getItemnow returns anItemStackTemplateinstead of anItemStack
- There is also an overload for a regular
net.minecraft.data.recipesRecipeBuildergetResultis removeddefaultId- The default identifiers for the recipe made with this builder.getDefaultRecipeIdnow takes in anItemInstanceinstead of anItemLike
RecipeProvideroreSmelting,oreBlastingnow take in aCookingBookCategoryoreCookingno longer takes in theRecipeSerializerand now takes in aCookingBookCategorycookRecipes,simpleCookingRecipeno longer take in theRecipeSerializershapelessnow takes in anItemStackTemplateinstead of anItemStack
ShapedRecipeBuildernow takes in anItemStackTemplatefor the result, with theItemLikemoved to an overload- Both constructors are
private
- Both constructors are
ShapelessRecipeBuildernow takes in anItemStackTemplatefor the result instead of anItemStackSimpleCookingRecipeBuildernow takes in anItemStackTemplatefor the result, with theItemLikemoved to an overloadgenericno longer takes in theRecipeSerializerand now takes in aCookingBookCategoryblasting,smeltingnow take in aCookingBookCategory
SingleItemRecipeBuildernow takes in anItemStackTemplatefor the result, with theItemLikemoved to an overload- The
ItemStackTemplateconstructor is madeprivate
- The
SmithingTransformRecipeBuildernow takes in anItemStackTemplatefor the result instead of anItemTransmuteRecipeBuildernow takes in anItemStackTemplatefor the result instead of aHolder<Item>- The constructor is
private transmutenow has an overload that takes in theItemStackTemplatefor the resultaddMaterialCountToOutput,setMaterialCount- Handles the size of the result stack based on the number of materials used.
- The constructor is
net.minecraft.network.chat.HoverEvent$ShowItemnow takes in anItemStackTemplateinstead of anItemStacknet.minecraft.server.dialog.body.ItemBodynow takes in anItemStackTemplateinstead of anItemStacknet.minecraft.world.entity.LivingEntitydropFromEntityInteractLootTablenow takes in anItemInstanceinstead of anItemStackfor the tooldropFromShearingLootTablenow takes in anItemInstanceinstead of anItemStackfor the tool
net.minecraft.world.itemBundleItem#getSelectedItemStack->getSelectedItem, now returning anItemStackTemplateinstead of anItemStackItemgetCraftingRemaindernow returns anItemStackTemplateinstead of anItemStack$Properties#craftRemaindernow has an overload that takes in theItemStackTemplate
ItemInstance- A typed item instance that can query the item, the size, and its components.ItemStacknow implementsItemInstanceSINGLE_ITEM_CODEC,STRICT_CODEC,STRING_SINGLE_ITEM_CODEC,SIMPLE_ITEM_CODECare removedgetMaxStackSize->ItemInstance#getMaxStackSize
ItemStackTemplate- A record containing the immutable components of a stack: the item, count, and components.
net.minecraft.world.item.componentBundleContentsnow takes in a list ofItemStackTemplates instead ofItemStacksitemsnow returns a list ofItemStackTemplates instead of an iterable ofItemStacksitemsCopyis removedgetSelectedItem- Returns the stack template of the selected item, ornullif no item is selected.
ChargedProjectileis now a record- The constructor takes in a list of
ItemStackTemplates instead ofItemStacks of->ofNonEmptygetItems->itemCopies
- The constructor takes in a list of
ItemContainerContentsstream->allItemsCopyStreamnonEmptyStream->nonEmptyItemCopyStreamnonEmptyItems,nonEmptyItemsCopy->nonEmptyItems, now returning an iterable ofItemStackTemplates instead ofItemStacks
UseRemaindernow takes in anItemStackTemplateinstead of anItemStack
net.minecraft.world.item.craftingAbstractCookingRecipenow takes in anItemStackTemplateinstead of anItemStackfor the result$Factory#createnow takes in anItemStackTemplateinstead of anItemStackfor the result
BlastingRecipenow takes in anItemStackTemplateinstead of anItemStackfor the resultCampfireCookingRecipenow takes in anItemStackTemplateinstead of anItemStackfor the resultShapedRecipenow takes in anItemStackTemplateinstead of anItemStackfor the resultShapelessRecipenow takes in anItemStackTemplateinstead of anItemStackfor the resultSingleItemRecipenow takes in anItemStackTemplateinstead of anItemStackfor the resultresultnow returns anItemStackTemplateinstead of anItemStack$Factory#createnow takes in anItemStackTemplateinstead of anItemStackfor the result
SmeltingRecipenow takes in anItemStackTemplateinstead of anItemStackfor the resultSmithingTransformRecipenow takes in anItemStackTemplateinstead of anItemStackfor the resultSmokingRecipenow takes in anItemStackTemplateinstead of anItemStackfor the resultStonecutterRecipenow takes in anItemStackTemplateinstead of anItemStackfor the resultTransmuteRecipenow takes in anItemStackTemplateinstead of anItemStackfor the resultTransmuteResult->ItemStackTemplate, not one-to-oneisResultUnchangedis removedapply->TransmuteRecipe#createWithOriginalComponents, not one-to-one
net.minecraft.world.item.crafting.display.SlotDisplay$ItemStackSlotDisplaynow takes in anItemStackTemplateinstead of anItemStacknet.minecraft.world.item.enchantment.EnchantmentHelper#getItemEnchantmentLevelnow takes in anItemInstanceinstead of anItemStacknet.minecraft.world.level.block.BlockdropFromBlockInteractLootTablenow takes in anItemInstanceinstead of anItemStackgetDropsnow takes in anItemInstanceinstead of anItemStack
net.minecraft.world.level.block.entity.DecoratedPotBlockEntity#createdDecoratedPotItem->createdDecoratedPotInstancecreateDecoratedPotTemplatecreates theItemStackTemplateinstead of theItemStack
net.minecraft.world.level.storage.lootLootContext$ItemStackTargetnow implements anItemInstancegeneric for the argument getter instead of theItemStackLootContextArg$ArgCodecBuilder#anyItemStacknow requires a function taking in anItemInstancecontext key instead of anItemStackcontext key
net.minecraft.world.level.storage.loot.parameters.LootContextParams#TOOLis now anItemInstancecontext key instead of anItemStackcontext key
Serializer Records and Recipe Info
Recipes have been slightly reworked in their implementation. First, RecipeSerializer is now a record taking in the MapCodec and StreamCodec used to serialize and deserialize the recipe. As such, Serializer classes have been removed in their entirety, replaced with providing the codecs to the record during registration:
// Assume some ExampleRecipe implements Recipe
// We'll say there's also only one INSTANCE
public static final RecipeSerializer<ExampleRecipe> EXAMPLE_RECIPE = new RecipeSerializer<>(
// The map codec for reading the recipe to/from disk.
MapCodec.unit(INSTANCE),
// The stream codec for reading the recipe to/from the network.
StreamCodec.unit(INSTANCE)
);
Second, some common data regarding the recipe settings and book information have been sectioned into separate objects. These objects are passed into the recipe as part of the constructor and used to more cleanly handle similar implementations across all recipes.
Vanilla provides four of these common object classes, split into two separate categories. Recipe$CommonInfo is used for general recipe settings. Meanwhile, Recipe$BookInfo is used for recipe book information, with CraftingRecipe$CraftingBookInfo for crafting recipes, and AbstractCookingRecipe$CookingBookInfo for cooking recipes (e.g., smelting, blasting, etc.). The common object classes provide methods for constructing the codecs as required, which can then be passed into the relevant recipe codec.
These classes are typically passed through the Recipe subclasses, used as boilerplate to implement abstract methods. None of the data in these objects are directly available outside the implementation itself, only through the methods defined in the Recipe interface. Because of this, classes like NormalCraftingRecipe, CustomRecipe, SimpleSmithingRecipe, and SingleItemRecipe, and AbstractCookingRecipe can be used to create a new recipe implementation by implementing a few methods.
Note that these common info classes are a design philosophy, which you can choose to implement if desired. It’s only when building off existing recipe subtypes that you are required to make use of them.
net.minecraft.data.recipesCustomCraftingRecipeBuilder- A recipe builder that creates an arbitrary crafting recipe from some common and crafting book information.RecipeBuilderdetermineBookCategory->determineCraftingBookCategorycreateCraftingCommonInfo- Creates the common recipe info.createCraftingBookInfo- Creates the crafting book info.
RecipeUnlockAdvancementBuilder- An advancement builder for unlocking a recipe.SpecialRecipeBuilder,specialnow takes in a suppliedRecipeinstead of a function ofCraftingBookCategorytoRecipeunlockedBy- The criteria required to unlock the recipe advancement.
net.minecraft.world.item.craftingAbstractCookingRecipenow takes in theRecipe$CommonInfoand$CookingBookInfoinstead of the group andCookingBookCategory$Factory#createnow takes in theRecipe$CommonInfoand$CookingBookInfoinstead of the group andCookingBookCategory$Serializerreplaced bycookingMapCodec,cookingStreamCodec$CookingBookInfo- A record containing the common cooking information for the recipe book.
BannerDuplicateRecipenow takes in the bannerIngredientand theItemStackTemplateresult instead of theCraftingBookCategoryMAP_CODEC,STREAM_CODEC,SERIALIZER- Serializers for the recipe.
BlastingRecipenow takes in theRecipe$CommonInfoand$AbstractCookingRecipeCookingBookInfoinstead of the group andCookingBookCategoryMAP_CODEC,STREAM_CODEC,SERIALIZER- Serializers for the recipe.
BookCloningRecipenow takes in theIngredientsource and material, theMinMaxBounds$Ints defining the generations that can be copied, and theItemStackTemplateresult instead of theCraftingBookCategoryALLOWED_BOOK_GENERATION_RANGES,DEFAULT_BOOK_GENERATION_RANGES- Ranges for the book generation cloning.MAP_CODEC,STREAM_CODEC,SERIALIZER- Serializers for the recipe.
CampfireCookingRecipenow takes in theRecipe$CommonInfoandAbstractCookingRecipe$CookingBookInfoinstead of the group andCookingBookCategoryMAP_CODEC,STREAM_CODEC,SERIALIZER- Serializers for the recipe.
CraftingRecipe$CraftingBookInfo- A record containing the common crafting information for the recipe book.CustomRecipeno longer takes in anything to its constructor$Serializeris removed, replaced by its implementation’s codecs
DecoratedPotRecipenow takes in theIngredientpatterns for each side along with theItemStackTemplateresult instead of theCraftingBookCategoryMAP_CODEC,STREAM_CODEC,SERIALIZER- Serializers for the recipe.
DyeRecipenow takes in theRecipe$CommonInfoandCraftingRecipe$CraftingBookInfoalong with theIngredienttarget and dye and theItemStackTemplateresult instead of theCraftingBookCategoryMAP_CODEC,STREAM_CODEC,SERIALIZER- Serializers for the recipe.
FireworkRocketRecipenow takes in theIngredientshell, fuel, and star along with theItemStackTemplateresult instead of theCraftingBookCategoryMAP_CODEC,STREAM_CODEC,SERIALIZER- Serializers for the recipe.
FireworkStarFadeRecipenow takes in theIngredienttarget and dye along with theItemStackTemplateresult instead of theCraftingBookCategoryMAP_CODEC,STREAM_CODEC,SERIALIZER- Serializers for the recipe.
FireworkStarRecipenow takes in the$ShapetoIngredientmap; theIngredienttrail, twinkle, fuel, and dye; along with theItemStackTemplateresult instead of theCraftingBookCategoryMAP_CODEC,STREAM_CODEC,SERIALIZER- Serializers for the recipe.
MapCloningRecipereplaced withTransmuteRecipeMapExtendingRecipenow extendsCustomRecipeinstead ofShapedRecipe- The constructor now takes in the
Ingredientmap and material along with theItemStackTemplateresult instead of theCraftingBookCategory MAP_CODEC,STREAM_CODEC,SERIALIZER- Serializers for the recipe.
- The constructor now takes in the
NormalCraftingRecipe- A class that defines the standard implementation for a crafting recipe.RecipeshowNotification,groupare no longer default$BookInfo- The information for the recipe book.$CommonInfo- The common information across all recipes.
RecipeSerializeris now a record containing theMapCodecandStreamCodec- The registered entries have been moved to
RecipeSerializers registeris removed
- The registered entries have been moved to
RecipeSerializers- All vanilla serializers for recipes.RepairItemRecipeno longer takes in anythingINSTANCE- The recipe serializer singleton.MAP_CODEC,STREAM_CODEC,SERIALIZER- Serializers for the recipe.
ShapedRecipenow extendsNormalCraftingRecipeinstead of implementingCraftingRecipe- The constructor now takes in the
Recipe$CommonInfoandCraftingRecipe$CraftingBookInfoinstead of the group andCraftingBookCategory $Serializer->MAP_CODEC,STREAM_CODEC,SERIALIZER; not one-to-one
- The constructor now takes in the
ShapelessRecipenow extendsNormalCraftingRecipeinstead of implementingCraftingRecipe- The constructor now takes in the
Recipe$CommonInfoandCraftingRecipe$CraftingBookInfoinstead of the group andCraftingBookCategory $Serializer->MAP_CODEC,STREAM_CODEC,SERIALIZER; not one-to-one
- The constructor now takes in the
ShieldDecorationRecipenow takes in theIngredientbanner and target along with theItemStackTemplateresult instead of theCraftingBookCategoryMAP_CODEC,STREAM_CODEC,SERIALIZER- Serializers for the recipe.
SimpleSmithingRecipe- A class that defines the standard implementation of a smithing recipe.SingleItemRecipenow takes in theRecipe$CommonInfoinstead of the groupcommonInfo- The common information for the recipe.$Factory#createnow takes in theRecipe$CommonInfoinstead of the group$Serializer->simpleMapCodec,simpleStreamCodec; not one-to-one
SmeltingRecipenow takes in theRecipe$CommonInfoandAbstractCookingRecipe$CookingBookInfoinstead of the group andCookingBookCategoryMAP_CODEC,STREAM_CODEC,SERIALIZER- Serializers for the recipe.
SmithingTransformRecipenow extendsSimpleSmithingRecipeinstead of implementingSmithingRecipe- The constructor now takes in the
Recipe$CommonInfo $Serializer->MAP_CODEC,STREAM_CODEC,SERIALIZER; not one-to-one
- The constructor now takes in the
SmithingTrimRecipenow extendsSimpleSmithingRecipeinstead of implementingSmithingRecipe- The constructor now takes in the
Recipe$CommonInfo $Serializer->MAP_CODEC,STREAM_CODEC,SERIALIZER; not one-to-one
- The constructor now takes in the
SmokingRecipenow takes in theRecipe$CommonInfoandAbstractCookingRecipe$CookingBookInfoinstead of the group andCookingBookCategoryMAP_CODEC,STREAM_CODEC,SERIALIZER- Serializers for the recipe.
StonecutterRecipenow takes in theRecipe$CommonInfoinstead of the groupMAP_CODEC,STREAM_CODEC,SERIALIZER- Serializers for the recipe.
TippedArrowRecipe->ImbueRecipe, not one-to-one- The constructor now takes in the
Recipe$CommonInfoandCraftingRecipe$CraftingBookInfoalong with theIngredientsource and material and theItemStackTemplateresult instead of theCraftingBookCategory MAP_CODEC,STREAM_CODEC,SERIALIZER- Serializers for the recipe.
- The constructor now takes in the
TransmuteRecipenow extendsNormalCraftingRecipeinstead of implementingCraftingRecipe- The constructor now takes in the
Recipe$CommonInfoandCraftingRecipe$CraftingBookInfoalong with theMinMaxBounds$Intsandbooleanhandling the material count and adding it to the result instead of the group andCraftingBookCategory $Serializer->MAP_CODEC,STREAM_CODEC,SERIALIZER; not one-to-one
- The constructor now takes in the
net.minecraft.world.item.crafting.display.SlotDisplay$OnlyWithComponent- A display only with the contents having the desired components.$WithAnyPotion- A display with the contents having any potion contents component.
net.minecraft.world.level.storage.loot.functions.SmeltItemFunction#smeltednow can take in whether to use the input material count
Dye Component
Specifying whether an item can be used as a dye material is now handled through the DYE data component. The component specifies a DyeColor, which can be set via Item$Properties#component:
public static final Item EXAMPLE_DYE = new Item(new Item.Properties().component(
DataComponents.DYE, DyeColor.WHITE
));
However, a dye material’s behavior is not fully encompassed by the component alone. In most cases, the component is used in conjunction with some other tag or subclass to get the desired behavior.
Entities and Signs
Dying sheeps and signs are handled purely through the DyeItem subclass, checking if the item has the DYE component.
Dying the collars of wolfs and cats, on the other hand, can be any item, assuming it has the DYE component. Additionally, the item must be in the ItemTags#WOLF_COLLAR_DYES or ItemTags#CAT_COLLAR_DYES tag, respectively.
Dye Recipes
The DyeRecipe, formerly named ArmorDyeRecipe, can take any target ingredient and apply the colors of the dye ingredients to obtain the desired result with the associated DYED_COLOR component. Any item can be considered a dye; however, those without the DYE component will default to DyeColor#WHITE. Armor makes used of RecipeProvider#dyedItem to allow any item in the ItemTags#DYES tag to dye armor. However, bundles and shulker boxes have their color components as different items, meaning instead the default recipes are tied directly to the vanilla DyeItem, meaning a separate recipe will need to be generated for applying dyes to those items.
The loom, firework star, and firework star face recipes on the other hand expect any dye material to have the DYE component. The loom has an additional requirement of the item being in the ItemTags#LOOM_DYES tag.
net.minecraft.core.component.DataComponents#DYE- Represents that an item can act as a dye for the specific color.net.minecraft.data.recipes.RecipeProviderdyedItem- Creates a dyed item recipe.dyedShulkerBoxRecipe- Creates a dyed shulker box recipe.dyedBundleRecipe- Creates a dyed bundle recipe.
net.minecraft.world.itemBundleItemgetAllBundleItemColors,getByColorare removed
DyeColor#VALUES- A list of all dye colors.DyeItemno longer takes in theDyeColorgetDyeColor,byColorare removed
net.minecraft.world.item.component.DyedItemColor#applyDyesnow takes in a list ofDyeColors instead ofDyeItems- An overload can also take in a
DyedItemColorcomponent instead of theItemStack
- An overload can also take in a
net.minecraft.world.item.crafting.ArmorDyeRecipe->DyeRecipe, not one-to-onenet.minecraft.world.item.crafting.display.SlotDisplay$DyedSlotDemo- A display for demoing dying an item.net.minecraft.world.level.blockBannerBlock#byColoris removedShulkerBoxBlock#getBlockByColor,getColoredItemStackare removed
World Clocks and Time Markers
World clocks are objects that represent some time that increases every tick from when the world first loads. These clocks are used as timers to properly handle timing-based events (e.g., the current day, sleeping). Vanilla provides two world clocks: one for minecraft:overworld and one for minecraft:the_end.
Creating a clock is rather simple: just an empty, datapack registry object in world_clock.
// For some world clock 'examplemod:EXAMPLE_CLOCK'
// JSON at 'data/examplemod/world_clock/EXAMPLE_CLOCK.json'
{}
From there, you can query the clock state through the ClockManager via Level#clockManager or MinecraftServer#clockManager:
// For some Level level
// Assume we have some ResourceKey<WorldClock> EXAMPLE_CLOCK
// Get the clock reference
Holder.Reference<WorldClock> clock = level.registryAccess().getOrThrow(EXAMPLE_CLOCK);
// Query the clock time
long ticksPassed = level.clockManager().getTotalTicks(clock);
If accessing the clock from the server, you can also modify the state of the clock:
// For some ServerLevel level
// Assume we have some ResourceKey<WorldClock> EXAMPLE_CLOCK
// Get the clock reference
Holder.Reference<WorldClock> clock = level.registryAccess().getOrThrow(EXAMPLE_CLOCK);
// Get the server clock manager
ServerClockManager clockManager = level.clockManager();
// Set the total number of ticks that have passed
clockManager.setTotalTicks(clock, 0L);
// Add the a certain value to the number of ticks
clockManager.addTicks(clock, 10L);
// Pause the clock
clockManager.setPaused(
clock,
// `true` to pause.
// `false` to unpause.
true
);
Marking Timelines
On its own, world clocks are rather limited in scope as you have to keep track of the number of ticks that have passed. However, when used with timelines, specific recurring times can be marked to handle timing-based events.
As a refresher, Timelines are a method of modifying attributes based on some WorldClock. Currently, all vanilla timelines use the minecraft:overworld world clock to keep track of their timing, via the clock field. All timelines must define a clock it uses; however, be aware that clocks to not support any synchronization by default, meaning that updating the time on one clock will not affect the other.
// For some timeline 'examplemod:example_timeline'
// In `data/examplemod/timeline/example_timeline.json
{
// Uses the custom clock.
// Any changes to the clock time will only affect
// timelines using this clock.
// e.g., `minecraft:overworld` will not be changed.
"clock": "examplemod:example_clock",
// Perform actions on a 24,000 tick interval.
"period_ticks": "24000",
// ...
}
// For some timeline 'examplemod:example_timeline_2'
// In `data/examplemod/timeline/example_timeline_2.json
{
// Uses the same clock as the one above.
// Changes to the clock time will affect both
// timelines.
"clock": "examplemod:example_clock",
// Perform actions on a 1,000 tick interval.
"period_ticks": "1000",
// ...
}
// For some timeline 'examplemod:example_overworld'
// In `data/examplemod/timeline/example_overworld.json
{
// Uses the vanilla overworld clock.
// Changes to the clock time will not affect
// the above timelines as they use a different
// clock.
"clock": "minecraft:overworld",
// Perform actions on a 6,000 tick interval.
"period_ticks": "6000",
// ...
}
Timelines can also define time markers, which is just some identifier for a time within the timeline period for a world clock. These are commonly used within commands (e.g. /time set), to check if a certain time has passed (e.g. village sieges), or to skip to the given time (e.g. waking up from sleep). Time markers are defined in time_markers, specifying the ticks within the period and whether it can be show_in_commands. As time markers are identified by their world clock, timelines using the same world clock cannot define the same time markers.
// For some timeline 'examplemod:example_timeline'
// In `data/examplemod/timeline/example_timeline.json
{
// The identifier of the clock.
"clock": "examplemod:example_clock",
// Perform actions on a 24,000 tick interval.
"period_ticks": "24000",
// The markers within the period specified by the timeline
"time_markers": {
// A marker
"examplemod:example_marker": {
// The number of ticks within the period
// that this marker represents.
// e.g., 5000, 29000, 53000, etc.
"ticks": 5000,
// When true, allows the time marker to be
// suggested in the command. If false,
// the time marker can still be used in the
// command, it just won't be suggested.
"show_in_commands": true
}
}
// ...
}
Once the time markers are defined, they are registered for a world clock in the ServerClockManager, allowing them to be used given the ResourceKey.
// For some ServerLevel level
// Assume we have some ResourceKey<WorldClock> EXAMPLE_CLOCK
// Assume we have some ResourceKey<ClockTimerMarker> EXAMPLE_MARKER
// Get the clock reference
Holder.Reference<WorldClock> clock = level.registryAccess().getOrThrow(EXAMPLE_CLOCK);
// Get the server clock manager
ServerClockManager clockManager = level.clockManager();
// Check if the time is at the specified marker
// This should be used when checking for a specific time event every tick
boolean atMarker = clockManager.isAtTimeMarker(clock, EXAMPLE_MARKER);
// Skip to the time specified by the marker
// If the world clock is at 3000, sets the clock time to 5000
// If the world clock is at 6000, sets the clock time to 29000
// Returns whether the time was set, which is always true if the marker
// exists for the clock.
boolean timeSet = clockManager.skipToTimeMarker(clock, EXAMPLE_MARKER);
net.minecraft.client.ClientClockManager- Manages the ticking of the world clocks on the client side.net.minecraft.client.gui.components.debug.DebugEntryDayCount- Displays the current day of the Minecraft world.net.minecraft.client.multiplayerClientLevelsetTimeFromServerno longer takes in thelongday time nor thebooleanof whether to tick the day time$ClientLevelData#setDayTimeis removed
ClientPacketListener#clockManager- Gets the client clock manager.
net.minecraft.client.renderer.EndFlashState#ticknow takes in the end clock time instead of the game timenet.minecraft.commands.arguments.ResourceArgumentgetClock- Gets a reference to the world clock given the string resource identifier.getTimeline- Gets a reference to the timeline given the string resource identifier.
net.minecraft.core.registries.Registries#WORLD_CLOCK- The registry identifier for the world clock.net.minecraft.gametest.framework.TestEnvironmentDefinition$TimeOfDay->$ClockTime, not one-to-one$Timelines- A test environment that uses a list of timelines.
net.minecraft.network.protocol.game.ClientboundSetTimePacketnow takes in a map of clocks to their network states instead of the day timelongandbooleannet.minecraft.serverMinecraftServerforceTimeSynchronization->forceGameTimeSynchronization, not one-to-oneclockManager- The server clock manager.
net.minecraft.server.level.ServerLevelsetDayTime,getDayCountare removedsetEnvironmentAttributes- Sets the environment attribute system to use.
net.minecraft.world.attribute.EnvironmentAttributeSystem$Builder#addTimelineLayernow takes in theClockManagerinstead of aLongSuppliernet.minecraft.world.clockClockManager- A manager that gets the total number of ticks that have passed for a world clock.ClockNetworkState- The current state of the clock to sync over the network.ClockState- The current state of the clock, including the total number of ticks and whether the clock is paused.ClockTimeMarker- A marker that keeps track of a certain period of time for a world clock.ClockTimeMarkers- All vanilla time markers.PackedClockStates- A map of clocks to their states, compressed for storage or other use.ServerClockManager- Manages the ticking of the world clocks on the server side.WorldClock- An empty record that represents a key for timing some location.WorldClocks- All vanilla world clocks.
net.minecraft.world.levelLevelgetDayTime->getOverworldClockTime, not one-to-oneclockManager- The clock manager.getDefaultClockTime- Gets the clock time for the current dimension.
LevelReader#getEffectiveSkyBrightness- Gets the sky brightness with the current darkening factor.
net.minecraft.world.level.dimension.DimensionTypenow takes in a default, holder-wrappedWorldClocknet.minecraft.world.level.storageLevelData#getDayTimeis removedServerLevelDatasetDayTimeis removedsetClockStates,clockStates- Handles the current states of the world clocks.
net.minecraft.world.level.storage.loot.predicates.TimeChecknow takes in a holder-wrappedWorldClocktimenow takes in a holder-wrappedWorldClock$Buildernow takes in a holder-wrappedWorldClock
net.minecraft.world.timelineAttributeTrack#bakeSamplernow takes in a holder-wrappedWorldClockAttributeTrackSamplernow takes in a holder-wrappedWorldClock, and aClockManagerinstead of aLongSupplierfor the day time getterTimelinenow takes in a holder-wrappedWorldClockalong with a map of time markers to their infos#buildernow takes in a holder-wrappedWorldClockgetPeriodCount- Gets the number of times a period has occurred within the given timeframe.getCurrentTicksnow takes in theClockManagerinstead of theLevelgetTotalTicksnow takes in theClockManagerinstead of theLevelclock- Returns the holder-wrappedWorldClock.registerTimeMarkers- Registers allClockTimeMarkerdefined in this timeline.createTrackSamplernow takes in aClockManagerinstead of aLongSupplierfor the day time getter$Builder#addTimeMarker- Adds a time markers at the given tick, along with whether the marker can be suggested in commands.
Timelines#DAY->OVERWORLD_DAY
Splitting the Primary Level Data into Saved Data
Some of the WorldData settings have been moved into SavedData, allowing for levels / dimensions to have more customizability. This addition also brings along some changes to how SavedData is referenced and queried.
Saved Data Changes
SavedDataType now identifies some SavedData using an Identifier, which is resolved against the data folder. This change allows subdirectories within the data folder, as the data storage will first create all missing parent directories before attempting to write the file.
public class ExampleData extends SavedData {
public static final SavedDataType<ExampleData> TYPE = new SavedDataType<>(
// The identifier for the saved data to resolve against
// Data can be found in:
// `<world_folder>/dimensions/<dimension_namespace>/<dimension_path>/data/examplemod/example/data.dat`
Identifier.fromNamespaceAndPath("examplemod", "example/data"),
// The constructor to create a new saved data
ExampleData::new,
// The codec to serialize the new saved data
MapCodec.unitCodec(ExampleData::new),
// The data fixer type
// Either some patched enum value or null depending on mod loader implementation.
null
);
}
The SavedData can then be queried through the SavedDataStorage, renamed from DimensionDataStorage. This was renamed because the MinecraftServer instance now has its own data storage for global instances in addition to the levels. This means that any global saved data should be stored on the server instance rather than the overworld.
// Given a MinecraftServer server
ExampleData data = server.getDataStorage().computeIfAbsent(ExampleData.TYPE);
// Given a ServerLevel level
ExampleData data = level.getDataStorage().computeIfAbsent(ExampleData.TYPE);
Additional Saved Data
The following information is now stored as saved data:
- Custom boss events
- Ender dragon fight
- Game rules
- Wandering trader spawning
- Weather
- World generation settings
Of these, only the ender dragon fight is on a per-level / dimension basis. The rest are still stored and accessed through the server data storage. Custom boss events, on the other hand, remain unique as it is up to the implementer to determine what players are part of the event.
net.minecraft.client.Minecraft#doWorldLoadnow takes in the optionalGameRulesnet.minecraft.client.gui.screens.worldselectionCreateWorldCallbacknow takes in theLevelDataAndDimensions$WorldDataAndGenSettingsand the optionalGameRulesinstead of thePrimaryLevelDataEditGameRulesScreen->AbstractGameRulesScreen- Implementations in
.screens.options.InWorldGameRulesScreenandWorldCreationGameRulesScreen
- Implementations in
WorldOpenFlowscreateLevelFromExistingSettingsnow takes in theLevelDataAndDimensions$WorldDataAndGenSettingsand the optionalGameRulesinstead of theWorldDataloadWorldStemnow takes in theLevelStorageSource$LevelStorageAccess
net.minecraft.client.server.IntegratedServernow takes in the optionalGameRulesnet.minecraft.serverMinecraftServernow takes in the optionalGameRulesgetGlobalGameRules- Gets the game rules for the overworld dimension.getWorldGenSettings- Gets the generation settings for the world.getWeatherData- Gets the weather data for the server.getDataStorage- Gets the saved data storage for the server.getGameRules- Gets the game rules for the server.
WorldStemnow takes in theLevelDataAndDimensions$WorldDataAndGenSettingsinstead of theWorldData
net.minecraft.server.bosseventsCustomBossEventnow takes in aUUIDfor the identifier along with aRunnablefor the callbackgetTextId->customIdaddOfflinePlayeris removedgetValue->valuegetMax->maxloadnow takes in theUUIDidentifier along with aRunnablefor the callback
CustomBossEventsnow extendsSavedDatacreatenow takes in aRandomSourcesave,load->TYPE, not one-to-one
net.minecraft.server.dedicated.DedicatedServernow takes in the optionalGameRulesnet.minecraft.server.levelChunkMap#getChunkDataFixContextTagnow takes in an optionalIdentifierinstead of aResourceKeyServerBossEventnow takes in anUUIDfor the idsetDirty- Marks the boss event as dirty for saving.
ServerLevelno longer takes in theRandomSequencessetWeatherParameters->MinecraftServer#setWeatherParametersgetWeatherData- Gets the weather data for the server.getRandomSequence->MinecraftServer#getRandomSequencegetRandomSequences->MinecraftServer#getRandomSequences
net.minecraft.world.entity.npc.wanderingtrader.WanderingTraderSpawnernow takes in theSavedDataStorageinstead of theServerLevelDataMIN_SPAWN_CHANCEis nowpublicfromprivate
net.minecraft.world.entity.raid.Raids#TYPE_END,getTypeare removednet.minecraft.world.levelLevel#prepareWeatheris removedLevelSettingsis now a record- The constructor now takes in the
$DifficultySettingsinstead of just theDifficulty withDifficultyLock- The settings with whether the difficulty is locked.copy- Copies the settings.$DifficultySettings- The settings for the difficulty.
- The constructor now takes in the
net.minecraft.world.level.dimension.DimensionTypenow takes in abooleanfor whether the dimension can have an ender dragon fightnet.minecraft.world.level.dimension.endDragonRespawnAnimation->DragonRespawnStage, not one-to-oneEndDragonFight->EnderDragonFight, not one-to-one
net.minecraft.world.level.gamerules.GameRuleMapnow extendsSavedDataTYPE- The saved data type.reset- Resets the rule to its default value.
net.minecraft.world.level.levelgen.WorldGenSettingsis now a final class instead of a record, extendingSavedDataencode,decodereplaced withTYPEof- Constructs the generation settings.
net.minecraft.world.level.saveddataSavedDataTypenow takes in anIdentifierinstead of a string for the idWanderingTraderData- The saved data for the wandering trader.WeatherData- The saved data for the weather.
net.minecraft.world.level.storageDimensionDataStorage->SavedDataStorage, not one-to-oneLevelData#isThundering,isRaining,setRainingnow inWeatherDataLevelDataAndDimensionsnow takes in a$WorldDataAndGenSettingsinstead of theWorldData$WorldDataAndGenSettings- Holds the world data and generation settings.
LevelResourceis now a recordPrimaryLevelDatafields have been moved to their respective saved data classesPLAYER->OLD_PLAYERSINGLEPLAYER_UUID- A string that represents the UUID of the player in a singleplayer world.WORLD_GEN_SETTINGS->OLD_WORLD_GEN_SETTINGSwriteLastPlayed- Writes the last played player.writeVersionTag- Writes the data version tag.
ServerLevelDatasetThundering,getRainTime,setRainTime,setThunderTime,getThunderTime,getClearWeatherTime,setClearWeatherTimemoved toWeatherDatagetWanderingTraderSpawnDelay,setWanderingTraderSpawnDelay,getWanderingTraderSpawnChance,setWanderingTraderSpawnChance,getWanderingTraderId,setWanderingTraderIdmoved toWanderingTraderDatagetLegacyWorldBorderSettings,setLegacyWorldBorderSettingsreplaced byWorldBordergetScheduledEvents->MinecraftServer#getScheduledEventsgetGameRulesreplaced byGameRuleMap
WorldDatagetCustomBossEvents,setCustomBossEventsreplaced byCustomBossEventscreateTagno longer takes in theRegistryAccessgetGameRulesreplaced byGameRuleMapgetLoadedPlayerTag->getSinglePlayerUUID, not one-to-oneendDragonFightData,setEndDragonFightDatareplaced byEnderDragonFightworldGenOptionsreplaced byWorldGenSettingssaved data
net.minecraft.world.level.timers.TimerQueuenow extendsSavedData- The constructor now takes in the
$Packedevents instead of theTimerCallbacksandStreamof event data storereplaced byCODEC,TYPE,codecloadEvent,storeEventreplaced by$Event$Packed#codec$Eventis now a record$Packed- The packed event data.
$Packed- The packed time queue.
- The constructor now takes in the
Even More Rendering Changes
Materials and Dynamic Layer Selection
Block and item models now no longer specify what RenderType or ChunkSectionLayer they belong to. Instead, this is computed when loading the model, determing the associated layer for each quad. This means that ItemBlockRenderTypes is removed, with setting the RenderType for an item removed altogether.
To determine what layer a quad or face gets set to, the Transparency of the texture is computed. Specifically, it checks that, for the UV area mapped to the quad, if there are any pixels that are transparent (have an alpha of 0), or translucent (have an alpha that is not 0 or 255). For the ChunkSectionLayer, ChunkSectionLayer#TRANSLUCENT is used if there is a translucent pixel, else CUTOUT is used if there is a transparent pixel, else SOLID. For the item RenderType, Sheets#translucentItemSheet and translucentBlockItemSheet for block items are used if there is a translucent pixel, or cutoutItemSheet and cutoutBlockItemSheet for block items. The Transparency also affects using MipmapStrategy#AUTO, using CUTOUT instead of MEAN as the default if there is a transparent pixel.
One can influence a quad’s Transparency through the Material texture defined by the model JSON. A Material specifies the texture’s sprite, which represents the relative path to the texture, and optionally force_translucent, which forces any quad using this texture to use Transparency#TRANSLUCENT (transparent is false while translucent is true):
// For some model `examplemod:example_model`
// In: `assets/examplemod/models/example_model.json`
{
"parent": "minecraft:block/template_glass_pane_post",
"textures": {
// A Material can be a simple texture reference
// Points to `assets/minecraft/textures/block/glass_pane_top.png`
"edge": "minecraft:block/glass_pane_top",
// Or it can be an object
"pane": {
// The relative texture reference for faces using this key
// Points to `assets/minecraft/textures/block/glass.png`
"sprite": "minecraft:block/glass",
// When true, sets all faces using this texture key to
// always have a transparent pixel.
"force_translucent": true
}
}
// ...
}
This change also defines the rendering order, where all solid quads are rendered first, followed by cutout quads, and finally translucent quads, sorted by distance from the camera.
Materials and Sprites
As you may have noticed, Materials were originally used to define some texture in an atlas. The addition of materials in texture JSONs have changed the naming of these classes. Materials now explicitly refer to texture references within model JSONs. This means that all references to the raw texture location have been replaced with Material, if unbaked, and Material$Baked, if baked. Additionally, the SpriteGetter is now MaterialBaker.
As for the original Material, these are now known as sprites, where Material is renamed to SpriteId, and MaterialSet is renamed to SpriteGetter.
Quad Particle Layers
The SingleQuadParticle$Layers have been split into OPAQUE_* and TRANSLUCENT_* layers, depending on if the particle texture used by the atlas contains a translucent pixel. Note that ‘opaque’ in this instance means cutout, where pixels with an alpha of less than 0.1 are discarded. If not creating a new layer, $Layer#bySprite can be used to determine what layer the particle texture should use.
public class ExampleParticle extends SingleQuadParticle {
private final SingleQuadParticle.Layer layer;
public SingleQuadParticle(ClientLevel level, double x, double y, double z, TextureAtlasSprite sprite) {
super(level, x, y, z, sprite);
this.layer = SingleQuadParticle.Layer.bySprite(sprite);
}
@Override
protected SingleQuadParticle.Layer getLayer() {
return this.layer;
}
}
Block Models
The pipeline for rendering individual block models outside of the general world context has been rewritten similarly to ItemModels, where a ‘block model’ updates some render state, which then submits its elements for rendering. As such, most of the block model classes have been either rewritten or reorganized to a degree.
Due to the block model name being synonymous with the model JSONs in general, many classes were moved and rename to separate the model JSONs, from the block state JSONs, from the now block models. As such, geometry for models that originally had ‘block’ in the name were changed to ‘cuboid’: (e.g., BlockModel -> CuboidModel, BlockModelWrapper -> CuboidItemModelWrapper). Additionally, parts of the rendering process referring to the definitions within a block state JSON were changed from ‘block’ to ‘block state’ (e.g., BlockModelPart -> BlockStateModelPart, BlockModelDefinition -> BlockStateModelDispatcher). You can consider most of the ‘block model’ classes to be new, with those renamed replacing the SpecialBlockModelRenderer system.
The block model system starts from the ModelManager after all models and definitions are loaded and resolved, ready to be baked. Block models are loaded through BuiltInBlockModels#crateBlockModels, which links some BlockState to a BlockModel$Unbaked. Similarly to item models, the unbaked instance defines the properties of how the block model should be constructed. These are stored within LoadedBlockModels, to which they are then subsequently baked after all JSONs into BlockModels via bake. This BlockState to BlockModel map is then stored within the BlockModelSet, ready to be queried through get, or more commonly through BlockModelResolver#update, which calls in the model set. Any models not defined lazily resolve to a wrapper around the BlockStateModel.
Vanilla provides six BlockModel implementations for common usage. There is EmptyBlockModel, which submit no elements, and as such renders nothing; and BlockStateModelWrapper, which wraps around and displays the associated BlockStateModel. Then, there are equivalents for changing the model based on some property switch (SelectBlockModel), a conditional boolean (ConditionalBlockModel), and composing multiple models together (CompositeBlockModel). Finally, there is the SpecialBlockModelWrapper, which submits its elements through the stored SpecialModelRenderer, the unified submitter between item and block models.
// As the block model system is hardcoded through its in-code bootstrap,
// this example will assume there exists some method to get access to the
// `BuiltInBlockModels$Builder` builder.
// We will also assume we have some Block EXAMPLE_BLOCK_* to attach the models to.
// Regular block model
builder.put(
// A factory that takes in the `BlockColors` and `BlockState` to return
// a `BlockModel$Unbaked`.
(colors, state) -> new BlockStateModelWrapper.Unbaked(
// The state to get the `BlockStateModel` of.
state,
// The tint layers for the model.
colors.getTintSources(state),
// An optional transformation to apply to the `PoseStack` before
// submitting the model.
Optional.empty(new Transformation(new Matrix4f().translation(0.5f, 0.5f, 0.5f)))
),
// The block to use this model for. Will loop through a construct one
// per state.
EXAMPLE_BLOCK_1
);
// Block model switched on some property
builder.put(
(colors, state) -> new SelectBlockModel.Unbaked(
// An optional transformation to apply to the `PoseStack` before
// submitting the model.
Optional.empty(),
// A record containing the property to switch on, along with the
// values when a specific block model should be selected.
new SelectBlockModel.UnbakedSwitch<>(
// The `SelectBlockModelProperty` to switch on. The property
// value is determined from the `BlockState` and its `BlockDisplayContext`.
(state, displayContext) -> state.getRenderShape(),
// The list of cases to determine what `BlockModel` to use.
List.of(
new SelectBlockModel.SwitchCase<>(
// The list of values this model applies to.
List.of(RenderShape.INVISIBLE),
// The model to use when this property is met.
new EmptyBlockModel.Unbaked()
)
),
// An optional fallback if no switch case matches the state's
// property.
Optional.of(new EmptyBlockModel.Unbaked())
)
),
EXAMPLE_BLOCK_2
);
// Block model based on some conditional
builder.put(
(colors, state) -> new ConditionalBlockModel.Unbaked(
// An optional transformation to apply to the `PoseStack` before
// submitting the model.
Optional.empty(),
// The `ConditionalBlockModelProperty` that determines the
// `boolean` from the `BlockState`.
BlockState::isSignalSource,
// The model to display when the property returns `true`.
new EmptyBlockModel.Unbaked(),
// The model to display when the property returns `false`.
new EmptyBlockModel.Unbaked()
),
EXAMPLE_BLOCK_3
);
// A composite block model
builder.put(
(colors, state) -> new CompositeBlockModel.Unbaked(
// The first model to display.
new EmptyBlockModel.Unbaked(),
// The second model to display.
new EmptyBlockModel.Unbaked(),
// An optional transformation to apply to the `PoseStack` before
// submitting the model.
Optional.empty()
),
EXAMPLE_BLOCK_4
);
// Special block model
builder.put(
(colors, state) -> new SpecialBlockModelWrapper.Unbaked(
// The unbaked `SpecialModelRenderer` used to submit elements for the
// model.
new BellSpecialRenderer.Unbaked(),
// An optional transformation to apply to the `PoseStack` before
// submitting the model.
Optional.empty()
),
EXAMPLE_BLOCK_5
);
During the feature submission process, block models are handled through the BlockModelResolver and BlockModelRenderState. This is similar to how other render states work. First, BlockModelResolver#update sets up the BlockModelRenderState. Setup is handled through either the basic path – BlockModelRenderState#setupModel, add the model parts to the returned list, then setupTints, or through setupSpecialModel for the special renderers. Then, the render state submits its elements for rendering through BlockModelRenderState#submit. The render state also provides submitOnlyOutline which uses the outline render type, and submitWithZOffset which uses the sold entity forward Z-offset render type.
// BlockEntity example
public class ExampleRenderState extends BlockEntityRenderState {
// Hold the render state.
public final BlockModelRenderState exampleBlock = new BlockModelRenderState();
}
public class ExampleRenderer implements BlockEntityRenderer<ExampleBlockEntity, ExampleRenderState> {
// The display context for use in the block entity renderer.
public static final BlockDisplayContext BLOCK_DISPLAY_CONTEXT = BlockDisplayContext.create();
private final BlockModelResolver blockResolver;
public ExampleRenderer(BlockEntityRendererProvider.Context ctx) {
super(ctx);
// Get the model resolver.
this.blockResolver = ctx.blockModelResolver();
}
@Override
public void extractRenderState(ExampleBlockEntity blockEntity, ExampleRenderState state, float partialTick, Vec3 cameraPosition, ModelFeatureRenderer.CrumblingOverlay breakProgress) {
super.extractRenderState(blockEntity, state, partialTick, cameraPosition, breakProgress);
// Update the model state.
this.blockResolver.update(state.exampleBlock, Blocks.DIRT.defaultBlockState(), BLOCK_DISPLAY_CONTEXT);
}
@Override
public void submit(ExampleRenderState state, PoseStack pose, SubmitNodeCollector collector, CameraRenderState camera) {
super.submit(state, pose, collector, camera);
// Submit the model state for rendering.
state.exampleBlock.submit(
// The current pose stack,
pose,
// The node collector.
collector,
// The light coordinates.
state.lightCoords,
// The overlay coordinates.
OverlayTexture.NO_OVERLAY,
// The outline color.
0
);
}
}
// Entity example
public class ExampleRenderState extends EntityRenderState {
// Hold the render state.
public final BlockModelRenderState exampleBlock = new BlockModelRenderState();
}
public class ExampleRenderer extends EntityRenderer<ExampleEntity, ExampleRenderState> {
// The display context for use in the entity renderer.
public static final BlockDisplayContext BLOCK_DISPLAY_CONTEXT = BlockDisplayContext.create();
private final BlockModelResolver blockResolver;
public ExampleRenderer(EntityRendererProvider.Context ctx) {
super(ctx);
// Get the model resolver.
this.blockResolver = ctx.getBlockModelResolver();
}
@Override
public void extractRenderState(ExampleEntity entity, ExampleRenderState state, float partialTick) {
super.extractRenderState(entity, state, partialTick);
// Update the model state.
this.blockResolver.update(state.exampleBlock, Blocks.DIRT.defaultBlockState(), BLOCK_DISPLAY_CONTEXT);
}
@Override
public void submit(ExampleRenderState state, PoseStack pose, SubmitNodeCollector collector, CameraRenderState camera) {
super.submit(state, pose, collector, camera);
// Submit the model state for rendering.
state.exampleBlock.submit(
// The current pose stack.
pose,
// The node collector.
collector,
// The light coordinates.
state.lightCoords,
// The overlay coordinates.
OverlayTexture.NO_OVERLAY,
// The outline color.
state.outlineColor
);
}
}
Block Tint Sources
BlockColor has been completely replaced by BlockTintSource, which sets the ARGB tint of a particular index based on the desired context. There are three contexts a tint source can provide:
colorfor the general context, used byBlockModelscolorInWorldfor the world context, used byModelBlockRenderer#tesselateBlockcolorAsTerrainParticlefor the particle context, used by the falling dust and terrain particle
In addition, BlockTintSource provides a relevantProperties if the Propertys of a BlockState are used to determine what color to tint. This is used by the LevelRenderer to determine whether a change in state requires a model to be re-rendered.
BlockTintSources are still registered to BlockColors via register, taking in a list of sources followed by the vararg of blocks. The tintindex specfied in the model JSON is used to index into the tint source list.
// Assume access to BlockColors colors
colors.register(
// The list of tints to apply to some block model.
List.of(
// "tintindex": 0
(state) -> 0xFFFF0000,
// "tintindex": 1
new BlockTintSource() {
@Override
public int color(BlockState state) {
return 0xFF00FF00;
}
@Override
public int colorInWorld(BlockState state, BlockAndTintGetter level, BlockPos pos) {
return 0xFF0000FF;
}
}
),
// The blocks these tint sources will apply to.
EXAMPLE_BLOCK_1
);
Removing the Old Block and Item Renderers
Since ItemModels and BlockModel are now fully handled through their own feature submission pipeline, BlockRenderDispatcher and ItemRenderer have been completely removed, replaced by the corresponding systems.
Object Definition Transformations
ItemModels and BlockModels can now take in an optional Transformation, which transforms how the model should be displayed. As such, the $Unbaked#bake methods now take in the parent Matrix4fc transformation, to which the transformation is multiplied to via Transformation#compose. For item models, this is known as a local transform separate from the model JSON item transform. The local transforms are always applied after the item transform.
Note that adding support for transformations should always be done through Transformation#compose as the matrices passed around are mutable by nature. Assume any custom methods not performed through a vanilla interface should copy before performing any modifications.
Quad Instance
The brightness / tint color, lightmap, and overlay coordinates have been consolidated into a single object: QuadInstance. The mutable class sets its values through its associated set* methods, and can pull the information for each quad vertex via the get* methods. Brightness and tinting are stored together as the color, rather them being two separate values.
QuadInstance does not replace all usecases, such as when adding a single vertex. It only updates methods for the VertexConsumer, splitting putBulkData into putBlockBakedQuad for quads in block models, and putBakedQuad for all other uses.
In addition, mmany methods used to upload BakedQuads to a buffer now take in a BlockQuadOutput. This has the same parameters as VertexConsumer#putBlockBakedQuad, and was added due to the section renderer uploading to a newly allocated BufferBuilder for use with the uber buffer.
Gui Extractor
GUI classes methods have gone through a massive renaming scheme, indicating that the submitted elements are ‘extracted’ into a general tree to be submitted and then rendered. As such, methods that began with draw* or render* are now prefixed with extract*, and potentially suffixed with *RenderState (e.g., Renderable#render -> extractRenderState, AbstractContainerScreen#renderLabels -> extractLabels, AbstractWidget#renderWidget -> extractWidgetRenderState). Some shorthands were also expanded, either by renamining or replacing the method with another (e.g., AbstractContainerScreen#renderBg replaced by Screen#extractBackground).
GuiGraphics was also renamed to GuiGraphicsExtractor in the same fashion. The methods follow similar patterns to the rest of the GUI changes (e.g. hline -> horizontalLine), except that draw*, render*, and submit* prefixes along with *RenderState suffixes are removed (e.g. renderOutline -> outline, submitEntityRenderState -> entity). The only rename is that *String* method names are replaced with *Text*.
Fluid Models
Defining a fluid’s textures and tint has now been moved out of the FluidRenderer (previously LiquidBlockRenderer) and into its own separate FluidModel record. Initially, given the small number of fluids, the unbaked variants (FluidModel$Unbaked) are stored as constants. Then, after BlockModel have been baked, the fluid models are baked via FluidStateModelSet#bake, linking a Fluid to its FluidModel. This map is then stored within the FluidStateModelSet, ready to be queried through get.
A FluidModel$Unbaked has four arguments: three Materials for the still, flowing, and optional overlay textures; and one for the BlockTintSource. The tint is obtained via BlockTintSource#colorInWorld. During the baking process, it will determine the ChunkSectionLayer based on the transparency of the provided materials.
// As the fluid model system is hardcoded within its baking, this example
// will assume there exists some method to get modifiable access to the
// `Map<Fluid, FluidModel>` fluidModels returned by `FluidStateModelSet#bake`.
// We will also assume we have some Fluid EXAMPLE_FLUID* to attach the models to.
FluidModel.Unbaked exampleFluidModel = new FluidModel.Unbaked(
// The texture for the still fluid.
new Material(
// The relative identifier for the texture.
// Points to `assets/examplemod/textures/block/example_fluid_still.png`
Identifier.fromNamespaceAndPath("examplemod", "block/example_fluid_still"),
// When true, sets all faces using this texture key to
// always have a transparent pixel.
true
),
// The texture for the flowing fluid.
new Material(Identifier.fromNamespaceAndPath("examplemod", "block/example_fluid_flowing")),
// If not null, the texture for the overlay when the side of the fluid is
// occluded by a `HalfTransparentBlock` or `LeavesBlock`.
null,
// If not null, the tint source to apply to the fluid's texture when in
// the world.
null
);
// Assume we have access to the `MaterialBaker` materials.
FluidModel exampleBakedFluidModel = exampleFluidModel.bake(
// The baker to grab the atlas sprites for the materials.
materials,
// A supplied debug name to properly report which models have
// missing textures.
() -> "examplemod:example_fluid_model"
);
fluidModels.put(
// The fluid the model should be used by.
EXAMPLE_FLUID,
// The baked fluid model.
exampleBakedFluidModel
);
fluidModels.put(EXAMPLE_FLUID_FLOWING, exampleBakedFluidModel);
Name Tag Offsets
EntityRenderer#submitNameTag has been renamed to submitNameDisplay, now optionally taking in the y offset from the name tag attachment.
Tint Getter
BlockAndTintGetter is now a client only interface attached to the ClientLevel. It previous uses were replaced with BlockAndLightGetter – which BlockAndTintGetter now extends – with the tint and lighting directions stripped.
Pipeline Depth and Color
Depth and color methods defined in the RenderPipeline have been consolidated into two state objects.
The DepthTestFunction, write boolean, and the bias floats are now stored in DepthStencilState. DepthTestFunction has been replaced with a more generic CompareOp, which defines how to compare two numbers. Each function has an simple equivalent, with NO_DEPTH_TEST replaced by CompareOp#ALWAYS_PASS. The depth information can be added to the pipeline via RenderPipeline$Builder#withDepthStencilState.
The optional BlendFunction and color / alpha booleans are now stored in ColorTargetState. The booleans are consolidated into an int using the lower four bits as flags: 1 is red, 2 is green, 4 is blue, and 8 is alpha. The color boolean uses 7 for red, green, and blue; the alpha boolean uses 8; while both combined use 15. The LopicOp is removed entirely. The color information can be added to the pipeline via RenderPipeline$Builder#withColorTargetState.
public static final RenderPipeline EXAMPLE_PIPELINE = RenderPipeline.builder()
.withLocation(ResourceLocation.fromNamespaceAndPath("examplemod", "pipeline/example"))
.withVertexShader(ResourceLocation.fromNamespaceAndPath("examplemod", "example"))
.withFragmentShader(ResourceLocation.fromNamespaceAndPath("examplemod", "example"))
.withVertexFormat(DefaultVertexFormat.POSITION_TEX_COLOR, VertexFormat.Mode.QUADS)
.withShaderDefine("ALPHA_CUTOUT", 0.5)
.withSampler("Sampler0")
.withUniform("ModelOffset", UniformType.VEC3)
.withUniform("CustomUniform", UniformType.INT)
.withPolygonMode(PolygonMode.FILL)
.withCull(false)
// Sets the color target when writing the buffer data.
.withColorTargetState(new ColorTargetState(
// Specifies the functions to use when blending two colors with alphas together.
// Made up of the `SourceFactor` and `DestFactor`.
// First two are for RGB, the last two are for alphas.
// If the optional is empty, then blending is disabled.
Optional.of(BlendFunction.TRANSLUCENT),
// The mask determining what colors to write to the buffer.
// Represented as a four bit value
// 0001 - Write the red channel..
// 0010 - Write the green channel.
// 0100 - Write the blue channel.
// 1000 - Write the alpha channel.
ColorTargetState.WRITE_RED | ColorTargetState.WRITE_GREEN | ColorTargetState.WRITE_BLUE | ColorTargetState.WRITE_ALPHA
))
// Sets the depth stencil when writing the buffer data.
.withDepthStencilState(new DepthStencilState(
// Sets the depth test function to use when rendering objects at varying
// distances from the camera.
// Values:
// - ALWAYS_PASS (GL_ALWAYS)
// - LESS_THAN (GL_LESS)
// - LESS_THAN_OR_EQUAL (GL_LEQUAL)
// - EQUAL (GL_EQUAL)
// - NOT_EQUAL (GL_NOTEQUAL)
// - GREATER_THAN_OR_EQUAL (GL_GEQUAL)
// - GREATER_THAN (GL_GREATER)
// - NEVER_PASS (GL_NEVER)
CompareOp.LESS_THAN_OR_EQUAL,
// Whether to mask writing values to the depth buffer
false,
// The scale factor used to calculate the depth values for the polygon.
0f,
// The unit offset used to calculate the depth values for the polygon.
0f
))
.build()
;
Blaze3d Backends
CommandEncoder, GpuDevice, and RenderPassBackend has been split into the *Backend interface, which functions similarly to the previous interface, and the wrapper class, which holds the backend and provides delegate calls, performing any validation necessary. The *Backend interfaces now explicitly perform the operation without checking whether the operation is valid.
Solid and Translucent Features
Feature rendering has been further split into two passes: one for solid render types, and one for translucent render types. As such, most render methods now have a renderSolid and renderTranslucent method, respectively. Those which only render solid or translucent data only have one of the methods.
Camera State
The Camera has been updated similarly to other render state implementations where the camera is extracted to the CameraRenderState during GameRenderer#renderLevel, and that is passed around with the data required to either submit and render elements.
Due to this change, FogRenderer#setupFog now returns the FogData, containing all the information needed to render the fog, instead of just its color, and storing that in CameraRenderState#fogData.
- Some shaders within
assets/minecraft/shaders/corenow usetextureovertexelFetchentity.vshitem.vshrendertype_leash.vshrendertype_text.vshrendertype_text_background.vshrendertype_text_intensity.vsh
assets/minecraft/shaders/coreblock.vsh#minecraft_sample_lightmap->sample_lightmap.glsl#sample_lightmaprendertype_crumblingno longer takes intexCoord2(lightmap)rendertype_entity_alpha,rendertype_entity_decalmerged intoentity.fshusing aDissolveMaskSamplerrendertype_item_entity_translucent_cull->item, not one-to-onerendertype_translucent_moving_blockis removed- This now uses the the shaders provided by the
ChunkSectionLayer
- This now uses the the shaders provided by the
com.mojang.blaze3dGLFWErrorCapture- Captures errors during a GL process.GLFWErrorScope- A closable that defines the scope of the GL errors to capture.
com.mojang.blaze3d.openglGlProgram#BUILT_IN_UNIFORMS,INVALID_PROGRAMare now finalGlBackend- A GPU backend for OpenGL.GlCommandEncodernow implementsCommandEncoderBackendinstead ofCommandEncoder, the class now package-privategetDeviceis removed
GlConst#toGlnow takes in aCompareOpinstead of theDepthTestFunctionGlDevicenow implementsGpuDeviceBackendinstead ofGpuDevice, the class now package-private- The constructor now takes in a
GpuDebugOptionscontaining the log level, whether to use synchronous logs, and whether to use debug labels instead of those parameters being passed in directly
- The constructor now takes in a
GlRenderPassnow implementsRenderPassBackendinstead ofRenderPass, the class now package-private- The constructor now takes in the
GlDevice
- The constructor now takes in the
GlStateManager#_colorMasknow takes anintfor the color mask instead of fourbooleans
com.mojang.blaze3d.platformClientShutdownWatchdognow takes in theMinecraftinstanceDebugMemoryUntracker#untrackis removedGLX#make(T, Consumer)is removedNativeImagecomputeTransparency- Returns whether there is at least one transparent or translucent pixel in the image.- This crashes if the image’s area is greater than 512MiB, or 2GiB with color data.
isClosed- Whether the image is closed or deallocated.
Transparency- An object of whether some image has a translucent and/or transparent pixel.Windownow takes theGpuBackendinstead of theScreenManagercreateGlfwWindow- Directly creates the GLFW window with the provided settings.updateDisplay->updateFullscreenIfChanged, not one-to-oneisResized,resetIsResized- Handles whether the window has been resized.backend- Returns theGpuBackend.$WindowInitFailedconstructor is nowpublicfromprivate
WindowEventHandler#resizeDisplay->resizeGui
com.mojang.blaze3d.pipelineColorTargetState- A record containing the blend function and mask for the color.DepthStencilState- A record containing the data for the depth stencil.RenderPipelinenow takes in theColorTargetStateinstead of the optionalBlendFunction, color and alphabooleans, andLogicOp; and theDepthStencilStateinstead of theDepthTestFunction, depthboolean, and biasfloatsgetDepthTestFunction,isWriteDepth,getDepthBiasScaleFactor,getDepthBiasConstant->getDepthStencilState, not one-to-onegetColorLogic,getBlendFunction,isWriteColor,isWriteAlpha->getColorTargetState, not one-to-one$BuilderwithDepthTestFunction,withDepthWrite,withDepthBias->withDepthStencilState, not one-to-onewithBlend,withColorWrite,withColorLogic->withColorTargetState, not one-to-one
$Snippetnow takes in theColorTargetStateinstead of the optionalBlendFunction, color and alphabooleans, andLogicOp; and theDepthStencilStateinstead of theDepthTestFunctionand depthboolean
com.mojang.blaze3d.platformBackendOptions- A configuration for initializing the backend with.DepthTestFunction->CompareOp, not one-to-oneNO_DEPTH_TEST->CompareOp#ALWAYS_PASSEQUAL_DEPTH_TEST->CompareOp#EQUALLEQUAL_DEPTH_TEST->CompareOp#LESS_THAN_OR_EQUALLESS_DEPTH_TEST->CompareOp#LESS_THANGREATER_DEPTH_TEST->CompareOp#GREATER_THAN
GLX_initGlfwnow takes in theBackendOptionsglfwBool-1iftrue,0iffalse.
LogicOpenum is removed
com.mojang.blaze3d.shaders.GpuDebugOptions- The debug options for the GPU pipeline.com.mojang.blaze3d.systemsBackendCreationException- An exception thrown when the GPU backend couldn’t be created.CommandEncoder->CommandEncoderBackend- The original interface is now a class wrapper around the interface, delegating to the backend after performing validation checks
GpuBackend- An interface responsible for creating the used GPU device and window to display to.GpuDevice->GpuDeviceBackend- The original interface is now a class wrapper around the interface, delegating to the backend after performing validation checks
setVsync- Sets whether VSync is enabled.presentFrame- Swaps the front and back buffers of the window to display the present frame.isZZeroToOne- Whether the 0 to 1 Z range is used instead of -1 to 1.
RenderPass->RenderPassBackend- The original interface is now a class wrapper around the interface, delegating to the backend after performing validation checks
RenderSystempollEventsis now publicflipFrameno longer takes in theWindowinitRenderernow only takes in theGpuDevicelimitDisplayFPS->FramerateLimiter#limitDisplayFPSinitBackendSystemnow takes in theBackendOptions
com.mojang.blaze3d.vertexDefaultVertexFormat#BLOCKno longer takes in the normal vectorPoseStack#mulPose,$Pose#mulPosenow has an overload that takes in theTransformationQuadInstance- A class containing the color, light coordinates, and overlay of a quad.TlsfAllocator- A two-level segregate fit allocator for dynamic memory allocation.UberGpuBuffer- A buffer for uploading dynamically sized data to the GPU, used for chunk section layers.VertexConsumerputBulkData->putBlockBakedQuad,putBakedQuad; not one-to-one- Brightness
floatarray, colorfloats, lightmapintarray, and overlayintare replaced withQuadInstance putBlockBakedQuadreplaces thePoseStack$Posewith the XYZfloatblock position
- Brightness
addVertex(PoseStack$Pose, Vector3f)->addVertex(PoseStack$Pose, Vector3fc)setNormal(PoseStack$Pose, Vector3f)->setNormal(PoseStack$Pose, Vector3fc)
com.mojang.mathMatrixUtilcheckPropertyRawis nowpublicfromprivateisOrthonormalis removed
TransformationIDENTITYis nowpublicfromprivate- Replaces
identitymethod
- Replaces
getTranslation->translationgetLeftRotation->leftRotationgetScale->scalegetRightRotation->rightRotationcompose- Applies the transformation to the given matrix, if present.
net.minecraft.SharedConstantsDEBUG_DUMP_INTERPOLATED_TEXTURE_FRAMESis removedDEBUG_PREFER_WAYLAND- When true, prevents the platform initialization hint from being set to X11 if both Wayland and X11 are supported.
net.minecraft.clientCameraBASE_HUD_FOV- The base hud field-of-view.setup->update, not one-to-oneextractRenderState- Extract the state of the camera.getFov- Gets the field-of-view.getViewRotationMatrix- Gets the matrix for a projection view.setEntity- Sets the entity the camera is attached to.getNearPlanenow takes in thefloatfield-of-viewpanoramicForwards- The forward vector when in panorama mode.getPartialTickTimeis removedsetLevel- Sets the level the camera is in.getCameraEntityPartialTicks- Gets the partial tick based on the state of the entity.
DeltaTracker#advanceTimereplaced byadvanceGameTimewhen thebooleanwastrue, andadvanceRealTimeadvanceGameTime,advanceRealTimewere previouslyprivate, nowpublic
FramerateLimiter- A utility for limiting the framerate of the client.MinecraftnoRenderis removeduseAmbientOcclusionis removedgetBlockRendereris removedgetItemRendereris removed
OptionsgetCloudsType->getCloudStatusexclusiveFullscreen- Whentrue, fullscreen mode takes full control of the monitor.
net.minecraft.client.color.blockBlockColorreplaced byBlockTintSource, not one-to-onegetColor->colorInWorld,colorAsTerrainParticle; not one-to-one
BlockColorsgetColorreplaced bygetTintSources,getTintSource; not one-to-oneregisternow takes in a list ofBlockTintSources instead of aBlockColor
BlockTintSource- A source for how to tint aBlockStatein isolation or with context.BlockTintSources- Utilites for common block tint sources.
net.minecraft.client.data.modelsBlockModelGeneratorscreateSuffixedVariantnow takes in a function ofMaterialtoTextureMappingfor the textures instead of just anIdentifiercreateAirLikeBlocknow takes in aMaterialinstead of anIdentifierfor the particle texturegenerateSimpleSpecialItemModelnow takes in an optionalTransformationcreateChestnow has an overload that takes in theMutiblockChestResourcestextures
ItemModelGenerators#generateLayeredItemnow takes inMaterials instead ofIdentifiers for the textures
net.minecraft.client.data.models.modelItemModelUtilsspecialModelnow has overloads that take in theTransformationconditionalnow has overloads that take in theTransformationselectnow has an overload that takes in theTransformationselectBlockItemPropertynow has an overload that takes in theTransformation
TexturedModel#createAllSamenow takes in aMaterialinstead of anIdentifierfor the textureTextureMappingput,putForcednow take in aMaterialinstead of anIdentifierfor the texturegetnow returns aMaterialinstead of anIdentifierfor the texturecopyAndUpdatenow takes in aMaterialinstead of anIdentifierfor the textureupdateSlots- Replaces all slots using the provided mapper function.forceAllTranslucent- Sets the force translucency flag for all material textures.defaultTexture,cube,cross,plant,rail,wool,crop,singleSlot,particle,torch,cauldron,layer0now take in aMaterialinstead of anIdentifierfor the texturecolumn,door,layerednow take inMaterials instead ofIdentifiers for the texturesgetBlockTeture,getItemTexturenow return aMaterialinstead of anIdentifierfor the texture
net.minecraft.client.entity.ClientAvatarEntity#belowNameDisplay->Entity#belowNameDisplaynet.minecraft.client.guiFontdrawInBatch,drawInBatch8xOutlinenow take in aMatrix4fcinstead of aMatrix4ffor the pose$GlyphVisitor#forMultiBufferSourcenow takes in aMatrix4fcinstead of aMatrix4ffor the pose
Guirender*methods have been renamed toextract*render->extractRenderState$RenderFunctioninterface is removed
GuiGraphics->GuiGraphicsExtractorhLine->horizontalLinevLine->verticalLinerenderOutline->outlinedrawCenteredString->centeredTextdrawString->textdrawStringWithBackdrop->textWithBackdroprenderItem->itemrenderFakeItem->fakeItemrenderItemDecorations->itemDecorationssubmitMapRenderState->mapsubmitEntityRenderState->entitysubmitSkinRenderState->skinsubmitBookModelRenderState->booksubmitBannerPatternRenderState->bannerPatternsubmitSignRenderState->signsubmitProfilerChartRenderState->profilerChartrenderTooltip->tooltiprenderComponentHoverEffect->componentHoverEffect, nowprivateinstead ofpublic
net.minecraft.client.gui.components- Most methods that begin with
render*ordraw*have been renamed to eitherextract*orextract*RenderStatedepending on usage. AbstractWidget#renderWidget->extractWidgetRenderStateDebugScreenOverlay#render3dCrosshairnow takes in theCameraRenderStateinstead of theCamera, and the gui scaleintLogoRenderer#renderLogo->extractRenderStatePlayerFaceRenderer->PlayerFaceExtractordraw->extractRenderState
Renderable#render->extractRenderStateStringWidget#clipText->ComponentRenderUtils#clipTextTextCursorUtils#draw*->extract*
- Most methods that begin with
net.minecraft.client.gui.components.debugchartAbstractDebugChartdrawChart->extractRenderStatedrawDimensions->extractSampleBarsdrawMainDimension->extractMainSampleBardrawAdditionalDimensions->extractAdditionalSampleBarsrenderAdditionalLinesAndLabels->extractAdditionalLinesAndLabelsdrawStringWithShade->extractStringWithShade
ProfilerPieChart#render->extractRenderState
net.minecraft.client.gui.components.spectator.SpectatorGui#render*->extract*net.minecraft.client.gui.components.toastsNowPlayingToast#renderToast->extractToastToast#render->extractRenderStateToastManager,$ToastInstance#render->extractRenderStateTutorialToast$Icons#render->extractRenderState
net.minecraft.client.gui.contextualbar.ContextualBarRendererrenderBackground->extractBackgroundrender->extractRenderStaterenderExperienceLevel->extractExperienceLevel
net.minecraft.client.gui.fontPlainTextRenderable#renderSpritenow takes in aMatrix4fcinstead of aMatrix4ffor the poseTextRenderable#rendernow takes in aMatrix4fcinstead of aMatrix4ffor the pose
net.minecraft.client.gui.renderDynamicAtlasAllocator- An allocator for handling a dynamically sized texture atlas.GuiItemAtlas- An atlas for all items displayed in a user interface.GuiRenderer#incrementFrameNumber->endFrame, not one-to-one
net.minecraft.client.gui.render.state.*->.client.rendererer.state.gui.*GuiItemRenderStateno longer takes in theStringnamenameis removed
net.minecraft.client.gui.render.state.pip.*->.client.rendererer.state.gui.pip.*net.minecraft.client.gui.screensLevelLoadingScreen#renderChunks->extractChunksForRenderingScreenrenderWithTooltipAndSubtitles->extractRenderStateWithTooltipAndSubtitlesrenderBackground->extractBackgroundrenderBlurredBackground->extractBlurredBackgroundrenderPanorama->extractPanoramarenderMenuBackground->extractMenuBackgroundrenderMenuBackgroundTexture->extractMenuBackgroundTexturerenderTransparentBackground->extractTransparentBackground
net.minecraft.client.gui.screens.advancementsAdvancementTab#draw*->extract*AdvancementTabTypedraw->extractRenderStatedrawIcon->extractIcon
AdvancementWidgetdraw->extractRenderStatedraw*->extract*
net.minecraft.client.gui.screens.inventory- Most methods that begin with
render*ordraw*have been renamed to eitherextract*orextract*RenderStatedepending on usage. AbstractContainerScreenrenderContents->extractContentsrenderCarriedItem->extractCarriedItemrenderSnapbackItem->extractSnapbackItemrenderSlots->extractSlotsrenderTooltip->extractTooltiprenderLabels->extractLabelsrenderBgreplaced byScreen#extractBackgroundrenderSlot->extractSlot
AbstractMountInventoryScreen#drawSlot->extractSlotAbstractSignEditScreen#renderSignBackground->extractSignBackgroundCyclingSlotBackground#render->extractRenderStateEffectsInInventory#render->extractRenderStateInventoryScreen#renderEntityInInventoryFollowsMouse->extractEntityInInventoryFollowsMouseItemCombinerScreen#renderErrorIcon->extractErrorIcon
- Most methods that begin with
net.minecraft.client.gui.screens.inventory.tooltipClientTooltipComponentrenderText->extractTextrenderImage->extractImage
TooltipRenderUtil#renderTooltipBackground->extractTooltipBackground
net.minecraft.client.gui.screens.optionsDifficultyButtonsis now a record that takes in theLayoutElement,CycleButtonfor the difficulty, theLockIconButton, and the currentLevelcreatenow takes in theLeveland returns theDifficultyButtonsinstead of aLayoutElementrefresh- Sets the data of the held button components.
HasDifficultyReaction- An interface that responds to when the difficulty has changed.OptionsScreennow implementsHasDifficultyReactionWorldOptionsScreennow implementsHasDifficultyReaction- The constructor now takes in the
Level
- The constructor now takes in the
net.minecraft.client.gui.screens.recipebookGhostSlotsrender->extractRenderStaterenderTooltip->extractTooltip
RecipeBookComponent#render*->extract*RecipeBookPagerender->extractRenderStaterenderTooltip->extractTooltip
net.minecraft.cilent.gui.screens.reporting.ChatSelectionScreen$ChatSelectionList#renderItem->extractItemnet.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen$GameRuleEntry#renderLabel->extractLabelnet.minecraft.client.gui.spectator.SpectatorMenuItem#renderIcon->extractIconnet.minecraft.client.model.Model#renderTypenow has an overload that returns the passed in functionnet.minecraft.client.model.object.book.BookModel$Stateno longer takes in the animation pos, and moves the openfloatto the first parameterforAnimation- Gets the current state of the animation for the book based on the progress.
net.minecraft.client.model.object.statue.CopperGolemStatueModelnow usesUnitfor the generic instead ofDirectionnet.minecraft.client.multiplayer.ClientLevelnow implementsBlockAndTintGetterupdate- Updates the lighting of the level.
net.minecraft.client.multiplayer.chat.GuiMessageTag$Icon#draw->extractRenderStatenet.minecraft.client.particleParticle#getLightColor->getLightCoordsSimpleVerticalParticle- A particle that moves vertically.SingleQuadParticle$LayerTERRAIN->OPAQUE_TERRAIN,TRANSLUCENT_TERRAINITEMS->OPAQUE_ITEMS,TRANSLUCENT_ITEMSbySprite- Gets the layer from the atlas sprite.
net.minecraft.client.rendererCachedOrthoProjectionMatrixBuffer,CachedPerspectiveProjectionMatrixBuffer,PerspectiveProjectionMatrixBuffer->ProjectionMatrixBufferwith sometimesProjection, not one-to-oneCloudRenderernow takes in the cloud rangeintCubeMapno longer takes in theMinecraftinstanceGameRenderernow takes in theModelManagerinstead of theBlockRenderDispatcherPROJECTION_Z_NEAR->Camera#PROJECTION_Z_NEARsetPanoramicScreenshotParameters,getPanoramicScreenshotParameters->Camera#enablePanoramicMode,disablePanoramicMode; not one-to-oneisPanoramicMode->Camera#isPanoramicModegetProjectionMatrix->Camera#getViewRotationProjectionMatrix, not one-to-oneupdateCamera->Camera#update, not one-to-onegetRenderDistanceis removedcubeMap->GuiRenderer#cubeMap, nowprivatefromprotectedgetDarkenWorldAmount->getBossOverlayWorldDarkeninglightTexture->lightmap,levelLightmap; not one-to-onegetLevelRenderStatereplaced bygetGameRenderState, returning theGameRenderStateinstead of theLevelRenderStatepick->Minecraft#pick, nowprivatefrompublicrendersplit betweenupdate,extract, andrender; with thebooleannow taking in whether to advance the game time rather than render the level
GlobalSettingsUniformnow takes in theVec3camera position instead of the mainCameraitselfItemBlockRenderTypesis removedgetChunkRenderType,getMovingBlockRenderTypenow stored withinBakedQuad$SpriteInfogetRenderLayer(FluidState)->FluidModel#layer, not one-to-onesetCutoutLeavesis removed- This should be obtained directly from the options
MultiblockChestResources- A record containing some data based on theChestType.LevelRenderernow takes in theGameRenderStateinstaed of theLevelRenderStateupdate- Updates the level.renderLevelnow takes in theCameraRenderStateinstead of theCamera, aMatrix4fcinstead of aMatrix4ffrom the model view, and theChunkSectionsToRender; it no longer takes in theMatrix3ffor the projection matricesextractLevel- Extracts the level state.prepareChunkRendersis nowpublicinstead ofprivatecaptureFrustum,killFrustum,getCapturedFrustumare removedgetLightColor->getLightCoords, now taking in theBlockAndLightGetterinstead of theBlockAndTintGetter$BrightnessGetter#packedBrightnessnow takes in theBlockAndLightGetterinstead of theBlockAndTintGetter
LightTexture->Lightmaptick->LightmapRenderStateExtractor#tickupdateLightTexture->renderpack->LightCoordsUtil#packblock->LightCoordsUtil#blocksky->LightCoordsUtil#skylightCoordsWithEmission->LightCoordsUtil#lightCoordsWithEmission
MaterialMapper->SpriteMapperOrderedSubmitNodeCollectorsubmitBlockis removedsubmitBlockModelnow takes in a list ofBlockStateModelParts instead of theBlockStateModel, and an array ofints (array of tint colors) instead of threefloats for a single colorsubmitItemno longer takes in theRenderTypesubmitModelnow has overloads that takes in theIdentifierfor the texture, or aSpriteIdwith theSpriteGetteralong with aninttint colorsubmitBreakingBlockModel- Submits the block breaking overlay.
PanoramaRendererreplaced byPanoramaregisterTextures->GuiRenderer#registerPanoramaTexturesrender->extractRenderState
PanoramicScreenshotParametersrecord is removedPostChainnow takes in aProjectionandProjectionMatrixBufferinstead of anCachedOrthoProjectionMatrixBufferloadnow takes in aProjectionandProjectionMatrixBufferinstead of anCachedOrthoProjectionMatrixBuffer
RenderPipelinesENTITY_CUTOUT_NO_CULL->ENTITY_CUTOUT- The original cutout with cull is replaced by
ENTITY_CUTOUT_CULL
- The original cutout with cull is replaced by
ENTITY_CUTOUT_NO_CULL_Z_OFFSET->ENTITY_CUTOUT_Z_OFFSETENTITY_SMOOTH_CUTOUT->END_CRYSTAL_BEAMENTITY_NO_OUTLINEreplaced byENTITY_TRANSLUCENT, render type constructed with affects outline being falseENTITY_DECAL,DRAGON_EXPLOSION_ALPHA->ENTITY_CUTOUT_DISSOLVE, not one-to-oneITEM_ENTITY_TRANSLUCENT_CULL->ENTITY_TRANSLUCENT_CULL,ITEM_CUTOUT,ITEM_TRANSLUCENT; not one-to-oneTRANSLUCENT_MOVING_BLOCKreplaced byTRANSLUCENT_BLOCKBANNER_PATTERN- A pipeline for rendering the patterns on a banner.
ScreenEffectRenderer#renderScreenEffectnow takes inbooleans for whether the player is in first person and whether to hide the GUISheets*CHEST_*LOCATION*have been combined into one of theCHEST_*fields based on what the resource was fortranslucentBlockSheet- A cullable entity item translucent render type using the block atlas.cutoutBlockItemSheet- An item cutout render type using the block atlas.bannerSheet->RenderTypes#entityTranslucent, not one-to-onecutoutItemSheet- An item cutout render type using the item atlas.get*Material->get*SpritechooseMaterial->chooseSprite
SpecialBlockModelRendererreplaced byBuiltInBlockModels, not one-to-onerenderByBlock->BlockModelRenderState#submit*, not one-to-one
SubmitNodeCollectiongetBlockSubmitsis removedgetBreakingBlockModelSubmits- Gets the submitted breaking block overlay.
SubmitNodeCollector$ParticleGroupRendererisEmpty- Whether there are no particles to render in this group.preparenow takes whether the particles are being prepared for the translucent layerrenderno longer takes in the translucentboolean
SubmitNodeStorage$BlockModelSubmitnow takes in a list ofBlockStateModelParts instead of theBlockStateModel, and an array ofints (array of tint colors) instead of threefloats for a single color$BlockSubmitis removed$BreakingBlockModelSubmit- A record containing the information to render the block breaking overlay.$ItemSubmitno longer takes in theRenderType$MovingBlockSubmit,$NameTagSubmit,$ShadowSubmit,$TextSubmitnow take in aMatrix4fcinstead of aMatrix4ffor the pose
VirtualScreenreplaced byGpuBackend
net.minecraft.client.renderer.blockBlockAndTintGetter- A getter for positional block tinting (e.g., biomes).BlockModelRenderState- The render state for a block model.BlockModelResolver- A helper for setting up the render state for aBlockState.BlockModelSet- Holds theBlockModelassociated with eachBlockState.BlockModelShaper->BlockStateModelSet, not one-to-onegetParticleIcon->getParticleMaterial, now returning aMaterial$Bakedinstead of aTextureAtlasSpritegetBlockModel->getgetModelManager,replaceCacheare removed
BlockQuadOutput- A functional interface for writing the baked quad information to some output, like a buffer.BlockRenderDispatcherclass is removedgetBlockModelShaper->getModelSet, not one-to-onerenderBreakingTexturereplaced withSubmitNodeCollector#submitBreakingBlockModelrenderBatchedreplaced with direct call toModelBlockRenderer#tesselateBlockrenderLiquidreplaced with direct call toFluidRenderer#tesselaterenderSingleBlockis now inlined withinBlockFeatureRenderer#renderBlockModelSubmits, aprivatemethod- Use
ModelBlockRenderer#tesselateBlockas an alternative
- Use
FluidModel- The base fluid model that holds the data for the renderer.FluidStateModelSet- Holds theFluidModelassociated with eachFluid.LoadedBlockModels- A task for baking theBlockModelfor eachBlockState.LiquidBlockRenderer->FluidRenderer, not one-to-one- The constructor now takes in the
FluidStateModelSetinstead of theSpriteGetter tesselatenow takes in aFluidRenderer$Outputinstead of aVertexConsumer$Output- Gets theVertexConsumerto use for theChunkSectionLayer.
- The constructor now takes in the
ModelBlockRenderernow takes inbooleans for ambient occlusion and cullingtesselateBlocknow takes in aBlockQuadOutputinstead of aVertexConsumer, the XYZfloats instead of aPoseStack, theBlockStateModelinstead of the list ofBlockModelParts, no longer takes in the cullbooleanandintoverlay, and takes in the seedlongtesselateWithAO->tesselateAmbientOcclusion, nowprivateinstead ofpublictesselateWithoutAO->tesselateFlat, nowprivateinstead ofpublicrenderModelis now inlined withinBlockFeatureRenderer#renderBlockModelSubmits, aprivatemethodforceOpaque- Whether the block textures should be opaque instead of translucent.enableCaching->BlockModelLighter$Cache#enableclearCache->BlockModelLighter$Cache#disable$AdjacencyInfo->BlockModelLighter$AdjacencyInfo, nowprivateinstead ofprotected$AmbientOcclusionRenderStorageis replaced byBlockModelLighter, not one-to-one$AmbientVertexRemap->BlockModelLighter$AmbientVertexRemap$Cache->BlockModelLighter$Cache$CommonRenderStorageis replaced byBlockModelLighter, not one-to-one$SizeInfo->BlockModelLighter$SizeInfo
MovingBlockRenderState#level->cardinalLighting,lightEngine; not one-to-oneSelectBlockModel- A block model that determined or selected by its resolved property.
net.minecraft.client.renderer.block.modelBakedQuad->.client.resources.model.geometry.BakedQuad- The constructor now takes in a
$MaterialInfoinstead of theTextureAtlasSprite,inttint index,intlight emission, andbooleanshade FLAG_TRANSLUCENT- A flag that marks the baked quad has having translucency.FLAG_ANIMATED- A flag that marks the baked quad has having an animated texture.isTinted->$MaterialInfo#isTinted$MaterialFlags- An annotation that marks whether a given integer defines the flags for a material.$MaterialInfo- A record holding the information on how to render the quad.
- The constructor now takes in a
BlockDisplayContext- An object that represents the display context of a block.BlockElement->.client.resources.model.cuboid.CuboidModelElementBlockElementFace->.client.resources.model.cuboid.CuboidFaceBlockElementRotation->.client.resources.model.cuboid.CuboidRotationBlockModel- The base block model that updates the render state for use outside the world context.- The original implementation has been moved to
.client.resources.model.cuboid.CuboidModel
- The original implementation has been moved to
BlockModelDefinition->.block.dispatch.BlockStateModelDispatcherBlockModelPart->.block.dispatch.BlockStateModelPartparticleIcon->particleMaterial, now returning aMaterial$Bakedinstead of aTextureAtlasSpritematerialFlags- Handles the flags for the material(s) used by the model.
BlockStateModel->.block.dispatch.BlockStateModelparticleIcon->particleMaterial, now returning aMaterial$Bakedinstead of aTextureAtlasSpritematerialFlags,hasMaterialFlag- Handles the flags for the material(s) used by the model.
BlockStateModelWrapper- The basic block model that contains the model, tints, and transformation.CompositeBlockModel- Overlays multiple block models together.ConditionalBlockModel- A block model that shows a different model based on a boolean obtained from some property.EmptyBlockModel- A block model that shows nothing.FaceBakery->.client.resources.model.cuboid.FaceBakerybakeQuadoverload now takes in aModelBakerinstead of theModelBaker$PartCache, and aMaterial$Bakedinstead of aTextureAtlasSprite- It also has an overload taking in the fields of the
BlockElementFaceinstead of the object itself
- It also has an overload taking in the fields of the
- Another
bakedQuadovrload now takes in theBakedQuad$MaterialInfoinstead of theinttint index and light emission, and the shadeboolean
ItemModelGenerator->.client.resources.model.cuboid.ItemModelGeneratorItemTransform->.client.resources.model.cuboid.ItemTransformItemTransforms->.client.resources.model.cuboid.ItemTransformsSimpleModelWrapper->.client.resources.model.SimpleModelWrapper- The constructor now takes in a
Material$Bakedinstead of aTextureAtlasSpritefor the particle
- The constructor now takes in a
SimpleUnbakedGeometry->.client.resources.model.cuboid.UnbakedCuboidGeometrySingleVariant->.block.dispatch.SingleVariantSpecialBlockModelWrapper- A block model for models that submit their elements throughSpecialModelRenderers.TextureSlots->.client.resources.model.sprite.TextureSlotsVariant->.block.dispatch.VariantVariantMutator->.block.dispatch.VariantMutatorVariantSelector->.block.dispatch.VariantSelector
net.minecraft.client.renderer.block.model.multipart.*->.block.dispatch.multipart.*net.minecraft.client.renderer.block.model.properties.conditionalConditionalBlockModelProperty- A property that computes somebooleanfrom theBlockState.IsXmas- Returns whether the current time is between December 24th - 26th.
net.minecraft.client.renderer.block.model.properties.selectDisplayContext- A case based on the currentBlockDisplayContext.SelectBlockModelProperty- A property that computes some switch state from theBlockState.
net.minecraft.client.renderer.blockentityAbstractEndPortalRendererrenderCube->submitCube, nowprotectedandstaticfromprivatesubmitSpecial- Submits the end portal cube, used by the special renderer.getExtents- Gets the vertices of each face.getOffsetUp,getOffsetDownare removedrenderTypeis removed
AbstractSignRenderernow takes in a generic for theSignRenderStategetSignModelnow takes in theSignRenderStategeneric instead of theBlockStateandWoodTypegetSignModelRenderScale,getSignTextRenderScale,getTextOffset,translateSignreplaced bySignRenderState#transformations,SignRenderState$SignTransformationsgetSignMaterial->getSignSprite
BannerRendererTRANSFORMATIONS- The transformations to apply when on the wall or ground.submitPatternsno longer takes in the baseSpriteId, whether the pattern has foil, and the outline colorsubmitSpecialnow takes in theBannerBlock$AttachmentType
BedRenderersubmitSpecialis removed- This is replaced by calling
submitPiecetwice, or making a composite for each bed part via theBedSpecialRenderer
- This is replaced by calling
submitPieceis nowpublicfromprivate, taking in theBedPartinstead of theModel$Simple,Direction, or thebooleanof whether to translate in the Z directiongetExtentsnow takes in theBedPartmodelTransform- Gets the transformation for the givenDirection.
BlockEntityRenderDispatchernow takes in theBlockModelResolverinstead of theBlockRenderDispatcher, and no longer takes in theItemRendererpreparenow takes in aVec3camera position instead of theCameraitself
BlockEntityRendererProvider$Contextnow takes in theBlockModelResolverinstead of theBlockRenderDispatcher, and no longer takes in theItemRenderermaterials->sprites
ChestRendererLAYERS- Holds the model layers of the chest.modelTransformation- Gets the transformation for the givenDirection.
ConduitRenderer#DEFAULT_TRANSFORMATION- The default transformation to apply.CopperGolemStatueBlockRenderer#modelTransformation- Gets the transformation for the givenDirection.DecoratedPotRenderer#modelTransformation- Gets the transformation for the givenDirection.HangingSignRenderernow uses aHangingSignRenderStateMODEL_RENDER_SCALEis nowprivatefrompublicTRANSFORMATIONS- The transformations to apply when on the wall or ground.translateBase->baseTransformation, nowprivatefrompublic$AttachmentType->HangingSignBlock$AttachmentbyBlockState->$Models#get
$ModelKeyrecord is removed
ShulkerBoxRenderermodelTransform- Gets the transformation for the givenDirection.getExtentsno longer takes in theDirection
SignRenderer->StandingSignRendererTRANSFORMATIONS- The transformations to apply when on the wall or ground.createSignModelnow takes in aPlainSignBlock$Attachmentinstead of abooleanfor whether the block is standing
SkullBlockRendererTRANSFORMATIONS- The transformations to apply when on the wall or ground.submitSkullno longer takes in theDirectionorfloatrotation
WallAndGroundTransformations- A class that holds a map ofDirections to transforms to apply for the wall, and anintfunction to compute the ground transformations, with theintsegments generally acting as the number of rotation states.
net.minecraft.client.renderer.blockentity.stateBannerRenderStateangle->transformation, not one-to-onestanding->attachmentType, not one-to-one
BedRenderState#isHead->part, not one-to-oneBlockEntityRenderState#blockStateis nowprivatefrompublicChestRenderState#angle->facing, not one-to-oneCondiutRenderState->ConduitRenderStateCopperGolemStatueRenderState#oxidationState- The current oxidation state.HangingSignRenderState- The render state for the hanging sign.ShelfRenderState#facing- The direction the shelf is facing.SignRenderState#woodType- The type of wood the sign is made of.SkullblockRenderState#direction,rotationDegrees->transformation, not one-to-oneStandingSignRenderState- The render state for the standing sign.
net.minecraft.client.renderer.chunkChunkSectionLayernow takes in abooleanfor whether the layer is translucent rather than just sorting on uploadbyTransparency- Gets the layer by its transparency setting.sortOnUpload->translucent, not one-to-onevertexFormat- The vertex format of the pipeline used by the layer.
ChunkSectionsToRender#drawsPerLayer->drawGroupsPerLayer, with its value being aintto list of draws mapCompiledSectionMeshuploadMeshLayerreplaced byisVertexBufferUploaded,setVertexBufferUploadeduploadLayerIndexBufferreplaced byisIndexBufferUploaded,setIndexBufferUploaded
RenderRegionCache#createRegionnow takes in theClientLevelinstead of theLevelSectionBuffers->SectionRenderDispatcher$RenderSectionBufferSlice, not one-to-oneSectionCompilernow takes in thebooleans for ambient occlusion and cutout leaves, theBlockStateModelSet, theFluidStateModelSet, and theBlockColorsinstead of theBlockRenderDispatcherSectionMeshgetBuffers->getSectionDraw, not one-to-one$SectionDraw- The draw information for the section.
SectionRenderDispatchernow takes in theSectionCompilerinstead of theBlockRenderDispatcherandBlockEntityRenderDispatchergetRenderSectionSlice- Gets the buffer slice of the section mesh to render for the chunk layer.uploadAllPendingUploads->uploadGlobalGeomBuffersToGPU, not one-to-onelock,unlock- Handles locking the dispatcher when copying data from location to another, usually for GPU allocation.getToUploadis removedsetLevelnow takes in theSectionCompiler$RenderSectionupload,uploadSectionIndexBuffer->addSectionBuffersToUberBuffer, now private$CompileTaskdoTasknow returns a$SectionTaskResultinstead of aCompletableFuture
$SectionTaskResult->$RenderSection$CompileTask$SectionTaskResult
net.minecraft.client.renderer.culling.Frustumnow takes in aMatrix4fcinstead of aMatrix4ffor the model viewset- Copies the information from another frustum.
net.minecraft.client.renderer.entityAbstractBoatRenderernow takes in theIdentifiertexturerenderTypeis removed
AbstractMinecartRendererBLOCK_DISPLAY_CONTEXT- The context of how to display the block inside the minecart.submitMinecartContentsnow takes in aBlockModelRenderStateinstead of theBlockState
CopperGolemRenderer#BLOCK_DISPLAY_CONTEXT- The context of how to display the antenna block.DisplayRendererBLOCK_DISPLAY_CONTEXT- The context of how to display the displayed block.blockModelResolver- The block model resolver.
EndermanRenderer#BLOCK_DISPLAY_CONTEXT- The context of how to display the held block.EntityRenderDispatchernow takes in theBlockModelResolverinstead of theBlockRenderDispatcherEntityRenderer#submitNameTag->submitNameDisplay, now optionally taking in the y positionintas an offset from the name tag attachmentEntityRendererProvider$Contextnow takes in theBlockModelResolverinstead of theBlockRenderDispatchergetMaterials->getSpritesgetBlockRenderDispatcherreplaced bygetBlockModelResolver
IronGolemRenderer#BLOCK_DISPLAY_CONTEXT- The context of how to display the held block.ItemFrameRenderer#BLOCK_DISPLAY_CONTEXT- The context of how to display the displayed block.ItemRendererclass is removed- Use the
ItemStackRenderStateto submit elements to the feature dispatcher instead ENCHANTED_GLINT_ARMOR->ItemFeatureRenderer#ENCHANTED_GLINT_ARMORENCHANTED_GLINT_ITEM->ItemFeatureRenderer#ENCHANTED_GLINT_ITEMNO_TINT->ItemFeatureRenderer#NO_TINTgetFoilBuffer->ItemFeatureRenderer#getFoilBuffergetFoilRenderType->ItemFeatureRenderer#getFoilRenderType, nowpublicfromprivate
- Use the
MushroomCowRenderer#BLOCK_DISPLAY_CONTEXT- The context of how to display the attached blocks.SnowGolemRenderer#BLOCK_DISPLAY_CONTEXT- The context of how to display the head block.TntRenderer#BLOCK_DISPLAY_CONTEXT- The context of how to display the TNT block.TntMinecartRenderer#submitWhiteSolidBlocknow takes in aBlockModelRenderStateinstead of theBlockState
net.minecraft.client.renderer.entity.layersBlockDecorationLayernow takes in a function that returns aBlockModelRenderStateinstead of an optionalBlockStateMushroomCowMushroomLayerno longer takes in theBlockRenderDispatcherSnowGolemHeadLayerno longer takes in theBlockRenderDispatcher
net.minecraft.client.renderer.entity.stateAvatarRenderState#scoreText->EntityRenderState#scoreTextBlockDisplayEntityRenderState#blockRenderState->blockModel, now aBlockModelRenderStateinstead of aBlockRenderStateCopperGolemRenderState#blockOnAntennanow aBlockModelRenderStateinstead of an optionalBlockStateEndermanRenderState#carriedBlocknow aBlockModelRenderStateinstead of a nullableBlockStateIronGolemRenderState#flowerBlock- The flower held by the iron golem.ItemFrameRenderState#frameModel- The model of the item frame block.MinecartRenderState#displayBlockState->displayBlockModel, now aBlockModelRenderStateinstead of aBlockStateMushroomCowRenderState#mushroomModel- The model of mushrooms attached to the cow.SnowGolemRenderState#hasPumpkin->headBlock, now aBlockModelRenderStateinstead of abooleanTntRenderState#blockStatenow aBlockModelRenderStateinstead of a nullableBlockState
net.minecraft.client.renderer.features- Feature
rendermethods have been split intorenderSolidfor solid render types, andrenderTranslucentfor see-through render types - Some
render*methods now take in theOptionsRenderState BlockFeatureRendererrenderSolidnow takes in theBlockStateModelSetinstead of theBlockRenderDispatcherrenderTranslucentnow takes in theBlockStateModelSetand the crumblingMultiBufferSource$BufferSourceinstead of theBlockRenderDispatcher
FeatureRenderDispatchernow takes in theGameRenderStateandModelManagerrenderAllFeatureshas been split intorenderSolidFeaturesandrenderTranslucentFeatures- The original method now calls both of these methods, first solid then translucent
clearSubmitNodes- Clears the submit node storage.renderTranslucentParticles- Renders collected translucent particles.
FlameFeatureRenderer#render->renderSolidLeashFeatureRenderer#render->renderSolidNameTagFeatureRenderer#render->renderTranslucentShadowFeatureRenderer#render->renderTranslucentTextFeatureRenderer#render->renderTranslucent
- Feature
net.minecraft.client.renderer.fogFogData#color- The color of the fog.FogRenderersetupFognow returns aFogDatainstead of theVector4ffog colorupdateBuffer- Updates the buffer with the fog data.
net.minecraft.client.renderer.gizmos.DrawableGizmoPrimitives#rendernow takes in aMatrix4fcinstead of aMatrix4ffor the model viewnet.minecraft.client.renderer.itemBlockModelWrapper->CuboidItemModelWrapper- The constructor no longer takes in the
RenderTypefunction, and now takes in theMatrix4fctransformation $Unbakednow takes in an optionalTransformation
- The constructor no longer takes in the
CompositeModel$Unbakednow takes in an optionalTransformationConiditionalItemModel$Unbakednow takes in an optionalTransformationItemModel$BakingContextmaterials->spritesmissingItem- Gets the missing item model with the givenMatrix4fctransformation.
$Unbaked#bakenow takes in theMatrix4fctransformation from any parent client items
ItemStackRenderStatepickParticleIcon->pickParticleMaterial, now returning aMaterial$Bakedinstead of aTextureAtlasSprite$LayerRenderStateEMPTY_TINTS- Anintarray representing no tints to apply.setRenderTypeis removedsetParticleIcon->setParticleMaterial, now taking aMaterial$Bakedinstead of aTextureAtlasSpritesetTransform->setItemTransformsetLocalTransform- Sets the client item transform that’s applied after item display transforms.prepareTintLayers->tintLayers, not one-to-one
MissingItemModel#withTransform- Gets a missing item model with the given transform.ModelRenderProperties#particleIcon->particleMaterial, now taking aMaterial$Bakedinstead of aTextureAtlasSpriteRangeSelectItemModel$Unbakednow takes in an optionalTransformationSelectItemModel$ModelSelector#getno longer supports nullableItemModels.$Unbakednow takes in an optionalTransformation$UnbakedSwitch#bakenow takes in theMatrix4fctransformation
SpecialModelWrappernow takes in theMatrix4fctransformation$Unbakednow takes in an optionalTransformation
net.minecraft.client.renderer.rendertypeRenderType#outputTarget- Gets the output target.RenderTypesMOVING_BLOCK_SAMPLERreplaced bycreateMovingBlockSetup, nowprivateentityCutoutNoCull->entityCutout- The original cutout with cull is replaced by
entityCutoutCull
- The original cutout with cull is replaced by
entityCutoutNoCullZOffset->entityCutoutZOffsetentitySmoothCutout->endCrystalBeamentityNoOutline->entityTranslucentwithaffectsOutlineasfalseentityDecal,dragonExplosionAlpha->entityCutoutDissolve, not one-to-oneitemEntityTranslucentCull->entityTranslucentCullItemTarget,itemCutout,itemTranslucent; not one-to-onebannerPattern- The render type for rendering the patterns of banners.
net.minecraft.client.renderer.specialBannerSpecialRenderer,$Unbakednow take in theBannerBlock$AttachmentType$Unbakednow usesBannerPatternLayersfor the generic
BedSpecialRenderer,$Unbakednow take in theBedPart$Unbakednow implementsNoDataSpecialModelRenderer$Unbaked
BellSpecialRenderer- A special renderer for the bell.BookSpecialRenderer- A special renderer for the book on the enchantment table.ChestSpecialRenderer$Unbakednow implementsNoDataSpecialModelRenderer$Unbaked- The constructor now takes in the
ChestType *_CHEST_TEXTUREis removed from the field name, now aMultiBlockChestResourcesENDER_CHEST_TEXTURE->ENDER_CHEST
- The constructor now takes in the
ConduitSpecialRenderer$Unbakednow implementsNoDataSpecialModelRenderer$UnbakedCopperGolemStatueSpecialRenderer$Unbakednow implementsNoDataSpecialModelRenderer$UnbakedDecoratedPotSpecialRenderer$Unbakednow usesPotDecorationsfor the genericEndCubeSpecialRenderer- A special renderer for the end portal cube.HangingSignSpecialRenderer$Unbakednow implementsNoDataSpecialModelRenderer$Unbaked- The constructor now takes in the
HangingSignBlock$Attachment
- The constructor now takes in the
NoDataSpecialModelRenderersubmitno longer takes in theItemDisplayContext$Unbaked- The unbaked renderer for a special model renderer not needing extracted data.
PlayerHeadSpecialRenderer$Unbakednow usesPlayerSkinRenderCache$RenderInfofor the genericShieldSpecialRendererDEFAULT_TRANSFORMATION- The default transformation to apply.$Unbakednow usesDataComponentMapfor the generic
ShulkerBoxSpecialRenderer,$Unbakedno longer takes in theDirectionorientation$Unbakednow implementsNoDataSpecialModelRenderer$Unbaked
SkullSpecialRenderer$Unbakednow implementsNoDataSpecialModelRenderer$UnbakedSpecialModelRenderersubmitno longer takes in theItemDisplayContext$BakingContextmaterials->sprites$Simplereplaced byBlockModel$BakingContext,ItemModel$BakingContextmaterials->sprites
$Unbakednow has the generic of the argument to extract from the representing object
SpecialModelRenderers#createBlockRenderers->BuiltInBlockModels#createBlockModels, not one-to-oneStandingSignSpecialRenderer$Unbakednow implementsNoDataSpecialModelRenderer$Unbaked- The constructor now takes in the
PlainSignBlock$Attachment
- The constructor now takes in the
TridentSpecialRendererDEFAULT_TRANSFORMATION- The default transformation to apply.$Unbakednow implementsNoDataSpecialModelRenderer$Unbaked
net.minecraft.client.renderer.state.*->.state.level.*net.minecraft.client.renderer.stateGameRenderState- The render state of the game.OptionsRenderState- The render state of the client user options.WindowRenderState- The render state of the game window.
net.minecraft.client.renderer.state.gui.GuiRenderState#submit*methods have been renamed toadd*net.minecraft.client.renderer.state.levelBlockBreakingRenderStateis now a record, and no longer extendsMovingBlockRenderState- The constructor takes in the
BlockPos,BlockState, and the currentintprogress
- The constructor takes in the
CameraEntityRenderState- The render state for the camera entity.CameraRenderStatexRot,yRot- The rotation of the camera.entityPosis removedisPanoramicMode- Whether the camera is in panorama mode.cullFrustum- The cull frustum.fogType,fogData- Fog metadata.hudFov- The hud field-of-view.depthFar- The depth Z far plane.projectionMatrix,viewRotationMatrix- The matrices for moving from world space to screen space.entityRenderState- The entity the camera is attached to.
LevelRenderStatelastEntityRenderStateCount- The number of entities being rendered to the screen.cloudColor,cloudHeight- Cloud metadata.
LightmapRenderState- The render state for the lightmap.
net.minecraft.client.renderer.textureMipmapGenerator#generateMipLevelsnow takes in the computedTransparencyof the imageSpriteContentstransparency- Gets the transparency of the sprite.getUniqueFramesnow returns anIntListinstaed of anIntStreamcomputeTransparency- Computes the transparency of the selected UV bounds.$AnimatedTexture#getUniqueFramesnow returns anIntListinstaed of anIntStream
TextureAtlasSprite#transparency- Gets the transparency of the sprite.
net.minecraft.client.resources.modelAtlasManager->.model.sprite.AtlasManagerBlockModelRotation->.client.renderer.block.dispatch.BlockModelRotationMaterial->.model.sprite.SpriteId, not one-to-oneMaterialSet->.model.sprite.SpriteGetterMissingBlockModel->.model.cuboid.MissingCuboidModelModelBakersprites->materialsparts->interner$PartCache->$Internervector(float, float, float)is removedmaterialInfo- Gets the interned material info object.
ModelBakeryBANNER_BASE->Sheets#BANNER_BASESHIELD_BASE->Sheets#SHIELD_BASENO_PATTERN_SHIELD->Sheets#SHIELD_BASE_NO_PATTERNLAVA_*->FluidStateModelSet#LAVA_MODEL, nowprivatefrompublicWATER_*->FluidStateModelSet#WATER_MODEL, nowprivatefrompublic$BakingResult#getBlockStateModel- Gets theBlockStateModelfrom theBlockState.$MissingModelsnow takes in aMissingItemModelinstead of anItemModelfor theItem, and aFluidModel
ModelManagerBLOCK_OR_ITEMis removedgetMissingBlockStateModel->BlockStateModelSet#missingModelgetBlockModelShaper->getBlockStateModelSet, not one-to-onegetBlockModelSet- Gets the map ofBlockStateto block model.specialBlockModelRendereris removedgetFluidStateModelSet- Gets the map ofFluidto fluid model.
ModelState->.client.renderer.block.dispatch.ModelStateQuadCollection->.model.geometry.QuadCollectionaddAll- Adds all elements from another quad collection.materialFlags,hasMaterialFlag- Handles the flags for the material(s) used by the model.
ResolvedModel#resolveParticleSprite->resolveParticleMaterial, now returning aMaterial$Bakedinstead of aTextureAtlasSpriteSpriteGetter->.model.sprite.MaterialBakerUnbakedGeometry->.model.geometry.UnbakedGeometryWeightedVariants->.client.renderer.block.dispatch.WeightedVariants
net.minecraft.client.resources.model.sprite.Material- A reference to a texture sprite, along with whether to force translucency on the texture.net.minecraft.world.entity.animal.Animal#isBrightEnoughToSpawnnow takes in aBlockAndLightGetterinstead of theBlockAndTintGetternet.minecraft.world.levelBlockAndTintGetter->BlockAndLightGetterBlockAndTintGetteris now client only, implementingBlockAndLightGettergetShade->cardinalLighting; not one-to-onegetBlockTint->BlockAndTintGetter#getBlockTint
CardinalLighting- Holds the lighting applied in each direction.EmptyBlockAndTintGetter->BlockAndTintGetter#EMPTYLevelReadernow implementsBlockAndLightGetterinstead ofBlockAndTintGetter
net.minecraft.world.level.blockBannerBlock$AttachmentType- Where the banner attaches to another block.CeilingHangingSignBlocknow implementsHangingSignBlockgetAttachmentPoint- Gets where the sign attaches to another block.
HangingSignBlock- An interface that defines a hanging sign attached to another block.PlainSignBlock- An inteface that defines a plain sign attached to another block.StandingSignBlocknow implementsPlainSignBlockWallingHangingSignBlocknow implementsHangingSignBlockWallSignBlocknow implementsPlainSignBlock
net.minecraft.world.level.block.state.BlockBehaviour#getLightBlock,$BlockStateBase#getLightBlock->getLightDampeningnet.minecraft.world.level.block.state.propertiesBedPart#CODEC- The codec for the bed part.ChestType#CODEC- The codec for the chest type.
net.minecraft.world.level.dimension.DimensionType$CardinalLightType->CardinalLighting$Type
Minor Migrations
The following is a list of useful or interesting additions, changes, and removals that do not deserve their own section in the primer.
Plantable Tags
The blocks to determine whether a plantable can survive or be placed on has been moved to block and fluid tags. Each of these tags starts with support_* along with the block (e.g., bamboo, cactus) or group (e.g., crops, dry_vegetation). This is handled by the relevant block subclasses overriding either Block#canSurvive, or for vegetation VegetationBlock#mayPlaceOn.
net.minecraft.world.level.blockAttachedStemBlocknow takes in aTagKeyfor the blocks it can be placed onFarmBlock->FarmlandBlockFungusBlock->NetherFungusBlock, not one-to-oneRootsBlock->NetherRootsBlock, not one-to-oneWaterlilyBlock->LilyPadBlock, not one-to-oneStemBlocknow takes in aTagKeyfor the blocks it can be placed on, and aTagKeyfor the blocks its fruit can be placed on
Container Screen Changes
The usage of AbstractContainerScreens has changed slightly, requiring some minor changes. First imageWidth and imageHeight are now final, settable as parameters within the constructor. If these two are not specified, they default to the original 176 x 166 background image.
// Assume some AbstractContainerMenu subclass exists
public class ExampleContainerScreen extends AbstractContainerScreen<ExampleContainerMenu> {
// Constructor
public ExampleContainerScreen(ExampleContainerMenu menu, Inventory playerInventory, Component title) {
// Specify image width and height as the last two parameters in the constructor
super(menu, playerInventory, title, 256, 256);
}
}
Additionally, the AbstractContainerScreen#render override now calls renderTooltip at the end of the call stack. This means that, in most cases, you should not override render in subtypes of the AbstractContainerScreen. Everything can be done in one of the other methods provided by the class.
net.minecraft.client.gui.screens.inventory.AbstractContainerScreennow optionally takes in the background image width and heightimageWidth,imageHeightare now finalDEFAULT_IMAGE_WIDTH,DEFAULT_IMAGE_HEIGHT- The default width and height of the container background image.slotClickednow takes is aContainerInputinstead of aClickTyperenderoverride now callsrenderTooltipby default
net.minecraft.world.inventoryAbstractContainerMenu#clickednow takes in aContainerInputinstead of aClickTypeClickType->ContainerInput
New Tag Providers
A new TagsProvider has been added that provides a utility for working with Holder$References, known as HolderTagProvider. This is only used by the PotionTagsProvider.
Additionally, the TagBuilder now provides a method of setting the replace field on a tag, which removes all previous read entries during deserialization.
net.minecraft.data.tagsFeatureTagsProvider- A tag provider forConfiguredFeatures.HolderTagProvider- A tag provider with a utility for appending tags by their reference holder.KeyTagProvider#tagnow has an overload of whether to replace the entries in the tag.PotionTagsProvider- A provider for potion tags.TradeRebalanceTradeTagsProvider- A provider for villager trade tags for the trade rebalance.VillagerTradesTagsProvider- A provider for villager trade tags.
net.minecraft.tagsFeatureTags- Tags forConfiguredFeatures.TagBuilder#shouldReplace,setReplace- Handles thereplacefield that removes all previously read entries during deserialization.
Test Environment State Tracking
TestEnvironmentDefinitions can now keep track of the original state of the world when being created, such that it can be properly restored on run. This is done through a generic known as the ‘SavedDataType’. On setup, each environment will return the generic data representing the original state of what was modified. Then, on teardown, the original state will be restored to the level for the next test case.
// The generic should represent the original data stored on the level
public record RespawnEnvironment(LevelData.RespawnData respawn) implements TestEnvironmentDefinition<LevelData.RespawnData> {
@Override
public LevelData.RespawnData setup(ServerLevel level) {
// Modify the level while logging the original state.
var original = level.getRespawnData();
level.setRespawnData(this.respawn);
// Return the original state.
return original;
}
@Override
public void teardown(ServerLevel level, LevelData.RespawnData original) {
// Reset the state of the level to the original values.
level.setRespawnData(original);
}
@Override
public MapCodec<RespawnEnvironment> codec() {
// Return the registered MapCodec here.
// ...
}
}
net.minecraft.gametest.framework.TestEnvironmentDefinitionnow has a generic representing the original state of the given modification performed by the test environmentsetupnow returns the generic representing the original stateteardownis no longer default, taking in the original state to restoreactivate,$Activation- Handles an active test environment.
Typed Instance
TypedInstance is an interface that is attached to certain objects that represent an instance of some other ‘type’ object. For example, and Entity is a typed instance of EntityType, or a BlockState is a typed instance of Block. This interface is meant as a standard method to provide access to the type Holder and check whether the backing type, and therefore the instance, is equivalent to some identifier, tag, or raw object via is.
// For some Entity entity, check the EntityType
entity.is(EntityType.PLAYER);
// For some ItemStack itemStack, check the Item
itemStack.is(ItemTags.BUTTONS);
// For some BlockEntity blockEntity, check the BlockEntityType
blockEntity.is(BlockEntityType.CHEST);
// For some BlockState blockState, check the Block
blockState.is(Blocks.DIRT);
// For some FluidState fluidState, check the Fluid
fluidState.is(FluidTags.WATER);
net.minecraft.core.TypedInstance- An interface that represents that this object is an instance for some other ‘type’ object.net.minecraft.world.entityEntitynow implementsTypedInstance<EntityType<?>>EntityType#is->TypedInstance#is- Now on the
Entityinstance
- Now on the
net.minecraft.world.item.ItemStacknow implementsTypedInstance<Item>getItemHolder->typeHoldergetTags->tags
net.minecraft.world.level.block.entityBlockEntitynow implementsTypedInstance<BlockEntityType>BlockEntityType#getKeyis removed
net.minecraft.world.level.block.state.BlockBehaviour$BlockStateBasenow implementsTypedInstance<Block>getBlockHolder->typeHoldergetTags->tags
net.minecraft.world.level.material.FluidStatenow implementsTypedInstance<Fluid>holder->typeHoldergetTags->tags
Entity Textures and Adult/Baby Models
Entity textures within assets/minecraft/textures/entity/* have now been sorted into subdirectories (e.g., entity/panda for panda textures, or entity/pig for pig textures). Most textures have been named with the entity type starting followed by an underscore along with its variant (e.g., arrow_tipped for tipped arrow, pig_cold for the cold pig variant, or panda_brown for the brown panda variant).
Additionally, some animal models have been split into separate classes for the baby and adult variants. These models either directly extend an abstract model implementation (e.g., AbstractFelineModel) or the original model class (e.g., PigModel).
net.minecraft.client.animation.definitionsBabyArmadilloAnimation- Animations for the baby armadillo.BabyAxolotlAnimation- Animations for the baby axolotl.BabyRabbitAnimation- Animations for the baby rabbit.CamelBabyAnimation- Animations for the baby camel.FoxBabyAnimation- Animations for the baby fox.RabbitAnimation- Animations for the rabbit.
net.minecraft.client.modelHumanoidModelADULT_ARMOR_PARTS_PER_SLOT,BABY_ARMOR_PARTS_PER_SLOT- A map of equipment slot to model part keys.createBabyArmorMeshSet- Creates the armor model set for a baby humanoid.createArmorMeshSetcan now take in a map of equipment slot to model part keys for what to retainsetAllVisibleis removed
QuadrupedModelnow has a constructor that takes in a function for theRenderType
net.minecraft.client.model.animal.armadilloAdultArmadilloModel- Entity model for the adult armadillo.ArmadilloModelis now abstract- The constructor now takes in the definitions for the walk, roll out/up, and peek animations
BABY_TRANSFORMERhas been directly merged into the layer definition for theBabyArmadilloModelHEAD_CUBE,RIGHT_EAR_CUBE,LEFT_EAR_CUBEare nowprotectedinstead ofprivatecreateBodyLayer->AdultArmadilloModel#createBodyLayer,BabyArmadilloModel#createBodyLayer
BabyArmadilloModel- Entity model for the baby armadillo.
net.minecraft.client.model.animal.axolotl.AxolotlModel->AdultAxolotlModel,BabyAxolotlModelnet.minecraft.client.model.animal.beeAdultBeeModel- Entity model for the adult bee.BabyBeeModel- Entity model for the baby bee.BeeModelis now abstractBABY_TRANSFORMERhas been directly merged into the layer definition for theBabyBeeModelBONE,STINGER,FRONT_LEGS,MIDDLE_LEGS,BACK_LEGSare nowprotectedinstead ofprivateboneis nowprotectedinstead ofprivatecreateBodyLayer->AdultBeeModel#createBodyLayer,BabyBeeModel#createBodyLayerbobUpAndDown- Bobs the bee up and down at the desired speed, depending on its current age.
net.minecraft.client.model.animal.camelAdultCamelModel- Entity model for the adult camel.BabyCamelModel- Entity model for the baby camel.CamelModelis now abstract- The constructor now takes in the definitions for the walk, sit with/without pose, standup, idle, and dash animations
BABY_TRANSFORMERhas been directly merged into the layer definition for theBabyCamelModelcreateBodyLayer->AdultCamelModel#createBodyLayer,BabyCamelModel#createBodyLayer
CameSaddleModelnow extendsAdultCamelModelinstead ofCamelModel
net.minecraft.client.model.animal.chickenAdultChickenModel- Entity model for the adult chicken.BabyChickenModel- Entity model for the baby chicken.ChickenModelis now abstractRED_THING->AdultChickenModel#RED_THINGBABY_TRANSFORMERhas been directly merged into the layer definition for theBabyChickenModelcreateBodyLayer->AdultChickenModel#createBodyLayercreateBaseChickenModel->AdultChickenModel#createBaseChickenModel
ColdChickenModelnow extendsAdultChickenModel
net.minecraft.client.model.animal.cow.BabyCowModel- Entity model for the baby cow.net.minecraft.client.model.animal.dolphin.BabyDolphinModel- Entity model for the baby dolphin.net.minecraft.client.model.animal.equineAbstractEquineModelnow has an overload that directly specifies theModelParts to useBABY_TRANSFORMERhas been directly merged into the layer definition for theBabyDonkeyModelrightHindLeg,leftHindLeg,rightFrontLeg,leftFrontLegare nowprotectedfromprivatecreateBabyMesh->BabyHorseModel#createBabyMesh, not one-to-oneoffsetLegPositionWhenStanding- Offsets the position of the legs when the entity is standing.getLegStandAngle,getLegStandingYOffset,getLegStandingZOffset,getLegStandingXRotOffset,getTailXRotOffset- Offsets and angles for parts of the equine model.animateHeadPartsPlacement- Animates the head based on its eating and standing states.
BabyDonkeyModel- Entity model for the baby donkey.BabyHorseModel- Entity model for the baby horse.DonkeyModelnow has an overload that directly specifies theModelParts to usecreateBabyLayer->BabyDonkeyModel#createBabyLayer
EquineSaddleModel#createFullScaleSaddleLayeris removed Merged intocreateSaddleLayer, with the baby variant removed
net.minecraft.client.model.animal.felineCatModel->AdultCatModel,BabyCatModel; not one-to-oneFelineModel->AbstractFelineModel, not one-to-one- Implementations in
AdultFelineModelandBabyFelineModel
- Implementations in
OcelotModel->AdultOcelotModel,BabyOcelotModel; not one-to-one
net.minecraft.client.model.animal.foxAdultFoxModel- Entity model for the adult fox.BabyFoxModel- Entity model for the baby fox.FoxModelis now abstractBABY_TRANSFORMERhas been directly merged into the layer definition for theBabyFoxModelbody,rightHindLeg,leftHindLeg,rightFontLeg,leftFrontLeg,tailare nowprotectedinstead ofprivatecreateBodyLayer->AdultFoxModel#createBodyLayer,BabyFoxModel#createBodyLayerset*Pose- Methods for setting the current pose of the fox.
net.minecraft.client.model.animal.goatBabyGoatModel- Entity model for the baby goat.GoatModel#BABY_TRANSFORMERhas been directly merged into the layer definition for theBabyGoatModel
net.minecraft.client.model.animal.llamaBabyLlamaModel- Entity model for the baby llama.LlamaModel#createBodyLayerno longer takes in thebooleanfor if the entity is a baby
net.minecraft.client.model.animal.pandaBabyPandaModel- Entity model for the baby panda.PandaModelBABY_TRANSFORMERhas been directly merged into the layer definition for theBabyPandaModelanimateSitting- Animates the panda sitting.
net.minecraft.client.model.animal.pig.BabyPigModel- Entity model for the baby pig.net.minecraft.client.model.animal.polarbearBabyPolarBearModel- Entity model for the baby polar bear.PolarBearModel#BABY_TRANSFORMERhas been directly merged into the layer definition for theBabyPolarBearModel
net.minecraft.client.model.animal.rabbitAdultRabbitModel- Entity model for the adult rabbit.BabyRabbitModel- Entity model for the baby rabbit.RabbitModelis now abstract- The constructor now takes in two animation definitions for the hop and idle head tilt
FRONT_LEGS,BACK_LEGS- The child name for the entity legs.LEFT_HAUNCH,RIGHT_HAUNCHare nowprotectedcreateBodyLayer->AdultRabbitModel#createBodyLayer,BabyRabbitModel#createBodyLayer; not one-to-one
net.minecraft.client.model.animal.sheepBabySheepModel- Entity model for the baby sheep.SheepModel#BABY_TRANSFORMERhas been directly merged into the layer definition for theBabySheepModel
net.minecraft.client.model.animal.snifferSnifferModel#BABY_TRANSFORMERhas been directly merged into the layer definition for theSniffletModelSniffletModel- Entity model for the baby sniffer.
net.minecraft.client.model.animal.squidBabySquidModel- Entity model for the baby squid.SquidModel#createTentacleNameis now protected from private
net.minecraft.client.model.animal.turtleAdultTurtleModel- Entity model for the adult turtle.BabyTurtleModel- Entity model for the baby turtle.TurtleModelis now abstract- The constructor can how take in the render type function
BABY_TRANSFORMERhas been directly merged into the layer definition for theBabyTurtleModelcreateBodyLayer->AdultTurtleModel#createBodyLayer,BabyTurtleModel#createBodyLayer
net.minecraft.client.model.animal.wolfAdultWolfModel- Entity model for the adult wolf.BabyWolfModel- Entity model for the baby wolf.WolfModelis now abstractModelPartfields are now all protectedcreateMeshDefinition->AdultWolfModel#createBodyLayer,BabyWolfModel#createBodyLayer; not one-to-oneshakeOffWater- Sets the body rotation when shaking off water.setSittingPose- Sets the sitting pose of the wolf.
net.minecraft.client.model.geomModelLayersCOLD_CHICKEN_BABYis removedCOLD_PIG_BABYis removedPIG_BABY_SADDLEis removedSHEEP_BABY_WOOL_UNDERCOATis removedWOLF_BABY_ARMORis removedDONKEY_BABY_SADDLEis removedHORSE_BABY_ARMORis removedHORSE_BABY_SADDLEis removedMULE_BABY_SADDLEis removedSKELETON_HORSE_BABY_SADDLEis removedUNDEAD_HORSE_BABY_ARMORis removedZOMBIE_HORSE_BABY_SADDLEis removedSTRIDER_BABY_SADDLEis removed
PartNames#WAIST- The waist part.
net.minecraft.client.model.monster.hoglinBabyHoglinModel- Entity model for the baby hoglin.HoglinModelBABY_TRANSFORMERhas been directly merged into the layer definition for theBabyHoglinModelheadis nowprotectedfromprivatecreateBabyLayer->BabyHoglinModel#createBodyLayer
net.minecraft.client.model.monster.piglinAbstractPiglinModelis now abstractleftSleeve,rightSleeve,leftPants,rightPants,jacketare removedADULT_EAR_ANGLE_IN_DEGREES,BABY_EAR_ANGLE_IN_DEGREES- The angle of the piglin ears.createMeshreplaced byAdultPiglinModel#createBodyLayer,AdultZombifiedPiglinModel#createBodyLayer,BabyPiglinModel#createBodyLayer,BabyZombifiedPiglinModel#createBodyLayercreateBabyArmorMeshSet- Create the armor meshes for the baby piglin model.getDefaultEarAngleInDegrees- Gets the default ear angle.
AdultPiglinModel- Entity model for the adult piglin.AdultZombifiedPiglinModel- Entity model for the adult zombified piglin.BabyPiglinModel- Entity model for the baby piglin.BabyZombifiedPiglinModel- Entity model for the baby zombified piglin.PiglinModelis now abstractZombifiedPiglinModelis now abstract
net.minecraft.client.model.monster.striderAdultStriderModel- Entity model for the adult strider.BabyStriderModel- Entity model for the baby strider.StriderModelis now abstractBABY_TRANSFORMERhas been directly merged into the layer definition for theBabyStriderModelrightLeg,leftLeg,bodyare nowprotectedfromprivateSPEED- The speed scalar of the movement animation.customAnimations- Additional animation setup.animateBristle- Animates the bristles of the strider.
net.minecraft.client.model.monster.zombieBabyDrownedModel- Entity model for the baby drowned.BabyZombieModel- Entity model for the baby zombie.BabyZombieVillagerModel- Entity model for the baby zombie villager.
net.minecraft.client.model.npcBabyVillagerModel- Entity model for the baby villager.VillagerModel#BABY_TRANSFORMERhas been directly merged into the layer definition for theBabyVillagerModel
net.minecraft.client.renderer.entityAxolotlRenderernow takes in anEntityModel<AxolotlRenderState>for its genericCamelHuskRenderernow extendsMobRendererinstead ofCamelRendererCamelRenderer#createCamelSaddleLayeris nowstaticCatRenderernow takes in anAbstractFelineModelfor its genericDonkeyRenderernow takes in anEquipmentClientInfo$LayerTypeandModelLayerLocationfor the saddle layer and model, and splits theDonkeyRenderer$Typeinto the adult type and baby type$TypeDONKEY_BABY- A baby variant of the donkey.MULE_BABY- A baby variant of the mule.
OcelotRenderernow takes in anAbstractFelineModelfor its genericUndeadHorseRenderernow takes in anEquipmentClientInfo$LayerTypeandModelLayerLocationfor the saddle layer and model, and splits theUndeadHorseRenderer$Typeinto the adult type and baby type$TypeSKELETON_BABY- A baby variant of the skeleton horse.ZOMBIE_BABY- A baby variant of the zombie horse.
net.minecraft.client.renderer.entity.layers.CatCollarLayernow takes in anAbstractFelineModelfor its genericnet.minecraft.client.renderer.entity.stateAxolotlRenderStateswimAnimation- The state of swimming.walkAnimationState- The state of walking on the ground, not underwater.walkUnderWaterAnimationState- The state of walking underwater.idleUnderWaterAnimationState- The state of idling underwater but not on the ground.idleUnderWaterOnGroundAnimationState- The state of idling underwater while touching the seafloor.idleOnGroundAnimationState- The state of idling on the ground, not underwater.playDeadAnimationState- The state of playing dead.
RabbitRenderStatehopAnimationState- The state of the hop the entity is performing.idleHeadTiltAnimationState- The state of the head tilt when performing the idle animation.
net.minecraft.client.resources.model.EquipmentClientInfo$LayerType#HUMANOID_BABY- The baby humanoid equipment layer.net.minecraft.sounds.SoundEvents#PIG_EAT_BABY- Ths sound played when a baby big is eating.net.minecraft.world.entity.AgeableMobcanUseGoldenDandelion- Whether a golden dandelion can be used to agelock an entity.setAgeLocked- Sets the entity as agelocked.makeAgeLockedParticle- Creates the particles when agelocking an entity.AGE_LOCK_DOWNWARDS_MOVING_PARTICLE_Y_OFFSET- The Y offset for the particle’s starting position.
net.minecraft.world.entity.animal.axolotl.AxolotlswimAnimation- The state of swimming.walkAnimationState- The state of walking on the ground, not underwater.walkUnderWaterAnimationState- The state of walking underwater.idleUnderWaterAnimationState- The state of idling underwater but not on the ground.idleUnderWaterOnGroundAnimationState- The state of idling underwater while touching the seafloor.idleOnGroundAnimationState- The state of idling on the ground, not underwater.playDeadAnimationState- The state of playing dead.$AnimationState->$AxolotlAnimationState
net.minecraft.world.entity.animal.chicken.ChickenVariantnow takes in a resource for the baby texturenet.minecraft.world.entity.animal.cow.CowVariantnow takes in a resource for the baby texturenet.minecraft.world.entity.animal.cat.CatVariantnow takes in a resource for the baby textureCatVariant#assetInfo- Gets the entity texture based on whether the entity is a baby.
net.minecraft.world.entity.animal.equine.AbstractHorse#BABY_SCALE- The scale of the baby size compared to an adult.net.minecraft.world.entity.animal.frog.TadpoleageLockParticleTimer- A timer for how long the particles for the agelocked entity should spawn.setAgeLocked,isAgeLocked- Handles agelocking for the tadpole.
net.minecraft.world.entity.animal.goat.GoatBABY_DEFAULT_X_HEAD_ROT- The default head X rotation for the baby variant.MAX_ADDED_RAMMING_X_HEAD_ROT- The maximum head X rotation.addHorns,removeHornsare removed
net.minecraft.world.entity.animal.pig.PigVariantnow takes in a resource for the baby texturenet.minecraft.world.entity.animal.rabbit.RabbithopAnimationState- The state of the hop the entity is performing.idleHeadTiltAnimationState- The state of the head tilt when performing the idle animation.
net.minecraft.world.entity.animal.wolfWolfSoundVariant->WolfSoundVariant$WolfSoundSet- The class itself now holds two sound sets for the adult wolf and baby wolf.
WolfSoundVariants$SoundSet#getSoundEventSuffix->getSoundEventIdentifier
net.minecraft.world.entity.animal.wolf.WolfVariantnow takes in an asset info for the baby variantnet.minecraft.world.item.equipment.EquipmentAssets#TRADER_LLAMA_BABY- Equipment asset for baby trader llamas.
The Removal of interactAt
Entity#interactAt has been removed, with all further invocation merged with Entity#interact. Originally, Entity#interactAt was called if the hit result was within the entity’s interaction range. If interactAt did not consume the action (i.e., InteractionResult#consumesAction returns false), then Entity#interact is called. Now, Entity#interact is called if within the entity’s interaction range, taking in the Vec3 location of interaction.
// In some Entity subclass
@Override
public InteractionResult interact(Player player, InteractionHand hand, Vec3 location) {
// Handle the interaction
super.interact(player, hand, location);
}
interactAt checks if result does not consume the interaction, and if not calls interact
Now, interact is called with the entity hit
net.minecraft.client.multiplayer.MultiPlayerGameModeinteractnow takes in theEntityHitResultinteractAtis removed
net.minecraft.world.entity.Entityinteractnow takes in aVec3for the location of the interactioninteractAtis removed
net.minecraft.world.entity.player.Player#interactOnnow takes in aVec3for the location of the interaction
ChunkPos, now a record
ChunkPos is now a record. The BlockPos constructor has been replaced by ChunkPos#containing while the packed long constructor has been replaced by ChunkPose#unpack.
net.minecraft.world.level.ChunkPosis now a recordChunkPos(BlockPos)->containingChunkPos(long)->unpacktoLong,asLong->pack
No More Tripwire Pipelines
The tripwire render pipeline has been completely removed. Now, tripwires make use of cutout with an alpha_cutoff_bias of 0.1 for the texture.
net.minecraft.client.renderer.RenderPipelines#TRIPWIRE_BLOCK,TRIPWIRE_TERRAINare removednet.minecraft.client.renderer.chunkChunkSectionLayer#TRIPWIREis removedChunkSectionLayerGroup#TRIPWIREis removed
net.minecraft.client.renderer.rendertype.RenderTypes#tripwireMovingBlockis removed
Activities and Brains
Activities, which define how a living entity behaves during a certain phase, now are stored and passed around through ActivityData. This contains the activity type, the behaviors to perform along with their priorities, the conditions on when this activity activates, and the memories to erase when the activity has stopped. Brain#provider now takes in an $ActivitySupplier to construct a list of ActivityData the entity performs.
Brains have also changed slightly. First, the Brain itself is not directly serializable. Instead, the brain is $Packed into the record, holding a map of its current memories. To get the memory types used, they are typically extracted from those that the Sensor#requires. Additionally, LivingEntity#brainProvider no longer exists, instead opting to store the provider in a static constant on the entity itself. This means that brains are now completely constructed through the makeBrain method, taking in the previous $Packed data:
// For some ExampleEntity extends LivingEntity
// Assume extends Mob subclass
private static final Brain.Provider<ExampleEntity> BRAIN_PROVIDER = Brain.provider(
// The list of sensors the entity uses.
ImmutableList.of(),
// A function that takes in the entity and returns a list of activities.
entity -> List.of(
new ActivityData(
// The activity type
Activity.CORE,
// A list of priority and behavior pairs
ImmutableList.of(Pair.of(0, new MoveToTargetSink())),
// A set of memory conditions for the activity to run
// For example, this memory value must be present
ImmutableSet.of(Pair.of(MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_PRESENT)),
// The set of memories to erase when the activity has stopped
ImmutableSet.of(MemoryModuleType.ATTACK_TARGET)
)
)
);
@Override
protected Brain.Provider<ExampleEntity> makeBrain(Brain.Packed packedBrain) {
// Make the brain, populating any previous memories
return BRAIN_PROVIDER.makeBrain(this, packedBrain);
}
net.minecraft.world.entity.LivingEntitybrainProvideris removedmakeBrainnow takes in aBrain$Packedinstead of aDynamic
net.minecraft.world.entity.aiActivityData- A record containing the activity being performed, the behaviors to perform during that activity, any memory conditions, and what memories to erase once stopped.Brainis now protected, taking in a list ofActivityData, aMemoryMapinstead of an immutable list of memories, aRandomSource, and not the suppliedCodec- The public constructor no longer takes in anything
providernow has an overload that only takes in the sensor types, defaulting the memory types to an empty list- Some
providermethods also take in theBrain$ActivitySupplierto perform
- Some
codec,serializeStartare replaced bypack,Brain$PackedaddActivityAndRemoveMemoryWhenStopped,addActivityWithConditionsmerged intoaddActivity- Alternatively use
ActivityData#create
- Alternatively use
copyWithoutBehaviorsis removedgetMemoriesreplaced byforEach$ActivitySupplier- Creates a list of activities for the entity.$MemoryValueis removed$Packed- A record containing the data to serialize the brain to disk.$Provider#makeBrainnow takes in the entity and theBrain$Packedto deserialize the memories$Visitor- Visits the memories within a brain, whether defined but empty, present, or present with some timer.
net.minecraft.world.entity.ai.behavior.VillagerGoalPackages#get*Packageno longer take in theVillagerProfessionnet.minecraft.world.entity.ai.memoryExpirableValue->MemorySlot, not one-to-one- The original
ExpirableValueis now a record that defines when a memory should expire, rather than be updated itself
- The original
MemoryMap- A map linking the memory type to its stored value.MemoryModuleType- Whether a memory can be serialized.
net.minecraf.tworld.entity.ai.sensing.Sensor#randomlyDelayStart- How long to delay a sensor.net.minecraft.world.entity.animal.allay.AllayAiSENSOR_TYPES,MEMORY_TYPES->BRAIN_PROVIDER, now private; not one-to-onemakeBrain->getActivities, not one-to-one
net.minecraft.world.entity.animal.armadillo.ArmadilloAi#makeBrain,brainProvider->getActivities, nowprotected, not one-to-onenet.minecraft.world.entity.animal.axolotlAxolotlSENSOR_TYPES->BRAIN_PROVIDER, now private; not one-to-oneAxolotlAimakeBrain->getActivities, not one-to-oneinitPlayDeadActivity, nowprotected, no longer taking in anythinginitFightActivity, nowprotected, no longer taking in anythinginitCoreActivity, nowprotected, no longer taking in anythinginitIdleActivity, nowprotected, no longer taking in anything
net.minecraft.world.entity.animal.camel.CamelAi#makeBrain,brainProvider->getActivities, nowprotected, not one-to-onenet.minecraft.world.entity.animal.frogFrog#SENSOR_TYPES->BRAIN_PROVIDER, now private; not one-to-oneFrogAi#makeBrain->getActivities, not one-to-oneTadpole#SENSOR_TYPES->BRAIN_PROVIDER, now private; not one-to-one
net.minecraft.world.entity.animal.frog.TadpoleAi#makeBrain->getActivities, nowpublic, not one-to-onenet.minecraft.world.entity.animal.goatGoat#SENSOR_TYPES->BRAIN_PROVIDER, now private; not one-to-oneGoatAi#makeBrain->getActivities, not one-to-one
net.minecraft.world.entity.animal.golem.CopperGolemAi#makeBrain,brainProvider->getActivities, nowprotected, not one-to-onenet.minecraft.world.entity.animal.happyghast.HappyGhastAi#makeBrain,brainProvider->getActivities, nowprotected, not one-to-onenet.minecraft.world.entity.animal.nautilusNautilusAiSENSOR_TYPES,MEMORY_TYPES->Nautilus#BRAIN_PROVIDER, now private, not one-to-onemakeBrain,brainProvider->getActivities, nowpublic, not one-to-one
ZombieNautilusAiSENSOR_TYPES,MEMORY_TYPES->ZombieNautilus#BRAIN_PROVIDER, now private, not one-to-onemakeBrain,brainProvider->getActivities, nowpublic, not one-to-one
net.minecraft.world.entity.animal.sniffer.SnifferAi#makeBrain->getActivities, nowpublic, not one-to-onenet.minecraft.world.entity.monster.ZoglinSENSOR_TYPES->BRAIN_PROVIDER, now private, not one-to-onegetActivities- The activities the zoglin performs.
net.minecraft.world.entity.monster.breeze.BreezeAi#makeBrain->getActivities, not one-to-onenet.minecraft.world.entity.monster.creaking.CreakingAi#makeBrain,brainProvider->getActivities, nowprotected, not one-to-onenet.minecraft.world.entity.monster.hoglinHoglin#SENSOR_TYPES->BRAIN_PROVIDER, now private; not one-to-oneHoglinAi#makeBrain->getActivities, not one-to-one
net.minecraft.world.entity.monster.piglinPiglin#SENSOR_TYPES,MEMORY_TYPES->BRAIN_PROVIDER, now private, not one-to-onePiglinAi#makeBrain->getActivities, nowpublic, not one-to-onePiglinBrute#SENSOR_TYPES,MEMORY_TYPES->BRAIN_PROVIDER, now private, not one-to-onePiglinBruteAi#makeBrain->getActivities, nowpublic, not one-to-one
net.minecraft.world.entity.monster.warden.WardenAi#makeBrain->getActivities, not one-to-one
File Fixer Upper
The file fixer upper is a new system to help with upgrading game files between versions, in conjunction with the data fixer upper. Similar to how the data within files can be modified or ‘upgraded’ between Minecraft versions via data fixers, file fixers can modify anything within a world directory, from moving files and directories to deleting them outright. As such, file fixers are always applied before data fixers.
Unlike when upgrading when data fixers, file fixers change the structure of the world folder. Because of this, downgrading is rarely possible, as the file names and locations will have likely changed location.
File fixers are applied through a FileFix, which defines some operation(s) to perform on a file using makeFixer. This is done typically through the addFileContentFix, providing access to the desired files through the FileAccess, and then modifying the data like any other Dynamic instance. Operations are commonly defined as FileFixOperations, which can move the file structure around.
The file fixes are then applied through the FileFixerUpper, which uses a copy-on-write file system to operate on the files. The fixer is constructed using the $Builder, using addSchema and addFixer to apply the fixers for the desired version. During the upgrade process, the files are created in a temporary folder, then moved to the world folder. The original world folder is moved to another folder before being deleted.
net.minecraft.client.gui.screens.FileFixerAbortedScreen- A screen that’s shown when the file fixing has been aborted.net.minecraft.client.gui.screens.worldselection.FileFixerProgressScreen- A screen that’s displayed when attempting to show the progress of upgrading and fixing the world files.net.minecraft.server.packs.linkfsDummyFileAttributes->.minecraft.util.DummyFileAttributesLinkFSPathDIRECTORY_ATTRIBUTES->DummyFileAttributes#DIRECTORYFILE_ATTRIBUTES->DummyFileAttributes#FILE
net.minecraft.utilExtraCodecspathCodec- A codec for a path, converting from a string and storing with Unix separators.relaiveNormalizedSubPathCodec- A codec for a path, normalized and validated to make sure it is relative.guardedPathCodec- A codec for a path, resolved and relativatized from some base path.
FileUtilisPathNormalized,createPathToResourceare removedisEmptyPath- Returns whether the path is empty.
Util#safeMoveFile- Safely moves a file from some source to a destination with the given options.
net.minecraft.util.filefixAbortedFileFixException- An exception thrown when the file fix has been aborted and was unable to revert moves.AtmoicMoveNotSupportedFileFixException- An exception thrown when the user file system does not support atomic moves.CanceledFileFixException- An exception thrown when the file fix upgrade proccess is canceled.FailedCleanupFileFixException- An exception thrown when the file fix was not able to move or delete folders for cleanup.FileFix- A fixer that performs some operation on a file.FileFixerUpper- The file fixers to perform operations with.FileFixException- An exception thrown when attempting to upgrade a world through the file fixer.FileFixUtil- A utility for performing some file operations.FileSystemCapabilities- The capabilities of the file system from a directory.
net.minecraft.util.filefix.accessChunkNbt- Handles upgrading a chunk nbt.CompressedNbt- Handles upgrading a compressed nbt file.FileAccess- Provides an reference to some file resource(s), given its relation.FileAccessProvider- A provider of file accesses, given some relation to the origin.FileRelation- A definition of how a file relates to some origin bpath.FileResourceType- Defines the type of resource to access.FileResourceTypes- All defined file resource types.LevelDat- Handles upgrading a level dat.PlayerData- Handles upgrading the player data.SavedDataNbt- Handles upgrading the saved data.
net.minecraft.util.filefix.fixes.*- The vanilla fixes to apply to the file(s).net.minecraft.util.filefix.operationsApplyInFolders- Applies the given operations within the related folders.DeleteFileOrEmptyDirectory- Deletes the target file or empty directory.FileFixOperation- An operation performed within some base directory.FileFixOperations- All vanilla file fix operations.GroupMove- Moves some directory, applying any move operation on its contents.ModifyContent- Modifies the content of a file.Move- Moves a file from some source to some destination.RegexMove- Moves all files that match the given source pattern to the destination, replacing the matched sections.
net.minecraft.util.filefix.virtualfilesystemCopyOnWriteFileStore- A file store using the copy-on-write principle.CopyOnWriteFileSystem- A file system using the copy-on-write principle.CopyOnWriteFSPath- A path using the copy-on-write principle.CopyOnWriteFSProvider- A file system provider using the copy-on-write principle.DirectoryNode- A directory node for some copy-on-write file system path.FileMove- A record containing the path a file has been moved from to.FileNode- A file node for some copy-on-write file system path.Node- A node for some copy-on-write file system path.
net.minecraft.util.filefix.virtualfilesystem.exceptionCowFSCreationException- ACowFSFileSystemExceptionwhen the file system cannot be created.CowFSDirectoryNotEmptyException- ADirectoryNotEmptyExceptionspecifically for a copy-on-write system.CowFSFileAlreadyExistsException- AFileAlreadyExistsExceptionspecifically for a copy-on-write system.CowFSFileSystemException- AFileSystemExceptionspecifically for a copy-on-write system.CowFSIllegalArgumentException- AnIllegalArgumentExceptionwhen attempting to operate upon a copy-on-write system.CowFSNoSuchFileException- ANoSuchFileExceptionspecifically for a copy-on-write system.CowFSNotDirectoryException- ANotDirectoryExceptionspecifically for a copy-on-write system.CowFSSymlinkException- ACowFSCreationExceptionwhen attempting to use the copy-on-write system with a symlink.
net.minecraft.util.worldupdateUpgradeProgressgetTotalFiles->getTotalFileFixState, not one-to-oneaddTotalFiles->addTotalFileFixOperations, not one-to-onegetTypeFileFixStats,getRunningFileFixerStats- Gets the fixer stats for the specific file group.incrementFinishedOperations,incrementFinishedOperationsBy- Increments the number of operations that have finished.setType,getType- Gets the type of the upgrade progress.setApplicableFixerAmount- Sets the total number of finished operations for the running file fixers.incrementRunningFileFixer- Increments the number of finished operations.logProgress- Logs the progress of the upgrade every second.$FileFixStats- A counter for the operations performed / finished.$Type- The type of upgrade being performed on the world data.
WorldUpgraderno longer takes in theWorldDataSTATUS_*messages have been combined inUpgradeStatusTranslator- This also contains the specific datafix type
running,finished,progress,totalChunks,totalFiles,converted,skipped,progressMap,statushave all been moved intoUpgradeProgress, stored inupgradeProgressgetProgress->getTotalProgress, not one-to-one$AbstractUpgrader,$SimpleRegionStorageUpgrader->RegionStorageUpgrader, no longer taking in the suppliedLegacyTagFixer, not one-to-one$ChunkUpgrader,$EntityUpgrader,$PoiUpgraderare now just constructed withinWorldUpgrader#work$Builder#setLegacyFixeris removed
$ChunkUpgrader#tryProcessOnePositionhas been partially abstracted intogetDataFixContentTag,verifyChunkPosAndEraseCache,verifyChunkPos$FileToUpgrade->FileToUpgrade
net.minecraft.world.level.ChunkPos#getRegionX,getRegionZ- Gets the region the chunk is in.net.minecraft.world.level.chunk.ChunkGenerator#getTypeNameForDataFixernow returns an optionalIdentifierinstead of aResourceKeynet.minecraft.world.level.chunk.storageLegacyTagFixerinterface is removedRecreatingSimpleRegionStorageno longer takes in the suppliedLegacyTagFixerSimpleRegionStorageno longer takes in the suppliedLegacyTagFixermarkChunkDoneis removed
net.minecraft.world.level.levelgen.structureLegacyStructureDataHandlerclass is removedStructureFeatureIndexSavedDataclass is removed
net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManagerSTRUCTURE_RESOURCE_DIRECTORY_NAME->STRUCTURE_DIRECTORY_NAME, not one-to-oneWORLD_STRUCTURE_LISTER,RESOURCE_TEXT_STRUCTURE_LISTER- Id converters for the structure nbts.savenow has an overload that takes in the path,StructureTemplate, andbooleanfor whether to write the data as textcreateAndValidatePathToGeneratedStructure->TemplatePathFactory#createAndValidatePathToStructure, not one-to-oneworldTemplates,testTemplates- The template path factories.
net.minecraft.world.level.levelgen.structure.templatesystem.loaderDirectoryTemplateSource- A template source for some directory.ResourceManagerTemplateSource- A template source for the resource manager.TemplatePathFactory- A factory that gets the path to some structure.TemplateSource- A loader for structure templates.
net.minecraft.world.level.storageLevelStorageSourcegetLevelDataAndDimensionsnow takes in the$LevelStorageAccessreadExistingSavedData- Reads any existing saved data.writeGameRules- Writes the game rules to the saved data.$LevelStorageAccess#releaseTemporarilyAndRun- Releases the access and runs before recreating the lock.collectIssues- Collects any issues when attempting to upgrade the data.getSummary->fixAndGetSummary,fixAndGetSummaryFromTag; not one-to-onegetDataTag->getUnfixedDataTag, not one-to-onegetDataTagFallback->getUnfixedDataTagWithFallback, not one-to-onesaveDataTagno longer takes in theRegistryAccesssaveLevelData- Saves the level dat.
LevelSummarynow takes in whether it requires file fixingUPGRADE_AND_PLAY_WORLD- A component telling the user to upgrade their world and play.requiresFileFixing- Whether the level requires file fixing.$BackupStatus#FILE_FIXING_REQUIRED- Whether file fixing is require to play this level on this version.
Chat Permissions
The chat system now has an associated set of permissions indicating what messages the player can send or receive. Permissions#CHAT_SEND_MESSAGES and CHAT_SEND_COMMANDS determine if the player can send messages or commands, respectively. Likewise, CHAT_RECEIVE_PLAYER_MESSAGES and CHAT_RECEIVE_SYSTEM_MESSAGES if the player can receive messages from other players or the system, respectively. Note that all of these permissions are only handled clientside and are not validated serverside.
net.minecraft.SharedConstants#DEBUG_CHAT_DISABLED- A flag that disables the chat box.net.minecraft.clientGuiMessage->.multiplayer.chat.GuiMessageGuiMessageTag->.multiplayer.chat.GuiMessageTagMinecraftgetChatStatus->computeChatAbilities, not one-to-one$ChatStatus->ChatRestriction, not one-to-one
net.minecraft.client.gui.Gui#setChatDisabledByPlayerShown,isShowingChatDisabledByPlayer- Handles whether the chat is disabled by the shown player.net.minecraft.client.gui.componentsChatComponentGO_TO_RESTRICTIONS_SCREEN- An identifier for redirecting to the restrictions screen.setVisibleMessageFilter- Sets the message filter function.render,captureClickableTextnow take in the$DisplayModeinstead of abooleanfor if the player is chattingaddMessageis now private- Split for use into
addClientSystemMessage,addServerSystemMessage,addPlayerMessage
- Split for use into
$DisplayMode- How the chat should be displayed.
CommandSuggestionsUSAGE_FORMAT,USAGE_OFFSET_FROM_BOTTOM,LINE_HEIGHT- Constants for showing the command suggestions.setRestrictions- Sets the restrictions of the messages that can be typed.hasAllowedInput- Whether the chat box can allow input.
net.minecraft.client.gui.screens.ChatScreen#USAGE_BACKGROUND_COLOR- The background color of the command suggestions box.net.minecraft.client.gui.screens.multiplayer.RestrictionsScreen- A screen for settings the restrictions of the player’s chat box.net.minecraft.client.gui.screens.reporting.ReportPlayerScreennow takes in abooleanfor if the chat is disabled or blockednet.minecraft.client.multiplayer.chatChatAbilities- The set of restrictions the player has on chatting with the chat box.ChatListenerhandleSystemMessagebooleanis now used for if the system is remote instead of overlay- The overlay is now handled through
handleOverlay
- The overlay is now handled through
GuiMessageSource- The source the message came from.
net.minecraft.client.player.LocalPlayernow takes in theChatAbilitieschatAbilities,refreshChatAbilities- Handles the chat abilities.
net.minecraft.server.permissions.PermissionsCHAT_SEND_MESSAGES- If the player can send chat messages.CHAT_SEND_COMMANDS- If the player can send commands.CHAT_RECEIVE_PLAYER_MESSAGES- If the player can receive other player messages.CHAT_RECEIVE_SYSTEM_MESSAGES- If the player can receive system messages.CHAT_PERMISSIONS- A set of available chat permissions.
net.minecraft.world.entity.player.Player#displayClientMessagesplit intosendSystemMessagewhen overlay message wasfalse, andsendOverlayMessagewhen the overlay message wastrue
More Entity Sound Variant Registries
Cats, chickens, cows, and pigs now have sound variants: a databack registry object that specifies the sounds an entity plays. This does not need to be directly tied to an actual entity variant, as it only defines the sounds an entity plays, typically during Mob#finalizeSpawn.
For cows:
// A file located at:
// - `data/examplemod/cow_sound_variant/example_cow_sound.json`
{
// The registry name of the sound event to play randomly on idle.
"ambient_sound": "minecraft:entity.cow.ambient",
// The registry name of the sound event to play when killed.
"death_sound": "minecraft:entity.cow.death",
// The registry name of the sound event to play when hurt.
"hurt_sound": "minecraft:entity.cow.hurt",
// The registry name of the sound event to play when stepping.
"step_sound": "minecraft:entity.cow.step"
}
For chickens and pigs:
// A file located at:
// - `data/examplemod/chicken_sound_variant/example_chicken_sound.json`
{
// The sounds played when an entity's age is greater than or equal to 0 (an adult).
"adult_sounds": {
// The registry name of the sound event to play randomly on idle.
"ambient_sound": "minecraft:entity.chicken.ambient",
// The registry name of the sound event to play when killed.
"death_sound": "minecraft:entity.chicken.death",
// The registry name of the sound event to play when hurt.
"hurt_sound": "minecraft:entity.chicken.hurt",
// The registry name of the sound event to play when stepping.
"step_sound": "minecraft:entity.chicken.step"
},
// The sounds played when an entity's age is less than 0 (a baby).
"baby_sounds": {
"ambient_sound": "minecraft:entity.baby_chicken.ambient",
"death_sound": "minecraft:entity.baby_chicken.death",
"hurt_sound": "minecraft:entity.baby_chicken.hurt",
"step_sound": "minecraft:entity.baby_chicken.step"
}
}
For pigs:
// A file located at:
// - `data/examplemod/pig_sound_variant/example_pig_sound.json`
{
// The sounds played when an entity's age is greater than or equal to 0 (an adult).
"adult_sounds": {
// The registry name of the sound event to play randomly on idle.
"ambient_sound": "minecraft:entity.pig.ambient",
// The registry name of the sound event to play when killed.
"death_sound": "minecraft:entity.pig.death",
// The registry name of the sound event to play when eating.
"eat_sound": "minecraft:entity.pig.eat",
// The registry name of the sound event to play when hurt.
"hurt_sound": "minecraft:entity.pig.hurt",
// The registry name of the sound event to play when stepping.
"step_sound": "minecraft:entity.pig.step"
},
// The sounds played when an entity's age is less than 0 (a baby).
"baby_sounds": {
"ambient_sound": "minecraft:entity.baby_pig.ambient",
"death_sound": "minecraft:entity.baby_pig.death",
"eat_sound": "minecraft:entity.baby_pig.eat",
"hurt_sound": "minecraft:entity.baby_pig.hurt",
"step_sound": "minecraft:entity.baby_pig.step"
}
}
For cats:
// A file located at:
// - `data/examplemod/cat_sound_variant/example_cat_sound.json`
{
// The sounds played when an entity's age is greater than or equal to 0 (an adult).
"adult_sounds": {
// The registry name of the sound event to play randomly on idle when tamed.
"ambient_sound": "minecraft:entity.cat.ambient",
// The registry name of the sound event to play when non-tamed and tempted by food.
"beg_for_food_sound": "minecraft:entity.cat.beg_for_food",
// The registry name of the sound event to play when killed.
"death_sound": "minecraft:entity.cat.death",
// The registry name of the sound event to play when fed.
"eat_sound": "minecraft:entity.cat.eat",
// The registry name of the sound event to play when hissing, typically at a pursuing phantom.
"hiss_sound": "minecraft:entity.cat.hiss",
// The registry name of the sound event to play when hurt.
"hurt_sound": "minecraft:entity.cat.hurt",
// The registry name of the sound event to play when purring, typically when in love or lying down.
"purr_sound": "minecraft:entity.cat.purr",
// The registry name of the sound event to play randomly on idle when tamed 25% of the time.
"purreow_sound": "minecraft:entity.cat.purreow",
// The registry name of the sound event to play randomly on idle when not tamed.
"stray_ambient_sound": "minecraft:entity.cat.stray_ambient"
},
// The sounds played when an entity's age is less than 0 (a baby).
"baby_sounds": {
"ambient_sound": "minecraft:entity.baby_cat.ambient",
"beg_for_food_sound": "minecraft:entity.baby_cat.beg_for_food",
"death_sound": "minecraft:entity.baby_cat.death",
"eat_sound": "minecraft:entity.baby_cat.eat",
"hiss_sound": "minecraft:entity.baby_cat.hiss",
"hurt_sound": "minecraft:entity.baby_cat.hurt",
"purr_sound": "minecraft:entity.baby_cat.purr",
"purreow_sound": "minecraft:entity.baby_cat.purreow",
"stray_ambient_sound": "minecraft:entity.baby_cat.stray_ambient"
}
}
net.minecraft.core.registries.RegistriesCAT_SOUND_VARIANT- The registry key for the sounds a cat should make.CHICKEN_SOUND_VARIANT- The registry key for the sounds a chicken should make.COW_SOUND_VARIANT- The registry key for the sounds a cow should make.PIG_SOUND_VARIANT- The registry key for the sounds a pig should make.
net.minecraft.network.synched.EntityDataSerializersCAT_SOUND_VARIANT- The entity serializer for the sounds a cat should make.CHICKEN_SOUND_VARIANT- The entity serializer for the sounds a chicken should make.COW_SOUND_VARIANT- The entity serializer for the sounds a cow should make.PIG_SOUND_VARIANT- The entity serializer for the sounds a pig should make.
net.minecraft.sounds.SoundEventsCAT_*sounds are now eitherHolder$References or stored in the map ofCAT_SOUNDSCHICKEN_*sounds are now eitherHolder$References or stored in the map ofCHICKEN_SOUNDSCOW_*sounds are stored in the map ofCOW_SOUNDSPIG_*sounds are now eitherHolder$References or stored in the map ofPIG_SOUNDS
net.minecraft.world.entity.animal.chickenChickenSoundVariant- The sounds that are played for a chicken variant.ChickenSoundVariants- All vanilla chicken variants.
net.minecraft.world.entity.animal.cowAbstractCow#getSoundSet- Gets the sounds a cow makes.CowSoundVariant- The sounds that are played for a cow variant.CowSoundVariants- All vanilla cow variants.
net.minecraft.world.entity.animal.felineCatSoundVariant- The sounds that are played for a cat variant.CatSoundVariants- All vanilla cat variants.
net.minecraft.world.entity.animal.chickenChickenSoundVariant- The sounds that are played for a chicken variant.ChickenSoundVariants- All vanilla chicken variants.
net.minecraft.world.entity.animal.pigPigSoundVariant- The sounds that are played for a pig variant.PigSoundVariants- All vanilla pig variants.
Audio Changes
Audio devices are now handled through the DeviceTracker which, depending on the backing machine, allows for either the machine to send system events when audio devices change, or using a standard polling interval to requery the list of available devices.
com.mojang.blaze3d.audioAbstractDeviceTracker- An abstract tracker for managing the changes of audio devices.CallbackDeviceTracker- A device tracker that uses the SOFT system events callback to determine changes.DeviceList- A list of all audio devices, including the default device, if available.DeviceTracker- An interface for managing the changes of audio devices.LibraryNO_DEVICEis nowpublicfromprivateinitnow takes in theDeviceListgetDefaultDeviceNamemoved toDeviceList#defaultDevicegetCurrentDeviceName->currentDeviceNamehasDefaultDeviceChangedmoved toAbstractDeviceTracker, not one-to-onegetAvailableSoundDevicesmoved toDeviceList, not one-to-onecreateDeviceTracker- Creates the tracker for managing audio device changes.getDebugString->getChannelDebugString
PollingDeviceTracker- A device tracker that uses polling intervals to determine changes.SoundBufferformat- The format of the sound stream.size- The number of bytes in the sound stream.isValid- If the sound stream is in a valid state.
net.minecraft.client.OptionsDEFAULT_SOUND_DEVICEis nowprivatefrompublicisSoundDeviceDefault- Checks if the device is the default audio device.
net.minecraft.client.gui.components.debugDebugEntrySoundCache- A debug entry displaying the current cache for loaded sound streams.DebugScreenEntries#SOUND_CACHE- The identifier for the sound stream cache debug information.
net.minecraft.client.soundsSoundBufferLibraryenumerate- Loops through all cached sounds, outputting its id, size, and format.$DebugOutput- An interface that accepts some sound metadata.$Counter- An output implementation that keepts track of the number of sound streams and the total size.
SoundEnginegetDebugString->getChannelDebugString,getSoundCacheDebugStats; not one-to-one$DeviceCheckStateis removed
SoundManager#getDebugString->getChannelDebugString,getSoundCacheDebugStats; not one-to-one
Input Message Editor Support
Minecraft now has support for Input Message Editors (IME), which allow complex characters from languages like Chinese or Hindi to be inputted instead of the temporary preedit text. The preedit text is displayed as an overlay within the game, while any other IME features provided by the host OS. With this addition, support can be added within screens through GuiEventListener#preeditUpdated, or by using an existing vanilla widget which implements the method.
com.mojang.blaze3d.platformInputConstants#setupKeyboardCallbacksnow takes in theGLFWCharCallbackIinstead ofGLFWCharModsCallbackIfor the character typed callback,GLFWPreeditCallbackIto handle inputting complex characters via an input method editor, andGLFWIMEStatusCallbackIfor notifying about the status of the editorMessageBox- A utility for creating OS native messages boxes.TextInputManager- A manager for handling when text is inputted in the game window.setTextInputArea- Sets the area where the predicted text cursor should appear.startTextInput,stopTextInput- Handles toggling the input message editor.
net.minecraft.clientKeyboardHandlerresubmitLastPreeditEvent- Repeats the last preedit event that was sent.submitPreeditEvent- Tells the listener that the preedit text has been updated.
MinecrafttextInputManager- Returns the input manager.onTextInputFocusChange- Changes the editor input status based on if the text input is focused.
net.minecraft.client.gui.GuiGraphicssetPreeditOverlay- Sets the overlay drawing the preedit text.renderDeferredElementsnow takes in theints for the mouse position and the game time delta ticksfloat
net.minecraft.client.gui.componentsIMEPreeditOverlay- The overlay for displaying the preedit text for an input message editor.TextCursorUtils- A utility for drawing the text cursor.
net.minecraft.client.gui.components.events.GuiEventListener#preeditUpdated- Listens for when the preedit text changes.net.minecraft.client.inputCharacterEventno longer takes in the modifierintsetPreeditEvent- An event containing the preedit text along with the cursor location.
Cauldron Interaction Dispatchers
Cauldron interactions have been reorganized somewhat, with all registration being moved to CauldronInteractions from CauldronInteraction. In addition, the backing $InteractionMap for a cauldron type has been replaced with a $Dispatcher that can register interactions for both tags and items. Tags are checked before items.
CauldronInteractions.EMPTY.put(
// The Item or TagKey to use
ItemTags.WOOL,
// The cauldron interaction to apply
(state, level, pos, player, hand, itemInHand) -> InteractionResult.TRY_WITH_EMPTY_HAND
);
net.minecraft.core.cauldronCauldronInteraction- All fields regarding to registering interactions to a map have been moved to
CauldronInteractionsINTERACTIONS->CauldronInteractions#ID_MAPPER, nowprivate
DEFAULT- The default interaction with a cauldron$InteractionMap->$Dispatcher, not one-to-one
- All fields regarding to registering interactions to a map have been moved to
CauldronInteractions- All vanilla cauldron interactions.
Rule-Based Block State Providers
RuleBasedStateProvider now extends BlockStateProvider, allowing it to be used wherever a state provider is required. It’s implementation hasn’t changed, now only requiring rule_based_state_provider to be specified as the type. As such, all configurations that used RuleBasedBlockStateProvider have been broadened to allow any BlockStateProvider.
net.minecraft.world.level.levelgen.feature.configurationsDiskConfigurationnow takes in aBlockStateProviderinstead of aRuleBasedBlockStateProviderTreeConfigurationnow takes in aBlockStateProviderinstead of aRuleBasedBlockStateProviderbelowTrunkProvideris now aBlockStateProviderinstead of aRuleBasedBlockStateProvider$TreeConfigurationBuildernow takes in aBlockStateProviderinstead of aRuleBasedBlockStateProvider
net.minecraft.world.level.levelgen.feature.stateprovidersBlockStateProvider#getOptionalState- Gets the state of the block, or otherwisenull.BlockStateProviderType#RULE_BASED_STATE_PROVIDER- The type for the rule based state provider.RuleBasedBlockStateProvider->RuleBasedStateProvider, now a class, implementingBlockStateProvider- The constructor can now take in a nullable fallback
BlockStateProvider ifTrueThenProvide- If the predicate is true, provide the given block.simple->always$Builder- A builder for constructing the rules for the block to place.
- The constructor can now take in a nullable fallback
Fluid Logic Reorganization
Generic entity fluid movement has been moved into a separate EntityFluidInteraction class, where all tracked fluids are updated and then potentially pushed by the current at a layer time.
net.minecraft.world.entityEntityupdateInWaterStateAndDoFluidPushing->updateFluidInteraction, not one-to-oneupdateFluidHeightAndDoFluidPushing->EntityFluidInteraction#updategetFluidInteractionBox- Gets the bounding box of the entity during fluid interactions.modifyPassengerFluidInteractionBox- Returns the modified bounding box of the entity when riding in some vehicle.
EntityFluidInteraction- A handler for managing the fluid interactions and basic movement with an entity.
net.minecraft.world.level.chunk.LevelChunkSection#hasFluid- Whether the chunk section has a fluid block.
Removal of Random Patch Feature
The random patch feature has been completely removed in favor of using placements like most other features. To convert, the ConfiguredFeature defined as part of the configuration should be its own file. Then, the placements should specify the CountPlacement, followed by the RandomOffsetPlacement using a TrapezoidInt, and finished with a BlockPredicateFilter:
// In `data/examplemod/worldgen/configured_feature/example_configured_feature.json`
{
// Previously config.feature.feature
"type": "minecraft:simple_block",
"config": {
"to_place": {
"type": "minecraft:simple_state_provider",
"state": {
"Name": "minecraft:sweet_berry_bush",
"Properties": {
"age": "3"
}
}
}
}
}
// In `data/examplemod/worldgen/placed_feature/example_placed_feature.json`
{
"feature": "examplemod:example_configured_feature",
"placement": [
{
// Previously config.tries
"type": "minecraft:count",
"count": 96
},
{
"type": "minecraft:random_offset",
"xz_spread": {
// Previously config.xz_spread
// The min and max are additive inverses
"type": "minecraft:trapezoid",
"max": 7,
"min": -7,
"plateau": 0
},
"y_spread": {
// Previously config.y_spread
"type": "minecraft:trapezoid",
"max": 3,
"min": -3,
"plateau": 0
}
},
{
// Previously config.feature.placement
// This contains the placements of the original placed feature
"type": "minecraft:block_predicate_filter",
"predicate": {
"type": "minecraft:all_of",
"predicates": [
{
"type": "minecraft:matching_block_tag",
"tag": "minecraft:air"
},
{
"type": "minecraft:matching_blocks",
"blocks": "minecraft:grass_block",
"offset": [ 0, -1, 0 ]
}
]
}
}
]
}
net.minecraft.data.worldgen.featuresFeatureUtils#simpleRandomPatchConfiguration,simplePatchConfigurationare removed- Typically replaced by
Feature#SIMPLE_BLOCKwith placements for random offset and filters
- Typically replaced by
NetherFeatures#PATCH_*fields no longer has thePATCH_*prefixVegetationFeaturesPATCH_*fields no longer has thePATCH_*prefixWILDFLOWERS_BIRCH_FOREST,WILDFLOWERS_MEADOW->WILDFLOWER, not one-to-onePALE_FOREST_FLOWERS->PALE_FOREST_FLOWER
net.minecraft.world.level.biome.BiomeGenerationSettings#getFlowerFeatures->getBoneMealFeaturesnet.minecraft.world.level.levelgen.featureConfiguredFeature#getFeatures->getSubFeatures, now returning a stream of holders-wrappedConfiguredFeatures without this featureFeatureFLOWER,NO_BONEMEAL_FLOWERare removedRANDOM_PATCHis removed
RandomPatchFeatureclass is removed
net.minecraft.world.level.levelgen.feature.configurationsFeatureConfiguration#getFeatures->getSubFeatures, now returning a stream of holders-wrappedConfiguredFeaturesRandomPatchConfigurationrecord is removed
net.minecraft.world.level.levelgen.placement.PlacedFeature#getFeaturesnow returns a stream of holders-wrappedConfiguredFeatures with this feature concatenated
Specific Logic Changes
- Picture-In-Picture submission calls are now taking in
0xF000F0instead of0x000000for the light coordinates. net.minecraft.client.multiplayer.RegistryDataCollector#collectGameRegistriesbooleanparameter now handles only updating components from synchronized registries along with tags.net.minecraft.client.renderer.RenderPipelines#VIGNETTEnow blends the alpha with a source of zero and a destination of one.net.minecraft.server.packs.PathPackResources#getResource,listPath,listResourcesresolves the path using the identifier’s namespace first.net.minecraft.world.entity.EntitySelector#CAN_BE_PICKEDcan now find entities in spectator mode, assumingEntity#isPickableis true.net.minecraft.world.entity.ai.sensing.NearestVisibleLivingEntitySensor#requiresis no longer implemented by default.net.minecraft.world.level.levelgen.WorldOptions#generate_featuresfield in JSON has been renamed togenerate_structuresto match its java field name.net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate#ONLY_IN_AIR_PREDICATEnow matches the air tag instead of just the air block.net.minecraft.world.level.timersFunctionCallback,FunctionTagCallbacknow useidinstead ofNamewhen serializingTimerCallbacksnow usestypeinstead ofTypewhen serializing
Data Component Additions
dye- Sets the item as a dye material, used in specific circumstances.additional_trade_cost- A modifier that offsets the trade cost by the specified amount.pig/sound_variant- The sounds a pig should make.cow/sound_variant- The sounds a cow should make.chicken/sound_variant- The sounds a chicken should make.cat/sound_variant- The sounds a cat should make.
Environment Attribute Additions
visual/block_light_tint- Tints the color of the light emitted by a block.visual/night_vision_color- The color when night vision is active.visual/ambient_light_color- The color of the ambient light in an environment.
Tag Changes
minecraft:blockbamboo_plantable_on->supports_bamboomushroom_grow_block->overrides_mushroom_light_requirementsmall_dripleaf_placeable->supports_small_dripleafbig_dripleaf_placeable->supports_big_dripleafdry_vegetation_may_place_on->supports_dry_vegetationsnow_layer_cannot_survive_on->cannot_support_snow_layersnow_layer_can_survive_on->support_override_snow_layerenables_bubble_column_drag_downenables_bubble_column_push_upsupports_vegetationsupports_cropssupports_stem_cropssupports_stem_fruitsupports_pumpkin_stemsupports_melon_stemsupports_pumpkin_stem_fruitsupports_melon_stem_fruitsupports_sugar_canesupports_sugar_cane_adjacentlysupports_cactussupports_chorus_plantsupports_chorus_flowersupports_nether_sproutssupports_azaleasupports_warped_fungussupports_crimson_fungussupports_mangrove_propagulesupports_hanging_mangrove_propagulesupports_nether_wartsupports_crimson_rootssupports_warped_rootssupports_wither_rosesupports_cocoasupports_lily_padsupports_frogspawnsupport_override_cactus_flowercannot_support_seagrasscannot_support_kelpgrows_cropsmudmoss_blocksgrass_blockssubstrate_overworldbeneath_tree_podzol_replaceablebeneath_bamboo_podzol_replaceablecannot_replace_below_tree_trunkice_spike_replaceableforest_rock_can_place_onhuge_brown_mushroom_can_place_onhuge_red_mushroom_can_place_onprevents_nearby_leaf_decay
minecraft:enchantmenttrades/desert_specialis removedtrades/jungle_specialis removedtrades/plains_specialis removedtrades/savanna_specialis removedtrades/snow_specialis removedtrades/swamp_specialis removedtrades/taiga_specialis removed
minecraft:entity_typecannot_be_age_locked
minecraft:fluidsupports_sugar_cane_adjacentlysupports_lily_padsupports_frogspawnbubble_column_can_occupy
minecraft:itemmetal_nuggetsdyeableis removed, split between:dyesloom_dyesloom_patternscauldron_can_remove_duecat_collar_dyeswolf_collar_dyes
mudmoss_blocksgrass_blocks
minecraft:potiontradable
minecraft:worldgen/configured_featurecan_spawn_from_bone_meal
List of Additions
net.minecraft.advancements.criterionFoodPredicate- A criterion predicate that can check the food level and saturation.MinMaxBoundsvalidateContainedInRange- Returns a function which validates the target range and returns as a data result.$Bounds#asRange- Converts the bounds into aRange.
net.minecraft.clientMinecraft#sendLowDiskSpaceWarning- Sends a system toast for low disk space.Options#keyDebugLightmapTexture- A key mapping to show the lightmap texture.
net.minecraft.client.gui.componentsAbstractScrollAreascrollbarWidth- The width of the scrollbar.defaultSettings- Constructs the default scrollbar settings given the scroll rate.$ScrollbarSettings- A record containing the metadata for the scrollbar.
DebugScreenOverlayshowLightmapTexture- Whether to render the lightmap texture on the overlay.toggleLightmapTexture- Toggles whether the lightmap texture should be rendered.
ScrollableLayoutsetMinHeight- Sets the minimum height of the container layout.$ReserveStrategy- What to use when reserving the width of the scrollbar within the layout.
Tooltipcomponent- The component of a tooltip to display.style- The identifier used to compute the tooltip background and frame.
net.minecraft.client.gui.components.debugDebugEntryDetailedMemory- A debug entry displaying the detailed memory usage.DebugEntryLookingAt#getHitResult- Gets the hit result of the camera entity.DebugEntryLookingAtEntityTags- A debug entry for displaying an entity’s tags.DebugScreenEntriesDETAILED_MEMORY- The identifier for the detailed memory usage debug entry.LOOKING_AT_ENTITY_TAGS- The identifier for the entity tags debug entry.
net.minecraft.client.gui.navigation.FocusNavigationEvent$ArrowNavigation#with- Sets the previous focus of the navigation.net.minecraft.client.gui.screens.GenericWaitingScreene#createWaitingWithoutButton- Creates a waiting screen without showing the button to cancel.net.minecraft.client.gui.screens.optionsDifficultyButtons- A class containing the layout element to create the difficulty buttons.HasGamemasterPermissionReaction- An interface marking an option screen as able to respond to changing gamemaster permissions.OptionsScreen#getLastScreen- Returns the previous screen that navigated to this one.WorldOptionsScreen- A screen containing the options for the current world the player is in.
net.minecraft.client.gui.screens.worldselection.EditWorldScreen#conditionallyMakeBackupAndShowToast- Only makes the backup and shows a toast if the passed inbooleanis true; otherwise, returns afalsefuture.net.minecraft.client.multiplayer.MultiPlayerGameMode#spectate- Sends a packet to the server that the player will spectate the given entity.net.minecraft.client.multiplayer.prediction.BlockStatePredictionHandler#onTeleport- Runs when a player is moved on the server, typically from some kind of teleportation (e.g. commands, riding an entity).net.minecraft.client.rendererLightmapRenderStateExtractor- Extracts the render state for the lightmap.UiLightmap- The lightmap when in a user interface.RenderPipelinesLINES_DEPTH_BIAS- A render pipeline that sets the polygon depth offset factor to -1 and the units to -1.ENTITY_CUTOUT_DISSOLVE- A render pipeline that dissolves an entity model into the background using a mask sampler.
net.minecraft.client.renderer.rendertype.RenderType#hasBlending- Whether the pipeline has a defined blend function.net.minecraft.commands.ArgumentVisitor- A helper for visiting the arguments for a command.net.minecraft.commands.arguments.selector.EntitySelector#COMPILABLE_CODEC- ACompilableStringcodec wrapped around anEntitySelectorParser.net.minecraft.core.component.predicatesDataComponentPredicates#VILLAGER_VARIANT- A predicate that checks a villager type.VillagerTypePredicate- A predicate that checks a villager’s type.
net.minecraft.core.dispenser.SpawnEggItemBehavior- The dispenser behavior for spawn eggs.net.minecraft.core.registries.ConcurrentHolderGetter- A getter that reads references from a local cache, synchronizing to the original when necessary.net.minecraft.dataBlockFamiliesEND_STONE- A family for end stone variants.getFamily- Gets the family for the base block, when present.
BlockFamily$Builder#tiles,$Variant#TILES- The block that acts as the tiles variant for some base block.$Builder#bricks,$Variant#BRICKS- The block that acts as the bricks variant for some base block.$Builder#cobbled,$Variant#COBBLED- The block that acts as the cobbled variant from some base block.
DataGenerator$Uncached- A data generator which does not cache any information about the files generated.
net.minecraft.data.recipes.RecipeProviderbricksBuilder,tilesBuilder- Builders for the bricks and tiles block variants.generateCraftingRecipe,generateStonecutterRecipe- Generates the appropriate recipes for the given block family.getBaseBlock->getBaseBlockForCraftingbredAnimal- Unlocks the recipe if the player has bred two animals together.
net.minecraft.gametest.frameworkGameTestEvent#createWithMinimumDelay- Creates a test event with some minimum delay.GameTestHelpergetBoundsWithPadding- Gets the bounding box of the test area with the specified padding.runBeforeTestEnd- Runs the runnable at one tick before the test ends.despawnItem- Despawns all item entities within the distance of the position.discard- Discards the entity.setTime- Sets the time of the dimension’s default clock.placeBlock- Places the given block at the relative position and direction.
GameTestInstance#padding- The number of blocks spaced around each game test.GameTestSequence#thenWaitAtLeast- Waits for at least the specified number of ticks before running the runnable.
net.minecraft.nbt.TextComponentTagVisitor$PlainStyling- A styling that stores the nbt in a component literal map.$RichStyling- A styling that stores the nbt with syntax highlighting and formatting.$Styling- An interface defining how the read tag should be styled.$Token- The tokens used to more richly represent the tag datas.
net.minecraft.network.chat.ResolutionContext- The context that the component is being resolved to a string within.net.minecraft.network.chat.contents.NbtContents#NBT_PATH_CODEC- ACompilableStringcodec wrapped around aNbtPathArgument$NbtPath.net.minecraft.network.chat.contents.data.BlockDataSource#BLOCK_POS_CDEC- ACompilableStringcodec wrapped aroundCoordinates.net.minecraft.network.protocol.gameClientboundGameRuleValuesPacket- A packet that sends the game rule values in string form to the client.ClientboundGamePacketListener#handleGameRuleValues- Handles the game rule values sent from the server.ClientboundLowDiskSpaceWarningPacket- A packet sent to the client warning about low disk space on the machine.ClientGamePacketListener#handleLowDiskSpaceWarning- Handles the warning packet about low disk space.ServerboundAttackPacket- A packet sent to the server about what entity the player attacked.ServerboundClientCommandPacket$Action#REQUEST_GAMERULE_VALUES- Requests the game rule values from the server.ServerboundSetGameRulePacket- A packet that sends the game rules entries to set from the client.ServerboundSpectateEntityPacket- A packet sent to the server about what entity the player wants to spectate.ServerGamePacketListenerhandleAttack- Handles the player’s attack on an entity.handleSpectateEntity- Handles the player wanting to spectate an entity.handleSetGameRule- Handles setting the game rules from the client.
net.minecraft.resourcesFileToIdConverter#extensionMatches- Checks if the identifier ends with the specified extension.IdentifierALLOWED_NAMESPACE_CHARACTERS- The characters allowed in an identifier’s namespace.resolveAgainst- Resolves the path from the given root by checking/<namespace>/<path>.
net.minecraft.serverBootstrap#shutdownStdout- Closes the stdout stream.MinecraftServerDEFAULT_GAME_RULES- The supplied default game rules for a server.warnOnLowDiskSpace- Sends a warning if the disk space is below 64 MiB.sendLowDiskSpaceWarning- Sends a warning for low disk space.
net.minecraft.server.commands.SwingCommand- A command that callsLivingEntity#swingfor all targets.net.minecraft.server.level.ServerPlayersendBuildLimitMessage- Sends an overlay message if the player cannot build anymore in the cooresponding Y direction.sendSpawnProtectionMessage- Sends an overlay message if the player cannot modify the terrain due to spawn protection.
net.minecraft.server.packs.AbstractPackResources#loadMetadata- Loads the rootpack.mcmeta.net.minecraft.server.packs.resources.ResourceMetadata$MapBased- A resource metadata that stores the sections in a map.net.minecraft.tags.TagLoader$ElementLookup#fromGetters- Constructs an element lookup from the givenHolderGetters depending on whether the element is required or not.net.minecraft.utilARGB#gray- Gets a grayscale color based on the given brightness.CompilableString- A utility for taking some string pattern and compiling it to an object through some parser.LightCoordsUtil- A utility for determining the light coordinates from light values.ProblemReporter$MapEntryPathElement- A path element for some entry key in a map.Util#allOfEnumExcept- Gets the set of all enums except the provided value.
net.minecraft.util.thread.BlockableEventLoop#hasDelayedCrash- Whether there is a crash report queued.net.minecraft.util.valueproviders.TrapezoidInt- Samples a random value with a trapezoidal distribution.net.minecraft.world.InteractionHand#STREAM_CODEC- The network codec for the interaction hand.net.minecraft.world.attributeAttributeType#toFloat- Gets the attribute value as afloat, or throws an exception if not defined.AttributeTypes#INTEGER- An integer attribute type.LerpFunction#ofInteger- A lerp function for an integer value.
net.minecraft.world.attribute.modifierAttributeModifier#INTEGER_LIBRARY- A library of operators to apply for integers.IntegerModifier- A modifier that applies some argument to the integer value.
net.minecraft.world.entityAgeableMobAGE_LOCK_COOLDOWN_TICKS- The number of ticks to wait before the entity can be age locked/unlocked.ageLockParticleTimer- The time for displaying particles while age locking/unlocking.
EntityapplyEffectsFromBlocksForLastMovements- Applies any block effects to this entity for the last movement, used by items.$Flags- An annotation that marks a particular value as a bitset of flags for an entity.
LivingEntity#getLiquidCollisionShape- Return’s the bounds of the entity when attempting to collide with a liquid.MobasValidTarget- Checks whether an entity is a valid target (can attack) for this entity.getTargetUnchecked- Gets the raw target without checking if its valid.canAgeUp- If the entity can grow up into a more mature variant.setAgeLocked,isAgeLocked- Whether the entity cannot grow up.
NeutralMob#getTargetUnchecked- Gets the raw target without checking if its valid.TamableAnimal#feed- The player gives the stack as food, healing them either based on the stored component or some default value.
net.minecraft.world.entity.ai.behaviorBehaviorControl#getRequiredMemories- The list of memories required by the behavior.GoAndGiveItemsToTarget$ItemThrower- An interface that handles what should occur if an item is thrown because of this entity’s behavior.
net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder$TriggerWithResult#memories- The list of memories required by the behavior.net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities#nearbyEntities- The list of entities within the follow range of this one.net.minecraft.world.entity.decoration.LeashFenceKnotEntitygetKnot- Finds the knot at the given position, else returns an empty optional.createKnot- Creates a new knot and adds it to the level.
net.minecraft.world.entity.monster.piglinPiglinAiMAX_TIME_BETWEEN_HUNTS- The maximum number of seconds before a piglin begins to hunt again.findNearbyAdultPiglins- Returns a list of all adult piglins in this piglin’s memory.
net.minecraft.world.entity.raid.RaidgetBannerComponentPatch- Gets the components of the banner pattern.getOminousBannerTemplate- Gets the stack template for the omnious banner.
net.minecraft.world.inventory.SlotRangesMOB_INVENTORY_SLOT_OFFSET- The start index of a mob’s inventory.MOB_INVENTORY_SIZE- The size of a mob’s inventory.
net.minecraft.world.item.component.BundleContents#BEEHIVE_WEIGHT- The weight of a beehive.net.minecraft.world.item.enchantment.EnchantmentTarget#NON_DAMAGE_CODEC- A codec that only allows the attacker and victim enchantment targets.net.minecraft.world.level.block.BigDripleafBlock#canGrowInto- Whether the dripleaf can grow into the specified position.net.minecraft.world.level.block.grower.TreeGrower#getMinimumHeight- If present, gets the base height of the trunk placer.net.minecraft.world.level.block.stateBlockBehaviour$PostProcess- An interface that gets the position to mark for post-processing.StateDefinitionpropertiesCodec- The map codec for the state properties.isSingletonState- If the definition only contains one state.
StateHolder#isSingletonState- If the holder only contains one state.
net.minecraft.world.level.block.state.propertiesNoteBlockInstrumentTRUMPET- The sound a copper block makes when placed under a note block.TRUMPET_EXPOSED- The sound an exposed copper block makes when placed under a note block.TRUMPET_OXIDIZED- The sound an oxidized copper block makes when placed under a note block.TRUMPET_WEATHERED- The sound a weathered copper block makes when placed under a note block.
Property$Value#valueName- Gets the name of the value.
net.minecraft.world.level.dimension.DimensionDefaultsBLOCK_LIGHT_TINT- The default tint for the block light.NIGHT_VISION_COLOR- The default color when in night vision.TURTLE_EGG_HATCH_CHANCE- The chance of a turtle egg hatching on a random tick.
net.minecraft.world.level.gamerules.GameRule#getIdentifierWithFallback- Gets the identifier of the game rule, or else the unregistered identifier.net.minecraft.world.level.levelgenNoiseBasedChunkGenerator#getInterpolatedNoiseValue- Gets the interpolated density at the given position, or the not-a-number value if the Y is outside the range of the noise settings.NoiseChunk#getInterpolatedDensity- Computes the full noise density.
net.minecraft.world.level.levelgen.feature.AbstractHugeMushroomFeature#MIN_MUSHROOM_HEIGHT- The minimum mushroom height.net.minecraft.world.level.levelgen.feature.configurations.BlockBlobConfiguration- The configuration for the block blob feature.net.minecraft.world.level.levelgen.feature.trunkplacers.TrunkPlacer#getBaseHeight- Returns the minimum height of the trunk.net.minecraft.world.level.levelgen.placement.RandomOffsetPlacement#ofTriangle- Creates a trapezoidal distribution to select from for the XZ and Y range.net.minecraft.world.level.materialFluidState#isFull- If the fluid amount is eight.LavaFluid#LIGHT_EMISSION- The amount of light the lava fluid emits.
net.minecraft.world.level.pathfinder.PathType#BIG_MOBS_CLOSE_TO_DANGER- A path malus for mobs with an entity width greater than a block.net.minecraft.world.level.storage.LevelStorageSource#writeWorldGenSettings- Wriets the world generation settings to its saved data location.net.minecraft.world.level.storage.loot.functionsEnchantRandomlyFunction$Builder#withOptions- Specifies the enchantments that can be used to randomly enchant this item.SetRandomDyesFunction- An item function that applies a random dye (if the item is in thedyeabletag) to theDYED_COLORcomponent from the provided list.SetRandomPotionFunction- An item function that applies a random potion to thePOTION_CONTENTScomponent from the provided list.
net.minecraft.world.level.storage.loot.parameters.LootContextParams#ADDITIONAL_COST_COMPONENT_ALLOWED- Enables a trade to incur an additional cost if desired by the wanted stack or modifiers.net.minecraft.world.level.storage.loot.predicates.EnvironmentAttributeCheck- A loot condition that checks whether that given attribute matches the provided value.net.minecraft.world.level.storage.loot.providers.numberEnvironmentAttributeValue- A provider that gets the attribute value as a float.Sum- A provider that sums the value of all provided number providers.
net.minecraft.world.phys.AABB$Builder#isDefined- Checks if there is at least one point making up the bounding box.
List of Changes
net.minecraft.advancements.criterionEntityTypePredicate#matchesnow takes in a holder-wrappedEntityTypeinstead of the raw type itselfKilledTrigger$TriggerInstance#entityPredicate->entityPlayerPredicatenow takes in aFoodPredicate- Can be set using
PlayerPredicate$Builder#setFood
- Can be set using
net.minecraft.client.guiGuiGraphicsblitnow has an overload that takes in theGpuTextureViewand theGpuSamplersetTooltipForNextFramenow has an overload that takes in a list ofFormattedCharSequences for the tooltip and whether to replace any existing tooltip
ItemSlotMouseAction#onSlotClickednow takes in aContainerInputinstead of aClickType
net.minecraft.client.gui.componentsAbstractContainerWidgetnow takes in anAbstractScrollArea$ScrollbarSettingsAbstractScrollAreanow takes in anAbstractScrollArea$ScrollbarSettingsscrollbarVisible->scrollablescrollBarYis now publicscrollRateis now longer abstract
AbstractTextAreaWidgetnow takes in anAbstractScrollArea$ScrollbarSettingsPopupScreen$Builder#setMessage->addMessage, not one-to-oneScrollableLayout$Containernow takes in anAbstractScrollArea$ScrollbarSettingsTooltip#createnow has an overload that takes in an optionalTooltipComponentand styleIdentifier
net.minecraft.client.gui.components.debugDebugEntryLookingAtBlock,DebugEntryLookingAtFluid->DebugEntryLookingAt- More specifically,
$BlockStateInfo,$BlockTagInfo,$FluidStateInfo,$FluidTagInfo
- More specifically,
DebugEntryLookingAtEntity#GROUPis now publicDebugScreenEntriesLOOKING_AT_BLOCK->LOOKING_AT_BLOCK_STATE,LOOKING_AT_BLOCK_TAGSLOOKING_AT_FLUID->LOOKING_AT_FLUID_STATE,LOOKING_AT_FLUID_TAGS
DebugScreenEntryListnow takes in aDataFixer
net.minecraft.client.gui.components.tabs.TabNavigationBar#setWidth->updateWidth, not one-to-onenet.minecraft.client.gui.navigation.FocusNavigationEvent$ArrowNavigationnow takes in a nullableScreenRectanglefor the previous focusnet.minecraft.client.gui.screensConfirmScreen#layoutis now finalDemoIntroScreenreplaced byClientPacketListener#openDemoIntroScreen, now privateGenericWaitingScreennow takes in threebooleans for showing the loading dots, the cancel button, and whether the screen should close on escape
net.minecraft.client.gui.screens.inventory.AbstractMountInventoryScreen#mountis now finalnet.minecraft.client.gui.screens.optionsOptionsScreennow implementsHasGamemasterPermissionReaction- The constructor now takes in a
booleanfor if the player is currently in a world createDifficultyButtonnow handles withinWorldOptionsScreen#createDifficultyButtons, not one-to-one
- The constructor now takes in a
WorldOptionsScreennow implementsHasGamemasterPermissionReactioncreateDifficultyButtons->DifficultyButtons#create, now public
net.minecraft.client.multiplayerClientLevel#syncBlockStatecan now take in a nullable player positionMultiPlayerGameMode#handleInventoryMouseClicknow takes in aContainerInputinstead of aClickTypeWeatherEffectRenderer#renderno longer takes in theMultiBufferSource
net.minecraft.client.renderer.block.ModelBlockRenderer$Cache#getLightColor->getLightCoordsnet.minecraft.client.renderer.blockentity.stateBrushableBlockRenderState#itemStateis now finalEndPortalRenderStateis now a final set ofDirections rather than anEnumSetShelfRenderState#itemsis now final
net.minecraft.client.renderer.entity.stateFallingBlockRenderState#movingBlockRenderStateis now finalHumanoidRenderState#attackArm->ArmedEntityRenderState#attackArmWitherRenderState#xHeadRots,yHeadRotsare now final
net.minecraft.client.resources.sounds.AbstractSoundInstance#randomis now finalnet.minecraft.commands.SharedSuggestionProvider#getCustomTabSugggestions->getCustomTabSuggestionsnet.minecraft.commands.arguments.ComponentArgument#getResolvedComponentnow takes in a non-nullableEntitynet.minecraft.commands.arguments.selector.SelectorPatternreplaced byCompilableStringnet.minecraft.core.HolderGetter$Provider#get,getOrThrownow has overloads that take in theTagKeynet.minecraft.dataBlockFamilyshouldGenerateRecipe->shouldGenerateCraftingRecipe,shouldGenerateStonecutterRecipe$Builder#dontGenerateRecipe->dontGenerateCraftingRecipe,generateStonecutterRecipe
DataGeneratoris now abstract- The constructor now only takes in the
Pathoutput, not theWorldVersionor whether to always generate- The original implementation can be founded in
DataGenerator$Cached
- The original implementation can be founded in
runis now abstract
- The constructor now only takes in the
Main#addServerProviders->addServerDefinitionProviders, no longer taking in the devboolean, not one-to-one- The remaining logic has been put into
addServerConverters, taking in the devbooleanbut not the reportboolean
net.minecraft.data.loot.BlockLootSubProviderexplosionResistantis now privateenabledFeaturesis now privatemapis now private
net.minecraft.data.recipesRecipeProvider$FamilyRecipeProvider->$FamilyCraftingRecipeProvider,$FamilyStonecutterRecipeProviderSingleItemRecipeBuilder#stonecuttingmoved to a parameter on theBlockFamily
net.minecraft.data.structures.SnbtToNbtnow has an overload that takes in a single input folder pathnet.minecraft.gametest.frameworkGameTestHelperassertBlockPresentnow has an overload that only takes in the block to check formoveTonow has overloads for taking in theBlockPosandVec3for the positionassertEntityInstancePresentnow has an overload that inflates (via adouble) the bounding box to check entities within
GameTestServer#createnow takes in anintfor the number of times to run all matching testsStructureUtils#testStructuresDirsplit intotestStructuresTargetDir,testStructuresSourceDirTestDatanow takes in anintfor the number of blocks padding around the test
net.minecraft.nbtNbtUtilsaddDataVersionnow uses a generic for theDynamicinstead of the explicit nbt taggetDataVersionnow has an overload that defaults to -1 if the version is not specified
TextComponentTagVisitorcan now take in a$Stylingand abooleanof whether to sort the keyshandleEscapePrettyis now aprivateinstance method fromprotectedstatic
net.minecraft.network.FriendlyByteBufreadVec3,writeVec3replaced withVec3#STREAM_CODECreadLpVec3,writeLpVec3replaced withVec3#LP_STREAM_CODEC
net.minecraft.network.chatComponentnbtnow takes in aCompilableStringinstead of aStringobjectnow has an overload that takes in aComponentfallback
ComponentContents#resolvenow takes in aResolutionContextinstead of theCommandSourceStackandEntityComponentUtils#updateForEnttiy->resolve, taking in theResolutionContextinstead of theCommandSourceStackandEntityLastSeenMessages#EMPTYis now final
net.minecraft.network.chat.contentsNbtContentsis now a record, the constructor taking in aCompilableStringinstead of aStringObjectContentsnow takes in an optionalComponentfor the fallback if its contents cannot be validated
net.minecraft.network.chat.contents.dataBlockDataSourcenow takes in aCompilableStringfor theCoordinatesinstead of the pattern and compiled positionEntityDataSourcenow takes in aCompilableStringfor theEntitySelectorinstead of the pattern and compiled selector
net.minecraft.network.chat.contents.objects.ObjectInfo#description->defaultFallbacknet.minecraft.network.protocol.gameClientboundSetEntityMotionPacketis now a recordServerboundContainerClickPacketnow takes in aContainerInputinstead of aClickTypeServerboundInteractPacketis now a record, now taking in theVec3interaction location
net.minecraft.referencesBlocks->BlockIdsItems->ItemIds
net.minecraft.resourcesFileToIdConverteris now a recordRegistryDataLoader#loadnow returns aCompletableFutureof the frozen registry access
net.minecraft.server.MinecraftServernow takes in abooleanof whether to propogate crashes, usually to throw a delayed crashthrowIfFatalException->BlockableEventLoop#throwDelayedException, now private, not one-to-onesetFatalException->BlockableEventLoop#delayCrash,relayDelayCrash; not one-to-one
net.minecraft.server.commands.ChaseCommand#DIMENSION_NAMESis now finalnet.minecraft.server.dedicated.DedicatedServerProperties#acceptsTransfersis now finalnet.minecraft.server.packsBuiltInMetadatahas been merged inResourceMetadataget->ResourceMetadata#getSectionof->ResourceMetadata#of
PathPackResources#getNamespacesnow has a static overload that takes in the root directoryPathVanillaPackResourcesBuilder#setMetadatanow takes in aResourceMetadatainstead of aBuiltInMetadata
net.minecraft.server.players.OldUsersConverter#serverReadyAfterUserconversionreplaced byareOldUserListsRemoves, nowpublicnet.minecraft.tags.TagLoaderloadTagsFromNetworknow takes in aRegistryinstead of aWritableRegistry, returning a map of tag keys to a list of holder entriesloadTagsForRegistrynow has an overload which takes in registry key along with an element lookup, returning a map of tag keys to a list of holder entries
net.minecraft.utilBrightnesspack->LightCoordsUtil#packblock->LightCoordsUtil#blocksky->LightCoordsUtil#sky
RandomSource#createNewThreadLocalInstance->createThreadLocalInstance- Now has an overload to specify the seed
Util#copyAndAddnow has an overload that takes in a varargs of elements
net.minecraft.util.threadBlockableEventLoopnow takes in abooleanof whether to propogate crashes, usually to throw a delayed crashReentrantBlockableEventLoopnow takes in abooleanof whether to propogate crashes, usually to throw a delayed crash
net.minecraft.world.InteractionResult$ItemContext#NONE,DEFAULTare now finalnet.minecraft.world.attributeAttributeTypenow takes in aToFloatFunctionfor use in a number providerofInterpolatednow takes in aToFloatFunction
EnvironmentAttributeReader#getValuenow has an overload that takes in theLootContext
net.minecraft.world.entityAvataris now abstractEntityfluidHeightis now finalgetTags->entityTagsgetRandomYnow has an overload that specifies the spreaddouble
Leashable$Wrench#ZEROis now finalLivingEntityinterpolationis now finalswingingArmis now nullablecanAttackType->canAttack, not one-to-one, taking in theLivingEntityinstead of theEntityTypelungeForwardMaybe->postPiercingAttackentityAttackRange->getAttackRangeWith, now taking in theItemStackused to attack
net.minecraft.world.entity.ai.behaviorGoAndGiveItemsToTargetnow takes in the$ItemThrowerthrowItem->BehaviorUtils#throwItem, not one-to-one
SpearAttackno longer takes in the approach distancefloatTryLaySpawnOnWaterNearLand->TryLaySpawnOnFluidNearLand, not one-to-one
net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder#sequencenow takes in aOneshotfor the second entry instead of aTriggernet.minecraft.world.entity.ai.goalBoatGoals->FollowPlayerRiddenEntityGoal$FollowEntityGoalBOATis replaced byENTITY
FollowBoatGoal->FollowPlayerRiddenEntityGoal, not one-to-one
net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal#targetConditionsis now finalnet.minecraft.world.entity.ai.sensing.NearestVisibleLivingEntitySensor#getMemory->getMemoryToSetnet.minecraft.world.entity.decoration.Mannequin#getProfile->Avatar#getProfile, nowpublicandabstract- Still implemented in
Mannequin
- Still implemented in
net.minecraft.world.entity.item.ItemEntity#DEFAULT_HEALTHis nowpublicfromprivatenet.minecraft.world.entity.monster.breeze.Breeze#idle,slide,slideBack,longJump,shoot,inhaleare now finalnet.minecraft.world.entity.monster.piglin.PiglinAi#isZombifiednow takes in theEntityinstead of theEntityTypenet.minecraft.world.entity.monster.warden.Warden#roarAnimationState,sniffAnimationState,emergeAnimationState,diggingAnimationState,attackAnimationState,sonicBoomAnimationStateare now finalnet.minecraft.world.entity.monster.zombie.Zombie#handleAttributesnow takes in theEntitySpawnReasonnet.minecraft.world.entity.playerInput#EMPTYis now finalPlayercurrentImpulseImpactPos->LivingEntity#currentImpulseImpactPoscurrentExplosionCause->LivingEntity#currentExplosionCausesetIgnoreFallDamageFromCurrentImpulse->LivingEntity#setIgnoreFallDamageFromCurrentImpulseapplyPostImpulseGraceTime->LivingEntity#applyPostImpulseGraceTimeisIgnoringFallDamageFromCurrentImpulse->LivingEntity#isIgnoringFallDamageFromCurrentImpulsetryResetCurrentImpulseContext->LivingEntity#tryResetCurrentImpulseContextresetCurrentImpulseContext->LivingEntity#resetCurrentImpulseContextisInPostImpulseGraceTime->LivingEntity#isInPostImpulseGraceTimeisWithinAttackRangenow takes in theItemStackattacked with
net.minecraft.world.entity.vehicle.minecart.NewMinecartBehavior$MinecartStep#EMPTYis now finalnet.minecraft.world.inventory.AbstractContainerMenu#getQuickCraftPlaceCountnow takes in the number of quick craft slots instead of the set of slots itselfnet.minecraft.world.itemBundleItem#getSelectedItem->getSelectedItemIndexCreativeModeTab$Outputis nowprotectedfrompublicEnderpearlItem#PROJECTILE_SHOOT_POWERis now finalItem$Properties#requiredFeaturesnow has an overload that takes in aFeatureFlagSetItems#register*methods are nowprivatefrompublicItemUtils#onContainerDestroyednow takes in aStreamofItemStacks instead of anIterableSignApplicator#tryApplyToSign,canApplyToSignnow take in theItemStackbeing usedSnowballItem#PROJECTILE_SHOOT_POWERis now finalThrowablePotionItem#PROJECTILE_SHOOT_POWERis now finalWindChargeItem#PROJECTILE_SHOOT_POWERis now final
net.minecraft.world.item.alchemy.Potionsnow deal withHolder$References instead of the superHoldernet.minecraft.world.item.componentAttackRangeminRange->minReachmaxRange->maxReachminCreativeRange->minCreativeReachmaxCreativeRange->maxCreativeReach
BundleContentsweightnow returns aDataResult-wrappedFractioninstead of the raw objectgetSelectedItem->getSelectedItemIndex
WrittenBookContenttryCraftCopy->craftCopyresolveForItem,resolvenow take in theResolutionContextandHolderLookup$Providerinstead of theCommandSourceStackandPlayer
net.minecraft.world.item.enchantmentConditionalEffect#codecno longer takes in theContextKeySetEnchantment#doLunge->doPostPiercingAttackEnchantmentHelper#doLungeEffects->doPostPiercingAttackEffectsTargetedConditionalEffect#codec,equipmentDropsCodecno longer take in theContextKeySet
net.minecraft.world.item.enchantment.effects.EnchantmentAttributeEffect#CODEC->MAP_CODECnet.minecraft.world.item.equipment.Equippable#canBeEquippedBynow takes in a holder-wrappedEntityTypeinstead of the raw type itselfnet.minecraft.world.item.trading.VillagerTrades#LIBRARIAN_5_EMERALD_NAME_TAGwas replaced withLIBRARIAN_5_EMERALD_YELLOW_CANDLE,LIBRARIAN_5_EMERALD_RED_CANDLE, not one-to-one- The original trade was moved to
WANDERING_TRADER_EMERALD_NAME_TAG
- The original trade was moved to
net.minecraft.world.levelLevelAccessorno longer implementsLevelReaderLevelHeightAccessor#isInsideBuildHeightnow has an overload that takes in theBlockPos
net.minecraft.world.level.blockBigDripleafBlock#canPlaceAtnow takes in theLevelReaderinstead of theLevelHeightAccessor, and no longer takes in the old stateBubbleColumnBlock#updateColumnnow takes in the bubble columnBlockFireBlock#setFlammableis nowprivatefrompublicMultifaceSpreader$DefaultSpreaderConfig#blockis now finalSnowyDirtBlock->SnowyBlockSpreadingSnowyDirtBlock->SpreadingSnowyBlock- The constructor now takes in the
ResourceKeyfor the ‘base’ block, or the block when the snow or any other decoration (e.g. grass) is removed
- The constructor now takes in the
net.minecraft.world.level.block.entity.TestInstanceBlockEntitygetTestBoundingBox- The bounding box of the test inflated by its padding.getTestBounds- The axis aligned bounding box of the test inflated by its padding.
net.minecraft.world.level.block.entity.vaultVaultConfig#DEFAULT,CODECare now finalVaultServerData#CODECis now finalVaultSharedData#CODECis now final
net.minecraft.world.level.block.stateBlockBehaviour$BlockStateBasenow takes in an array ofPropertys andComparablevalues instead of one value map, and no longer takes in theMapCodechasPostProcess->getPostProcessPos, not one-to-one$Properties#hasPostProcess->getPostProcessPos, not one-to-one
BlockStatenow takes in an array ofPropertys andComparablevalues instead of one value map, and no longer takes in theMapCodecStateHoldernow takes in an array ofPropertys andComparablevalues instead of one value map, and no longer takes in theMapCodecpopulateNeighbours->initializeNeighbors, now package-private instead ofpublic; not one-to-onegetValuesnow returns a stream ofProperty$Valuescodecnow takes in the function that gets the state definition from some object
net.minecraft.world.level.chunk.ChunkAccess#blendingDatais now finalnet.minecraft.world.level.chunk.storage.SimpleRegionStorage#upgradeChunkTagnow takes in anintfor the target versionnet.minecraft.world.level.gameevent.vibrations.VibrationSystem$Data#CODECis now finalnet.minecraft.world.level.gamerules.GameRulesnow has an overload that takes in a list ofGameRulesnet.minecraft.world.level.levelgenNoiseRouterData#cavesno longer takes in theHolderGetterfor theNormalNoise$NoiseParametersWorldDimensions#keysInOrdernow takes in a set ofLevelStemkeys instead of a stream
net.minecraft.world.level.levelgen.blockpredicatesTrueBlockPredicate#INSTANCEis now finalUnobstructedPredicate#INSTANCEis now final
net.minecraft.world.level.levelgen.featureAbstractHugeMushrromFeatureisValidPositionnow takes in aWorldGenLevelinstead of theLevelAccessorplaceTrunknow takes in theWorldGenLevelinstead of theLevelAccessormakeCapnow takes in theWorldGenLevelinstead of theLevelAccessor
BlockBlobFeaturenow uses aBlockBlobConfigurationgenericFeatureFOREST_ROCKreplaced byBLOCK_BLOBICE_SPIKEreplaced bySPIKE
IceSpikeFeature->SpikeFeature, not one-to-oneSpikeFeatureis nowEndSpikeFeature, not one-to-oneNUMBER_OF_SPIKES->EndSpikeFeature#NUMBER_OF_SPIKESgetSpikesForLevel->EndSpikeFeature#getSpikesForLevel
net.minecraft.world.level.levelgen.feature.configurationsHugeMushroomFeatureConfigurationis now a record, taking in a can place onBlockPredicateSpikeConfiguration->EndSpikeConfigurationis now a record- The original
SpikeConfigurationis now for the ice spike, taking in the blocks to use, along with predicates of where to place and whether it can replace a block present
- The original
TreeConfigurationdirtProvider,forceDirthave been replaced bybelowTrunkProviderdirtProvidercommonly usesCAN_PLACE_BELOW_OVERWORLD_TRUNKSforceDirtcommonly usesPLACE_BELOW_OVERWORLD_TRUNKS
$TreeConfigurationBuilderdirtProvider,dirt,forceDirthave been replaced bybelowTrunkProvider
net.minecraft.world.level.levelgen.feature.foliageplacers.FoliagePlacercreateFoliagenow takes in aWorldGenLevelisntead of aLevelSimulatedReaderplaceLeavesRow,placeLeavesRowWithHangingLeavesBelownow take in aWorldGenLevelisntead of aLevelSimulatedReadertryPlaceExtension,tryPlaceLeafnow take in aWorldGenLevelisntead of aLevelSimulatedReader
net.minecraft.world.level.levelgen.feature.rootplacers.RootPlacer#placeRoots,placeRootnow take in aWorldGenLevelinstead of aLevelSimulatedReadernet.minecraft.world.level.levelgen.feature.stateprovidersBlockStateProvider#getStatenow takes in theWorldGenLevel
net.minecraft.world.level.levelgen.feature.treedecoratorsTreeDecorator$Contextnow takes in aWorldGenLevelinstead of theLevelSimulatedReaderlevelnow returns aWorldGenLevelinstead of theLevelSimulatedReader
net.minecraft.world.level.levelgen.feature.trunkplacers.TrunkPlacerplaceTrunknow takes in aWorldGenLevelinstead of theLevelSimulatedReadersetDirtAt->placeBelowTrunkBlock, now taking in aWorldGenLevelinstead of theLevelSimulatedReaderplaceLognow takes in aWorldGenLevelinstead of theLevelSimulatedReaderplaceLogIfFreenow takes in aWorldGenLevelinstead of theLevelSimulatedReadervalidTreePosnow takes in aWorldGenLevelinstead of theLevelSimulatedReaderisFreenow takes in aWorldGenLevelinstead of theLevelSimulatedReader
net.minecraft.world.level.levelgen.placement.BiomeFilter#CODECis now finalnet.minecraft.world.level.levelgen.structure.TemplateStructurePiece#template,placeSettingsare now finalnet.minecraft.world.level.levelgen.structure.pools.aliasDirectPoolAlias#CODECis now finalRandomGroupPoolAlias#CODECis now finalRandomPoolAlias#CODECis now final
net.minecraft.world.level.levelgen.structure.templatesystem.LiquidSettings#CODECis now finalnet.minecraft.world.level.levelgen.synth.PerlinNoise#getValueno longer takes in thebooleanfor whether to flat the Y value instead of applying the frequency factornet.minecraft.world.level.material.FluidStatenow takes in an array ofPropertys andComparablevalues instead of one value map, and no longer takes in theMapCodecnet.minecraft.world.level.pathfinder.PathTypeDANGER_POWDER_SNOW->ON_TOP_OF_POWDER_SNOWDANGER_FIRE->FIRE_IN_NEIGHBORDAMAGE_FIRE->FIREDANGER_OTHER->DAMAGING_IN_NEIGHBORDAMAGE_OTHER->DAMAGING,DANGER_TRAPDOOR->ON_TOP_OF_TRAPDOOR
net.minecraft.world.level.saveddata.maps.MapItemSavedData#tickCarriedBynow takes in a nullableItemFramenet.minecraft.world.level.storage.loot.functionsEnchantRandomlyFunctionnow takes in abooleanof whether to include the additional trade cost component from the stack being enchanted- Set via
$Builder#includeAdditionalCostComponent
- Set via
EnchantWithLevelsFunctionnow takes in abooleanof whether to include the additional trade cost component from the stack being enchanted- Set via
$Builder#includeAdditionalCostComponent $Builder#fromOptions->withOptions, now with overload to take in an optionalHolderSet
- Set via
List of Removals
net.minecraft.SharedConstants#USE_WORKFLOWS_HOOKSnet.minecraft.client.data.models.BlockModelGenerators#createGenericCubenet.minecraft.client.Minecraft#delayCrashRawnet.minecraft.client.gui.components.EditBox#setFilternet.minecraft.client.multiplayer.ClientPacketListener#getIdnet.minecraft.client.renderer.SheetsshieldSheetbedSheetshulkerBoxSheetsignSheethangingSignSheetchestSheet
net.minecraft.client.renderer.rendertype.RenderTypes#weathernet.minecraft.data.loot.BlockLootSubProvider(Set, FeatureFlagSet, Map, HolderLookup$Provider)net.minecraft.gametest.framework.StructureUtils#DEFAULT_TEST_STRUCTURES_DIRnet.minecraft.nbt.NbtUtilsaddCurrentDataVersionprettyPrint(Tag)
net.minecraft.server.packs.AbstractPackResources#getMetadataFromStreamnet.minecraft.server.players.PlayerList#getSingleplayerDatanet.minecraft.utilMth#createInsecureUUIDLightCoordsUtil#UI_FULL_BRIGHT
net.minecraft.worldContainerListenerDifficulty#getKeySimpleContainer#addListener,removeListener
net.minecraft.world.entity.ai.memory.MemoryModuleType#INTERACTABLE_DOORSnet.minecraft.world.entity.monster.Zoglin#MEMORY_TYPESnet.minecraft.world.entity.monster.creaking.Creaking#MEMORY_TYPESnet.minecraft.world.entity.monster.hogling.Hoglin#MEMORY_TYPESnet.minecraft.world.itemBundleItem#hasSelectedItemItem#getName()ItemStackisFramed,getFramesetEntityRepresentation,getEntityRepresentation
net.minecraft.world.item.componentBundleContentsgetItemUnsafehasSelectedItem
WrittenBookContent#MAX_CRAFTABLE_GENERATION
net.minecraft.world.level.block.LiquidBlock#SHAPE_STABLEnet.minecraft.world.level.levelgen.featureFeature#isStone,isDirt,isGrassOrDirt
net.minecraft.world.level.levelgen.material.WorldGenMaterialRulenet.minecraft.world.level.storage.loot.functions.SetOminousBottleAmplifierFunction#amplifier