# Minecraft 1.21.11 向 26.1 版本模组迁移指南

本文是关于如何将模组从1.21.11版本迁移至26.1版本的高层次概览（非详尽说明）。内容不针对特定模组加载器，仅涉及原版类的变更。

本指南采用[知识共享署名4.0国际许可协议](http://creativecommons.org/licenses/by/4.0/)授权，欢迎作为参考资料使用，使用时请保留原文链接以便其他读者查阅。

若发现任何错误或遗漏信息，请在本代码库提交issue，或在Neoforged Discord服务器中@ChampionAsh5357。

特别鸣谢：
- @Shnupbups 的语法修正
- @cassiancc 提供的Java 25 IDE支持信息
- @boq 关于输入法支持的信息
- @lolothepro 发现的拼写错误

## 资源包变更

原版还存在许多面向用户的改动未在本文讨论，这些内容可能对模组开发者具有参考价值。具体变更清单可查看[Misode的版本更新日志](https://misode.github.io/versions/?id=26.1&tab=changelog)。

## Java 25 与反混淆

26.1 在通用流程中引入了两项新变化。

首先，Java 开发工具包已从 21 升级到 25。原版使用了这些新特性，例如 [JEP 447](https://openjdk.org/jeps/447)，它允许在构造函数中在 `super` 之前使用语句。对于模组开发社区的用户，请确保相应更新，或利用您的 IDE 或构建工具功能。Microsoft 的 OpenJDK 可以在[此处](https://learn.microsoft.com/en-us/java/openjdk/download#openjdk-25)找到。

您可能需要更新 IDE 以支持 Java 25。如果使用 Eclipse，您至少需要 2025-12 版本，或者使用 Java 25 支持市场插件的 2025-09 版本。如果使用 IntelliJ IDEA，您至少需要 2025.2 版本。

原版也已回归到反混淆状态，这意味着所有值类型现在都具有 Mojang 提供的官方名称。由于 Java 编译过程，仍然有一些内容未被捕获，例如内联原始类型和字符串常量，但大部分现已提供。这对于使用不同于官方映射的值类型映射集的用户或模组加载器来说将产生影响。

## 战利品类型展开

战利品池条目、物品函数、物品条件、NBT 提供者、数字提供者、分数提供者、整数提供者和浮点数提供者不再使用包装对象类型作为注册实例。现在，注册表直接接受用于序列化和反序列化过程的 `MapCodec`。因此，持有编解码器的 `*Type` 类或记录已被移除。此外，`getType` 现已重命名为 `codec`，接受注册的 `MapCodec`。

```java
// 以下是一个 LootItemFunction 的示例，但大致也适用于其他实例

public record NoopItemFunction() implements LootItemFunction {
    public static final NoopItemFunction INSTANCE = new NoopItemFunction();
    // 用作注册表对象的映射编解码器
    public static final MapCodec<NoopItemFunction> MAP_CODEC = MapCodec.unit(INSTANCE);

    // 取代 getType
    @Override
    public MapCodec<NoopItemFunction> codec() {
        // 返回注册表对象
        return MAP_CODEC;
    }
}

// 将映射编解码器注册到适当的注册表
Registry.register(BuiltInRegistries.LOOT_FUNCTION_TYPE, Identifier.fromNamespaceAndPath("examplemod", "noop"), NoopItemFunction.MAP_CODEC);
```

- `net.minecraft.core.registries.BuiltInRegistries`、`Registries`
    - `LOOT_POOL_ENTRY_TYPE` 现在持有 `LootPoolEntryContainer` 的映射编解码器，而不是 `LootPoolEntryType`
    - `LOOT_FUNCTION_TYPE` 现在持有 `LootItemFunction` 的映射编解码器，而不是 `LootItemFunctionType`
    - `LOOT_CONDITION_TYPE` 现在持有 `LootItemCondition` 的映射编解码器，而不是 `LootItemConditionType`
    - `LOOT_NUMBER_PROVIDER_TYPE` 现在持有 `NumberProvider` 的映射编解码器，而不是 `LootNumberProviderType`
    - `LOOT_NBT_PROVIDER_TYPE` 现在持有 `NbtProvider` 的映射编解码器，而不是 `LootNbtProviderType`
    - `LOOT_SCORE_PROVIDER_TYPE` 现在持有 `ScoreboardNameProvider` 的映射编解码器，而不是 `LootScoreProviderType`
    - `FLOAT_PROVIDER_TYPE` 现在持有 `FloatProvider` 的映射编解码器，而不是 `FloatProviderType`
    - `INT_PROVIDER_TYPE` 现在持有 `IntProvider` 的映射编解码器，而不是 `IntProviderType`
- `net.minecraft.util.valueproviders` 现在将 `CODEC` 字段重命名为 `MAP_CODEC`
    - `FloatProvider` 的子类型现在都是记录
    - `IntProvider` 的子类型，除了 `WeightedListInt`，现在都是记录
    - `FloatProvider` 现在从 `class` 变为 `interface`
        - `CODEC` -> `FloatProviders#CODEC`
        - `codec` -> `FloatProviders#codec`
        - `getType` -> `codec`，不是一对一
        - `getMinValue` -> `min`
        - `getMaxValue` -> `max`
    - `FloatProviders` - 所有要注册的原版浮点数提供者。
    - `FloatProviderType` 接口已移除
        - 所有单例字段已被移除，请改用每个类中的映射编解码器
        - `codec` -> `FloatProvider#codec`
    - `IntProvider` 现在从 `class` 变为 `interface`
        - `CODEC` -> `IntProviders#CODEC`
        - `NON_NEGATIVE_CODEC` -> `IntProviders#NON_NEGATIVE_CODEC`
        - `POSITIVE_CODEC` -> `IntProviders#POSITIVE_CODEC`
        - `codec` -> `IntProviders#codec`
        - `validateCodec` -> `IntProviders#validateCodec`
        - `getMinValue` -> `minInclusive`
        - `getMaxValue` -> `maxInclusive`
        - `getType` -> `codec`，不是一对一
    - `IntProviders` - 所有要注册的原版整数提供者。
    - `IntProviderType` 接口已移除
        - 所有单例字段已被移除，请改用每个类中的映射编解码器
        - `codec` -> `IntProvider#codec`
- `net.minecraft.world.level.storage.loot.entries` 现在将 `CODEC` 字段重命名为 `MAP_CODEC`
    - `LootPoolEntries` 的所有单例字段已被移除
        - 应改用每个类中的映射编解码器
        - `bootstrap` - 注册战利品池条目。
    - `LootPoolEntryContainer#getType` -> `codec`，不是一对一
    - `LootPoolEntryType` 记录已移除
- `net.minecraft.world.level.storage.loot.functions` 现在将 `CODEC` 字段重命名为 `MAP_CODEC`
    - `LootItemFunction#getType` -> `codec`，不是一对一
    - `LootItemFunctions` 的所有单例字段已被移除
        - 应改用每个类中的映射编解码器
        - `bootstrap` - 注册战利品物品函数。
    - `LootItemFunctionType` 记录已移除
- `net.minecraft.world.level.storage.loot.predicates` 现在将 `CODEC` 字段重命名为 `MAP_CODEC`
    - `LootItemCondition#getType` -> `codec`，不是一对一
    - `LootItemConditions` 的所有单例字段已被移除
        - 应改用每个类中的映射编解码器
        - `bootstrap` - 注册战利品物品条件。
    - `LootItemConditionType` 记录已移除
- `net.minecraft.world.level.storage.loot.providers.nbt` 现在将 `CODEC` 字段重命名为 `MAP_CODEC`
    - `LootNbtProviderType` 记录已移除
    - `NbtProvider` 现在实现 `LootContextUser`
        - `getType` -> `codec`，不是一对一
    - `NbtProviders` 的所有单例字段已被移除
        - 应改用每个类中的映射编解码器
        - `bootstrap` - 注册 NBT 提供者。
    - `LootItemConditionType` 记录已移除
- `net.minecraft.world.level.storage.loot.providers.number` 现在将 `CODEC` 字段重命名为 `MAP_CODEC`
    - `LootNumberProviderType` 记录已移除
    - `NumberProvider#getType` -> `codec`，不是一对一
    - `NumberProviders` 的所有单例字段已被移除
        - 应改用每个类中的映射编解码器
        - `bootstrap` - 注册数字提供者。
- `net.minecraft.world.level.storage.loot.providers.score` 现在将 `CODEC` 字段重命名为 `MAP_CODEC`
    - `LootScoreProviderType` 记录已移除
    - `ScoreProvider` 现在实现 `LootContextUser`
        - `getType` -> `codec`，不是一对一
    - `ScoreProviders` 的所有单例字段已被移除
        - 应改用每个类中的映射编解码器
        - `bootstrap` - 注册分数提供者。

## 验证大修

用于收集然后报告数据生成内容问题的验证处理程序已被大修。这从来就不是字段验证的替代品。验证处理程序专门用于更方便地处理多个信息之间的验证，这些信息可能无法暴露给单个字段，例如战利品提供者是否可用于给定的上下文参数。

所有经过验证的对象都实现 `Validatable`，或者专门针对进度条件的 `CriterionTriggerInstance`。这两种方法都提供一个方法：`validate`，用于检查对象的有效性。`validate` 接受一个 `ValidationContext`，它本质上持有用于收集问题的 `ProblemReporter`、当前上下文参数以及一个引用解析器。`CriterionTriggerInstance` 提供一个 `ValidationContextSource`，但可以使用 `context` 方法之一将其转换为 `ValidationContext`，提供要检查的上下文参数。如果无法验证特定对象，则调用 `ValidationContext#reportProblem`，详细说明具体问题。

```java
// 对于某个实现 Validatable 的对象

@Override
public void validate(ValidationContext ctx) {
    // 检查特定条件是否通过验证。
    if (this.foo() != this.bar()) {
        // 如果没有，则报告存在问题。
        ctx.reportProblem(() -> "'Foo' 不等于 'bar'。");
    }
}
```

如果对象本身没有问题，而是特定字段有问题，那么报告器可以在检查各个元素时跟踪堆栈跟踪，使用 `ValidationContext#for*` 方法之一，执行类似操作。

```java
// 对于某个实现 Validatable 的对象
// 假设它有一个子对象列表。

@Override
public void validate(ValidationContext ctx) {
    for (int i = 0; i < this.children.size(); i++) {
        // 获取列表中子项的特定上下文
        var childCtx = ctx.forIndexedField("children", i);
        // 检查特定条件是否通过验证。
        if (this.foo() != this.bar()) {
            // 如果没有，则报告存在问题。
            childCtx.reportProblem(() -> "'Foo' 不等于 'bar'。");
        }
    }
}
```

`Validatable` 还提供了一些用于检查其他 `Validatable` 字段的静态实用程序。

```java
// 对于某个实现 Validatable 的对象
// 假设某个子对象也实现了 Validatable

@Override
public void validate(ValidationContext ctx) {
    Validatable.validate(ctx, "child", this.child);
}
```

在所有必需的对象上实现 `Validatable` 后，可以根据使用位置（通常在反序列化之后或序列化之前）调用验证。这些的调用堆栈通常如下：

```java
// 对于某个 Validatable validatable
// 假设我们可以访问 HolderGetter.Provider provider。
// 如果不可用，参数本身是可选的。

// 创建问题收集器和验证上下文。
// 上下文参数应仅包括正在提供的参数。
ProblemReporter reporter = new ProblemCollector.Collector();
ValidationContext ctx = new ValidationContext(reporter, LootContextParamSets.ALL_PARAMS, provider);

// 调用验证器
validatable.validate(ctx);
```

这也可以通过 `Codec#validate` 附加到编解码器的末尾：

```java
public record ExampleObject() implements Validatable {
    public static final Codec<ExampleObject> CODEC = MapCodec.unitCodec(
        ExampleObject::new
    ).validate(
        // 提供验证器以及要检查的上下文参数。
        // 此方法无法访问注册表提供者。
        Validatable.validatorForContext(LootContextParamSets.ALL_PARAMS)
    );

    @Override
    public void validate(ValidationContext ctx) {
        // ...
    }
}
```

- `net.minecraft.advancements.CriterionTriggerInstance#validate` 现在接受 `ValidationContextSource` 而不是 `CriterionValidator`
- `net.minecraft.advancements.criterion`
    - `ContextAwarePredicate` 现在实现 `Validatable`
    - `CriterionValidator` -> `ValidationContextSource` 和 `Validatable`
        - `Validatable` 包含 `validate*` 方法
        - `ValidationContextSource` 持有上下文和报告器
- `net.minecraft.world.item.enchantment`
    - `ConditionalEffect` 现在实现 `Validatable`
        - `conditionCodec` 被加载后调用 `validate` 取代
    - `TargetedConditionalEffect` 现在实现 `Validatable`
- `net.minecraft.world.level.storage.loot`
    - `IntRange` 现在实现 `LootContextUser`
        - `getReferencedContextParams` 被 `validate` 取代
    - `LootContext$VisitedEntry` 泛型现在必须扩展 `Validatable`
    - `LootContextUser` 现在实现 `Validatable`
    - `LootDataType` 泛型现在必须扩展 `Validatable`
        - 构造函数现在接受 `$ContextGetter` 而不是 `$Validator`
        - `runValidation` 现在接受 `ValidationContextSource` 而不是 `ValidationContext`
            - 还有一个接受 `HolderLookup` 而不是键值对的重载
        - `createSimpleValidator`、`createLootTableValidator`、`$Validator` 被 `Validatable` 取代
        - `$ContextGetter` - 获取某个值的 `ContextKeySet`。
    - `LootPool` 现在实现 `Validatable`
    - `LootTable` 现在实现 `Validatable`
    - `Validatable` - 一个接口，处理其实例在给定上下文中的验证。
    - `ValidationContext`
        - `forField` - 为给定字段创建上下文。
        - `forIndexedField` - 为列表中的给定条目创建上下文。
        - `forMapField` - 为映射中的给定键创建上下文。
        - `setContextKeySet` 已移除
    - `ValidationContextSource` - 进行验证的定义上下文的源。
- `net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer` 现在实现 `Validatable`
- `net.minecraft.world.level.storage.loot.functions`
    - `SetAttributesFunction$Modifier` 现在实现 `LootContextUser`
    - `SetStewEffectFunction$EffectEntry` 现在实现 `LootContextUser`

## 数据包村民交易

村民交易现已从其原始的基于映射的设置变为数据生成的注册表。虽然初步印象可能使该系统看起来更受限，但实际上它同样具有可扩展性，尽管方式相当复杂，因为交易本身就是一个战利品表，用于确定商人可以提供哪些 `MerchantOffer`。为了便于理解，本节将介绍交易重写的基础知识，以及如何将每个先前的物品列表转换为 `VillagerTrade`。

### 理解交易格式

所有交易都表示为 `VillagerTrade`，其核心是确定商人 `wants`（想要）什么以及它 `gives`（给予）什么作为回报。每个交易还可以提供对物品本身或其成本的修改器，或者根据给定条件决定是否可以达成特定交易。每个交易还指定可以进行的交易次数、给予多少经验值，或者与用户声誉相乘的价格倍数。然后通过 `getOffer` 将 `VillagerTrade` 转换为 `MerchantOffer`，接受 `LootContext`，通常带有上下文参数 `LootContextParamSets#VILLAGER_TRADE`，提供商人本身（`THIS_ENTITY`）及其位置（`ORIGIN`）。

交易本身位于 `data/<namespace>/villager_trade/<path>`。通常，路径包含职业和交易等级，例如 `examplemod:example_profession/1/example_trade`

```json5
// 对于某个村民交易 'examplemod:example_profession/1/example_trade'
// JSON 位于 'data/examplemod/villager_trade/example_profession/1/example_trade.json'
{
    // 商人想要的堆栈。
    "wants": {
        // 堆栈的物品。
        "id": "minecraft:apple",
        // 一个数字提供者，用于确定想要多少该物品。一旦确定了数量，
        // `gives` 堆栈上的任何额外成本（通过 `ADDITIONAL_TRADE_COST` 组件）
        // 将在钳制到最大堆栈大小之前添加到数量中。
        // 如果未指定，默认为 1。
        "count": {
            "type": "minecraft:uniform",
            "min": 1,
            "max": 5
        },
        // 堆栈应具有的任何组件。堆栈必须具有确切指定的组件。
        // 如果未指定，则不会检查任何组件，这意味着此项被忽略。
        "components": {
            // 注册表键到组件值的映射。
            "minecraft:custom_name": "苹果...？"
        }
    },
    // 商人额外想要的一个堆栈。
    // 如果未指定，商人只检查 `wants`。
    "additional_wants": {
        "id": "minecraft:emerald"
    },
    // 商人给予的堆栈模板。
    "gives": {
        // 堆栈的物品。
        "id": "minecraft:golden_apple",
        // 一个数字 [1, 99]。
        // 如果未指定，默认为 1。
        "count": 1,
        // 要应用于堆栈的组件。
        // 如果未指定，则仅应用默认的物品组件。
        "components": {
            "minecraft:custom_name": "不是苹果"
        }
    },
    // 一个数字提供者，用于确定玩家在商人补货之前可以进行交易的次数。
    // 该值将至少为 1。
    // 如果未指定，默认为 4。
    "max_uses": {
        "type": "minecraft:uniform",
        "min": 1,
        "max": 20
    },
    // 一个数字提供者，用于确定根据玩家与商人的声誉以及物品需求
    // 应用于物品成本的价格乘数，该乘数根据玩家进行交易的次数计算。
    // 这通常应该是一个小数，因为用户每个商人的最大声誉是 150，
    // 尽管用户最多更可能拥有 25 的声誉。
    // 然而，即使声誉折扣乘以声誉表示 100% 或更多折扣，
    // 交易也必须始终至少有一个物品。
    // 如果未指定，默认为 0。
    "reputation_discount": {
        "type": "minecraft:uniform",
        "min": 0,
        "max": 0.05
    },
    // 一个数字提供者，用于确定玩家与商人进行交易获得的经验值。
    // 对于原版交易，这通常在 5-30 经验值左右。
    // 如果未指定，默认为 1。
    "xp": {
        "type": "minecraft:uniform",
        "min": 10,
        "max": 20
    },
    // 一个战利品物品条件，确定商人是否可以向玩家提供此交易。
    // 如果未指定，默认为始终为 true。
    "merchant_predicate": {
        // 此交易只能由来自沙漠或雪地村庄的村民执行。
        "condition": "minecraft:entity_properties",
        "entity": "this",
        "predicate": {
            "predicates": {
                "minecraft:villager/variant": [
                    "minecraft:desert",
                    "minecraft:snow"
                ]
            }
        }
    },
    // 一个战利品物品函数列表，用于修改从 `gives` 提供给玩家的物品。
    // 如果未指定，`gives` 不会被修改。
    "given_item_modifiers": [
        {
            // 从提供的标签中选择一个随机附魔
            "function": "minecraft:enchant_randomly",
            // 如果为 true，则交易成本增加所需的 `wants` 物品数量。
            "include_additional_cost_component": true,
            "only_compatible": false,
            "options": "#minecraft:trades/desert_common"
        }
    ],
    // 可以是一个附魔 id，例如 "minecraft:protection"，
    // 或一个附魔 id 列表，例如 ["minecraft:protection", "minecraft:smite", ...]，
    // 或一个附魔标签，例如 "#minecraft:trades/desert_common"。
    // 当提供时，如果 `gives` 物品在修饰后包含此列表中的附魔，
    // 则所需的 `wants` 物品数量乘以 2。
    // 如果未指定，则不执行任何操作。
    "double_trade_price_enchantments": "#minecraft:trades/desert_common"
}
```

### 商人的交易

每个商人都可以进行许多交易，通常从称为 `TradeSet` 的指定池中选择。交易集本身是一个单独的数据包注册表，它使用 `VillagerTrade`。每组交易决定可以提供多少交易以及是否可以多次选择相同的交易。提供的交易在 `AbstractVillager#addOffersFromTradeSet` 中计算，首先调用 `TradeSet#calculateNumberOfTrades` 获取报价数量，然后使用 `AbstractVillager#addOffersFromItemListings` 或 `AbstractVillager#addOffersFromItemListingsWithoutDuplicates` 来选择要使用的报价。

请注意，如果允许重复交易，则存在潜在的竞争条件，如果所有交易的 `merchant_predicate` 都失败，则报价将永远循环。这是因为该方法总是假设至少存在一个可以进行的交易。

交易集位于 `data/<namespace>/trade_set/<path>`。通常，路径包含职业和交易等级，例如 `examplemod:example_profession/level_1.json`

```json5
// 对于某个交易集 'examplemod:example_profession/level_1'
// JSON 位于 'data/examplemod/villager_trade/trade_set/level_1.json'
{
    // 可以是一个村民交易 id，例如 "examplemod:example_profession/1/example_trade"，
    // 或一个交易 id 列表，例如 ["examplemod:example_profession/1/example_trade", "minecraft:farmer/1/wheat_emerald", ...]，
    // 或一个交易标签，例如 "#examplemod:example_profession/level_1"。
    // 这是商人可以提供的交易集合。
    // 这应该始终是一个村民交易标签，以便其他用户
    // 可以轻松地将自己的交易添加到商人。
    "trades": "#examplemod:example_profession/level_1",
    // 一个数字提供者，用于确定商人可以提供的报价数量。
    "amount": {
        "type": "minecraft:uniform",
        "min": 1,
        "max": 5
    },
    // 是否可以使用相同的交易进行多个报价。
    // 如果未指定，默认为 false。
    "allow_duplicates": true,
    // 一个标识符，用于确定在确定报价时要使用的唯一随机实例。
    // 如果未指定，则使用等级随机。
    "random_sequence": "examplemod:example_profession/level_1"
}
```

村民交易标签可以是：

```json5
// 对于某个标签 'examplemod:example_profession/level_1'
// JSON 位于 'data/examplemod/tags/villager_trade/example_profession/level_1.json'
{
    "values": [
        "examplemod:example_profession/1/example_trade"
    ]
}
```

这也意味着可以通过添加到关联的标签来轻松地将交易添加到现有的交易集中：

```json5
// 对于某个标签 'minecraft:farmer/level_1'
// JSON 位于 'data/minecraft/tags/villager_trade/farmer/level_1.json'
{
    "values": [
        "examplemod:example_profession/1/example_trade"
    ]
}
```

同时，通过将等级 int 映射到 `tradeSetsByLevel` 中的交易集键来添加到新的 `VillagerProfession`：

```java
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,
        // 职业等级到交易集键的映射
        Int2ObjectMap.ofEntries(
            Int2ObjectMap.entry(
                // 职业等级
                1,
                // 交易集 id
                ResourceKey.create(Registries.TRADE_SET, Identifier.fromNamespaceAndPath("examplemod", "example_profession/level_1"))
            )
        )
    )
);
```

### 物品列表转换

考虑到所有这些，我们现在可以将物品列表转换为其新的数据生成村民交易。

#### 绿宝石 <-> 物品

对于以下交易：

```java
public static final VillagerTrades.ItemListing ITEM_TO_EMERALD = new VillagerTrades.EmeraldForItems(
    // 商人想要的物品。
    Items.WHEAT,
    // 商人想要的物品数量。
    20,
    // 补货前可以进行的最大交易次数。
    16,
    // 交易给予的经验值。
    2,
    // 给予的绿宝石数量。
    1
);

public static final VillagerTrades.ItemListing EMERALD_TO_ITEM = new VillagerTrades.ItemsForEmeralds(
    // 商人将给予的物品。
    Items.BREAD,
    // 商人想要的绿宝石数量。
    1,
    // 商人将给予的物品数量。
    6,
    // 补货前可以进行的最大交易次数。
    16,
    // 交易给予的经验值。
    1,
    // 应用于报价的价格乘数，考虑声誉和需求。
    0.05f
);
```

它们的等价形式为：

```json5
// 对于某个村民交易 'examplemod:item_to_emerald'
// JSON 位于 'data/examplemod/villager_trade/item_to_emerald.json'
{
    "gives": {
        // 给予的绿宝石数量。
        "count": 1,
        "id": "minecraft:emerald"
    },
    // 补货前可以进行的最大交易次数。
    "max_uses": 16,
    // 应用于报价的价格乘数，考虑声誉和需求。
    // `EmeraldForItems` 将此硬编码为 0.05
    "reputation_discount": 0.05,
    "wants": {
        // 商人想要的物品数量。
        "count": 20,
        // 商人想要的物品。
        "id": "minecraft:wheat"
    },
    // 交易给予的经验值。
    "xp": 2
}


// 对于某个村民交易 'examplemod:emerald_to_item'
// JSON 位于 'data/examplemod/villager_trade/emerald_to_item.json'
{
    "gives": {
        // 商人将给予的物品数量。
        "count": 6,
        // 商人将给予的物品。
        "id": "minecraft:bread"
    },
    // 补货前可以进行的最大交易次数。
    "max_uses": 16,
    // 应用于报价的价格乘数，考虑声誉和需求。
    "reputation_discount": 0.05,
    "wants": {
        "id": "minecraft:emerald",
        // 商人想要的绿宝石数量。
        "count": 1
    },
    // 交易给予的经验值。
    "xp": 1
}
```

#### 物品和绿宝石 -> 物品

对于以下交易：

```java
public static final VillagerTrades.ItemListing ITEM_EMERALD_TO_ITEM = new VillagerTrades.ItemsAndEmeraldsToItems(
    // 商人想要的物品。
    Items.COD,
    // 商人想要的物品数量。 
    6,
    // 商人额外想要的绿宝石数量。
    1,
    // 商人将给予的物品。
    Items.COOKED_COD,
    // 商人将给予的物品数量。
    6,
    // 补货前可以进行的最大交易次数。
    16,
    // 交易给予的经验值。
    1,
    // 应用于报价的价格乘数，考虑声誉和需求。
    0.05f
);
```

等价形式为：

```json5
// 对于某个村民交易 'examplemod:item_emerald_to_item'
// JSON 位于 'data/examplemod/villager_trade/item_emerald_to_item.json'
{
    // 商人额外想要的绿宝石。
    "additional_wants": {
        "id": "minecraft:emerald",
    },
    "gives": {
        // 商人将给予的物品数量。
        "count": 6,
        // 商人将给予的物品。
        "id": "minecraft:cooked_cod"
    },
    // 补货前可以进行的最大交易次数。
    "max_uses": 16,
    // 应用于报价的价格乘数，考虑声誉和需求。
    "reputation_discount": 0.05,
    "wants": {
        // 商人想要的物品数量。 
        "count": 6,
        // 商人想要的物品。
        "id": "minecraft:cod"
    },
    // 交易给予的经验值。
    "xp": 1
}
```

#### 绿宝石 -> 染色盔甲

对于以下交易：

```java
public static final VillagerTrades.ItemListing EMERALD_TO_DYED_ARMOR = new VillagerTrades.DyedArmorForEmeralds(
    // 商人将给予并染色的物品。
    Items.LEATHER_HELMET,
    // 商人想要的绿宝石数量。
    5,
    // 补货前可以进行的最大交易次数。
    12,
    // 交易给予的经验值。
    5
);
```

等价形式为：

```json5
// 对于某个村民交易 'examplemod:emerald_to_dyed_armor'
// JSON 位于 'data/examplemod/villager_trade/emerald_to_dyed_armor.json'
{
    "given_item_modifiers": [
        {
            // 在盔甲上设置随机染料。
            "function": "minecraft:set_random_dyes",
            "number_of_dyes": {
                "type": "minecraft:sum",
                "summands": [
                    1.0,
                    {
                        "type": "minecraft:binomial",
                        "n": 2.0,
                        "p": 0.75
                    }
                ]
            }
        },
        {
            // 检查染料是否成功应用于物品。
            "function": "minecraft:filtered",
            "item_filter": {
                "items": "minecraft:leather_helmet",
                "predicates": {
                    "minecraft:dyed_color": {}
                }
            },
            // 如果失败，则丢弃报价。
            "on_fail": {
                "function": "minecraft:discard"
            }
        }
    ],
    "gives": {
        "count": 1,
        // 商人将给予并染色的物品。
        "id": "minecraft:leather_helmet"
    },
    // 补货前可以进行的最大交易次数。
    "max_uses": 12,
    // 应用于报价的价格乘数，考虑声誉和需求。
    "reputation_discount": 0.05,
    "wants": {
        // 商人想要的绿宝石数量。
        "count": 5,
        "id": "minecraft:emerald"
    },
    // 交易给予的经验值。
    "xp": 5
}
```

#### 绿宝石 -> 附魔物品

对于以下交易：

```java
public static final VillagerTrades.ItemListing EMERALD_TO_ENCHANTED_BOOK = new VillagerTrades.EnchantBookForEmeralds(
    // 交易给予的经验值。
    30,
    // 选择书籍上存储附魔时使用的最小等级。
    3,
    // 选择书籍上存储附魔时使用的最大等级。
    3,
    // 包含可供书籍选择的可用附魔列表的标签。
    EnchantmentTags.TRADES_DESERT_SPECIAL
);

public static final VillagerTrades.ItemListing EMERALD_TO_ENCHANTED_ITEM = new VillagerTrades.EnchantedItemForEmeralds(
    // 商人将给予并尝试附魔的物品。
    Items.FISHING_ROD,
    // 商人想要的绿宝石基础数量。
    3,
    // 补货前可以进行的最大交易次数。
    3,
    // 交易给予的经验值。
    10,
    // 应用于报价的价格乘数，考虑声誉和需求。
    0.2f
);
```

等价形式为：

```json5
// 对于某个村民交易 'examplemod:emerald_to_enchanted_book'
// JSON 位于 'data/examplemod/villager_trade/emerald_to_enchanted_book.json'
{
    // 商人期望一本书来写入附魔。
    "additional_wants": {
        "id": "minecraft:book"
    },
    // 当在双倍交易价格标签中时，绿宝石交易成本增加。
    "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",
                // 选择书籍上存储附魔时使用的最小等级。
                "min": 3,
                // 选择书籍上存储附魔时使用的最大等级。
                "max": 3
            },
            // 可供书籍选择的可用附魔列表。
            "options": [
                "minecraft:efficiency"
            ]
        },
        {
            // 确保附魔已成功添加且具有给定等级。
            "function": "minecraft:filtered",
            "item_filter": {
                "items": "minecraft:enchanted_book",
                "predicates": {
                    "minecraft:stored_enchantments": [
                        {
                            "levels": {
                                // 选择书籍上存储附魔时使用的最小等级。
                                "min": 3,
                                // 选择书籍上存储附魔时使用的最大等级。
                                "max": 3
                            }
                        }
                    ]
                }
            },
            // 失败时丢弃
            "on_fail": {
                "function": "minecraft:discard"
            }
        }
    ],
    // 商人给予附魔书。
    "gives": {
        "count": 1,
        "id": "minecraft:enchanted_book"
    },
    // 补货前可以进行的最大交易次数被硬编码为 12。
    "max_uses": 12,
    // 应用于报价的价格乘数，考虑声誉和需求，硬编码为 0.2。
    "reputation_discount": 0.2,
    "wants": {
        "count": {
            "type": "minecraft:sum",
            "summands": [
                // 基于附魔最小和最大等级的硬编码计算。
                11.0,
                {
                    "type": "minecraft:uniform",
                    "max": 35.0,
                    "min": 0.0
                }
            ]
        },
        "id": "minecraft:emerald"
    },
    // 交易给予的经验值。
    "xp": 30
}

// 对于某个村民交易 'examplemod:emerald_to_enchanted_item'
// JSON 位于 'data/examplemod/villager_trade/emerald_to_enchanted_item.json'
{
    "given_item_modifiers": [
        {
            // 将附魔应用于给定的装备。
            "function": "minecraft:enchant_with_levels",
            "include_additional_cost_component": true,
            "levels": {
                "type": "minecraft:uniform",
                "max": 20,
                "min": 5
            },
            "options": "#minecraft:on_traded_equipment"
        },
        {
            // 检查以确保附魔已应用。
            "function": "minecraft:filtered",
            "item_filter": {
                "items": "minecraft:fishing_rod",
                "predicates": {
                    "minecraft:enchantments": [
                        {}
                    ]
                }
            },
            // 失败时，不给予任何东西。
            "on_fail": {
                "function": "minecraft:discard"
            }
        }
    ],
    "gives": {
        "count": 1,
        // 商人将给予并尝试附魔的物品。
        "id": "minecraft:fishing_rod"
    },
    // 补货前可以进行的最大交易次数。
    "max_uses": 3,
    // 应用于报价的价格乘数，考虑声誉和需求。
    "reputation_discount": 0.2,
    "wants": {
        "count": {
            "type": "minecraft:sum",
            "summands": [
                // 商人想要的绿宝石基础数量。
                3,
                {
                    // 基于附魔等级的变化。
                    // 最初，这将是物品函数中使用的值，但由于它们现在被隔离，
                    // 这些值可能不同。
                    "type": "minecraft:uniform",
                    "max": 20,
                    "min": 5
                }
            ]
        },
        "id": "minecraft:emerald"
    },
    // 交易给予的经验值。
    "xp": 10
}
```

#### 物品和绿宝石 -> 药水效果物品

对于以下交易：

```java
public static final VillagerTrades.ItemListing EMERALD_TO_SUSPICIOUS_STEW = new VillagerTrades.SuspiciousStewForEmerald(
    // 可疑炖菜应用的效果。
    MobEffects.NIGHT_VISION,
    // 效果应激活的刻数。
    100,
    // 交易给予的经验值。
    15
);

public static final VillagerTrades.ItemListing ITEM_EMERALD_TO_TIPPED_ARROW = new VillagerTrades.TippedArrowForItemsAndEmeralds(
    // 商人额外想要的物品。
    Items.ARROW,
    // 商人额外想要的物品数量。
    5,
    // 商人将给予的物品。
    Items.TIPPED_ARROW,
    // 商人将给予的物品数量。
    5,
    // 商人想要的绿宝石数量。
    2,
    // 补货前可以进行的最大交易次数。
    12,
    // 交易给予的经验值。
    30
);
```

等价形式为：

```json5
// 对于某个村民交易 'examplemod:emerald_to_suspicious_stew'
// JSON 位于 'data/examplemod/villager_trade/emerald_to_suspicious_stew.json'
{
    "given_item_modifiers": [
        {
            "effects": [
                {
                    // 可疑炖菜应用的效果。
                    "type": "minecraft:night_vision",
                    // 效果应激活的刻数。
                    "duration": 100
                }
                // 原版将所有可疑炖菜报价合并为一个，
                // 因为此函数随机选择一个炖菜效果。
            ],
            "function": "minecraft:set_stew_effect"
        }
    ],
    "gives": {
        "count": 1,
        "id": "minecraft:suspicious_stew"
    },
    // 补货前可以进行的最大交易次数，硬编码为 12。
    "max_uses": 12,
    // 应用于报价的价格乘数，考虑声誉和需求，硬编码为 0.05。
    "reputation_discount": 0.05,
    "wants": {
        "id": "minecraft:emerald"
    },
    // 交易给予的经验值。
    "xp": 15
}

// 对于某个村民交易 'examplemod:item_emerald_to_tipped_arrow'
// JSON 位于 'data/examplemod/villager_trade/item_emerald_to_tipped_arrow.json'
{
    "additional_wants": {
        // 商人额外想要的物品数量。
        "count": 5,
        // 商人额外想要的物品。
        "id": "minecraft:arrow"
    },
    "given_item_modifiers": [
        {
            // 从可交易的药水中随机应用一种药水效果。
            // 原始实现只是随机选择任何药水。
            "function": "minecraft:set_random_potion",
            "options": "#minecraft:tradeable"
        }
    ],
    "gives": {
        // 商人将给予的物品数量。
        "count": 5,
        // 商人将给予的物品。
        "id": "minecraft:tipped_arrow"
    },
    // 补货前可以进行的最大交易次数。
    "max_uses": 12,
    // 应用于报价的价格乘数，考虑声誉和需求，硬编码为 0.05。
    "reputation_discount": 0.05,
    "wants": {
        // 商人想要的绿宝石数量。
        "count": 2,
        "id": "minecraft:emerald"
    },
    // 交易给予的经验值。
    "xp": 30
}
```

#### 绿宝石 -> 宝藏地图

对于以下交易：

```java
public static final VillagerTrades.ItemListing EMERALD_TO_TREASURE_MAP = new VillagerTrades.TreasureMapForEmeralds(
    // 商人想要的绿宝石数量。
    8,
    // 一个包含要找到最近宝藏结构的列表的标签。
    StructureTags.ON_TAIGA_VILLAGE_MAPS,
    // 地图名称的翻译键。
    "filled_map.village_taiga",
    // 用于装饰地图上找到的宝藏位置的图标。
    MapDecorationTypes.TAIGA_VILLAGE,
    // 补货前可以进行的最大交易次数。
    12,
    // 交易给予的经验值。
    5
);
```

等价形式为：

```json5
// 对于某个村民交易 'examplemod:emerald_to_treasure_map'
// JSON 位于 'data/examplemod/villager_trade/emerald_to_treasure_map.json'
{
    "additional_wants": {
        // 商人额外想要的物品，硬编码为指南针。
        "id": "minecraft:compass"
    },
    "given_item_modifiers": [
        {
            // 找到要在地图上显示的宝藏结构。

            // 用于装饰地图上找到的宝藏位置的图标。
            "decoration": "minecraft:village_taiga",
            // 一个包含要找到最近宝藏结构的列表的标签。
            "destination": "minecraft:on_taiga_village_maps",
            "function": "minecraft:exploration_map",
            "search_radius": 100
        },
        {
            // 设置地图的名称。

            "function": "minecraft:set_name",
            "name": {
                // 地图名称的翻译键。
                "translate": "filled_map.village_taiga"
            },
            "target": "item_name"
        },
        {
            // 检查以确保找到了结构。

            "function": "minecraft:filtered",
            "item_filter": {
                "items": "minecraft:filled_map",
                "predicates": {
                    "minecraft:map_id": {}
                }
            },
            "on_fail": {
                "function": "minecraft:discard"
            }
        }
    ],
    "gives": {
        "count": 1,
        // 返回一张填充了宝藏位置的地图。
        "id": "minecraft:map"
    },
    // 补货前可以进行的最大交易次数。
    "max_uses": 12,
    // 应用于报价的价格乘数，考虑声誉和需求，硬编码为 0.05。
    "reputation_discount": 0.05,
    "wants": {
        // 商人想要的绿宝石数量。
        "count": 8,
        "id": "minecraft:emerald"
    },
    // 交易给予的经验值。
    "xp": 5
}
```

#### 村民变体

一些商人会根据村民类型提供不同的选项，作为一个巨大的物品列表映射。现在，每种类型都有自己独立的村民交易，使用 `merchant_predicate` 来检查是否可以向特定村民类型提供报价：

```json5
// 对于某个村民交易 'examplemod:villager_type_item'
// JSON 位于 'data/examplemod/villager_trade/villager_type_item.json'
{
    // ...
    "merchant_predicate": {
        // 检查实体。
        "condition": "minecraft:entity_properties",
        "entity": "this",
        "predicate": {
            "predicates": {
                // 村民类型必须是沙漠才能选择此交易。
                "minecraft:villager/variant": "minecraft:desert"
            }
        }
    },
    // ...
}
```

- `net.minecraft.core.registries.Registries`
    - `TRADE_SET` - 指向持有交易列表的注册表的键。
    - `VILLAGER_TRADE` - 指向持有单个交易的注册表的键。
- `net.minecraft.tags.VillagerTradeTags` - 村民交易的标签。
- `net.minecraft.world.entity.npc.villager`
    - `AbstractVillager#addOffersFromItemListings` -> `addOffersFromTradeSet`，接受交易集的键而不是 `$ItemListing` 和报价数量；不是一对一
    - `VillagerProfession` 现在接受一个交易员等级到 `TradeSet` 的映射
        - `getTrades` - 返回给定等级的交易集键。
    - `VillagerTrades` 已被拆分为许多不同的类和实现
        - `TRADES`、`EXPERIMENTAL_TRADES`、`WANDERING_TRADER_TRADES` 现在由 `VillagerProfession#tradeSetsByLevel` 表示
            - 由于它们现在是数据包条目，因此存储在其各自的数据包中
            - `TRADES`、`EXPERIMENTAL_TRADES` 由 `data/minecraft/trade_set/<profession>/*` 表示
            - `WANDERING_TRADER_TRADES` 由 `data/minecraft/trade_set/wandering_trader/*` 表示
        - `$DyedArmorForEmeralds` -> `VillagerTrades#dyedItem`、`addRandomDye`；不是一对一
        - `$EmeraldForItems` -> `VillagerTrade`，不是一对一
        - `$EmeraldsForVillagerTypeItem` -> `VillagerTrades#registerBoatTrades`，参见用法，不是一对一
        - `$EnchantBookForEmeralds` -> `VillagerTrades#enchantedBook`，不是一对一
        - `$EnchantedItemForEmeralds` -> `VillagerTrades#enchantedItem`，不是一对一
        - `$ItemListing` -> `VillagerTrade`
        - `$ItemsAndEmeraldsToItems` -> 带有 `additionalWants` 的 `VillagerTrade`
        - `$ItemsForEmeralds` -> `VillagerTrade`，不是一对一
        - `$SuspiciousStewForEmerald` -> 带有 `SetStewEffectFunction` 的 `VillagerTrade`
        - `$TippedArrowForItemsAndEmeralds` -> 带有 `SetRandomPotionFunction` 的 `VillagerTrade`
        - `$TreasureMapForEmeralds` -> `VillagerTrades$VillagerExplorerMapEntry`，参见用法，不是一对一
        - `$TypeSpecificTrade` -> `VillagerTrades#villagerTypeRestriction`、`villagerTypeHolderSet`；不是一对一
- `net.minecraft.world.item.enchantment.providers.TradeRebalanceEnchantmentProviders` 接口已移除
    - 被 `TradeRebalanceVillagerTrades`、`TradeRebalanceRegistries` 取代
- `net.minecraft.world.item.trading`
    - `TradeCost` - 正在与某个商人交易的 `ItemStack`。
    - `TradeRebalanceVillagerTrades` - 属于交易平衡数据包的所有交易。
    - `TradeSet` - 一组可以由某个等级的交易员执行的交易。
    - `TradeSets` - 某个等级的交易员的所有原版交易集。
    - `VillagerTrade` - 商人和玩家之间的交易。
    - `VillagerTrades` - 所有原版交易。
- `net.minecraft.world.level.storage.loot.parameters.LootContextParamSets#VILLAGER_TRADE` - 进行村民交易时的战利品上下文，包含交易来源和交易实体。

## `Level#random` 字段现在为 protected

`Level#random` 字段现在是 `protected` 而不是 `public`。因此，应改用公共的 `getRandom` 方法。

```java
// 对于某个 Level level
RandomSource random = level.getRandom();
```

- `net.minecraft.world.level.Level#random` 字段现在是 `protected` 而不是 `public`
    - 改用 `getRandom` 方法

## 数据组件初始化器

数据组件已开始从原始对象转移到 `Holder` 本身。这是为了正确处理在构造期间不可用的对象，例如物品的数据包注册表对象。目前，这仅针对 `Item` 实现，但该系统允许任何注册表对象（给定其包装的持有者）存储某些定义的数据组件。

数据组件通过 `DataComponentInitializers` 附加到其持有者。在对象构造期间，调用 `DataComponentInitializers#add`，提供注册表对象的 `ResourceKey` 标识符以及一个 `DataComponentInitializers$Initializer`。初始化器接受三个参数：组件映射的构建器、完整的注册表 `HolderLookup$Provider` 以及传递给 `DataComponentInitializers#add` 的键。初始化器的功能类似于消费者，也允许通过 `$Initializer#andThen` 链接其他初始化器，或通过 `$Initializer#add` 轻松添加组件。

```java
// 对于某个自定义注册表对象
public ExampleObject(ResourceKey<ExampleObject> id) {
    // 注册数据组件初始化器
    BuiltInRegistries.DATA_COMPONENT_INITIALIZERS.add(
        // 注册表对象的标识符
        id,
        // 初始化器函数，接受组件构建器、注册表上下文和 id
        (components, context, key) -> components
            .set(DataComponents.MAX_DAMAGE, 1)
            .set(DataComponents.DAMAGE_TYPE, context.getOrThrow(DamageTypes.SPEAR))
    );
}
```

然后，每当调用 `ReloadableServerResources#loadResources`（在数据包重载时）时，数据组件就会被初始化或重新初始化。首先加载数据包对象，然后在 `Holder$Reference` 上设置组件。然后，可以通过 `Holder#components` 收集组件。

```java
// 对于某个 Holder<ExampleObject> EXAMPLE_HOLDER
DataComponentMap components = EXAMPLE_HOLDER.components();
```

### 物品

由于组件现在在资源重载期间初始化，`Item$Properties` 提供了两种方法来将组件初始化延迟到此类数据组件加载完成之后：`delayedComponent` 和 `delayedHolderComponent`。`delayedComponent` 接受组件类型和一个接受 `HolderLookup$Provider` 并返回组件值的函数。`delayedHolderComponent` 委托给 `delayedComponent`，接受一个 `ResourceKey` 并将注册表对象设置为组件值。

```java
public static final Item EXAMPLE_ITEM = new Item(
    new Item.Properties()
        .delayedComponent(
            // 应延迟初始化的组件类型。
            DataComponents.JUKEBOX_PLAYABLE,
            // 一个接受注册表并返回组件值的函数。
            context -> new JukeboxPlayable(context.getOrThrow(
                JukeboxSongs.THIRTEEN
            ))
        )
        .delayedHolderComponent(
            // 具有持有者值类型的组件类型。
            DataComponents.DAMAGE_TYPE
            // 关联持有者泛型类型的注册表对象的资源键。
            DamageTypes.SPEAR
        )
        // ...
);
```

### 配方

由于数据组件现在持有在资源重载后延迟初始化的真实值，`Recipe#assemble` 不再接受 `HolderLookup$Provider`。相反，它假设配方已将所有必需的数据存储在传递到配方的堆栈或直接存储中。

- `net.minecraft.core`
    - `Holder`
        - `areComponentsBound` - 组件是否已绑定到持有者。
        - `components` - 存储在持有者上的对象组件。
        - `direct`、`$Direct` 现在可以接受 `DataComponentMap`
        - `$Reference#bindComponents` - 将组件存储在持有者引用上。
    - `Registry#componentLookup` - 获取组件到持有者的查找。
    - `WritableRegistry#bindTag` -> `bindTags`，现在接受一个键到持有者列表的映射，而不是一个映射
- `net.minecraft.core.component`
    - `DataComponentInitializers` - 一个处理为组件附加对象初始化数据组件的类。
    - `DataComponentLookup` - 一个将组件类型映射到使用它的持有者的查找表。
    - `DataComponentMap$Builder#addValidator` - 为对象上的组件添加验证器。
    - `DataComponentPatch`
        - `get` 现在接受 `DataComponentGetter` 并返回原始组件值
        - `$Builder#set` 现在有一个接受 `TypedDataComponent` 可迭代对象的重载
    - `DataComponents`
        - `DAMAGE_TYPE` 现在是一个持有者包装的 `DamageType`，而不是 `EitherHolder` 包装的
        - `PROVIDES_TRIM_MATERIAL` 现在是一个持有者包装的 `TrimMaterial`，而不是 `ProvidesTrimMaterial`
        - `CHICKEN_VARIANT` 现在是一个持有者包装的 `ChickenVariant`，而不是 `EitherHolder` 包装的
        - `ZOMBIE_NAUTILUS_VARIANT` 现在是一个持有者包装的 `ZombieNautilusVariant`，而不是 `EitherHolder` 包装的
        - `PROVIDES_BANNER_PATTERNS` 现在是一个 `HolderSet`，而不是 `TagKey`
- `net.minecraft.core.registries`
    - `BuiltInRegistries#DATA_COMPONENT_INITIALIZERS` - 附加到注册表条目的数据组件列表。
    - `Registries#componentsDirPath` - 注册表中组件的路径目录。
- `net.minecraft.data.PackOutput#createRegistryComponentPathProvider` - 用于组件注册表报告的路径提供者。
- `net.minecraft.data.info.ItemListReport` -> `RegistryComponentsReport`，不是一对一
- `net.minecraft.resources`
    - `NetworkRegistryLoadTask` - 一个加载任务，处理从网络注册注册表对象和标签，否则从资源注册。
    - `RegistryDataLoader`
        - `$PendingRegistration` -> `RegistryLoadTask$PendingRegistration`
        - `$RegistryData` 现在接受一个 `RegistryValidator` 而不是一个 `boolean`
        - `$RegistryLoadTask` -> `RegistryLoadTask`，不是一对一
    - `RegistryValidator` - 一个接口，用于验证注册表中的条目，将所有错误存储在映射中。
    - `ResourceManagerRegistryLoadTask` - 一个加载任务，处理从本地资源管理器注册注册表对象和标签。
- `net.minecraft.server.ReloadableServerResources#updateStaticRegistryTags` -> `updateComponentsAndStaticRegistryTags`，不是一对一
- `net.minecraft.world.item`
    - `EitherHolder` 类已移除
    - `Item`
        - `CODEC_WITH_BOUND_COMPONENTS` - 一个验证组件已绑定的物品编解码器。
        - `$Properties`
            - `delayedComponent` - 延迟设置组件，提供 `HolderLookup$Provider` 以获取任何动态元素。
            - `delayedHolderComponent` - 为某个持有者包装的注册表对象延迟设置组件。
    - `ItemStack#validateComponents` 现在从 `public` 变为 `private`
    - `JukeboxPlayable` 现在持有持有者包装的 `JukeboxSong`，而不是 `EitherHolder` 包装的变体
    - `JukeboxSong#fromStack` 不再接受 `HolderLookup$Provider`
    - `SpawnEggItem`
        - `spawnEntity` 现在是 `static`
        - `byId` 现在返回一个可选的持有者包装的 `Item`，而不是 `SpawnEggItem`
        - `eggs` 已移除
        - `getType` 现在是 `static`
        - `spawnOffspringFromSpawnEgg` 现在是 `static`
- `net.minecraft.world.item.component`
    - `BlocksAttacks` 现在持有一个可选的持有者集包装的 `DamageType`，而不是 `TagKey`
    - `DamageResistant` 现在持有一个持有者集 `DamageType`，而不是 `TagKey`
    - `InstrumentComponent` 现在持有一个持有者包装的 `Instrument`，而不是 `EitherHolder` 包装的变体
        - `unwrap` 已移除
    - `ProvidesTrimMaterial` 现在持有一个持有者包装的 `TrimMaterial`，而不是 `EitherHolder` 包装的变体
- `net.minecraft.world.item.crafting`
    - `Recipe#assemble` 不再接受 `HolderLookup$Provider`
    - `SmithingTrimRecipe#applyTrim` 不再接受 `HolderLookup$Provider`
- `net.minecraft.world.item.equipment.trim.TrimMaterials#getFromIngredient` 已移除
- `net.minecraft.world.level.storage.loot.functions.SetInstrumentFunction`、`#setInstrumentOptions` 现在接受持有者集包装的 `Instrument`，而不是 `TagKey`
- `net.minecraft.world.timeline.Timeline#validateRegistry` - 验证每个时间标记仅定义一次。

## 物品实例与堆栈模板

`ItemStack` 现在有一个称为 `ItemStackTemplate` 的不可变实例。与 `ItemStack` 类似，它包含持有者包装的 `Item`、它表示的物品数量以及要应用于堆栈的组件的 `DataComponentPatch`。模板可以通过 `create` 转换为堆栈，或者如果需要添加额外数据组件，则通过 `apply` 转换。`ItemStack` 同样可以通过 `ItemStackTemplate#fromNonEmptyStack` 转换为模板。现在在需要不可变性的地方（例如，进度、配方等）使用模板代替 `ItemStack`。它们为网络通信提供了常规的 `CODEC`、`MAP_CODEC` 和 `STREAM_CODEC`。

```java
ItemStackTemplate apple = new ItemStackTemplate(
    // 堆栈的物品
    Items.APPLE.builtInRegistryHolder(),
    // 持有的物品数量
    5,
    // 应用于堆栈的组件
    DataComponentPatch.builder()
        .set(DataComponents.ITEM_NAME, Component.literal("苹果？"))
        .build()
);

// 将模板转换为堆栈
ItemStack stack = apple.create();

// 从非空堆栈创建模板
ItemStackTemplate fromStack = ItemStackTemplate.fromNonEmptyStack(stack);
```

为了帮助标准化访问两者之间的通用组件，模板和堆栈都实现了 `ItemInstance`，它提供了对标准持有者方法检查、计数和 `DataComponentGetter` 的访问。公共接口还意味着，如果堆栈是否可变无关紧要，则可以使用 `ItemInstance` 作为类型。

```java
// 两者都是物品实例
ItemInstance stack = new ItemStack(Items.APPLE);
ItemInstance template = new ItemStackTemplate(Items.APPLE);

// 获取持有者或检查某些内容
Holder<Item> item = stack.typeHolder();
template.is(Items.APPLE);

// 获取堆栈或模板中的物品数量
int stackCount = stack.count();
int templateCount = template.count();

// 获取组件值
Identifier stackModel = stack.get(DataComponents.ITEM_MODEL);
Identifier templateModel = template.get(DataComponents.ITEM_MODEL);
```

### 配方构建器

由于 `ItemStackTemplate` 的加入，`RecipeBuilder` 的实现略有变化。首先，构建器不再为结果存储 `Item`，而是将 `defaultId` 定义为配方的资源键。因此，这允许更清晰地定义不导出 `Item` 的自定义配方。

当然，这种新格式的更改只需让 `defaultId` 返回带有 `ItemInstance`（堆栈或模板）的 `RecipeBuilder#getDefaultRecipeId`，如下所示：

```java
public class ExampleRecipeBuilder implements RecipeBuilder {

    // 配方的结果
    private final ItemStackTemplate result;

    public ExampleRecipeBuilder(ItemStackTemplate result) {
        this.result = result;
    }

    @Override
    public ResourceKey<Recipe<?>> defaultId() {
        // 从结果获取默认配方 id
        return RecipeBuilder.getDefaultRecipeId(this.result);
    }

    // 在此处实现其他所有内容
    // ...
}
```

- `net.minecraft.advancements`
    - `Advancement$Builder#display` 现在接受 `ItemStackTemplate` 而不是 `ItemStack`
    - `DisplayInfo` 现在接受 `ItemStackTemplate` 而不是 `ItemStack`
        - `getIcon` 现在返回 `ItemStackTemplate` 而不是 `ItemStack`
- `net.minecraft.advancements.criterion`
    - `AnyBlockInteractionTrigger#trigger` 现在接受 `ItemInstance` 而不是 `ItemStack`
    - `ItemPredicate` 现在实现 `ItemInstance` 的谓词而不是 `ItemStack`
    - `ItemUsedOnLocationTrigger#trigger` 现在接受 `ItemInstance` 而不是 `ItemStack`
- `net.minecraft.client.particle.BreakingItemParticle$ItemParticleProvider#getSprite` 现在接受 `ItemStackTemplate` 而不是 `ItemStack`
- `net.minecraft.commands.arguments.item`
    - `ItemInput` 现在是一个记录
        - `serialize` 已移除
        - `createItemStack` 不再接受用于检查大小的 `boolean`
    - `ItemParser#parse` 现在返回 `ItemResult` 而不是 `ItemParser$ItemResult`
        - `$ItemResult` 合并到 `ItemInput`
- `net.minecraft.core.component.predicates`
    - `BundlePredicate` 现在处理 `ItemInstance` 的可迭代对象而不是 `ItemStack`
    - `ContainerPredicate` 现在处理 `ItemInstance` 的可迭代对象而不是 `ItemStack`
- `net.minecraft.core.particles.ItemParticleOption` 现在接受 `ItemStackTemplate` 而不是 `ItemStack`
    - 还有一个接受常规 `Item` 的重载
    - `getItem` 现在返回 `ItemStackTemplate` 而不是 `ItemStack`
- `net.minecraft.data.recipes`
    - `RecipeBuilder`
        - `getResult` 已移除
        - `defaultId` - 使用此构建器制作的配方的默认标识符。
        - `getDefaultRecipeId` 现在接受 `ItemInstance` 而不是 `ItemLike`
    - `RecipeProvider`
        - `oreSmelting`、`oreBlasting` 现在接受 `CookingBookCategory`
        - `oreCooking` 不再接受 `RecipeSerializer`，现在接受 `CookingBookCategory`
        - `cookRecipes`、`simpleCookingRecipe` 不再接受 `RecipeSerializer`
        - `shapeless` 现在接受 `ItemStackTemplate` 而不是 `ItemStack`
    - `ShapedRecipeBuilder` 现在接受 `ItemStackTemplate` 作为结果，`ItemLike` 移至重载
        - 两个构造函数都是 `private`
    - `ShapelessRecipeBuilder` 现在接受 `ItemStackTemplate` 作为结果而不是 `ItemStack`
    - `SimpleCookingRecipeBuilder` 现在接受 `ItemStackTemplate` 作为结果，`ItemLike` 移至重载
        - `generic` 不再接受 `RecipeSerializer`，现在接受 `CookingBookCategory`
        - `blasting`、`smelting` 现在接受 `CookingBookCategory`
    - `SingleItemRecipeBuilder` 现在接受 `ItemStackTemplate` 作为结果，`ItemLike` 移至重载
        - `ItemStackTemplate` 构造函数是 `private`
    - `SmithingTransformRecipeBuilder` 现在接受 `ItemStackTemplate` 作为结果而不是 `Item`
    - `TransmuteRecipeBuilder` 现在接受 `ItemStackTemplate` 作为结果而不是 `Holder<Item>`
        - 构造函数是 `private`
        - `transmute` 现在有一个接受 `ItemStackTemplate` 作为结果的重载
        - `addMaterialCountToOutput`、`setMaterialCount` - 根据使用的材料数量处理结果堆栈的大小。
- `net.minecraft.network.chat.HoverEvent$ShowItem` 现在接受 `ItemStackTemplate` 而不是 `ItemStack`
- `net.minecraft.server.dialog.body.ItemBody` 现在接受 `ItemStackTemplate` 而不是 `ItemStack`
- `net.minecraft.world.entity.LivingEntity`
    - `dropFromEntityInteractLootTable` 现在接受 `ItemInstance` 而不是 `ItemStack` 作为工具
    - `dropFromShearingLootTable` 现在接受 `ItemInstance` 而不是 `ItemStack` 作为工具
- `net.minecraft.world.item`
    - `BundleItem#getSelectedItemStack` -> `getSelectedItem`，现在返回 `ItemStackTemplate` 而不是 `ItemStack`
    - `Item`
        - `getCraftingRemainder` 现在返回 `ItemStackTemplate` 而不是 `ItemStack`
        - `$Properties#craftRemainder` 现在有一个接受 `ItemStackTemplate` 的重载
    - `ItemInstance` - 一个类型化的物品实例，可以查询物品、大小及其组件。
    - `ItemStack` 现在实现 `ItemInstance`
        - `SINGLE_ITEM_CODEC`、`STRICT_CODEC`、`STRING_SINGLE_ITEM_CODEC`、`SIMPLE_ITEM_CODEC` 已移除
        - `getMaxStackSize` -> `ItemInstance#getMaxStackSize`
    - `ItemStackTemplate` - 一个包含堆栈不可变组件的记录：物品、数量和组件。
- `net.minecraft.world.item.component`
    - `BundleContents` 现在接受 `ItemStackTemplate` 列表而不是 `ItemStack`
        - `items` 现在返回 `ItemStackTemplate` 列表而不是 `ItemStack` 的可迭代对象
        - `itemsCopy` 已移除
        - `getSelectedItem` - 返回选中物品的堆栈模板，如果没有选中物品则返回 `null`。
    - `ChargedProjectile` 现在是一个记录
        - 构造函数接受 `ItemStackTemplate` 列表而不是 `ItemStack`
        - `of` -> `ofNonEmpty`
        - `getItems` -> `itemCopies`
    - `ItemContainerContents`
        - `stream` -> `allItemsCopyStream`
        - `nonEmptyStream` -> `nonEmptyItemCopyStream`
        - `nonEmptyItems`、`nonEmptyItemsCopy` -> `nonEmptyItems`，现在返回 `ItemStackTemplate` 的可迭代对象而不是 `ItemStack`
    - `UseRemainder` 现在接受 `ItemStackTemplate` 而不是 `ItemStack`
- `net.minecraft.world.item.crafting`
    - `AbstractCookingRecipe` 现在接受 `ItemStackTemplate` 而不是 `ItemStack` 作为结果
        - `$Factory#create` 现在接受 `ItemStackTemplate` 而不是 `ItemStack` 作为结果
    - `BlastingRecipe` 现在接受 `ItemStackTemplate` 而不是 `ItemStack` 作为结果
    - `CampfireCookingRecipe` 现在接受 `ItemStackTemplate` 而不是 `ItemStack` 作为结果
    - `ShapedRecipe` 现在接受 `ItemStackTemplate` 而不是 `ItemStack` 作为结果
    - `ShapelessRecipe` 现在接受 `ItemStackTemplate` 而不是 `ItemStack` 作为结果
    - `SingleItemRecipe` 现在接受 `ItemStackTemplate` 而不是 `ItemStack` 作为结果
        - `result` 现在返回 `ItemStackTemplate` 而不是 `ItemStack`
        - `$Factory#create` 现在接受 `ItemStackTemplate` 而不是 `ItemStack` 作为结果
    - `SmeltingRecipe` 现在接受 `ItemStackTemplate` 而不是 `ItemStack` 作为结果
    - `SmithingTransformRecipe` 现在接受 `ItemStackTemplate` 而不是 `ItemStack` 作为结果
    - `SmokingRecipe` 现在接受 `ItemStackTemplate` 而不是 `ItemStack` 作为结果
    - `StonecutterRecipe` 现在接受 `ItemStackTemplate` 而不是 `ItemStack` 作为结果
    - `TransmuteRecipe` 现在接受 `ItemStackTemplate` 而不是 `ItemStack` 作为结果
    - `TransmuteResult` -> `ItemStackTemplate`，不是一对一
        - `isResultUnchanged` 已移除
        - `apply` -> `TransmuteRecipe#createWithOriginalComponents`，不是一对一
- `net.minecraft.world.item.crafting.display.SlotDisplay$ItemStackSlotDisplay` 现在接受 `ItemStackTemplate` 而不是 `ItemStack`
- `net.minecraft.world.item.enchantment.EnchantmentHelper#getItemEnchantmentLevel` 现在接受 `ItemInstance` 而不是 `ItemStack`
- `net.minecraft.world.level.block.Block`
    - `dropFromBlockInteractLootTable` 现在接受 `ItemInstance` 而不是 `ItemStack`
    - `getDrops` 现在接受 `ItemInstance` 而不是 `ItemStack`
- `net.minecraft.world.level.block.entity.DecoratedPotBlockEntity#createdDecoratedPotItem` -> `createdDecoratedPotInstance`
    - `createDecoratedPotTemplate` 创建 `ItemStackTemplate` 而不是 `ItemStack`
- `net.minecraft.world.level.storage.loot`
    - `LootContext$ItemStackTarget` 现在为参数获取器实现 `ItemInstance` 泛型，而不是 `ItemStack`
    - `LootContextArg$ArgCodecBuilder#anyItemStack` 现在需要一个接受 `ItemInstance` 上下文键的函数，而不是 `ItemStack` 上下文键
- `net.minecraft.world.level.storage.loot.parameters.LootContextParams#TOOL` 现在是 `ItemInstance` 上下文键，而不是 `ItemStack` 上下文键

## 序列化器记录与配方信息

配方的实现已略有重做。首先，`RecipeSerializer` 现在是一个记录，接受用于序列化和反序列化配方的 `MapCodec` 和 `StreamCodec`。因此，`Serializer` 类已被完全移除，取而代之的是在注册期间向记录提供编解码器：

```java
// 假设某个 ExampleRecipe 实现了 Recipe
// 我们假设只有一个 INSTANCE
public static final RecipeSerializer<ExampleRecipe> EXAMPLE_RECIPE = new RecipeSerializer<>(
    // 用于从磁盘读取/写入配方的映射编解码器。
    MapCodec.unit(INSTANCE),
    // 用于从网络读取/写入配方的流编解码器。
    StreamCodec.unit(INSTANCE)
);
```

其次，一些关于配方设置和配方书信息的常见数据已被分离到单独的对象中。这些对象作为构造函数的一部分传递给配方，并用于更清晰地处理所有配方的类似实现。

原版提供了四个这样的常见对象类，分为两个不同的类别。`Recipe$CommonInfo` 用于通用配方设置。同时，`Recipe$BookInfo` 用于配方书信息，`CraftingRecipe$CraftingBookInfo` 用于合成配方，以及 `AbstractCookingRecipe$CookingBookInfo` 用于烹饪配方（例如，熔炼、高炉等）。这些常见对象类提供了根据需要构造编解码器的方法，然后可以将其传递给相关的配方编解码器。

这些类通常通过 `Recipe` 子类传递，用作实现抽象方法的样板。这些对象中的数据都不能直接在实现本身之外访问，只能通过 `Recipe` 接口中定义的方法访问。因此，可以使用 `NormalCraftingRecipe`、`CustomRecipe`、`SimpleSmithingRecipe`、`SingleItemRecipe` 和 `AbstractCookingRecipe` 等类通过实现几个方法来创建新的配方实现。

请注意，这些常见信息类是一种设计理念，您可以根据需要选择实现。只有在构建现有配方子类型时才需要使用它们。

- `net.minecraft.data.recipes`
    - `CustomCraftingRecipeBuilder` - 一个配方构建器，从某些常见和合成书籍信息创建任意合成配方。
    - `RecipeBuilder`
        - `determineBookCategory` -> `determineCraftingBookCategory`
        - `createCraftingCommonInfo` - 创建常见的配方信息。
        - `createCraftingBookInfo` - 创建合成书籍信息。
    - `RecipeUnlockAdvancementBuilder` - 用于解锁配方的进度构建器。
    - `SpecialRecipeBuilder`、`special` 现在接受一个提供的 `Recipe` 而不是一个 `CraftingBookCategory` 到 `Recipe` 的函数
        - `unlockedBy` - 解锁配方进度所需的条件。
- `net.minecraft.world.item.crafting`
    - `AbstractCookingRecipe` 现在接受 `Recipe$CommonInfo` 和 `$CookingBookInfo` 而不是 group 和 `CookingBookCategory`
        - `$Factory#create` 现在接受 `Recipe$CommonInfo` 和 `$CookingBookInfo` 而不是 group 和 `CookingBookCategory`
        - `$Serializer` 被 `cookingMapCodec`、`cookingStreamCodec` 取代
        - `$CookingBookInfo` - 一个包含配方书常见烹饪信息的记录。
    - `BannerDuplicateRecipe` 现在接受旗帜 `Ingredient` 和 `ItemStackTemplate` 结果，而不是 `CraftingBookCategory`
        - `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER` - 配方的序列化器。
    - `BlastingRecipe` 现在接受 `Recipe$CommonInfo` 和 `$AbstractCookingRecipeCookingBookInfo` 而不是 group 和 `CookingBookCategory`
        - `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER` - 配方的序列化器。
    - `BookCloningRecipe` 现在接受源和材料的 `Ingredient`、定义可复制代数的 `MinMaxBounds$Int`s，以及 `ItemStackTemplate` 结果，而不是 `CraftingBookCategory`
        - `ALLOWED_BOOK_GENERATION_RANGES`、`DEFAULT_BOOK_GENERATION_RANGES` - 书籍代数克隆的范围。
        - `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER` - 配方的序列化器。
    - `CampfireCookingRecipe` 现在接受 `Recipe$CommonInfo` 和 `AbstractCookingRecipe$CookingBookInfo` 而不是 group 和 `CookingBookCategory`
        - `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER` - 配方的序列化器。
    - `CraftingRecipe$CraftingBookInfo` - 一个包含配方书常见合成信息的记录。
    - `CustomRecipe` 不再接受任何构造函数参数
        - `$Serializer` 已移除，被其实现的编解码器取代
    - `DecoratedPotRecipe` 现在接受每侧的 `Ingredient` 图案以及 `ItemStackTemplate` 结果，而不是 `CraftingBookCategory`
        - `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER` - 配方的序列化器。
    - `DyeRecipe` 现在接受 `Recipe$CommonInfo` 和 `CraftingRecipe$CraftingBookInfo`，以及目标物品和染料的 `Ingredient` 和 `ItemStackTemplate` 结果，而不是 `CraftingBookCategory`
        - `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER` - 配方的序列化器。
    - `FireworkRocketRecipe` 现在接受外壳、燃料和星星的 `Ingredient` 以及 `ItemStackTemplate` 结果，而不是 `CraftingBookCategory`
        - `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER` - 配方的序列化器。
    - `FireworkStarFadeRecipe` 现在接受目标物品和染料的 `Ingredient` 以及 `ItemStackTemplate` 结果，而不是 `CraftingBookCategory`
        - `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER` - 配方的序列化器。
    - `FireworkStarRecipe` 现在接受 `$Shape` 到 `Ingredient` 的映射；踪迹、闪烁、燃料和染料的 `Ingredient`；以及 `ItemStackTemplate` 结果，而不是 `CraftingBookCategory`
        - `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER` - 配方的序列化器。
    - `MapCloningRecipe` 被 `TransmuteRecipe` 取代
    - `MapExtendingRecipe` 现在扩展 `CustomRecipe` 而不是 `ShapedRecipe`
        - 构造函数现在接受地图和材料的 `Ingredient` 以及 `ItemStackTemplate` 结果，而不是 `CraftingBookCategory`
        - `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER` - 配方的序列化器。
    - `NormalCraftingRecipe` - 一个定义合成配方标准实现的类。
    - `Recipe`
        - `showNotification`、`group` 不再是默认的
        - `$BookInfo` - 配方书的信息。
        - `$CommonInfo` - 所有配方的常见信息。
    - `RecipeSerializer` 现在是一个包含 `MapCodec` 和 `StreamCodec` 的记录
        - 注册的条目已移至 `RecipeSerializers`
        - `register` 已移除
    - `RecipeSerializers` - 所有配方的原版序列化器。
    - `RepairItemRecipe` 不再接受任何参数
        - `INSTANCE` - 配方序列化器单例。
        - `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER` - 配方的序列化器。
    - `ShapedRecipe` 现在扩展 `NormalCraftingRecipe` 而不是实现 `CraftingRecipe`
        - 构造函数现在接受 `Recipe$CommonInfo` 和 `CraftingRecipe$CraftingBookInfo` 而不是 group 和 `CraftingBookCategory`
        - `$Serializer` -> `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER`；不是一对一
    - `ShapelessRecipe` 现在扩展 `NormalCraftingRecipe` 而不是实现 `CraftingRecipe`
        - 构造函数现在接受 `Recipe$CommonInfo` 和 `CraftingRecipe$CraftingBookInfo` 而不是 group 和 `CraftingBookCategory`
        - `$Serializer` -> `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER`；不是一对一
    - `ShieldDecorationRecipe` 现在接受旗帜和目标物品的 `Ingredient` 以及 `ItemStackTemplate` 结果，而不是 `CraftingBookCategory`
        - `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER` - 配方的序列化器。
    - `SimpleSmithingRecipe` - 一个定义锻造配方标准实现的类。
    - `SingleItemRecipe` 现在接受 `Recipe$CommonInfo` 而不是 group
        - `commonInfo` - 配方的常见信息。
        - `$Factory#create` 现在接受 `Recipe$CommonInfo` 而不是 group
        - `$Serializer` -> `simpleMapCodec`、`simpleStreamCodec`；不是一对一
    - `SmeltingRecipe` 现在接受 `Recipe$CommonInfo` 和 `AbstractCookingRecipe$CookingBookInfo` 而不是 group 和 `CookingBookCategory`
        - `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER` - 配方的序列化器。
    - `SmithingTransformRecipe` 现在扩展 `SimpleSmithingRecipe` 而不是实现 `SmithingRecipe`
        - 构造函数现在接受 `Recipe$CommonInfo`
        - `$Serializer` -> `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER`；不是一对一
    - `SmithingTrimRecipe` 现在扩展 `SimpleSmithingRecipe` 而不是实现 `SmithingRecipe`
        - 构造函数现在接受 `Recipe$CommonInfo`
        - `$Serializer` -> `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER`；不是一对一
    - `SmokingRecipe` 现在接受 `Recipe$CommonInfo` 和 `AbstractCookingRecipe$CookingBookInfo` 而不是 group 和 `CookingBookCategory`
        - `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER` - 配方的序列化器。
    - `StonecutterRecipe` 现在接受 `Recipe$CommonInfo` 而不是 group
        - `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER` - 配方的序列化器。
    - `TippedArrowRecipe` -> `ImbueRecipe`，不是一对一
        - 构造函数现在接受 `Recipe$CommonInfo` 和 `CraftingRecipe$CraftingBookInfo`，以及源材料和材料的 `Ingredient` 和 `ItemStackTemplate` 结果，而不是 `CraftingBookCategory`
        - `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER` - 配方的序列化器。
    - `TransmuteRecipe` 现在扩展 `NormalCraftingRecipe` 而不是实现 `CraftingRecipe`
        - 构造函数现在接受 `Recipe$CommonInfo` 和 `CraftingRecipe$CraftingBookInfo`，以及处理材料数量并将其添加到结果的 `MinMaxBounds$Ints` 和 `boolean`，而不是 group 和 `CraftingBookCategory`
        - `$Serializer` -> `MAP_CODEC`、`STREAM_CODEC`、`SERIALIZER`；不是一对一
- `net.minecraft.world.item.crafting.display.SlotDisplay`
    - `$OnlyWithComponent` - 仅当内容具有所需组件时才显示的显示。
    - `$WithAnyPotion` - 内容具有任何药水内容组件的显示。
- `net.minecraft.world.level.storage.loot.functions.SmeltItemFunction#smelted` 现在可以接受是否使用输入材料数量

## 染料组件

指定物品是否可用作染料材料现在通过 `DYE` 数据组件处理。该组件指定一个 `DyeColor`，可以通过 `Item$Properties#component` 设置：

```java
public static final Item EXAMPLE_DYE = new Item(new Item.Properties().component(
    DataComponents.DYE, DyeColor.WHITE
));
```

然而，染料材料的行为并不仅仅由组件本身完全涵盖。在大多数情况下，该组件与某些其他标签或子类结合使用以获得所需的行为。

### 实体和告示牌

给绵羊和告示牌染色完全通过 `DyeItem` 子类处理，检查物品是否具有 `DYE` 组件。

另一方面，给狼和猫的项圈染色可以是任何物品，只要它具有 `DYE` 组件即可。此外，该物品必须分别位于 `ItemTags#WOLF_COLLAR_DYES` 或 `ItemTags#CAT_COLLAR_DYES` 标签中。

### 染料配方

`DyeRecipe`（以前称为 `ArmorDyeRecipe`）可以接受任何目标原料，并应用染料原料的颜色以获得带有关联 `DYED_COLOR` 组件的所需结果。任何物品都可以被视为染料；但是，没有 `DYE` 组件的物品将默认为 `DyeColor#WHITE`。盔甲使用 `RecipeProvider#dyedItem` 来允许 `ItemTags#DYES` 标签中的任何物品给盔甲染色。然而，捆绑包和潜影盒的颜色组件是不同的物品，这意味着默认配方直接与原版 `DyeItem` 绑定，因此需要为将这些物品应用染料生成单独的配方。

另一方面，织布机、烟花星和烟花星面配方期望任何染料材料都具有 `DYE` 组件。织布机还有一个额外要求，即物品位于 `ItemTags#LOOM_DYES` 标签中。

- `net.minecraft.core.component.DataComponents#DYE` - 表示物品可以作为特定颜色的染料。
- `net.minecraft.data.recipes.RecipeProvider`
    - `dyedItem` - 创建一个染色物品配方。
    - `dyedShulkerBoxRecipe` - 创建一个染色潜影盒配方。
    - `dyedBundleRecipe` - 创建一个染色捆绑包配方。
- `net.minecraft.world.item`
    - `BundleItem`
        - `getAllBundleItemColors`、`getByColor` 已移除
    - `DyeColor#VALUES` - 所有染料颜色的列表。
    - `DyeItem` 不再接受 `DyeColor`
        - `getDyeColor`、`byColor` 已移除
- `net.minecraft.world.item.component.DyedItemColor#applyDyes` 现在接受 `DyeColor` 列表而不是 `DyeItem`
    - 还有一个重载可以接受 `DyedItemColor` 组件而不是 `ItemStack`
- `net.minecraft.world.item.crafting.ArmorDyeRecipe` -> `DyeRecipe`，不是一对一
- `net.minecraft.world.item.crafting.display.SlotDisplay$DyedSlotDemo` - 用于演示物品染色的显示。
- `net.minecraft.world.level.block`
    - `BannerBlock#byColor` 已移除
    - `ShulkerBoxBlock#getBlockByColor`、`getColoredItemStack` 已移除

## 世界时钟与时间标记

世界时钟是表示从世界首次加载起每刻增加的时间的对象。这些时钟用作计时器，以正确处理基于时间的事件（例如，当前日期、睡眠）。原版提供了两个世界时钟：一个用于 `minecraft:overworld`，一个用于 `minecraft:the_end`。

创建时钟非常简单：只需在 `world_clock` 中创建一个空的数据包注册表对象。

```json5
// 对于某个世界时钟 'examplemod:EXAMPLE_CLOCK'
// JSON 位于 'data/examplemod/world_clock/EXAMPLE_CLOCK.json'
{}
```

然后，您可以通过 `ClockManager` 通过 `Level#clockManager` 或 `MinecraftServer#clockManager` 查询时钟状态：

```java
// 对于某个 Level level
// 假设我们有某个 ResourceKey<WorldClock> EXAMPLE_CLOCK

// 获取时钟引用
Holder.Reference<WorldClock> clock = level.registryAccess().getOrThrow(EXAMPLE_CLOCK);

// 查询时钟时间
long ticksPassed = level.clockManager().getTotalTicks(clock);
```

如果从服务器访问时钟，您还可以修改时钟的状态：

```java
// 对于某个 ServerLevel level
// 假设我们有某个 ResourceKey<WorldClock> EXAMPLE_CLOCK

// 获取时钟引用
Holder.Reference<WorldClock> clock = level.registryAccess().getOrThrow(EXAMPLE_CLOCK);

// 获取服务器时钟管理器
ServerClockManager clockManager = level.clockManager();

// 设置已过去的刻数总数
clockManager.setTotalTicks(clock, 0L);

// 将刻数增加某个值
clockManager.addTicks(clock, 10L);

// 暂停时钟
clockManager.setPaused(
    clock,
    // `true` 暂停。
    // `false` 恢复。
    true
);
```

### 标记时间线

世界时钟本身的范围相当有限，因为您必须跟踪已过去的刻数。然而，当与时间线一起使用时，可以标记特定的重复时间来处理基于时间的事件。

作为回顾，`Timeline` 是一种基于某个 `WorldClock` 修改属性的方法。目前，所有原版时间线都使用 `minecraft:overworld` 世界时钟通过 `clock` 字段来跟踪它们的时间。所有时间线都必须定义它使用的时钟；但是，请注意，时钟默认不支持任何同步，这意味着更新一个时钟的时间不会影响另一个时钟。

```json5
// 对于某个时间线 'examplemod:example_timeline'
// 在 `data/examplemod/timeline/example_timeline.json
{
    // 使用自定义时钟。
    // 对时钟时间的任何更改只会影响
    // 使用此时钟的时间线。
    // 例如，`minecraft:overworld` 不会被更改。
    "clock": "examplemod:example_clock",
    // 以 24,000 刻的间隔执行操作。
    "period_ticks": "24000",
    // ...
}


// 对于某个时间线 'examplemod:example_timeline_2'
// 在 `data/examplemod/timeline/example_timeline_2.json
{
    // 使用与上面相同的时钟。
    // 对时钟时间的更改将影响这两个
    // 时间线。
    "clock": "examplemod:example_clock",
    // 以 1,000 刻的间隔执行操作。
    "period_ticks": "1000",
    // ...
}

// 对于某个时间线 'examplemod:example_overworld'
// 在 `data/examplemod/timeline/example_overworld.json
{
    // 使用原版主世界时钟。
    // 对时钟时间的更改不会影响
    // 上面的时间线，因为它们使用不同的
    // 时钟。
    "clock": "minecraft:overworld",
    // 以 6,000 刻的间隔执行操作。
    "period_ticks": "6000",
    // ...
}
```

时间线还可以定义时间标记，这只是世界时钟时间线周期内某个时间的标识符。这些通常用于命令内部（例如 `/time set`），以检查是否已经过了某个时间（例如，村庄袭击），或跳转到给定时间（例如，从睡眠中醒来）。时间标记在 `time_markers` 中定义，指定周期内的 `ticks` 以及是否可以在 `show_in_commands` 中显示。由于时间标记由其世界时钟标识，因此使用相同世界时钟的时间线不能定义相同的时间标记。

```json5
// 对于某个时间线 'examplemod:example_timeline'
// 在 `data/examplemod/timeline/example_timeline.json
{
    // 时钟的标识符。
    "clock": "examplemod:example_clock",
    // 以 24,000 刻的间隔执行操作。
    "period_ticks": "24000",
    // 时间线指定的周期内的标记
    "time_markers": {
        // 一个标记
        "examplemod:example_marker": {
            // 此标记表示的周期内的刻数。
            // 例如，5000、29000、53000 等。
            "ticks": 5000,
            // 当为 true 时，允许在命令中建议时间标记。
            // 如果为 false，仍然可以在命令中使用时间标记，
            // 只是不会被建议。
            "show_in_commands": true
        }
    }
    // ...
}
```

一旦定义了时间标记，它们就会在 `ServerClockManager` 中为世界时钟注册，从而允许它们被给定 `ResourceKey` 使用。

```java
// 对于某个 ServerLevel level
// 假设我们有某个 ResourceKey<WorldClock> EXAMPLE_CLOCK
// 假设我们有某个 ResourceKey<ClockTimerMarker> EXAMPLE_MARKER

// 获取时钟引用
Holder.Reference<WorldClock> clock = level.registryAccess().getOrThrow(EXAMPLE_CLOCK);

// 获取服务器时钟管理器
ServerClockManager clockManager = level.clockManager();

// 检查时间是否在指定的标记处
// 这应在每刻检查特定时间事件时使用
boolean atMarker = clockManager.isAtTimeMarker(clock, EXAMPLE_MARKER);

// 跳转到标记指定的时间
// 如果世界时钟在 3000，则将时钟时间设置为 5000
// 如果世界时钟在 6000，则将时钟时间设置为 29000
// 返回时间是否被设置，如果标记对于时钟存在，则始终为 true。
boolean timeSet = clockManager.skipToTimeMarker(clock, EXAMPLE_MARKER);
```

- `net.minecraft.client.ClientClockManager` - 在客户端管理世界时钟的滴答。
- `net.minecraft.client.gui.components.debug.DebugEntryDayCount` - 显示 Minecraft 世界的当前日期。
- `net.minecraft.client.multiplayer`
    - `ClientLevel`
        - `setTimeFromServer` 不再接受 `long` 白天时间，也不再接受是否滴答白天时间的 `boolean`
        - `$ClientLevelData#setDayTime` 已移除
    - `ClientPacketListener#clockManager` - 获取客户端时钟管理器。
- `net.minecraft.client.renderer.EndFlashState#tick` 现在接受结束时钟时间而不是游戏时间
- `net.minecraft.commands.arguments.ResourceArgument`
    - `getClock` - 根据字符串资源标识符获取世界时钟的引用。
    - `getTimeline` - 根据字符串资源标识符获取时间线的引用。
- `net.minecraft.core.registries.Registries#WORLD_CLOCK` - 世界时钟的注册表标识符。
- `net.minecraft.gametest.framework.TestEnvironmentDefinition`
    - `$TimeOfDay` -> `$ClockTime`，不是一对一
    - `$Timelines` - 一个使用时间线列表的测试环境。
- `net.minecraft.network.protocol.game.ClientboundSetTimePacket` 现在接受一个时钟到其网络状态的映射，而不是白天时间 `long` 和 `boolean`
- `net.minecraft.server`
    - `MinecraftServer`
        - `forceTimeSynchronization` -> `forceGameTimeSynchronization`，不是一对一
        - `clockManager` - 服务器时钟管理器。
- `net.minecraft.server.level.ServerLevel`
    - `setDayTime`、`getDayCount` 已移除
    - `setEnvironmentAttributes` - 设置要使用的环境属性系统。
- `net.minecraft.world.attribute.EnvironmentAttributeSystem$Builder#addTimelineLayer` 现在接受 `ClockManager` 而不是 `LongSupplier`
- `net.minecraft.world.clock`
    - `ClockManager` - 一个管理器，获取世界时钟已过去的刻数总数。
    - `ClockNetworkState` - 要在网络上同步的时钟的当前状态。
    - `ClockState` - 时钟的当前状态，包括总刻数和时钟是否暂停。
    - `ClockTimeMarker` - 一个跟踪世界时钟某个时间段的标记。
    - `ClockTimeMarkers` - 所有原版时间标记。
    - `PackedClockStates` - 一个时钟到其状态的映射，为存储或其他用途而压缩。
    - `ServerClockManager` - 在服务器端管理世界时钟的滴答。
    - `WorldClock` - 一个表示某个位置计时键的空记录。
    - `WorldClocks` - 所有原版世界时钟。
- `net.minecraft.world.level`
    - `Level`
        - `getDayTime` -> `getOverworldClockTime`，不是一对一
        - `clockManager` - 时钟管理器。
        - `getDefaultClockTime` - 获取当前维度的时钟时间。
    - `LevelReader#getEffectiveSkyBrightness` - 使用当前变暗因子获取天空亮度。
- `net.minecraft.world.level.dimension.DimensionType` 现在接受一个默认的、持有者包装的 `WorldClock`
- `net.minecraft.world.level.storage`
    - `LevelData#getDayTime` 已移除
    - `ServerLevelData`
        - `setDayTime` 已移除
        - `setClockStates`、`clockStates` - 处理世界时钟的当前状态。
- `net.minecraft.world.level.storage.loot.predicates.TimeCheck` 现在接受一个持有者包装的 `WorldClock`
    - `time` 现在接受一个持有者包装的 `WorldClock`
    - `$Builder` 现在接受一个持有者包装的 `WorldClock`
- `net.minecraft.world.timeline`
    - `AttributeTrack#bakeSampler` 现在接受一个持有者包装的 `WorldClock`
    - `AttributeTrackSampler` 现在接受一个持有者包装的 `WorldClock`，以及一个 `ClockManager` 而不是用于白天时间获取器的 `LongSupplier`
    - `Timeline` 现在接受一个持有者包装的 `WorldClock` 以及一个时间标记到其信息的映射
        - `#builder` 现在接受一个持有者包装的 `WorldClock`
        - `getPeriodCount` - 获取在给定时间范围内已发生的周期数。
        - `getCurrentTicks` 现在接受 `ClockManager` 而不是 `Level`
        - `getTotalTicks` 现在接受 `ClockManager` 而不是 `Level`
        - `clock` - 返回持有者包装的 `WorldClock`。
        - `registerTimeMarkers` - 注册此时间线中定义的所有 `ClockTimeMarker`。
        - `createTrackSampler` 现在接受 `ClockManager` 而不是用于白天时间获取器的 `LongSupplier`
        - `$Builder#addTimeMarker` - 在给定刻数添加一个时间标记，以及是否可以在命令中建议该标记。
    - `Timelines#DAY` -> `OVERWORLD_DAY`

## 将主关卡数据拆分为保存数据

一些 `WorldData` 设置已移至 `SavedData`，允许等级/维度具有更多可定制性。这一增加还带来了一些关于如何引用和查询 `SavedData` 的变化。

### 保存数据变更

`SavedDataType` 现在使用 `Identifier` 标识某些 `SavedData`，该标识符针对数据文件夹进行解析。此更改允许数据文件夹内的子目录，因为数据存储将在尝试写入文件之前首先创建所有缺失的父目录。

```java
public class ExampleData extends SavedData {

    public static final SavedDataType<ExampleData> TYPE = new SavedDataType<>(
        // 要解析的保存数据的标识符
        // 数据可以在以下位置找到：
        // `<world_folder>/dimensions/<dimension_namespace>/<dimension_path>/data/examplemod/example/data.dat`
        Identifier.fromNamespaceAndPath("examplemod", "example/data"),
        // 创建新保存数据的构造函数
        ExampleData::new,
        // 序列化新保存数据的编解码器
        MapCodec.unitCodec(ExampleData::new),
        // 数据修复器类型
        // 要么是一些修补的枚举值，要么根据模组加载器实现为 null。
        null
    );
}
```

然后可以通过 `SavedDataStorage`（从 `DimensionDataStorage` 重命名而来）查询 `SavedData`。重命名是因为 `MinecraftServer` 实例现在除了等级之外，还有自己的用于全局实例的数据存储。这意味着任何全局保存的数据都应存储在服务器实例上，而不是主世界。

```java
// 给定一个 MinecraftServer server
ExampleData data = server.getDataStorage().computeIfAbsent(ExampleData.TYPE);


// 给定一个 ServerLevel level
ExampleData data = level.getDataStorage().computeIfAbsent(ExampleData.TYPE);
```

### 额外的保存数据

以下信息现在存储为保存数据：

- 自定义 Boss 事件
- 末影龙战斗
- 游戏规则
- 流浪商人生成
- 天气
- 世界生成设置

其中，只有末影龙战斗是基于每个等级/维度的。其余仍然通过服务器数据存储存储和访问。另一方面，自定义 Boss 事件仍然是唯一的，因为它由实现者决定哪些玩家参与事件。

- `net.minecraft.client.Minecraft#doWorldLoad` 现在接受可选的 `GameRules`
- `net.minecraft.client.gui.screens.worldselection`
    - `CreateWorldCallback` 现在接受 `LevelDataAndDimensions$WorldDataAndGenSettings` 和可选的 `GameRules`，而不是 `PrimaryLevelData`
    - `EditGameRulesScreen` -> `AbstractGameRulesScreen`
        - 实现在 `.screens.options.InWorldGameRulesScreen` 和 `WorldCreationGameRulesScreen` 中
    - `WorldOpenFlows`
        - `createLevelFromExistingSettings` 现在接受 `LevelDataAndDimensions$WorldDataAndGenSettings` 和可选的 `GameRules`，而不是 `WorldData`
        - `loadWorldStem` 现在接受 `LevelStorageSource$LevelStorageAccess`
- `net.minecraft.client.server.IntegratedServer` 现在接受可选的 `GameRules`
- `net.minecraft.server`
    - `MinecraftServer` 现在接受可选的 `GameRules`
        - `getGlobalGameRules` - 获取主世界维度的游戏规则。
        - `getWorldGenSettings` - 获取世界的生成设置。
        - `getWeatherData` - 获取服务器的天气数据。
        - `getDataStorage` - 获取服务器的保存数据存储。
        - `getGameRules` - 获取服务器的游戏规则。
    - `WorldStem` 现在接受 `LevelDataAndDimensions$WorldDataAndGenSettings` 而不是 `WorldData`
- `net.minecraft.server.bossevents`
    - `CustomBossEvent` 现在接受一个 `UUID` 作为标识符，以及一个 `Runnable` 作为回调
        - `getTextId` -> `customId`
        - `addOfflinePlayer` 已移除
        - `getValue` -> `value`
        - `getMax` -> `max`
        - `load` 现在接受 `UUID` 标识符以及一个 `Runnable` 作为回调
    - `CustomBossEvents` 现在扩展 `SavedData`
        - `create` 现在接受一个 `RandomSource`
        - `save`、`load` -> `TYPE`，不是一对一
- `net.minecraft.server.dedicated.DedicatedServer` 现在接受可选的 `GameRules`
- `net.minecraft.server.level`
    - `ChunkMap#getChunkDataFixContextTag` 现在接受一个可选的 `Identifier` 而不是 `ResourceKey`
    - `ServerBossEvent` 现在接受一个 `UUID` 作为 id
        - `setDirty` - 将 boss 事件标记为脏以进行保存。
    - `ServerLevel` 不再接受 `RandomSequences`
        - `setWeatherParameters` -> `MinecraftServer#setWeatherParameters`
        - `getWeatherData` - 获取服务器的天气数据。
        - `getRandomSequence` -> `MinecraftServer#getRandomSequence`
        - `getRandomSequences` -> `MinecraftServer#getRandomSequences`
- `net.minecraft.world.entity.npc.wanderingtrader.WanderingTraderSpawner` 现在接受 `SavedDataStorage` 而不是 `ServerLevelData`
    - `MIN_SPAWN_CHANCE` 现在从 `private` 变为 `public`
- `net.minecraft.world.entity.raid.Raids#TYPE_END`、`getType` 已移除
- `net.minecraft.world.level`
    - `Level#prepareWeather` 已移除
    - `LevelSettings` 现在是一个记录
        - 构造函数现在接受 `$DifficultySettings` 而不是仅仅 `Difficulty`
        - `withDifficultyLock` - 带有难度是否锁定的设置。
        - `copy` - 复制设置。
        - `$DifficultySettings` - 难度的设置。
- `net.minecraft.world.level.dimension.DimensionType` 现在接受一个 `boolean`，表示维度是否可以有末影龙战斗
- `net.minecraft.world.level.dimension.end`
    - `DragonRespawnAnimation` -> `DragonRespawnStage`，不是一对一
    - `EndDragonFight` -> `EnderDragonFight`，不是一对一
- `net.minecraft.world.level.gamerules.GameRuleMap` 现在扩展 `SavedData`
    - `TYPE` - 保存数据类型。
    - `reset` - 将规则重置为其默认值。
- `net.minecraft.world.level.levelgen.WorldGenSettings` 现在是一个 final 类而不是记录，扩展 `SavedData`
    - `encode`、`decode` 被 `TYPE` 取代
    - `of` - 构造生成设置。
- `net.minecraft.world.level.saveddata`
    - `SavedDataType` 现在接受 `Identifier` 而不是字符串作为 id
    - `WanderingTraderData` - 流浪商人的保存数据。
    - `WeatherData` - 天气的保存数据。
- `net.minecraft.world.level.storage`
    - `DimensionDataStorage` -> `SavedDataStorage`，不是一对一
    - `LevelData#isThundering`、`isRaining`、`setRaining` 现在在 `WeatherData` 中
    - `LevelDataAndDimensions` 现在接受 `$WorldDataAndGenSettings` 而不是 `WorldData`
        - `$WorldDataAndGenSettings` - 保存世界数据和生成设置。
    - `LevelResource` 现在是一个记录
    - `PrimaryLevelData` 字段已移至各自的保存数据类
        - `PLAYER` -> `OLD_PLAYER`
        - `SINGLEPLAYER_UUID` - 一个表示单机世界中玩家 UUID 的字符串。
        - `WORLD_GEN_SETTINGS` -> `OLD_WORLD_GEN_SETTINGS`
        - `writeLastPlayed` - 写入最后玩的玩家。
        - `writeVersionTag` - 写入数据版本标签。
    - `ServerLevelData`
        - `setThundering`、`getRainTime`、`setRainTime`、`setThunderTime`、`getThunderTime`、`getClearWeatherTime`、`setClearWeatherTime` 移至 `WeatherData`
        - `getWanderingTraderSpawnDelay`、`setWanderingTraderSpawnDelay`、`getWanderingTraderSpawnChance`、`setWanderingTraderSpawnChance`、`getWanderingTraderId`、`setWanderingTraderId` 移至 `WanderingTraderData`
        - `getLegacyWorldBorderSettings`、`setLegacyWorldBorderSettings` 被 `WorldBorder` 取代
        - `getScheduledEvents` -> `MinecraftServer#getScheduledEvents`
        - `getGameRules` 被 `GameRuleMap` 取代
    - `WorldData`
        - `getCustomBossEvents`、`setCustomBossEvents` 被 `CustomBossEvents` 取代
        - `createTag` 不再接受 `RegistryAccess`
        - `getGameRules` 被 `GameRuleMap` 取代
        - `getLoadedPlayerTag` -> `getSinglePlayerUUID`，不是一对一
        - `endDragonFightData`、`setEndDragonFightData` 被 `EnderDragonFight` 取代
        - `worldGenOptions` 被 `WorldGenSettings` 保存数据取代
- `net.minecraft.world.level.timers.TimerQueue` 现在扩展 `SavedData`
    - 构造函数现在接受 `$Packed` 事件，而不是 `TimerCallbacks` 和事件数据的 `Stream`
    - `store` 被 `CODEC`、`TYPE`、`codec` 取代
    - `loadEvent`、`storeEvent` 被 `$Event$Packed#codec` 取代
    - `$Event` 现在是一个记录
        - `$Packed` - 打包的事件数据。
    - `$Packed` - 打包的时间队列。

## 更多渲染变更

### 材质与动态层选择

方块和物品模型现在不再指定它们属于哪个 `RenderType` 或 `ChunkSectionLayer`。相反，这在加载模型时计算，确定每个四边形的关联层。这意味着 `ItemBlockRenderTypes` 被移除，物品的 `RenderType` 设置也被完全移除。

为了确定四边形或面被设置到哪个层，会计算纹理的 `Transparency`。具体来说，对于映射到四边形的 UV 区域，检查是否存在任何透明像素（alpha 为 0）或半透明像素（alpha 不为 0 或 255）。对于 `ChunkSectionLayer`，如果存在半透明像素则使用 `ChunkSectionLayer#TRANSLUCENT`，否则如果存在透明像素则使用 `CUTOUT`，否则使用 `SOLID`。对于物品 `RenderType`，如果存在半透明像素则使用 `Sheets#translucentItemSheet` 和用于方块物品的 `translucentBlockItemSheet`，否则使用 `cutoutItemSheet` 和用于方块物品的 `cutoutBlockItemSheet`。`Transparency` 也影响 `MipmapStrategy#AUTO` 的使用，如果存在透明像素则使用 `CUTOUT` 而不是 `MEAN` 作为默认值。

可以通过模型 JSON 定义的 `Material` 纹理来影响四边形的 `Transparency`。一个 `Material` 指定纹理的 `sprite`，它表示纹理的相对路径，以及可选的 `force_translucent`，它强制使用此纹理的任何四边形使用 `Transparency#TRANSLUCENT`（透明为 false，半透明为 true）：

```json5
// 对于某个模型 `examplemod:example_model`
// 在：`assets/examplemod/models/example_model.json`
{
    "parent": "minecraft:block/template_glass_pane_post",
    "textures": {
        // Material 可以是一个简单的纹理引用
        // 指向 `assets/minecraft/textures/block/glass_pane_top.png`
        "edge": "minecraft:block/glass_pane_top",
        // 或者它可以是一个对象
        "pane": {
            // 使用此键的面的相对纹理引用
            // 指向 `assets/minecraft/textures/block/glass.png`
            "sprite": "minecraft:block/glass",
            // 当为 true 时，将此纹理键的所有面设置为
            // 始终具有透明像素。
            "force_translucent": true
        }
    }
    // ...
}
```

此更改还定义了渲染顺序，其中所有实体四边形首先渲染，然后是切割四边形，最后是半透明四边形，按距离相机的距离排序。

### 材质与精灵

您可能已经注意到，`Material` 最初用于定义图集中的某些纹理。纹理 JSON 中材质的添加改变了这些类的命名。`Material` 现在明确指代模型 JSON 中的纹理引用。这意味着，所有对原始纹理位置的引用都已替换为 `Material`（如果未烘焙）和 `Material$Baked`（如果已烘焙）。此外，`SpriteGetter` 现在是 `MaterialBaker`。

至于原来的 `Material`，现在称为精灵，其中 `Material` 重命名为 `SpriteId`，`MaterialSet` 重命名为 `SpriteGetter`。

### 四边形粒子层

`SingleQuadParticle$Layer` 已拆分为 `OPAQUE_*` 和 `TRANSLUCENT_*` 层，具体取决于图集使用的粒子纹理是否包含半透明像素。请注意，这里的“opaque”指的是切割，其中 alpha 小于 0.1 的像素被丢弃。如果不创建新层，可以使用 `$Layer#bySprite` 来确定粒子纹理应使用的层。

```java
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;
    }
}
```

### 方块模型

在通用世界上下文之外渲染单个方块模型的管道已被重写，类似于 `ItemModel`，其中“方块模型”更新某个渲染状态，然后提交其元素进行渲染。因此，大多数方块模型类已被重写或在一定程度上重新组织。

由于方块模型名称通常与通用模型 JSON 同义，许多类被移动和重命名，以将模型 JSON 与方块状态 JSON 以及现在的方块模型分开。因此，原始名称中带有“block”的模型几何体已更改为“cuboid”：（例如，`BlockModel` -> `CuboidModel`，`BlockModelWrapper` -> `CuboidItemModelWrapper`）。此外，引用方块状态 JSON 内定义的渲染过程部分已从“block”更改为“block state”（例如，`BlockModelPart` -> `BlockStateModelPart`，`BlockModelDefinition` -> `BlockStateModelDispatcher`）。您可以认为大多数“block model”类是新的，而那些重命名的类取代了 `SpecialBlockModelRenderer` 系统。

方块模型系统从所有模型和定义加载并解析后的 `ModelManager` 开始，准备进行烘焙。方块模型通过 `BuiltInBlockModels#crateBlockModels` 加载，它将某个 `BlockState` 链接到 `BlockModel$Unbaked`。与物品模型类似，未烘焙实例定义了应如何构建方块模型的属性。这些存储在 `LoadedBlockModels` 中，然后在所有 JSON 之后通过 `bake` 烘焙成 `BlockModel`。然后，这个 `BlockState` 到 `BlockModel` 的映射存储在 `BlockModelSet` 中，准备好通过 `get` 查询，或者更常见的是通过 `BlockModelResolver#update` 查询，后者调用模型集。任何未延迟定义的模型都会解析为 `BlockStateModel` 的包装器。

原版为常见用途提供了六种 `BlockModel` 实现。有 `EmptyBlockModel`，它不提交任何元素，因此不渲染任何内容；以及 `BlockStateModelWrapper`，它包装并显示关联的 `BlockStateModel`。然后，有根据某些属性开关更改模型的等价物（`SelectBlockModel`）、条件 `boolean`（`ConditionalBlockModel`）以及将多个模型组合在一起的组合（`CompositeBlockModel`）。最后，有 `SpecialBlockModelWrapper`，它通过存储的 `SpecialModelRenderer` 提交其元素，这是物品和方块模型之间的统一提交器。

```java
// 由于方块模型系统通过其代码内引导程序进行硬编码，
// 此示例将假设存在某种方法来访问 `BuiltInBlockModels$Builder` 构建器。

// 我们还将假设我们有某个 Block EXAMPLE_BLOCK_* 来附加模型。

// 常规方块模型
builder.put(
    // 一个工厂，接受 `BlockColors` 和 `BlockState` 并返回
    // 一个 `BlockModel$Unbaked`。
    (colors, state) -> new BlockStateModelWrapper.Unbaked(
        // 要获取 `BlockStateModel` 的状态。
        state,
        // 模型的色调层。
        colors.getTintSources(state),
        // 在提交模型之前应用于 `PoseStack` 的可选变换。
        Optional.empty(new Transformation(new Matrix4f().translation(0.5f, 0.5f, 0.5f)))
    ),
    // 要使用此模型的方块。将为每个状态循环构造一个。
    EXAMPLE_BLOCK_1
);

// 根据某些属性切换的方块模型
builder.put(
    (colors, state) -> new SelectBlockModel.Unbaked(
        // 在提交模型之前应用于 `PoseStack` 的可选变换。
        Optional.empty(),
        // 一个包含要切换的属性以及当应选择特定方块模型时的值的记录。
        new SelectBlockModel.UnbakedSwitch<>(
            // 要切换的 `SelectBlockModelProperty`。属性
            // 值从 `BlockState` 及其 `BlockDisplayContext` 确定。
            (state, displayContext) -> state.getRenderShape(),
            // 用于确定要使用哪个 `BlockModel` 的情况列表。
            List.of(
                new SelectBlockModel.SwitchCase<>(
                    // 此模型适用的值列表。
                    List.of(RenderShape.INVISIBLE),
                    // 当满足此属性时要使用的模型。
                    new EmptyBlockModel.Unbaked()
                )
            ),
            // 如果没有开关情况与状态属性匹配，则使用可选的后备。
            Optional.of(new EmptyBlockModel.Unbaked())
        )
    ),
    EXAMPLE_BLOCK_2
);

// 基于某些条件的方块模型
builder.put(
    (colors, state) -> new ConditionalBlockModel.Unbaked(
        // 在提交模型之前应用于 `PoseStack` 的可选变换。
        Optional.empty(),
        // 从 `BlockState` 确定 `boolean` 的 `ConditionalBlockModelProperty`。
        BlockState::isSignalSource,
        // 当属性返回 `true` 时要显示的模型。
        new EmptyBlockModel.Unbaked(),
        // 当属性返回 `false` 时要显示的模型。
        new EmptyBlockModel.Unbaked()
    ),
    EXAMPLE_BLOCK_3
);

// 一个组合方块模型
builder.put(
    (colors, state) -> new CompositeBlockModel.Unbaked(
        // 要显示的第一个模型。
        new EmptyBlockModel.Unbaked(),
        // 要显示的第二个模型。
        new EmptyBlockModel.Unbaked(),
        // 在提交模型之前应用于 `PoseStack` 的可选变换。
        Optional.empty()
    ),
    EXAMPLE_BLOCK_4
);

// 特殊方块模型
builder.put(
    (colors, state) -> new SpecialBlockModelWrapper.Unbaked(
        // 用于为模型提交元素的未烘焙 `SpecialModelRenderer`。
        new BellSpecialRenderer.Unbaked(),
        // 在提交模型之前应用于 `PoseStack` 的可选变换。
        Optional.empty()
    ),
    EXAMPLE_BLOCK_5
);
```

在功能提交过程中，方块模型通过 `BlockModelResolver` 和 `BlockModelRenderState` 处理。这类似于其他渲染状态的工作方式。首先，`BlockModelResolver#update` 设置 `BlockModelRenderState`。设置通过基本路径处理——`BlockModelRenderState#setupModel`，将模型部件添加到返回的列表中，然后 `setupTints`，或者通过特殊渲染器的 `setupSpecialModel`。然后，渲染状态通过 `BlockModelRenderState#submit` 提交其元素进行渲染。渲染状态还提供 `submitOnlyOutline`，它使用轮廓渲染类型，以及 `submitWithZOffset`，它使用实体的前向 Z 偏移渲染类型。

```java
// BlockEntity 示例
public class ExampleRenderState extends BlockEntityRenderState {
    // 持有渲染状态。
    public final BlockModelRenderState exampleBlock = new BlockModelRenderState();
}

public class ExampleRenderer implements BlockEntityRenderer<ExampleBlockEntity, ExampleRenderState> {

    // 用于方块实体渲染器的显示上下文。
    public static final BlockDisplayContext BLOCK_DISPLAY_CONTEXT = BlockDisplayContext.create();
    private final BlockModelResolver blockResolver;

    public ExampleRenderer(BlockEntityRendererProvider.Context ctx) {
        super(ctx);
        // 获取模型解析器。
        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);

        // 更新模型状态。
        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);

        // 提交模型状态进行渲染。
        state.exampleBlock.submit(
            // 当前姿势堆栈，
            pose,
            // 节点收集器。
            collector,
            // 光照坐标。
            state.lightCoords,
            // 覆盖坐标。
            OverlayTexture.NO_OVERLAY,
            // 轮廓颜色。
            0
        );


    }
}

// Entity 示例
public class ExampleRenderState extends EntityRenderState {
    // 持有渲染状态。
    public final BlockModelRenderState exampleBlock = new BlockModelRenderState();
}

public class ExampleRenderer extends EntityRenderer<ExampleEntity, ExampleRenderState> {

    // 用于实体渲染器的显示上下文。
    public static final BlockDisplayContext BLOCK_DISPLAY_CONTEXT = BlockDisplayContext.create();
    private final BlockModelResolver blockResolver;

    public ExampleRenderer(EntityRendererProvider.Context ctx) {
        super(ctx);
        // 获取模型解析器。
        this.blockResolver = ctx.getBlockModelResolver();
    }

    @Override
    public void extractRenderState(ExampleEntity entity, ExampleRenderState state, float partialTick) {
        super.extractRenderState(entity, state, partialTick);

        // 更新模型状态。
        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);

        // 提交模型状态进行渲染。
        state.exampleBlock.submit(
            // 当前姿势堆栈。
            pose,
            // 节点收集器。
            collector,
            // 光照坐标。
            state.lightCoords,
            // 覆盖坐标。
            OverlayTexture.NO_OVERLAY,
            // 轮廓颜色。
            state.outlineColor
        );
    }
}
```

### 方块色调源

`BlockColor` 已被完全替换为 `BlockTintSource`，它根据所需的上下文设置特定索引的 ARGB 色调。色调源可以提供三种上下文：

- `color` 用于通用上下文，由 `BlockModel` 使用
- `colorInWorld` 用于世界上下文，由 `ModelBlockRenderer#tesselateBlock` 使用
- `colorAsTerrainParticle` 用于粒子上下文，由下落的灰尘和地形粒子使用

此外，如果使用 `BlockState` 的 `Property` 来确定要染色的颜色，`BlockTintSource` 会提供 `relevantProperties`。这被 `LevelRenderer` 用来确定状态更改是否需要重新渲染模型。

`BlockTintSource` 仍然通过 `register` 注册到 `BlockColors`，接受一个源列表，后跟可变参数的方块。模型 JSON 中指定的 `tintindex` 用于索引到色调源列表中。

```java
// 假设可以访问 BlockColors colors
colors.register(
    // 要应用于某个方块模型的色调列表。
    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;
            }
        }
    ),
    // 这些色调源将应用的方块。
    EXAMPLE_BLOCK_1
);
```

### 移除旧的方块和物品渲染器

由于 `ItemModel` 和 `BlockModel` 现在完全通过它们自己的功能提交管道处理，`BlockRenderDispatcher` 和 `ItemRenderer` 已被完全移除，被相应的系统取代。

### 对象定义变换

`ItemModel` 和 `BlockModel` 现在可以接受一个可选的 `Transformation`，它变换模型应如何显示。因此，`$Unbaked#bake` 方法现在接受父级 `Matrix4fc` 变换，变换通过 `Transformation#compose` 乘以此变换。对于物品模型，这被称为独立于模型 JSON 物品变换的局部变换。局部变换总是在物品变换之后应用。

请注意，添加对变换的支持应始终通过 `Transformation#compose` 完成，因为传递的矩阵本质上是可变的。假设任何不通过原版接口执行的自定义方法应在执行任何修改之前进行复制。

### 四边形实例

亮度/色调颜色、光照图和覆盖坐标已被合并到一个单一对象中：`QuadInstance`。这个可变类通过其关联的 `set*` 方法设置值，并可以通过 `get*` 方法为每个四边形顶点提取信息。亮度和色调作为颜色存储在一起，而不是两个单独的值。

`QuadInstance` 并不取代所有用例，例如添加单个顶点时。它仅更新 `VertexConsumer` 的方法，将 `putBulkData` 拆分为用于方块模型中四边形的 `putBlockBakedQuad`，以及用于所有其他用途的 `putBakedQuad`。

此外，许多用于将 `BakedQuad` 上传到缓冲区的方法现在接受一个 `BlockQuadOutput`。它具有与 `VertexConsumer#putBlockBakedQuad` 相同的参数，并且由于部分渲染器上传到新分配的 `BufferBuilder` 以用于超级缓冲区而添加。

### GUI 提取器

GUI 类方法经历了一个大规模的重命名方案，表明提交的元素被“提取”到一个通用树中以进行提交然后渲染。因此，以 `draw*` 或 `render*` 开头的方法现在以 `extract*` 为前缀，并可能以 `*RenderState` 为后缀（例如，`Renderable#render` -> `extractRenderState`，`AbstractContainerScreen#renderLabels` -> `extractLabels`，`AbstractWidget#renderWidget` -> `extractWidgetRenderState`）。一些缩写也被扩展，要么通过重命名，要么用另一个方法替换（例如，`AbstractContainerScreen#renderBg` 被 `Screen#extractBackground` 取代）。

`GuiGraphics` 也以同样的方式重命名为 `GuiGraphicsExtractor`。这些方法遵循与 GUI 其余部分类似的模式（例如，`hline` -> `horizontalLine`），不同之处在于 `draw*`、`render*` 和 `submit*` 前缀以及 `*RenderState` 后缀被移除（例如，`renderOutline` -> `outline`，`submitEntityRenderState` -> `entity`）。唯一的重命名是 `*String*` 方法名称被替换为 `*Text*`。

### 流体模型

定义流体的纹理和色调现已从 `FluidRenderer`（以前称为 `LiquidBlockRenderer`）中移出，并移入其自己的 `FluidModel` 记录中。最初，由于流体数量较少，未烘焙变体（`FluidModel$Unbaked`）存储为常量。然后，在 `BlockModel` 烘焙之后，流体模型通过 `FluidStateModelSet#bake` 烘焙，将 `Fluid` 链接到其 `FluidModel`。然后，此映射存储在 `FluidStateModelSet` 中，准备好通过 `get` 查询。

一个 `FluidModel$Unbaked` 有四个参数：三个用于静态、流动和可选覆盖纹理的 `Material`；以及一个用于 `BlockTintSource` 的参数。色调通过 `BlockTintSource#colorInWorld` 获得。在烘焙过程中，它将根据提供的材质的透明度确定 `ChunkSectionLayer`。

```java
// 由于流体模型系统在其烘焙中被硬编码，此示例
// 将假设存在某种方法可以修改访问
// `FluidStateModelSet#bake` 返回的 `Map<Fluid, FluidModel>` fluidModels。

// 我们还将假设我们有某个 Fluid EXAMPLE_FLUID* 来附加模型。

FluidModel.Unbaked exampleFluidModel = new FluidModel.Unbaked(
    // 静态流体的纹理。
    new Material(
        // 纹理的相对标识符。
        // 指向 `assets/examplemod/textures/block/example_fluid_still.png`
        Identifier.fromNamespaceAndPath("examplemod", "block/example_fluid_still"),
        // 当为 true 时，将此纹理键的所有面设置为
        // 始终具有透明像素。
        true
    ),
    // 流动流体的纹理。
    new Material(Identifier.fromNamespaceAndPath("examplemod", "block/example_fluid_flowing")),
    // 如果不为 null，则当流体侧面被 `HalfTransparentBlock` 或 `LeavesBlock` 遮挡时使用的覆盖纹理。
    null,
    // 如果不为 null，则在世界中时应用于流体纹理的色调源。
    null
);

// 假设我们可以访问 `MaterialBaker` materials。

FluidModel exampleBakedFluidModel = exampleFluidModel.bake(
    // 用于获取材质图集精灵的烘焙器。
    materials,
    // 一个提供的调试名称，以正确报告哪些模型
    // 缺少纹理。
    () -> "examplemod:example_fluid_model"
);

fluidModels.put(
    // 模型应使用的流体。
    EXAMPLE_FLUID,
    // 烘焙的流体模型。
    exampleBakedFluidModel
);
fluidModels.put(EXAMPLE_FLUID_FLOWING, exampleBakedFluidModel);
```

### 名称标签偏移

`EntityRenderer#submitNameTag` 已重命名为 `submitNameDisplay`，现在可以选择接受名称标签附件的 y 偏移。

### 色调获取器

`BlockAndTintGetter` 现在是一个附加到 `ClientLevel` 的客户端专用接口。它以前的用途被 `BlockAndLightGetter` 取代——`BlockAndTintGetter` 现在扩展了它——并剥离了色调和光照方向。

### 管道深度和颜色

`RenderPipeline` 中定义的深度和颜色方法已被合并到两个状态对象中。

`DepthTestFunction`、写入 `boolean` 以及偏置 `float` 现在存储在 `DepthStencilState` 中。`DepthTestFunction` 已被更通用的 `CompareOp` 取代，后者定义了如何比较两个数字。每个函数都有一个简单的等价物，`NO_DEPTH_TEST` 被 `CompareOp#ALWAYS_PASS` 取代。深度信息可以通过 `RenderPipeline$Builder#withDepthStencilState` 添加到管道中。

可选的 `BlendFunction` 以及颜色/alpha `boolean` 现在存储在 `ColorTargetState` 中。`boolean` 被合并到一个 `int` 中，使用低四位作为标志：`1` 是红色，`2` 是绿色，`4` 是蓝色，`8` 是 alpha。颜色 `boolean` 使用 `7` 表示红色、绿色和蓝色；alpha `boolean` 使用 `8`；而两者结合使用 `15`。`LopicOp` 已被完全移除。颜色信息可以通过 `RenderPipeline$Builder#withColorTargetState` 添加到管道中。

```java
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)
    // 在写入缓冲区数据时设置颜色目标。
    .withColorTargetState(new ColorTargetState(
        // 指定将两个带有 alpha 的颜色混合在一起时要使用的函数。
        // 由 `SourceFactor` 和 `DestFactor` 组成。
        // 前两个用于 RGB，后两个用于 alpha。
        // 如果 optional 为空，则禁用混合。
        Optional.of(BlendFunction.TRANSLUCENT),
        // 确定将哪些颜色写入缓冲区的掩码。
        // 表示为四位值
        // 0001 - 写入红色通道。
        // 0010 - 写入绿色通道。
        // 0100 - 写入蓝色通道。
        // 1000 - 写入 alpha 通道。
        ColorTargetState.WRITE_RED | ColorTargetState.WRITE_GREEN | ColorTargetState.WRITE_BLUE | ColorTargetState.WRITE_ALPHA
    ))
    // 在写入缓冲区数据时设置深度模板。
    .withDepthStencilState(new DepthStencilState(
        // 设置在离相机不同距离处渲染对象时要使用的深度测试函数。
        // 值：
        // - 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,
        // 是否屏蔽写入值到深度缓冲区
        false,
        // 用于计算多边形深度值的比例因子。
        0f,
        // 用于计算多边形深度值的单位偏移。
        0f
    ))
    .build()
;
```

### Blaze3d 后端

`CommandEncoder`、`GpuDevice` 和 `RenderPassBackend` 已拆分为 `*Backend` 接口，其功能类似于以前的接口，以及包装器类，它持有后端并提供委托调用，执行任何必要的验证。`*Backend` 接口现在显式执行操作，而不检查操作是否有效。

### 实体和半透明功能

功能渲染已进一步拆分为两个通道：一个用于实体渲染类型，一个用于半透明渲染类型。因此，大多数 `render` 方法现在分别具有 `renderSolid` 和 `renderTranslucent` 方法。那些只渲染实体或半透明数据的方法只具有其中一个方法。

### 相机状态

`Camera` 已更新，类似于其他渲染状态实现，其中相机在 `GameRenderer#renderLevel` 期间被提取到 `CameraRenderState`，并传递带有提交和渲染元素所需的数据。

由于此更改，`FogRenderer#setupFog` 现在返回 `FogData`，其中包含渲染雾所需的所有信息，而不仅仅是其颜色，并将其存储在 `CameraRenderState#fogData` 中。

- `assets/minecraft/shaders/core` 中的一些着色器现在使用 `texture` 而不是 `texelFetch`
    - `entity.vsh`
    - `item.vsh`
    - `rendertype_leash.vsh`
    - `rendertype_text.vsh`
    - `rendertype_text_background.vsh`
    - `rendertype_text_intensity.vsh`
- `assets/minecraft/shaders/core`
    - `block.vsh#minecraft_sample_lightmap` -> `sample_lightmap.glsl#sample_lightmap`
    - `rendertype_crumbling` 不再接受 `texCoord2`（光照图）
    - `rendertype_entity_alpha`、`rendertype_entity_decal` 合并到 `entity.fsh` 中，使用 `DissolveMaskSampler`
    - `rendertype_item_entity_translucent_cull` -> `item`，不是一对一
    - `rendertype_translucent_moving_block` 已移除
        - 现在使用 `ChunkSectionLayer` 提供的着色器
- `com.mojang.blaze3d`
    - `GLFWErrorCapture` - 在 GL 过程中捕获错误。
    - `GLFWErrorScope` - 一个定义要捕获的 GL 错误范围的可关闭对象。
- `com.mojang.blaze3d.opengl`
    - `GlProgram#BUILT_IN_UNIFORMS`、`INVALID_PROGRAM` 现在是 final
    - `GlBackend` - OpenGL 的 GPU 后端。
    - `GlCommandEncoder` 现在实现 `CommandEncoderBackend` 而不是 `CommandEncoder`，该类现在是包私有的
        - `getDevice` 已移除
    - `GlConst#toGl` 现在接受 `CompareOp` 而不是 `DepthTestFunction`
    - `GlDevice` 现在实现 `GpuDeviceBackend` 而不是 `GpuDevice`，该类现在是包私有的
        - 构造函数现在接受 `GpuDebugOptions`，其中包含日志级别、是否使用同步日志以及是否使用调试标签，而不是直接传入这些参数
    - `GlRenderPass` 现在实现 `RenderPassBackend` 而不是 `RenderPass`，该类现在是包私有的
        - 构造函数现在接受 `GlDevice`
    - `GlStateManager#_colorMask` 现在接受 `int` 作为颜色掩码，而不是四个 `boolean`
- `com.mojang.blaze3d.platform`
    - `ClientShutdownWatchdog` 现在接受 `Minecraft` 实例
    - `DebugMemoryUntracker#untrack` 已移除
    - `GLX#make(T, Consumer)` 已移除
    - `NativeImage`
        - `computeTransparency` - 返回图像中是否至少有一个透明或半透明像素。
            - 如果图像面积大于 512MiB，或带有颜色数据时大于 2GiB，则会崩溃。
        - `isClosed` - 图像是否已关闭或释放。
    - `Transparency` - 一个关于某个图像是否具有半透明和/或透明像素的对象。
    - `Window` 现在接受 `GpuBackend` 而不是 `ScreenManager`
        - `createGlfwWindow` - 直接使用提供的设置创建 GLFW 窗口。
        - `updateDisplay` -> `updateFullscreenIfChanged`，不是一对一
        - `isResized`、`resetIsResized` - 处理窗口是否已调整大小。
        - `backend` - 返回 `GpuBackend`。
        - `$WindowInitFailed` 构造函数现在从 `private` 变为 `public`
    - `WindowEventHandler#resizeDisplay` -> `resizeGui`
- `com.mojang.blaze3d.pipeline`
    - `ColorTargetState` - 一个包含颜色混合函数和掩码的记录。
    - `DepthStencilState` - 一个包含深度模板数据的记录。
    - `RenderPipeline` 现在接受 `ColorTargetState` 而不是可选的 `BlendFunction`、颜色和 alpha `boolean` 以及 `LogicOp`；以及 `DepthStencilState` 而不是 `DepthTestFunction`、深度 `boolean` 和偏置 `float`
        - `getDepthTestFunction`、`isWriteDepth`、`getDepthBiasScaleFactor`、`getDepthBiasConstant` -> `getDepthStencilState`，不是一对一
        - `getColorLogic`、`getBlendFunction`、`isWriteColor`、`isWriteAlpha` -> `getColorTargetState`，不是一对一
        - `$Builder`
            - `withDepthTestFunction`、`withDepthWrite`、`withDepthBias` -> `withDepthStencilState`，不是一对一
            - `withBlend`、`withColorWrite`、`withColorLogic` -> `withColorTargetState`，不是一对一
        - `$Snippet` 现在接受 `ColorTargetState` 而不是可选的 `BlendFunction`、颜色和 alpha `boolean` 以及 `LogicOp`；以及 `DepthStencilState` 而不是 `DepthTestFunction` 和深度 `boolean`
- `com.mojang.blaze3d.platform`
    - `BackendOptions` - 用于初始化后端的配置。
    - `DepthTestFunction` -> `CompareOp`，不是一对一
        - `NO_DEPTH_TEST` -> `CompareOp#ALWAYS_PASS`
        - `EQUAL_DEPTH_TEST` -> `CompareOp#EQUAL`
        - `LEQUAL_DEPTH_TEST` -> `CompareOp#LESS_THAN_OR_EQUAL`
        - `LESS_DEPTH_TEST` -> `CompareOp#LESS_THAN`
        - `GREATER_DEPTH_TEST` -> `CompareOp#GREATER_THAN`
    - `GLX`
        - `_initGlfw` 现在接受 `BackendOptions`
        - `glfwBool` - `true` 为 `1`，`false` 为 `0`。
    - `LogicOp` 枚举已移除
- `com.mojang.blaze3d.shaders.GpuDebugOptions` - GPU 管线的调试选项。
- `com.mojang.blaze3d.systems`
    - `BackendCreationException` - 当无法创建 GPU 后端时抛出的异常。
    - `CommandEncoder` -> `CommandEncoderBackend`
        - 原始接口现在是一个围绕接口的类包装器，在执行验证检查后委托给后端
    - `GpuBackend` - 一个负责创建使用的 GPU 设备和显示窗口的接口。
    - `GpuDevice` -> `GpuDeviceBackend`
        - 原始接口现在是一个围绕接口的类包装器，在执行验证检查后委托给后端
        - `setVsync` - 设置是否启用 VSync。
        - `presentFrame` - 交换窗口的前后缓冲区以显示当前帧。
        - `isZZeroToOne` - 是否使用 0 到 1 的 Z 范围而不是 -1 到 1。
    - `RenderPass` -> `RenderPassBackend`
        - 原始接口现在是一个围绕接口的类包装器，在执行验证检查后委托给后端
    - `RenderSystem`
        - `pollEvents` 现在是公开的
        - `flipFrame` 不再接受 `Window`
        - `initRenderer` 现在只接受 `GpuDevice`
        - `limitDisplayFPS` -> `FramerateLimiter#limitDisplayFPS`
        - `initBackendSystem` 现在接受 `BackendOptions`
- `com.mojang.blaze3d.vertex`
    - `DefaultVertexFormat#BLOCK` 不再接受法线向量
    - `PoseStack#mulPose`、`$Pose#mulPose` 现在有一个接受 `Transformation` 的重载
    - `QuadInstance` - 一个包含四边形颜色、光照坐标和覆盖的类。
    - `TlsfAllocator` - 一个用于动态内存分配的两级隔离适配分配器。
    - `UberGpuBuffer` - 一个用于将动态大小的数据上传到 GPU 的缓冲区，用于区块部分层。
    - `VertexConsumer`
        - `putBulkData` -> `putBlockBakedQuad`、`putBakedQuad`；不是一对一
            - 亮度 `float` 数组、颜色 `float`、光照图 `int` 数组和覆盖 `int` 被 `QuadInstance` 取代
            - `putBlockBakedQuad` 将 `PoseStack$Pose` 替换为 XYZ `float` 方块位置
        - `addVertex(PoseStack$Pose, Vector3f)` -> `addVertex(PoseStack$Pose, Vector3fc)`
        - `setNormal(PoseStack$Pose, Vector3f)` -> `setNormal(PoseStack$Pose, Vector3fc)`
- `com.mojang.math`
    - `MatrixUtil`
        - `checkPropertyRaw` 现在从 `private` 变为 `public`
        - `isOrthonormal` 已移除
    - `Transformation`
        - `IDENTITY` 现在从 `private` 变为 `public`
            - 取代了 `identity` 方法
        - `getTranslation` -> `translation`
        - `getLeftRotation` -> `leftRotation`
        - `getScale` -> `scale`
        - `getRightRotation` -> `rightRotation`
        - `compose` - 如果存在，将变换应用于给定矩阵。
- `net.minecraft.SharedConstants`
    - `DEBUG_DUMP_INTERPOLATED_TEXTURE_FRAMES` 已移除
    - `DEBUG_PREFER_WAYLAND` - 当为 true 时，如果同时支持 Wayland 和 X11，则阻止将平台初始化提示设置为 X11。
- `net.minecraft.client`
    - `Camera`
        - `BASE_HUD_FOV` - 基础 HUD 视场角。
        - `setup` -> `update`，不是一对一
        - `extractRenderState` - 提取相机的状态。
        - `getFov` - 获取视场角。
        - `getViewRotationMatrix` - 获取投影视图的矩阵。
        - `setEntity` - 设置相机附加到的实体。
        - `getNearPlane` 现在接受 `float` 视场角
        - `panoramicForwards` - 全景模式下的前向向量。
        - `getPartialTickTime` 已移除
        - `setLevel` - 设置相机所在的等级。
        - `getCameraEntityPartialTicks` - 根据实体的状态获取部分刻。
    - `DeltaTracker#advanceTime` 被 `advanceGameTime`（当 `boolean` 为 `true` 时）和 `advanceRealTime` 取代
        - `advanceGameTime`、`advanceRealTime` 以前是 `private`，现在是 `public`
    - `FramerateLimiter` - 一个用于限制客户端帧率的实用程序。
    - `Minecraft`
        - `noRender` 已移除
        - `useAmbientOcclusion` 已移除
        - `getBlockRenderer` 已移除
        - `getItemRenderer` 已移除
    - `Options`
        - `getCloudsType` -> `getCloudStatus`
        - `exclusiveFullscreen` - 当为 `true` 时，全屏模式完全控制显示器。
- `net.minecraft.client.color.block`
    - `BlockColor` 被 `BlockTintSource` 取代，不是一对一
        - `getColor` -> `colorInWorld`, `colorAsTerrainParticle`; 不是一对一
    - `BlockColors`
        - `getColor` 被 `getTintSources`、`getTintSource` 取代；不是一对一
        - `register` 现在接受一个 `BlockTintSource` 列表而不是一个 `BlockColor`
    - `BlockTintSource` - 一个用于确定如何对 `BlockState` 进行单独或上下文着色的源。
    - `BlockTintSources` - 通用块着色源的实用程序。
- `net.minecraft.client.data.models`
    - `BlockModelGenerators`
        - `createSuffixedVariant` 现在接受一个从 `Material` 到 `TextureMapping` 的函数用于纹理，而不仅仅是 `Identifier`
        - `createAirLikeBlock` 现在接受一个 `Material` 而不是 `Identifier` 作为粒子纹理
        - `generateSimpleSpecialItemModel` 现在接受一个可选的 `Transformation`
        - `createChest` 现在有一个接受 `MutiblockChestResources` 纹理的重载
    - `ItemModelGenerators#generateLayeredItem` 现在接受 `Material` 而不是 `Identifier` 作为纹理
- `net.minecraft.client.data.models.model`
    - `ItemModelUtils`
        - `specialModel` 现在有接受 `Transformation` 的重载
        - `conditional` 现在有接受 `Transformation` 的重载
        - `select` 现在有一个接受 `Transformation` 的重载
        - `selectBlockItemProperty` 现在有一个接受 `Transformation` 的重载
    - `TexturedModel#createAllSame` 现在接受一个 `Material` 而不是 `Identifier` 作为纹理
    - `TextureMapping`
        - `put`、`putForced` 现在接受一个 `Material` 而不是 `Identifier` 作为纹理
        - `get` 现在返回一个 `Material` 而不是 `Identifier` 作为纹理
        - `copyAndUpdate` 现在接受一个 `Material` 而不是 `Identifier` 作为纹理
        - `updateSlots` - 使用提供的映射函数替换所有槽位。
        - `forceAllTranslucent` - 为所有材质纹理设置强制半透明标志。
        - `defaultTexture`, `cube`, `cross`, `plant`, `rail`, `wool`, `crop`, `singleSlot`, `particle`, `torch`, `cauldron`, `layer0` 现在接受一个 `Material` 而不是 `Identifier` 作为纹理
        - `column`, `door`, `layered` 现在接受 `Material` 而不是 `Identifier` 作为纹理
        - `getBlockTeture`, `getItemTexture` 现在返回一个 `Material` 而不是 `Identifier` 作为纹理
- `net.minecraft.client.entity.ClientAvatarEntity#belowNameDisplay` -> `Entity#belowNameDisplay`
- `net.minecraft.client.gui`
    - `Font`
        - `drawInBatch`, `drawInBatch8xOutline` 现在接受一个 `Matrix4fc` 而不是 `Matrix4f` 作为姿态
        - `$GlyphVisitor#forMultiBufferSource` 现在接受一个 `Matrix4fc` 而不是 `Matrix4f` 作为姿态
    - `Gui`
        - `render*` 方法已重命名为 `extract*`
        - `render` -> `extractRenderState`
        - `$RenderFunction` 接口已移除
    - `GuiGraphics` -> `GuiGraphicsExtractor`
        - `hLine` -> `horizontalLine`
        - `vLine` -> `verticalLine`
        - `renderOutline` -> `outline`
        - `drawCenteredString` -> `centeredText`
        - `drawString` -> `text`
        - `drawStringWithBackdrop` -> `textWithBackdrop`
        - `renderItem` -> `item`
        - `renderFakeItem` -> `fakeItem`
        - `renderItemDecorations` -> `itemDecorations`
        - `submitMapRenderState` -> `map`
        - `submitEntityRenderState` -> `entity`
        - `submitSkinRenderState` -> `skin`
        - `submitBookModelRenderState` -> `book`
        - `submitBannerPatternRenderState` -> `bannerPattern`
        - `submitSignRenderState` -> `sign`
        - `submitProfilerChartRenderState` -> `profilerChart`
        - `renderTooltip` -> `tooltip`
        - `renderComponentHoverEffect` -> `componentHoverEffect`，现在为 `private` 而不是 `public`
- `net.minecraft.client.gui.components`
    - 大多数以 `render*` 或 `draw*` 开头的方法已根据用法重命名为 `extract*` 或 `extract*RenderState`
    - `AbstractWidget#renderWidget` -> `extractWidgetRenderState`
    - `DebugScreenOverlay#render3dCrosshair` 现在接受 `CameraRenderState` 而不是 `Camera`，以及 GUI 缩放 `int`
    - `LogoRenderer#renderLogo` -> `extractRenderState`
    - `PlayerFaceRenderer` -> `PlayerFaceExtractor`
        - `draw` -> `extractRenderState`
    - `Renderable#render` -> `extractRenderState`
    - `StringWidget#clipText` -> `ComponentRenderUtils#clipText`
    - `TextCursorUtils#draw*` -> `extract*`
- `net.minecraft.client.gui.components.debugchart`
    - `AbstractDebugChart`
        - `drawChart` -> `extractRenderState`
        - `drawDimensions` -> `extractSampleBars`
        - `drawMainDimension` -> `extractMainSampleBar`
        - `drawAdditionalDimensions` -> `extractAdditionalSampleBars`
        - `renderAdditionalLinesAndLabels` -> `extractAdditionalLinesAndLabels`
        - `drawStringWithShade` -> `extractStringWithShade`
    - `ProfilerPieChart#render` -> `extractRenderState`
- `net.minecraft.client.gui.components.spectator.SpectatorGui#render*` -> `extract*`
- `net.minecraft.client.gui.components.toasts`
    - `NowPlayingToast#renderToast` -> `extractToast`
    - `Toast#render` -> `extractRenderState`
    - `ToastManager`, `$ToastInstance#render` -> `extractRenderState`
    - `TutorialToast$Icons#render` -> `extractRenderState`
- `net.minecraft.client.gui.contextualbar.ContextualBarRenderer`
    - `renderBackground` -> `extractBackground`
    - `render` -> `extractRenderState`
    - `renderExperienceLevel` -> `extractExperienceLevel`
- `net.minecraft.client.gui.font`
    - `PlainTextRenderable#renderSprite` 现在接受一个 `Matrix4fc` 而不是 `Matrix4f` 作为姿态
    - `TextRenderable#render` 现在接受一个 `Matrix4fc` 而不是 `Matrix4f` 作为姿态
- `net.minecraft.client.gui.render`
    - `DynamicAtlasAllocator` - 一个用于处理动态大小纹理图集的分配器。
    - `GuiItemAtlas` - 一个用于用户界面中显示的所有物品的图集。
    - `GuiRenderer#incrementFrameNumber` -> `endFrame`，不是一对一
- `net.minecraft.client.gui.render.state.*` -> `.client.rendererer.state.gui.*`
    - `GuiItemRenderState` 不再接受 `String` 名称
        - `name` 已移除
- `net.minecraft.client.gui.render.state.pip.*` -> `.client.rendererer.state.gui.pip.*`
- `net.minecraft.client.gui.screens`
    - `LevelLoadingScreen#renderChunks` -> `extractChunksForRendering`
    - `Screen`
        - `renderWithTooltipAndSubtitles` -> `extractRenderStateWithTooltipAndSubtitles`
        - `renderBackground` -> `extractBackground`
        - `renderBlurredBackground` -> `extractBlurredBackground`
        - `renderPanorama` -> `extractPanorama`
        - `renderMenuBackground` -> `extractMenuBackground`
        - `renderMenuBackgroundTexture` -> `extractMenuBackgroundTexture`
        - `renderTransparentBackground` -> `extractTransparentBackground`
- `net.minecraft.client.gui.screens.advancements`
    - `AdvancementTab#draw*` -> `extract*`
    - `AdvancementTabType`
        - `draw` -> `extractRenderState`
        - `drawIcon` -> `extractIcon`
    - `AdvancementWidget`
        - `draw` -> `extractRenderState`
        - `draw*` -> `extract*`
- `net.minecraft.client.gui.screens.inventory`
    - 大多数以 `render*` 或 `draw*` 开头的方法已根据用法重命名为 `extract*` 或 `extract*RenderState`
    - `AbstractContainerScreen`
        - `renderContents` -> `extractContents`
        - `renderCarriedItem` -> `extractCarriedItem`
        - `renderSnapbackItem` -> `extractSnapbackItem`
        - `renderSlots` -> `extractSlots`
        - `renderTooltip` -> `extractTooltip`
        - `renderLabels` -> `extractLabels`
        - `renderBg` 被 `Screen#extractBackground` 取代
        - `renderSlot` -> `extractSlot`
    - `AbstractMountInventoryScreen#drawSlot` -> `extractSlot`
    - `AbstractSignEditScreen#renderSignBackground` -> `extractSignBackground`
    - `CyclingSlotBackground#render` -> `extractRenderState`
    - `EffectsInInventory#render` -> `extractRenderState`
    - `InventoryScreen#renderEntityInInventoryFollowsMouse` -> `extractEntityInInventoryFollowsMouse`
    - `ItemCombinerScreen#renderErrorIcon` -> `extractErrorIcon`
- `net.minecraft.client.gui.screens.inventory.tooltip`
    - `ClientTooltipComponent`
        - `renderText` -> `extractText`
        - `renderImage` -> `extractImage`
    - `TooltipRenderUtil#renderTooltipBackground` -> `extractTooltipBackground`
- `net.minecraft.client.gui.screens.options`
    - `DifficultyButtons` 现在是一个记录，接受 `LayoutElement`、用于难度的 `CycleButton`、`LockIconButton` 和当前 `Level`
        - `create` 现在接受 `Level` 并返回 `DifficultyButtons` 而不是 `LayoutElement`
        - `refresh` - 设置持有的按钮组件的数据。
    - `HasDifficultyReaction` - 一个响应难度更改的接口。
    - `OptionsScreen` 现在实现 `HasDifficultyReaction`
    - `WorldOptionsScreen` 现在实现 `HasDifficultyReaction`
        - 构造函数现在接受 `Level`
- `net.minecraft.client.gui.screens.recipebook`
    - `GhostSlots`
        - `render` -> `extractRenderState`
        - `renderTooltip` -> `extractTooltip`
    - `RecipeBookComponent#render*` -> `extract*`
    - `RecipeBookPage`
        - `render` -> `extractRenderState`
        - `renderTooltip` -> `extractTooltip`
- `net.minecraft.cilent.gui.screens.reporting.ChatSelectionScreen$ChatSelectionList#renderItem` -> `extractItem`
- `net.minecraft.client.gui.screens.worldselection.AbstractGameRulesScreen$GameRuleEntry#renderLabel` -> `extractLabel`
- `net.minecraft.client.gui.spectator.SpectatorMenuItem#renderIcon` -> `extractIcon`
- `net.minecraft.client.model.Model#renderType` 现在有一个返回传入函数的重载
- `net.minecraft.client.model.object.book.BookModel$State` 不再接受动画位置，并将开放的 `float` 移到第一个参数
    - `forAnimation` - 根据进度获取书本动画的当前状态。
- `net.minecraft.client.model.object.statue.CopperGolemStatueModel` 现在使用 `Unit` 作为泛型而不是 `Direction`
- `net.minecraft.client.multiplayer.ClientLevel` 现在实现 `BlockAndTintGetter`
    - `update` - 更新关卡的光照。
- `net.minecraft.client.multiplayer.chat.GuiMessageTag$Icon#draw` -> `extractRenderState`
- `net.minecraft.client.particle`
    - `Particle#getLightColor` -> `getLightCoords`
    - `SimpleVerticalParticle` - 一个垂直移动的粒子。
    - `SingleQuadParticle$Layer`
        - `TERRAIN` -> `OPAQUE_TERRAIN`, `TRANSLUCENT_TERRAIN`
        - `ITEMS` -> `OPAQUE_ITEMS`, `TRANSLUCENT_ITEMS`
        - `bySprite` - 从图集精灵获取层。
- `net.minecraft.client.renderer`
    - `CachedOrthoProjectionMatrixBuffer`, `CachedPerspectiveProjectionMatrixBuffer`, `PerspectiveProjectionMatrixBuffer` -> `ProjectionMatrixBuffer`，有时带有 `Projection`，不是一对一
    - `CloudRenderer` 现在接受云范围 `int`
    - `CubeMap` 不再接受 `Minecraft` 实例
    - `GameRenderer` 现在接受 `ModelManager` 而不是 `BlockRenderDispatcher`
        - `PROJECTION_Z_NEAR` -> `Camera#PROJECTION_Z_NEAR`
        - `setPanoramicScreenshotParameters`, `getPanoramicScreenshotParameters` -> `Camera#enablePanoramicMode`, `disablePanoramicMode`; 不是一对一
        - `isPanoramicMode` -> `Camera#isPanoramicMode`
        - `getProjectionMatrix` -> `Camera#getViewRotationProjectionMatrix`，不是一对一
        - `updateCamera` -> `Camera#update`，不是一对一
        - `getRenderDistance` 已移除
        - `cubeMap` -> `GuiRenderer#cubeMap`，现在为 `private` 而不是 `protected`
        - `getDarkenWorldAmount` -> `getBossOverlayWorldDarkening`
        - `lightTexture` -> `lightmap`, `levelLightmap`; 不是一对一
        - `getLevelRenderState` 被 `getGameRenderState` 取代，返回 `GameRenderState` 而不是 `LevelRenderState`
        - `pick` -> `Minecraft#pick`，现在为 `private` 而不是 `public`
        - `render` 拆分为 `update`、`extract` 和 `render`；`boolean` 现在表示是否推进游戏时间而不是渲染关卡
    - `GlobalSettingsUniform` 现在接受 `Vec3` 相机位置而不是主 `Camera` 本身
    - `ItemBlockRenderTypes` 已移除
        - `getChunkRenderType`、`getMovingBlockRenderType` 现在存储在 `BakedQuad$SpriteInfo` 中
        - `getRenderLayer(FluidState)` -> `FluidModel#layer`，不是一对一
        - `setCutoutLeaves` 已移除
            - 这应直接从选项中获取
    - `MultiblockChestResources` - 一个包含基于 `ChestType` 的一些数据的记录。
    - `LevelRenderer` 现在接受 `GameRenderState` 而不是 `LevelRenderState`
        - `update` - 更新关卡。
        - `renderLevel` 现在接受 `CameraRenderState` 而不是 `Camera`，一个 `Matrix4fc` 而不是 `Matrix4f` 用于模型视图，以及 `ChunkSectionsToRender`；不再接受用于投影矩阵的 `Matrix3f`
        - `extractLevel` - 提取关卡状态。
        - `prepareChunkRenders` 现在是 `public` 而不是 `private`
        - `captureFrustum`, `killFrustum`, `getCapturedFrustum` 已移除
        - `getLightColor` -> `getLightCoords`，现在接受 `BlockAndLightGetter` 而不是 `BlockAndTintGetter`
        - `$BrightnessGetter#packedBrightness` 现在接受 `BlockAndLightGetter` 而不是 `BlockAndTintGetter`
    - `LightTexture` -> `Lightmap`
        - `tick` -> `LightmapRenderStateExtractor#tick`
        - `updateLightTexture` -> `render`
        - `pack` -> `LightCoordsUtil#pack`
        - `block` -> `LightCoordsUtil#block`
        - `sky` -> `LightCoordsUtil#sky`
        - `lightCoordsWithEmission` -> `LightCoordsUtil#lightCoordsWithEmission`
    - `MaterialMapper` -> `SpriteMapper`
    - `OrderedSubmitNodeCollector`
        - `submitBlock` 已移除
        - `submitBlockModel` 现在接受一个 `BlockStateModelPart` 列表而不是 `BlockStateModel`，以及一个 `int` 数组（色调颜色数组）而不是三个 `float` 用于单一颜色
        - `submitItem` 不再接受 `RenderType`
        - `submitModel` 现在有接受纹理的 `Identifier` 或带有 `SpriteGetter` 的 `SpriteId` 以及一个 `int` 色调颜色的重载
        - `submitBreakingBlockModel` - 提交方块破坏覆盖层。
    - `PanoramaRenderer` 被 `Panorama` 取代
        - `registerTextures` -> `GuiRenderer#registerPanoramaTextures`
        - `render` -> `extractRenderState`
    - `PanoramicScreenshotParameters` 记录已移除
    - `PostChain` 现在接受一个 `Projection` 和 `ProjectionMatrixBuffer` 而不是 `CachedOrthoProjectionMatrixBuffer`
        - `load` 现在接受一个 `Projection` 和 `ProjectionMatrixBuffer` 而不是 `CachedOrthoProjectionMatrixBuffer`
    - `RenderPipelines`
        - `ENTITY_CUTOUT_NO_CULL` -> `ENTITY_CUTOUT`
            - 原来的带剔除的 cutout 被 `ENTITY_CUTOUT_CULL` 取代
        - `ENTITY_CUTOUT_NO_CULL_Z_OFFSET` -> `ENTITY_CUTOUT_Z_OFFSET`
        - `ENTITY_SMOOTH_CUTOUT` -> `END_CRYSTAL_BEAM`
        - `ENTITY_NO_OUTLINE` 被 `ENTITY_TRANSLUCENT` 取代，渲染类型构造时 affects outline 为 false
        - `ENTITY_DECAL`, `DRAGON_EXPLOSION_ALPHA` -> `ENTITY_CUTOUT_DISSOLVE`，不是一对一
        - `ITEM_ENTITY_TRANSLUCENT_CULL` -> `ENTITY_TRANSLUCENT_CULL`, `ITEM_CUTOUT`, `ITEM_TRANSLUCENT`; 不是一对一
        - `TRANSLUCENT_MOVING_BLOCK` 被 `TRANSLUCENT_BLOCK` 取代
        - `BANNER_PATTERN` - 用于渲染旗帜图案的管线。
    - `ScreenEffectRenderer#renderScreenEffect` 现在接受 `boolean` 表示玩家是否处于第一人称以及是否隐藏 GUI
    - `Sheets`
        - `*CHEST_*LOCATION*` 已根据资源用途合并到 `CHEST_*` 字段之一
        - `translucentBlockSheet` - 使用方块图集的可剔除实体物品半透明渲染类型。
        - `cutoutBlockItemSheet` - 使用方块图集的物品 cutout 渲染类型。
        - `bannerSheet` -> `RenderTypes#entityTranslucent`，不是一对一
        - `cutoutItemSheet` - 使用物品图集的物品 cutout 渲染类型。
        - `get*Material` -> `get*Sprite`
        - `chooseMaterial` -> `chooseSprite`
    - `SpecialBlockModelRenderer` 被 `BuiltInBlockModels` 取代，不是一对一
        - `renderByBlock` -> `BlockModelRenderState#submit*`，不是一对一
    - `SubmitNodeCollection`
        - `getBlockSubmits` 已移除
        - `getBreakingBlockModelSubmits` - 获取已提交的方块破坏覆盖层。
    - `SubmitNodeCollector$ParticleGroupRenderer`
        - `isEmpty` - 此组中是否没有要渲染的粒子。
        - `prepare` 现在接受是否为半透明层准备粒子
        - `render` 不再接受半透明 `boolean`
    - `SubmitNodeStorage`
        - `$BlockModelSubmit` 现在接受一个 `BlockStateModelPart` 列表而不是 `BlockStateModel`，以及一个 `int` 数组（色调颜色数组）而不是三个 `float` 用于单一颜色
        - `$BlockSubmit` 已移除
        - `$BreakingBlockModelSubmit` - 一个包含渲染方块破坏覆盖层信息的记录。
        - `$ItemSubmit` 不再接受 `RenderType`
        - `$MovingBlockSubmit`, `$NameTagSubmit`, `$ShadowSubmit`, `$TextSubmit` 现在接受一个 `Matrix4fc` 而不是 `Matrix4f` 作为姿态
    - `VirtualScreen` 被 `GpuBackend` 取代
- `net.minecraft.client.renderer.block`
    - `BlockAndTintGetter` - 一个用于位置方块着色（例如生物群系）的获取器。
    - `BlockModelRenderState` - 方块模型的渲染状态。
    - `BlockModelResolver` - 一个用于设置 `BlockState` 渲染状态的辅助类。
    - `BlockModelSet` - 持有与每个 `BlockState` 关联的 `BlockModel`。
    - `BlockModelShaper` -> `BlockStateModelSet`，不是一对一
        - `getParticleIcon` -> `getParticleMaterial`，现在返回 `Material$Baked` 而不是 `TextureAtlasSprite`
        - `getBlockModel` -> `get`
        - `getModelManager`, `replaceCache` 已移除
    - `BlockQuadOutput` - 一个用于将烘焙四边形信息写入某些输出（如缓冲区）的函数接口。
    - `BlockRenderDispatcher` 类已移除
        - `getBlockModelShaper` -> `getModelSet`，不是一对一
        - `renderBreakingTexture` 被 `SubmitNodeCollector#submitBreakingBlockModel` 取代
        - `renderBatched` 被直接调用 `ModelBlockRenderer#tesselateBlock` 取代
        - `renderLiquid` 被直接调用 `FluidRenderer#tesselate` 取代
        - `renderSingleBlock` 现在内联在 `BlockFeatureRenderer#renderBlockModelSubmits` 中，一个 `private` 方法
            - 使用 `ModelBlockRenderer#tesselateBlock` 作为替代
    - `FluidModel` - 持有渲染器数据的基础流体模型。
    - `FluidStateModelSet` - 持有与每个 `Fluid` 关联的 `FluidModel`。
    - `LoadedBlockModels` - 一个为每个 `BlockState` 烘焙 `BlockModel` 的任务。
    - `LiquidBlockRenderer` -> `FluidRenderer`，不是一对一
        - 构造函数现在接受 `FluidStateModelSet` 而不是 `SpriteGetter`
        - `tesselate` 现在接受一个 `FluidRenderer$Output` 而不是 `VertexConsumer`
        - `$Output` - 获取用于 `ChunkSectionLayer` 的 `VertexConsumer`。
    - `ModelBlockRenderer` 现在接受 `boolean` 用于环境光遮蔽和剔除
        - `tesselateBlock` 现在接受一个 `BlockQuadOutput` 而不是 `VertexConsumer`，XYZ `float` 而不是 `PoseStack`，`BlockStateModel` 而不是 `BlockModelPart` 列表，不再接受剔除 `boolean` 和 `int` 覆盖，并接受种子 `long`
        - `tesselateWithAO` -> `tesselateAmbientOcclusion`，现在是 `private` 而不是 `public`
        - `tesselateWithoutAO` -> `tesselateFlat`，现在是 `private` 而不是 `public`
        - `renderModel` 现在内联在 `BlockFeatureRenderer#renderBlockModelSubmits` 中，一个 `private` 方法
        - `forceOpaque` - 方块纹理是否应为不透明而不是半透明。
        - `enableCaching` -> `BlockModelLighter$Cache#enable`
        - `clearCache` -> `BlockModelLighter$Cache#disable`
        - `$AdjacencyInfo` -> `BlockModelLighter$AdjacencyInfo`，现在是 `private` 而不是 `protected`
        - `$AmbientOcclusionRenderStorage` 被 `BlockModelLighter` 取代，不是一对一
        - `$AmbientVertexRemap` -> `BlockModelLighter$AmbientVertexRemap`
        - `$Cache` -> `BlockModelLighter$Cache`
        - `$CommonRenderStorage` 被 `BlockModelLighter` 取代，不是一对一
        - `$SizeInfo` -> `BlockModelLighter$SizeInfo`
    - `MovingBlockRenderState#level` -> `cardinalLighting`, `lightEngine`; 不是一对一
    - `SelectBlockModel` - 一个由其解析属性确定或选择的方块模型。
- `net.minecraft.client.renderer.block.model`
    - `BakedQuad` -> `.client.resources.model.geometry.BakedQuad`
        - 构造函数现在接受一个 `$MaterialInfo` 而不是 `TextureAtlasSprite`、`int` 色调索引、`int` 光发射和 `boolean` 阴影
        - `FLAG_TRANSLUCENT` - 一个标志，标记烘焙四边形具有半透明性。
        - `FLAG_ANIMATED` - 一个标志，标记烘焙四边形具有动画纹理。
        - `isTinted` -> `$MaterialInfo#isTinted`
        - `$MaterialFlags` - 一个注解，标记给定的整数是否定义材质的标志。
        - `$MaterialInfo` - 一个持有如何渲染四边形信息的记录。
    - `BlockDisplayContext` - 一个表示方块显示上下文的对象。
    - `BlockElement` -> `.client.resources.model.cuboid.CuboidModelElement`
    - `BlockElementFace` -> `.client.resources.model.cuboid.CuboidFace`
    - `BlockElementRotation` -> `.client.resources.model.cuboid.CuboidRotation`
    - `BlockModel` - 基础方块模型，用于在世界上下文之外更新渲染状态。
        - 原始实现已移至 `.client.resources.model.cuboid.CuboidModel`
    - `BlockModelDefinition` -> `.block.dispatch.BlockStateModelDispatcher`
    - `BlockModelPart` -> `.block.dispatch.BlockStateModelPart`
        - `particleIcon` -> `particleMaterial`，现在返回 `Material$Baked` 而不是 `TextureAtlasSprite`
        - `materialFlags` - 处理模型使用的材质的标志。
    - `BlockStateModel` -> `.block.dispatch.BlockStateModel`
        - `particleIcon` -> `particleMaterial`，现在返回 `Material$Baked` 而不是 `TextureAtlasSprite`
        - `materialFlags`, `hasMaterialFlag` - 处理模型使用的材质的标志。
    - `BlockStateModelWrapper` - 包含模型、色调和变换的基础方块模型。
    - `CompositeBlockModel` - 将多个方块模型叠加在一起。
    - `ConditionalBlockModel` - 一个根据从某个属性获取的布尔值显示不同模型的方块模型。
    - `EmptyBlockModel` - 不显示任何内容的方块模型。
    - `FaceBakery` -> `.client.resources.model.cuboid.FaceBakery`
        - `bakeQuad` 重载现在接受一个 `ModelBaker` 而不是 `ModelBaker$PartCache`，以及一个 `Material$Baked` 而不是 `TextureAtlasSprite`
            - 它还有一个接受 `BlockElementFace` 字段而不是对象本身的重载
        - 另一个 `bakedQuad` 重载现在接受 `BakedQuad$MaterialInfo` 而不是 `int` 色调索引和光发射，以及阴影 `boolean`
    - `ItemModelGenerator` -> `.client.resources.model.cuboid.ItemModelGenerator`
    - `ItemTransform` -> `.client.resources.model.cuboid.ItemTransform`
    - `ItemTransforms` -> `.client.resources.model.cuboid.ItemTransforms`
    - `SimpleModelWrapper` -> `.client.resources.model.SimpleModelWrapper`
        - 构造函数现在接受一个 `Material$Baked` 而不是 `TextureAtlasSprite` 作为粒子
    - `SimpleUnbakedGeometry` -> `.client.resources.model.cuboid.UnbakedCuboidGeometry`
    - `SingleVariant` -> `.block.dispatch.SingleVariant`
    - `SpecialBlockModelWrapper` - 一个用于通过 `SpecialModelRenderer` 提交其元素的方块模型。
    - `TextureSlots` -> `.client.resources.model.sprite.TextureSlots`
    - `Variant` -> `.block.dispatch.Variant`
    - `VariantMutator` -> `.block.dispatch.VariantMutator`
    - `VariantSelector` -> `.block.dispatch.VariantSelector`
- `net.minecraft.client.renderer.block.model.multipart.*` -> `.block.dispatch.multipart.*`
- `net.minecraft.client.renderer.block.model.properties.conditional`
    - `ConditionalBlockModelProperty` - 一个从 `BlockState` 计算某个 `boolean` 的属性。
    - `IsXmas` - 返回当前时间是否在 12 月 24 日至 26 日之间。
- `net.minecraft.client.renderer.block.model.properties.select`
    - `DisplayContext` - 基于当前 `BlockDisplayContext` 的情况。
    - `SelectBlockModelProperty` - 一个从 `BlockState` 计算某个开关状态的属性。
- `net.minecraft.client.renderer.blockentity`
    - `AbstractEndPortalRenderer`
        - `renderCube` -> `submitCube`，现在为 `protected` 和 `static` 而不是 `private`
        - `submitSpecial` - 提交末地传送门立方体，由特殊渲染器使用。
        - `getExtents` - 获取每个面的顶点。
        - `getOffsetUp`, `getOffsetDown` 已移除
        - `renderType` 已移除
    - `AbstractSignRenderer` 现在接受一个泛型用于 `SignRenderState`
        - `getSignModel` 现在接受 `SignRenderState` 泛型而不是 `BlockState` 和 `WoodType`
        - `getSignModelRenderScale`, `getSignTextRenderScale`, `getTextOffset`, `translateSign` 被 `SignRenderState#transformations`、`SignRenderState$SignTransformations` 取代
        - `getSignMaterial` -> `getSignSprite`
    - `BannerRenderer`
        - `TRANSFORMATIONS` - 当在墙上或地上时要应用的变换。
        - `submitPatterns` 不再接受基础 `SpriteId`、图案是否有箔以及轮廓颜色
        - `submitSpecial` 现在接受 `BannerBlock$AttachmentType`
    - `BedRenderer`
        - `submitSpecial` 已移除
            - 这被调用两次 `submitPiece` 或通过 `BedSpecialRenderer` 为每个床部件制作组合体所取代
        - `submitPiece` 现在是 `public` 而不是 `private`，接受 `BedPart` 而不是 `Model$Simple`、`Direction` 或是否在 Z 方向平移的 `boolean`
        - `getExtents` 现在接受 `BedPart`
        - `modelTransform` - 获取给定 `Direction` 的变换。
    - `BlockEntityRenderDispatcher` 现在接受 `BlockModelResolver` 而不是 `BlockRenderDispatcher`，并且不再接受 `ItemRenderer`
        - `prepare` 现在接受一个 `Vec3` 相机位置而不是 `Camera` 本身
    - `BlockEntityRendererProvider$Context` 现在接受 `BlockModelResolver` 而不是 `BlockRenderDispatcher`，并且不再接受 `ItemRenderer`
        - `materials` -> `sprites`
    - `ChestRenderer`
        - `LAYERS` - 持有箱子的模型层。
        - `modelTransformation` - 获取给定 `Direction` 的变换。
    - `ConduitRenderer#DEFAULT_TRANSFORMATION` - 要应用的默认变换。
    - `CopperGolemStatueBlockRenderer#modelTransformation` - 获取给定 `Direction` 的变换。
    - `DecoratedPotRenderer#modelTransformation` - 获取给定 `Direction` 的变换。
    - `HangingSignRenderer` 现在使用 `HangingSignRenderState`
        - `MODEL_RENDER_SCALE` 现在是 `private` 而不是 `public`
        - `TRANSFORMATIONS` - 当在墙上或地上时要应用的变换。
        - `translateBase` -> `baseTransformation`，现在是 `private` 而不是 `public`
        - `$AttachmentType` -> `HangingSignBlock$Attachment`
            - `byBlockState` -> `$Models#get`
        - `$ModelKey` 记录已移除
    - `ShulkerBoxRenderer`
        - `modelTransform` - 获取给定 `Direction` 的变换。
        - `getExtents` 不再接受 `Direction`
    - `SignRenderer` -> `StandingSignRenderer`
        - `TRANSFORMATIONS` - 当在墙上或地上时要应用的变换。
        - `createSignModel` 现在接受一个 `PlainSignBlock$Attachment` 而不是一个表示方块是否站立的 `boolean`
    - `SkullBlockRenderer`
        - `TRANSFORMATIONS` - 当在墙上或地上时要应用的变换。
        - `submitSkull` 不再接受 `Direction` 或 `float` 旋转
    - `WallAndGroundTransformations` - 一个持有 `Direction` 到墙上变换映射的类，以及一个计算地面变换的 `int` 函数，其中 `int` 段通常表示旋转状态的数量。
- `net.minecraft.client.renderer.blockentity.state`
    - `BannerRenderState`
        - `angle` -> `transformation`，不是一对一
        - `standing` -> `attachmentType`，不是一对一
    - `BedRenderState#isHead` -> `part`，不是一对一
    - `BlockEntityRenderState#blockState` 现在是 `private` 而不是 `public`
    - `ChestRenderState#angle` -> `facing`，不是一对一
    - `CondiutRenderState` -> `ConduitRenderState`
    - `CopperGolemStatueRenderState#oxidationState` - 当前的氧化状态。
    - `HangingSignRenderState` - 悬挂标志的渲染状态。
    - `ShelfRenderState#facing` - 架子面向的方向。
    - `SignRenderState#woodType` - 标志的木材类型。
    - `SkullblockRenderState#direction`, `rotationDegrees` -> `transformation`，不是一对一
    - `StandingSignRenderState` - 站立标志的渲染状态。
- `net.minecraft.client.renderer.chunk`
    - `ChunkSectionLayer` 现在接受一个 `boolean` 表示层是否为半透明，而不是仅在上传时排序
        - `byTransparency` - 根据其透明度设置获取层。
        - `sortOnUpload` -> `translucent`，不是一对一
        - `vertexFormat` - 层使用的管线的顶点格式。
    - `ChunkSectionsToRender#drawsPerLayer` -> `drawGroupsPerLayer`，其值为 `int` 到绘图列表的映射
    - `CompiledSectionMesh`
        - `uploadMeshLayer` 被 `isVertexBufferUploaded`、`setVertexBufferUploaded` 取代
        - `uploadLayerIndexBuffer` 被 `isIndexBufferUploaded`、`setIndexBufferUploaded` 取代
    - `RenderRegionCache#createRegion` 现在接受 `ClientLevel` 而不是 `Level`
    - `SectionBuffers` -> `SectionRenderDispatcher$RenderSectionBufferSlice`，不是一对一
    - `SectionCompiler` 现在接受 `boolean` 用于环境光遮蔽和 cutout 树叶、`BlockStateModelSet`、`FluidStateModelSet` 和 `BlockColors` 而不是 `BlockRenderDispatcher`
    - `SectionMesh`
        - `getBuffers` -> `getSectionDraw`，不是一对一
        - `$SectionDraw` - 部分的绘图信息。
    - `SectionRenderDispatcher` 现在接受 `SectionCompiler` 而不是 `BlockRenderDispatcher` 和 `BlockEntityRenderDispatcher`
        - `getRenderSectionSlice` - 获取要为块层渲染的部分网格的缓冲区切片。
        - `uploadAllPendingUploads` -> `uploadGlobalGeomBuffersToGPU`，不是一对一
        - `lock`, `unlock` - 处理在将数据从一个位置复制到另一个位置时锁定调度程序，通常用于 GPU 分配。
        - `getToUpload` 已移除
        - `setLevel` 现在接受 `SectionCompiler`
        - `$RenderSection`
            - `upload`, `uploadSectionIndexBuffer` -> `addSectionBuffersToUberBuffer`，现在是 private
            - `$CompileTask`
                - `doTask` 现在返回一个 `$SectionTaskResult` 而不是 `CompletableFuture`
        - `$SectionTaskResult` -> `$RenderSection$CompileTask$SectionTaskResult`
- `net.minecraft.client.renderer.culling.Frustum` 现在接受一个 `Matrix4fc` 而不是 `Matrix4f` 用于模型视图
    - `set` - 从另一个视景体复制信息。
- `net.minecraft.client.renderer.entity`
    - `AbstractBoatRenderer` 现在接受 `Identifier` 纹理
        - `renderType` 已移除
    - `AbstractMinecartRenderer`
        - `BLOCK_DISPLAY_CONTEXT` - 显示矿车内方块的上下文。
        - `submitMinecartContents` 现在接受一个 `BlockModelRenderState` 而不是 `BlockState`
    - `CopperGolemRenderer#BLOCK_DISPLAY_CONTEXT` - 显示天线方块的上下文。
    - `DisplayRenderer`
        - `BLOCK_DISPLAY_CONTEXT` - 显示所显示方块的上下文。
        - `blockModelResolver` - 方块模型解析器。
    - `EndermanRenderer#BLOCK_DISPLAY_CONTEXT` - 显示手持方块的上下文。
    - `EntityRenderDispatcher` 现在接受 `BlockModelResolver` 而不是 `BlockRenderDispatcher`
    - `EntityRenderer#submitNameTag` -> `submitNameDisplay`，现在可选地接受 Y 位置 `int` 作为名称标签附件的偏移量
    - `EntityRendererProvider$Context` 现在接受 `BlockModelResolver` 而不是 `BlockRenderDispatcher`
        - `getMaterials` -> `getSprites`
        - `getBlockRenderDispatcher` 被 `getBlockModelResolver` 取代
    - `IronGolemRenderer#BLOCK_DISPLAY_CONTEXT` - 显示手持方块的上下文。
    - `ItemFrameRenderer#BLOCK_DISPLAY_CONTEXT` - 显示所显示方块的上下文。
    - `ItemRenderer` 类已移除
        - 使用 `ItemStackRenderState` 将元素提交给功能调度程序
        - `ENCHANTED_GLINT_ARMOR` -> `ItemFeatureRenderer#ENCHANTED_GLINT_ARMOR`
        - `ENCHANTED_GLINT_ITEM` -> `ItemFeatureRenderer#ENCHANTED_GLINT_ITEM`
        - `NO_TINT` -> `ItemFeatureRenderer#NO_TINT`
        - `getFoilBuffer` -> `ItemFeatureRenderer#getFoilBuffer`
        - `getFoilRenderType` -> `ItemFeatureRenderer#getFoilRenderType`，现在是 `public` 而不是 `private`
    - `MushroomCowRenderer#BLOCK_DISPLAY_CONTEXT` - 显示附加方块的上下文。
    - `SnowGolemRenderer#BLOCK_DISPLAY_CONTEXT` - 显示头部方块的上下文。
    - `TntRenderer#BLOCK_DISPLAY_CONTEXT` - 显示 TNT 方块的上下文。
    - `TntMinecartRenderer#submitWhiteSolidBlock` 现在接受一个 `BlockModelRenderState` 而不是 `BlockState`
- `net.minecraft.client.renderer.entity.layers`
    - `BlockDecorationLayer` 现在接受一个返回 `BlockModelRenderState` 的函数而不是可选的 `BlockState`
    - `MushroomCowMushroomLayer` 不再接受 `BlockRenderDispatcher`
    - `SnowGolemHeadLayer` 不再接受 `BlockRenderDispatcher`
- `net.minecraft.client.renderer.entity.state`
    - `AvatarRenderState#scoreText` -> `EntityRenderState#scoreText`
    - `BlockDisplayEntityRenderState#blockRenderState` -> `blockModel`，现在是 `BlockModelRenderState` 而不是 `BlockRenderState`
    - `CopperGolemRenderState#blockOnAntenna` 现在是 `BlockModelRenderState` 而不是可选的 `BlockState`
    - `EndermanRenderState#carriedBlock` 现在是 `BlockModelRenderState` 而不是可空的 `BlockState`
    - `IronGolemRenderState#flowerBlock` - 铁傀儡手持的花。
    - `ItemFrameRenderState#frameModel` - 物品框方块的模型。
    - `MinecartRenderState#displayBlockState` -> `displayBlockModel`，现在是 `BlockModelRenderState` 而不是 `BlockState`
    - `MushroomCowRenderState#mushroomModel` - 附着在牛上的蘑菇模型。
    - `SnowGolemRenderState#hasPumpkin` -> `headBlock`，现在是 `BlockModelRenderState` 而不是 `boolean`
    - `TntRenderState#blockState` 现在是 `BlockModelRenderState` 而不是可空的 `BlockState`
- `net.minecraft.client.renderer.features`
    - 功能 `render` 方法已拆分为 `renderSolid`（用于不透明渲染类型）和 `renderTranslucent`（用于半透明渲染类型）
    - 一些 `render*` 方法现在接受 `OptionsRenderState`
    - `BlockFeatureRenderer`
        - `renderSolid` 现在接受 `BlockStateModelSet` 而不是 `BlockRenderDispatcher`
        - `renderTranslucent` 现在接受 `BlockStateModelSet` 和 crumbling `MultiBufferSource$BufferSource` 而不是 `BlockRenderDispatcher`
    - `FeatureRenderDispatcher` 现在接受 `GameRenderState` 和 `ModelManager`
        - `renderAllFeatures` 已拆分为 `renderSolidFeatures` 和 `renderTranslucentFeatures`
            - 原始方法现在调用这两个方法，先 solid 后 translucent
        - `clearSubmitNodes` - 清除提交节点存储。
        - `renderTranslucentParticles` - 渲染收集的半透明粒子。
    - `FlameFeatureRenderer#render` -> `renderSolid`
    - `LeashFeatureRenderer#render` -> `renderSolid`
    - `NameTagFeatureRenderer#render` -> `renderTranslucent`
    - `ShadowFeatureRenderer#render` -> `renderTranslucent`
    - `TextFeatureRenderer#render` -> `renderTranslucent`
- `net.minecraft.client.renderer.fog`
    - `FogData#color` - 雾的颜色。
    - `FogRenderer`
        - `setupFog` 现在返回一个 `FogData` 而不是 `Vector4f` 雾颜色
        - `updateBuffer` - 用雾数据更新缓冲区。
- `net.minecraft.client.renderer.gizmos.DrawableGizmoPrimitives#render` 现在接受一个 `Matrix4fc` 而不是 `Matrix4f` 用于模型视图
- `net.minecraft.client.renderer.item`
    - `BlockModelWrapper` -> `CuboidItemModelWrapper`
        - 构造函数不再接受 `RenderType` 函数，现在接受 `Matrix4fc` 变换
        - `$Unbaked` 现在接受一个可选的 `Transformation`
    - `CompositeModel$Unbaked` 现在接受一个可选的 `Transformation`
    - `ConiditionalItemModel$Unbaked` 现在接受一个可选的 `Transformation`
    - `ItemModel`
        - `$BakingContext`
            - `materials` -> `sprites`
            - `missingItem` - 获取带有给定 `Matrix4fc` 变换的缺失物品模型。
        - `$Unbaked#bake` 现在接受来自任何父客户端物品的 `Matrix4fc` 变换
    - `ItemStackRenderState`
        - `pickParticleIcon` -> `pickParticleMaterial`，现在返回 `Material$Baked` 而不是 `TextureAtlasSprite`
        - `$LayerRenderState`
            - `EMPTY_TINTS` - 一个表示不应用色调的 `int` 数组。
            - `setRenderType` 已移除
            - `setParticleIcon` -> `setParticleMaterial`，现在接受 `Material$Baked` 而不是 `TextureAtlasSprite`
            - `setTransform` -> `setItemTransform`
            - `setLocalTransform` - 设置客户端物品变换，该变换在物品显示变换后应用。
            - `prepareTintLayers` -> `tintLayers`，不是一对一
    - `MissingItemModel#withTransform` - 获取带有给定变换的缺失物品模型。
    - `ModelRenderProperties#particleIcon` -> `particleMaterial`，现在接受 `Material$Baked` 而不是 `TextureAtlasSprite`
    - `RangeSelectItemModel$Unbaked` 现在接受一个可选的 `Transformation`
    - `SelectItemModel`
        - `$ModelSelector#get` 不再支持可空的 `ItemModel`。
        - `$Unbaked` 现在接受一个可选的 `Transformation`
        - `$UnbakedSwitch#bake` 现在接受 `Matrix4fc` 变换
    - `SpecialModelWrapper` 现在接受 `Matrix4fc` 变换
        - `$Unbaked` 现在接受一个可选的 `Transformation`
- `net.minecraft.client.renderer.rendertype`
    - `RenderType#outputTarget` - 获取输出目标。
    - `RenderTypes`
        - `MOVING_BLOCK_SAMPLER` 被 `createMovingBlockSetup` 取代，现在是 `private`
        - `entityCutoutNoCull` -> `entityCutout`
            - 原来的带剔除的 cutout 被 `entityCutoutCull` 取代
        - `entityCutoutNoCullZOffset` -> `entityCutoutZOffset`
        - `entitySmoothCutout` -> `endCrystalBeam`
        - `entityNoOutline` -> `entityTranslucent`，`affectsOutline` 为 `false`
        - `entityDecal`, `dragonExplosionAlpha` -> `entityCutoutDissolve`，不是一对一
        - `itemEntityTranslucentCull` -> `entityTranslucentCullItemTarget`, `itemCutout`, `itemTranslucent`; 不是一对一
        - `bannerPattern` - 用于渲染旗帜图案的渲染类型。
- `net.minecraft.client.renderer.special`
    - `BannerSpecialRenderer`, `$Unbaked` 现在接受 `BannerBlock$AttachmentType`
        - `$Unbaked` 现在使用 `BannerPatternLayers` 作为泛型
    - `BedSpecialRenderer`, `$Unbaked` 现在接受 `BedPart`
        - `$Unbaked` 现在实现 `NoDataSpecialModelRenderer$Unbaked`
    - `BellSpecialRenderer` - 钟的特殊渲染器。
    - `BookSpecialRenderer` - 附魔台上书的特殊渲染器。
    - `ChestSpecialRenderer$Unbaked` 现在实现 `NoDataSpecialModelRenderer$Unbaked`
        - 构造函数现在接受 `ChestType`
        - `*_CHEST_TEXTURE` 已从字段名中移除，现在是 `MultiBlockChestResources`
        - `ENDER_CHEST_TEXTURE` -> `ENDER_CHEST`
    - `ConduitSpecialRenderer$Unbaked` 现在实现 `NoDataSpecialModelRenderer$Unbaked`
    - `CopperGolemStatueSpecialRenderer$Unbaked` 现在实现 `NoDataSpecialModelRenderer$Unbaked`
    - `DecoratedPotSpecialRenderer$Unbaked` 现在使用 `PotDecorations` 作为泛型
    - `EndCubeSpecialRenderer` - 末地传送门立方体的特殊渲染器。
    - `HangingSignSpecialRenderer$Unbaked` 现在实现 `NoDataSpecialModelRenderer$Unbaked`
        - 构造函数现在接受 `HangingSignBlock$Attachment`
    - `NoDataSpecialModelRenderer`
        - `submit` 不再接受 `ItemDisplayContext`
        - `$Unbaked` - 不需要提取数据的特殊模型渲染器的未烘焙渲染器。
    - `PlayerHeadSpecialRenderer$Unbaked` 现在使用 `PlayerSkinRenderCache$RenderInfo` 作为泛型
    - `ShieldSpecialRenderer`
        - `DEFAULT_TRANSFORMATION` - 要应用的默认变换。
        - `$Unbaked` 现在使用 `DataComponentMap` 作为泛型
    - `ShulkerBoxSpecialRenderer`, `$Unbaked` 不再接受 `Direction` 方向
        - `$Unbaked` 现在实现 `NoDataSpecialModelRenderer$Unbaked`
    - `SkullSpecialRenderer$Unbaked` 现在实现 `NoDataSpecialModelRenderer$Unbaked`
    - `SpecialModelRenderer`
        - `submit` 不再接受 `ItemDisplayContext`
        - `$BakingContext`
            - `materials` -> `sprites`
            - `$Simple` 被 `BlockModel$BakingContext`、`ItemModel$BakingContext` 取代
                - `materials` -> `sprites`
        - `$Unbaked` 现在具有从表示对象中提取参数的泛型
    - `SpecialModelRenderers#createBlockRenderers` -> `BuiltInBlockModels#createBlockModels`，不是一对一
    - `StandingSignSpecialRenderer$Unbaked` 现在实现 `NoDataSpecialModelRenderer$Unbaked`
        - 构造函数现在接受 `PlainSignBlock$Attachment`
    - `TridentSpecialRenderer`
        - `DEFAULT_TRANSFORMATION` - 要应用的默认变换。
        - `$Unbaked` 现在实现 `NoDataSpecialModelRenderer$Unbaked`
- `net.minecraft.client.renderer.state.*` -> `.state.level.*`
- `net.minecraft.client.renderer.state`
    - `GameRenderState` - 游戏的渲染状态。
    - `OptionsRenderState` - 客户端用户选项的渲染状态。
    - `WindowRenderState` - 游戏窗口的渲染状态。
- `net.minecraft.client.renderer.state.gui.GuiRenderState#submit*` 方法已重命名为 `add*`
- `net.minecraft.client.renderer.state.level`
    - `BlockBreakingRenderState` 现在是一个记录，不再扩展 `MovingBlockRenderState`
        - 构造函数接受 `BlockPos`、`BlockState` 和当前进度 `int`
    - `CameraEntityRenderState` - 相机实体的渲染状态。
    - `CameraRenderState`
        - `xRot`, `yRot` - 相机的旋转。
        - `entityPos` 已移除
        - `isPanoramicMode` - 相机是否处于全景模式。
        - `cullFrustum` - 剔除视景体。
        - `fogType`, `fogData` - 雾元数据。
        - `hudFov` - HUD 视场角。
        - `depthFar` - 深度 Z 远平面。
        - `projectionMatrix`, `viewRotationMatrix` - 用于从世界空间转换到屏幕空间的矩阵。
        - `entityRenderState` - 相机附加到的实体。
    - `LevelRenderState`
        - `lastEntityRenderStateCount` - 渲染到屏幕的实体数量。
        - `cloudColor`, `cloudHeight` - 云元数据。
    - `LightmapRenderState` - 光照图的渲染状态。
- `net.minecraft.client.renderer.texture`
    - `MipmapGenerator#generateMipLevels` 现在接受计算出的图像 `Transparency`
    - `SpriteContents`
        - `transparency` - 获取精灵的透明度。
        - `getUniqueFrames` 现在返回一个 `IntList` 而不是 `IntStream`
        - `computeTransparency` - 计算选定 UV 边界的透明度。
        - `$AnimatedTexture#getUniqueFrames` 现在返回一个 `IntList` 而不是 `IntStream`
    - `TextureAtlasSprite#transparency` - 获取精灵的透明度。
- `net.minecraft.client.resources.model`
    - `AtlasManager` -> `.model.sprite.AtlasManager`
    - `BlockModelRotation` -> `.client.renderer.block.dispatch.BlockModelRotation`
    - `Material` -> `.model.sprite.SpriteId`，不是一对一
    - `MaterialSet` -> `.model.sprite.SpriteGetter`
    - `MissingBlockModel` -> `.model.cuboid.MissingCuboidModel`
    - `ModelBaker`
        - `sprites` -> `materials`
        - `parts` -> `interner`
        - `$PartCache` -> `$Interner`
            - `vector(float, float, float)` 已移除
            - `materialInfo` - 获取内部化的材质信息对象。
    - `ModelBakery`
        - `BANNER_BASE` -> `Sheets#BANNER_BASE`
        - `SHIELD_BASE` -> `Sheets#SHIELD_BASE`
        - `NO_PATTERN_SHIELD` -> `Sheets#SHIELD_BASE_NO_PATTERN`
        - `LAVA_*` -> `FluidStateModelSet#LAVA_MODEL`，现在是 `private` 而不是 `public`
        - `WATER_*` -> `FluidStateModelSet#WATER_MODEL`，现在是 `private` 而不是 `public`
        - `$BakingResult#getBlockStateModel` - 从 `BlockState` 获取 `BlockStateModel`。
        - `$MissingModels` 现在接受一个 `MissingItemModel` 而不是 `ItemModel` 用于 `Item`，以及一个 `FluidModel`
    - `ModelManager`
        - `BLOCK_OR_ITEM` 已移除
        - `getMissingBlockStateModel` -> `BlockStateModelSet#missingModel`
        - `getBlockModelShaper` -> `getBlockStateModelSet`，不是一对一
        - `getBlockModelSet` - 获取 `BlockState` 到方块模型的映射。
        - `specialBlockModelRenderer` 已移除
        - `getFluidStateModelSet` - 获取 `Fluid` 到流体模型的映射。
    - `ModelState` -> `.client.renderer.block.dispatch.ModelState`
    - `QuadCollection` -> `.model.geometry.QuadCollection`
        - `addAll` - 添加另一个四边形集合中的所有元素。
        - `materialFlags`, `hasMaterialFlag` - 处理模型使用的材质的标志。
    - `ResolvedModel#resolveParticleSprite` -> `resolveParticleMaterial`，现在返回 `Material$Baked` 而不是 `TextureAtlasSprite`
    - `SpriteGetter` -> `.model.sprite.MaterialBaker`
    - `UnbakedGeometry` -> `.model.geometry.UnbakedGeometry`
    - `WeightedVariants` -> `.client.renderer.block.dispatch.WeightedVariants`
- `net.minecraft.client.resources.model.sprite.Material` - 对纹理精灵的引用，以及是否强制纹理半透明。
- `net.minecraft.world.entity.animal.Animal#isBrightEnoughToSpawn` 现在接受一个 `BlockAndLightGetter` 而不是 `BlockAndTintGetter`
- `net.minecraft.world.level`
    - `BlockAndTintGetter` -> `BlockAndLightGetter`
        - `BlockAndTintGetter` 现在是客户端专用的，实现 `BlockAndLightGetter`
        - `getShade` -> `cardinalLighting`；不是一对一
        - `getBlockTint` -> `BlockAndTintGetter#getBlockTint`
    - `CardinalLighting` - 持有每个方向应用的光照。
    - `EmptyBlockAndTintGetter` -> `BlockAndTintGetter#EMPTY`
    - `LevelReader` 现在实现 `BlockAndLightGetter` 而不是 `BlockAndTintGetter`
- `net.minecraft.world.level.block`
    - `BannerBlock$AttachmentType` - 旗帜附着到另一个方块的位置。
    - `CeilingHangingSignBlock` 现在实现 `HangingSignBlock`
        - `getAttachmentPoint` - 获取标志附着到另一个方块的位置。
    - `HangingSignBlock` - 一个定义附着到另一个方块的悬挂标志的接口。
    - `PlainSignBlock` - 一个定义附着到另一个方块的普通标志的接口。
    - `StandingSignBlock` 现在实现 `PlainSignBlock`
    - `WallingHangingSignBlock` 现在实现 `HangingSignBlock`
    - `WallSignBlock` 现在实现 `PlainSignBlock`
- `net.minecraft.world.level.block.state.BlockBehaviour#getLightBlock`, `$BlockStateBase#getLightBlock` -> `getLightDampening`
- `net.minecraft.world.level.block.state.properties`
    - `BedPart#CODEC` - 床部分的编解码器。
    - `ChestType#CODEC` - 箱子类型的编解码器。
- `net.minecraft.world.level.dimension.DimensionType$CardinalLightType` -> `CardinalLighting$Type`

## 次要迁移

以下是有用或有趣的添加、更改和删除列表，这些内容在入门指南中不值得单独列出一个章节。

### 可种植标签

用于确定可种植植物能否存活或被放置的方块已移至方块和流体标签。每个此类标签以 `support_*` 开头，后跟方块（例如 `bamboo`、`cactus`）或组（例如 `crops`、`dry_vegetation`）。这由相关的方块子类通过重写 `Block#canSurvive` 或对于植被 `VegetationBlock#mayPlaceOn` 来处理。

- `net.minecraft.world.level.block`
    - `AttachedStemBlock` 现在接受一个 `TagKey` 表示它可以放置在上面的方块
    - `FarmBlock` -> `FarmlandBlock`
    - `FungusBlock` -> `NetherFungusBlock`，不是一对一
    - `RootsBlock` -> `NetherRootsBlock`，不是一对一
    - `WaterlilyBlock` -> `LilyPadBlock`，不是一对一
    - `StemBlock` 现在接受一个 `TagKey` 表示它可以放置在上面的方块，以及一个 `TagKey` 表示其果实可以放置在上面的方块

### 容器屏幕变更

`AbstractContainerScreen` 的使用略有变化，需要一些小的更改。首先，`imageWidth` 和 `imageHeight` 现在是 final 的，可以在构造函数中作为参数设置。如果未指定这两个参数，它们默认为原始的 176 x 166 背景图像。

```java
// 假设存在某个 AbstractContainerMenu 子类
public class ExampleContainerScreen extends AbstractContainerScreen<ExampleContainerMenu> {

    // 构造函数
    public ExampleContainerScreen(ExampleContainerMenu menu, Inventory playerInventory, Component title) {
        // 在构造函数的最后两个参数中指定图像宽度和高度
        super(menu, playerInventory, title, 256, 256);
    }
}
```

此外，`AbstractContainerScreen#render` 的重写现在在调用栈末尾调用 `renderTooltip`。这意味着，在大多数情况下，你不应该在 `AbstractContainerScreen` 的子类型中重写 `render`。所有事情都可以通过类提供的其他方法之一完成。

- `net.minecraft.client.gui.screens.inventory.AbstractContainerScreen` 现在可选地接受背景图像宽度和高度
    - `imageWidth`, `imageHeight` 现在是 final 的
    - `DEFAULT_IMAGE_WIDTH`, `DEFAULT_IMAGE_HEIGHT` - 容器背景图像的默认宽度和高度。
    - `slotClicked` 现在接受一个 `ContainerInput` 而不是 `ClickType`
    - `render` 重写现在默认调用 `renderTooltip`
- `net.minecraft.world.inventory`
    - `AbstractContainerMenu#clicked` 现在接受一个 `ContainerInput` 而不是 `ClickType`
    - `ClickType` -> `ContainerInput`

### 新标签提供者

添加了一个新的 `TagsProvider`，它提供了一个处理 `Holder$Reference` 的工具，称为 `HolderTagProvider`。这仅由 `PotionTagsProvider` 使用。

此外，`TagBuilder` 现在提供了一种设置标签上 `replace` 字段的方法，该方法在反序列化期间删除所有先前读取的条目。

- `net.minecraft.data.tags`
    - `FeatureTagsProvider` - 用于 `ConfiguredFeature` 的标签提供器。
    - `HolderTagProvider` - 一个带有通过其引用持有者附加标签的工具的标签提供器。
    - `KeyTagProvider#tag` 现在有一个重载，指示是否替换标签中的条目。
    - `PotionTagsProvider` - 用于药水标签的提供器。
    - `TradeRebalanceTradeTagsProvider` - 用于交易重新平衡的村民交易标签提供器。
    - `VillagerTradesTagsProvider` - 用于村民交易标签的提供器。
- `net.minecraft.tags`
    - `FeatureTags` - 用于 `ConfiguredFeature` 的标签。
    - `TagBuilder#shouldReplace`, `setReplace` - 处理 `replace` 字段，该字段在反序列化期间删除所有先前读取的条目。

### 测试环境状态追踪

`TestEnvironmentDefinition` 现在可以跟踪创建时世界的原始状态，以便在运行时正确恢复。这是通过一个称为 'SavedDataType' 的泛型完成的。在 `setup` 上，每个环境将返回表示修改内容原始状态的泛型数据。然后，在 `teardown` 上，原始状态将恢复到关卡中，以供下一个测试用例使用。

```java
// 泛型应表示存储在关卡上的原始数据
public record RespawnEnvironment(LevelData.RespawnData respawn) implements TestEnvironmentDefinition<LevelData.RespawnData> {

    @Override
    public LevelData.RespawnData setup(ServerLevel level) {
        // 修改关卡同时记录原始状态。
        var original = level.getRespawnData();
        level.setRespawnData(this.respawn);

        // 返回原始状态。
        return original;
    }

    @Override
    public void teardown(ServerLevel level, LevelData.RespawnData original) {
        // 将关卡状态重置为原始值。
        level.setRespawnData(original);
    }
    
    @Override
    public MapCodec<RespawnEnvironment> codec() {
        // 在此处返回注册的 MapCodec。
        // ...
    }
}
```

- `net.minecraft.gametest.framework.TestEnvironmentDefinition` 现在有一个泛型表示测试环境执行的给定修改的原始状态
    - `setup` 现在返回表示原始状态的泛型
    - `teardown` 不再是默认的，接受要恢复的原始状态
    - `activate`, `$Activation` - 处理一个活动的测试环境。

### 类型化实例

`TypedInstance` 是一个附加到某些对象的接口，这些对象表示某个其他“类型”对象的实例。例如，`Entity` 是 `EntityType` 的类型化实例，或者 `BlockState` 是 `Block` 的类型化实例。此接口旨在作为一种标准方法，提供对类型 `Holder` 的访问，并通过 `is` 检查后备类型（因此也是实例）是否等同于某个标识符、标签或原始对象。

```java
// 对于某个 Entity entity，检查 EntityType
entity.is(EntityType.PLAYER);

// 对于某个 ItemStack itemStack，检查 Item
itemStack.is(ItemTags.BUTTONS);

// 对于某个 BlockEntity blockEntity，检查 BlockEntityType
blockEntity.is(BlockEntityType.CHEST);

// 对于某个 BlockState blockState，检查 Block
blockState.is(Blocks.DIRT);

// 对于某个 FluidState fluidState，检查 Fluid
fluidState.is(FluidTags.WATER);
```

- `net.minecraft.core.TypedInstance` - 一个表示此对象是某个其他“类型”对象的实例的接口。
- `net.minecraft.world.entity`
    - `Entity` 现在实现 `TypedInstance<EntityType<?>>`
    - `EntityType#is` -> `TypedInstance#is`
        - 现在在 `Entity` 实例上
- `net.minecraft.world.item.ItemStack` 现在实现 `TypedInstance<Item>`
    - `getItemHolder` -> `typeHolder`
    - `getTags` -> `tags`
- `net.minecraft.world.level.block.entity`
    - `BlockEntity` 现在实现 `TypedInstance<BlockEntityType>`
    - `BlockEntityType#getKey` 已移除
- `net.minecraft.world.level.block.state.BlockBehaviour$BlockStateBase` 现在实现 `TypedInstance<Block>`
    - `getBlockHolder` -> `typeHolder`
    - `getTags` -> `tags`
- `net.minecraft.world.level.material.FluidState` 现在实现 `TypedInstance<Fluid>`
    - `holder` -> `typeHolder`
    - `getTags` -> `tags`

### 实体纹理与成年幼年模型

`assets/minecraft/textures/entity/*` 中的实体纹理现已分类到子目录中（例如，熊猫纹理的 `entity/panda`，或猪纹理的 `entity/pig`）。大多数纹理已以实体类型开头后跟下划线及其变体命名（例如，喷溅箭的 `arrow_tipped`，冷猪变体的 `pig_cold`，或棕色熊猫变体的 `panda_brown`）。

此外，一些动物模型已拆分为幼年和成年变体的单独类。这些模型要么直接扩展抽象模型实现（例如 `AbstractFelineModel`），要么扩展原始模型类（例如 `PigModel`）。

- `net.minecraft.client.animation.definitions`
    - `BabyArmadilloAnimation` - 幼年犰狳的动画。
    - `BabyAxolotlAnimation` - 幼年美西螈的动画。
    - `BabyRabbitAnimation` - 幼年兔子的动画。
    - `CamelBabyAnimation` - 幼年骆驼的动画。
    - `FoxBabyAnimation` - 幼年狐狸的动画。
    - `RabbitAnimation` - 兔子的动画。
- `net.minecraft.client.model`
    - `HumanoidModel`
        - `ADULT_ARMOR_PARTS_PER_SLOT`, `BABY_ARMOR_PARTS_PER_SLOT` - 装备槽位到模型部件键的映射。
        - `createBabyArmorMeshSet` - 为幼年类人生物创建盔甲模型集。
        - `createArmorMeshSet` 现在可以接受一个装备槽位到要保留的模型部件键的映射
        - `setAllVisible` 已移除
    - `QuadrupedModel` 现在有一个接受 `RenderType` 函数的构造函数
- `net.minecraft.client.model.animal.armadillo`
    - `AdultArmadilloModel` - 成年犰狳的实体模型。
    - `ArmadilloModel` 现在是抽象的
        - 构造函数现在接受行走、卷起/展开和窥视动画的定义
        - `BABY_TRANSFORMER` 已直接合并到 `BabyArmadilloModel` 的层定义中
        - `HEAD_CUBE`, `RIGHT_EAR_CUBE`, `LEFT_EAR_CUBE` 现在是 `protected` 而不是 `private`
        - `createBodyLayer` -> `AdultArmadilloModel#createBodyLayer`, `BabyArmadilloModel#createBodyLayer`
    - `BabyArmadilloModel` - 幼年犰狳的实体模型。
- `net.minecraft.client.model.animal.axolotl.AxolotlModel` -> `AdultAxolotlModel`, `BabyAxolotlModel`
- `net.minecraft.client.model.animal.bee`
    - `AdultBeeModel` - 成年蜜蜂的实体模型。
    - `BabyBeeModel` - 幼年蜜蜂的实体模型。
    - `BeeModel` 现在是抽象的
        - `BABY_TRANSFORMER` 已直接合并到 `BabyBeeModel` 的层定义中
        - `BONE`, `STINGER`, `FRONT_LEGS`, `MIDDLE_LEGS`, `BACK_LEGS` 现在是 `protected` 而不是 `private`
        - `bone` 现在是 `protected` 而不是 `private`
        - `createBodyLayer` -> `AdultBeeModel#createBodyLayer`, `BabyBeeModel#createBodyLayer`
        - `bobUpAndDown` - 以期望的速度上下摆动蜜蜂，取决于其当前年龄。
- `net.minecraft.client.model.animal.camel`
    - `AdultCamelModel` - 成年骆驼的实体模型。
    - `BabyCamelModel` - 幼年骆驼的实体模型。
    - `CamelModel` 现在是抽象的
        - 构造函数现在接受行走、坐下（带/不带姿势）、站立、闲置和冲刺动画的定义
        - `BABY_TRANSFORMER` 已直接合并到 `BabyCamelModel` 的层定义中
        - `createBodyLayer` -> `AdultCamelModel#createBodyLayer`, `BabyCamelModel#createBodyLayer`
    - `CameSaddleModel` 现在扩展 `AdultCamelModel` 而不是 `CamelModel`
- `net.minecraft.client.model.animal.chicken`
    - `AdultChickenModel` - 成年鸡的实体模型。
    - `BabyChickenModel` - 幼年鸡的实体模型。
    - `ChickenModel` 现在是抽象的
        - `RED_THING` -> `AdultChickenModel#RED_THING`
        - `BABY_TRANSFORMER` 已直接合并到 `BabyChickenModel` 的层定义中
        - `createBodyLayer` -> `AdultChickenModel#createBodyLayer`
        - `createBaseChickenModel` -> `AdultChickenModel#createBaseChickenModel`
    - `ColdChickenModel` 现在扩展 `AdultChickenModel`
- `net.minecraft.client.model.animal.cow.BabyCowModel` - 幼年牛的实体模型。
- `net.minecraft.client.model.animal.dolphin.BabyDolphinModel` - 幼年海豚的实体模型。
- `net.minecraft.client.model.animal.equine`
    - `AbstractEquineModel` 现在有一个直接指定要使用的 `ModelPart` 的重载
        - `BABY_TRANSFORMER` 已直接合并到 `BabyDonkeyModel` 的层定义中
        - `rightHindLeg`, `leftHindLeg`, `rightFrontLeg`, `leftFrontLeg` 现在是 `protected` 而不是 `private`
        - `createBabyMesh` -> `BabyHorseModel#createBabyMesh`，不是一对一
        - `offsetLegPositionWhenStanding` - 当实体站立时偏移腿的位置。
        - `getLegStandAngle`, `getLegStandingYOffset`, `getLegStandingZOffset`, `getLegStandingXRotOffset`, `getTailXRotOffset` - 马模型各部分的偏移和角度。
        - `animateHeadPartsPlacement` - 根据其进食和站立状态动画头部。
    - `BabyDonkeyModel` - 幼年驴的实体模型。
    - `BabyHorseModel` - 幼年马的实体模型。
    - `DonkeyModel` 现在有一个直接指定要使用的 `ModelPart` 的重载
        - `createBabyLayer` -> `BabyDonkeyModel#createBabyLayer`
    - `EquineSaddleModel#createFullScaleSaddleLayer` 已移除
        合并到 `createSaddleLayer` 中，移除了幼年变体
- `net.minecraft.client.model.animal.feline`
    - `CatModel` -> `AdultCatModel`, `BabyCatModel`; 不是一对一
    - `FelineModel` -> `AbstractFelineModel`，不是一对一
        - 实现为 `AdultFelineModel` 和 `BabyFelineModel`
    - `OcelotModel` -> `AdultOcelotModel`, `BabyOcelotModel`; 不是一对一
- `net.minecraft.client.model.animal.fox`
    - `AdultFoxModel` - 成年狐狸的实体模型。
    - `BabyFoxModel` - 幼年狐狸的实体模型。
    - `FoxModel` 现在是抽象的
        - `BABY_TRANSFORMER` 已直接合并到 `BabyFoxModel` 的层定义中
        - `body`, `rightHindLeg`, `leftHindLeg`, `rightFontLeg`, `leftFrontLeg`, `tail` 现在是 `protected` 而不是 `private`
        - `createBodyLayer` -> `AdultFoxModel#createBodyLayer`, `BabyFoxModel#createBodyLayer`
        - `set*Pose` - 设置狐狸当前姿势的方法。
- `net.minecraft.client.model.animal.goat`
    - `BabyGoatModel` - 幼年山羊的实体模型。
    - `GoatModel#BABY_TRANSFORMER` 已直接合并到 `BabyGoatModel` 的层定义中
- `net.minecraft.client.model.animal.llama`
    - `BabyLlamaModel` - 幼年羊驼的实体模型。
    - `LlamaModel#createBodyLayer` 不再接受表示实体是否为幼年的 `boolean`
- `net.minecraft.client.model.animal.panda`
    - `BabyPandaModel` - 幼年熊猫的实体模型。
    - `PandaModel`
        - `BABY_TRANSFORMER` 已直接合并到 `BabyPandaModel` 的层定义中
        - `animateSitting` - 动画熊猫坐下。
- `net.minecraft.client.model.animal.pig.BabyPigModel` - 幼年猪的实体模型。
- `net.minecraft.client.model.animal.polarbear`
    - `BabyPolarBearModel` - 幼年北极熊的实体模型。
    - `PolarBearModel#BABY_TRANSFORMER` 已直接合并到 `BabyPolarBearModel` 的层定义中
- `net.minecraft.client.model.animal.rabbit`
    - `AdultRabbitModel` - 成年兔子的实体模型。
    - `BabyRabbitModel` - 幼年兔子的实体模型。
    - `RabbitModel` 现在是抽象的
        - 构造函数现在接受跳跃和空闲头部倾斜的两个动画定义
        - `FRONT_LEGS`, `BACK_LEGS` - 实体腿的子名称。
        - `LEFT_HAUNCH`, `RIGHT_HAUNCH` 现在是 `protected`
        - `createBodyLayer` -> `AdultRabbitModel#createBodyLayer`, `BabyRabbitModel#createBodyLayer`; 不是一对一
- `net.minecraft.client.model.animal.sheep`
    - `BabySheepModel` - 幼年羊的实体模型。
    - `SheepModel#BABY_TRANSFORMER` 已直接合并到 `BabySheepModel` 的层定义中
- `net.minecraft.client.model.animal.sniffer`
    - `SnifferModel#BABY_TRANSFORMER` 已直接合并到 `SniffletModel` 的层定义中
    - `SniffletModel` - 幼年嗅探兽的实体模型。
- `net.minecraft.client.model.animal.squid`
    - `BabySquidModel` - 幼年鱿鱼的实体模型。
    - `SquidModel#createTentacleName` 现在是 protected 而不是 private
- `net.minecraft.client.model.animal.turtle`
    - `AdultTurtleModel` - 成年海龟的实体模型。
    - `BabyTurtleModel` - 幼年海龟的实体模型。
    - `TurtleModel` 现在是抽象的
        - 构造函数现在可以接受渲染类型函数
        - `BABY_TRANSFORMER` 已直接合并到 `BabyTurtleModel` 的层定义中
        - `createBodyLayer` -> `AdultTurtleModel#createBodyLayer`, `BabyTurtleModel#createBodyLayer`
- `net.minecraft.client.model.animal.wolf`
    - `AdultWolfModel` - 成年狼的实体模型。
    - `BabyWolfModel` - 幼年狼的实体模型。
    - `WolfModel` 现在是抽象的
        - `ModelPart` 字段现在都是 protected
        - `createMeshDefinition` -> `AdultWolfModel#createBodyLayer`, `BabyWolfModel#createBodyLayer`; 不是一对一
        - `shakeOffWater` - 甩水时设置身体旋转。
        - `setSittingPose` - 设置狼的坐姿。
- `net.minecraft.client.model.geom`
    - `ModelLayers`
        - `COLD_CHICKEN_BABY` 已移除
        - `COLD_PIG_BABY` 已移除
        - `PIG_BABY_SADDLE` 已移除
        - `SHEEP_BABY_WOOL_UNDERCOAT` 已移除
        - `WOLF_BABY_ARMOR` 已移除
        - `DONKEY_BABY_SADDLE` 已移除
        - `HORSE_BABY_ARMOR` 已移除
        - `HORSE_BABY_SADDLE` 已移除
        - `MULE_BABY_SADDLE` 已移除
        - `SKELETON_HORSE_BABY_SADDLE` 已移除
        - `UNDEAD_HORSE_BABY_ARMOR` 已移除
        - `ZOMBIE_HORSE_BABY_SADDLE` 已移除
        - `STRIDER_BABY_SADDLE` 已移除
    - `PartNames#WAIST` - 腰部部件。
- `net.minecraft.client.model.monster.hoglin`
    - `BabyHoglinModel` - 幼年疣猪兽的实体模型。
    - `HoglinModel`
        - `BABY_TRANSFORMER` 已直接合并到 `BabyHoglinModel` 的层定义中
        - `head` 现在是 `protected` 而不是 `private`
        - `createBabyLayer` -> `BabyHoglinModel#createBodyLayer`
- `net.minecraft.client.model.monster.piglin`
    - `AbstractPiglinModel` 现在是抽象的
        - `leftSleeve`, `rightSleeve`, `leftPants`, `rightPants`, `jacket` 已移除
        - `ADULT_EAR_ANGLE_IN_DEGREES`, `BABY_EAR_ANGLE_IN_DEGREES` - 猪灵耳朵的角度。
        - `createMesh` 被 `AdultPiglinModel#createBodyLayer`, `AdultZombifiedPiglinModel#createBodyLayer`, `BabyPiglinModel#createBodyLayer`, `BabyZombifiedPiglinModel#createBodyLayer` 取代
        - `createBabyArmorMeshSet` - 为幼年猪灵模型创建盔甲网格。
        - `getDefaultEarAngleInDegrees` - 获取默认耳朵角度。
    - `AdultPiglinModel` - 成年猪灵的实体模型。
    - `AdultZombifiedPiglinModel` - 成年僵尸猪灵的实体模型。
    - `BabyPiglinModel` - 幼年猪灵的实体模型。
    - `BabyZombifiedPiglinModel` - 幼年僵尸猪灵的实体模型。
    - `PiglinModel` 现在是抽象的
    - `ZombifiedPiglinModel` 现在是抽象的
- `net.minecraft.client.model.monster.strider`
    - `AdultStriderModel` - 成年炽足兽的实体模型。
    - `BabyStriderModel` - 幼年炽足兽的实体模型。
    - `StriderModel` 现在是抽象的
        - `BABY_TRANSFORMER` 已直接合并到 `BabyStriderModel` 的层定义中
        - `rightLeg`, `leftLeg`, `body` 现在是 `protected` 而不是 `private`
        - `SPEED` - 移动动画的速度标量。
        - `customAnimations` - 额外的动画设置。
        - `animateBristle` - 动画炽足兽的鬃毛。
- `net.minecraft.client.model.monster.zombie`
    - `BabyDrownedModel` - 幼年溺尸的实体模型。
    - `BabyZombieModel` - 幼年僵尸的实体模型。
    - `BabyZombieVillagerModel` - 幼年僵尸村民的实体模型。
- `net.minecraft.client.model.npc`
    - `BabyVillagerModel` - 幼年村民的实体模型。
    - `VillagerModel#BABY_TRANSFORMER` 已直接合并到 `BabyVillagerModel` 的层定义中
- `net.minecraft.client.renderer.entity`
    - `AxolotlRenderer` 现在接受一个 `EntityModel<AxolotlRenderState>` 作为其泛型
    - `CamelHuskRenderer` 现在扩展 `MobRenderer` 而不是 `CamelRenderer`
    - `CamelRenderer#createCamelSaddleLayer` 现在是 `static`
    - `CatRenderer` 现在接受一个 `AbstractFelineModel` 作为其泛型
    - `DonkeyRenderer` 现在接受一个 `EquipmentClientInfo$LayerType` 和 `ModelLayerLocation` 用于鞍层和模型，并将 `DonkeyRenderer$Type` 拆分为成年类型和幼年类型
        - `$Type`
            - `DONKEY_BABY` - 驴的幼年变体。
            - `MULE_BABY` - 骡的幼年变体。
    - `OcelotRenderer` 现在接受一个 `AbstractFelineModel` 作为其泛型
    - `UndeadHorseRenderer` 现在接受一个 `EquipmentClientInfo$LayerType` 和 `ModelLayerLocation` 用于鞍层和模型，并将 `UndeadHorseRenderer$Type` 拆分为成年类型和幼年类型
        - `$Type`
            - `SKELETON_BABY` - 骷髅马的幼年变体。
            - `ZOMBIE_BABY` - 僵尸马的幼年变体。
- `net.minecraft.client.renderer.entity.layers.CatCollarLayer` 现在接受一个 `AbstractFelineModel` 作为其泛型
- `net.minecraft.client.renderer.entity.state`
    - `AxolotlRenderState`
        - `swimAnimation` - 游泳的状态。
        - `walkAnimationState` - 在地面（非水下）行走的状态。
        - `walkUnderWaterAnimationState` - 在水下行走的状态。
        - `idleUnderWaterAnimationState` - 在水下但未在地面闲置的状态。
        - `idleUnderWaterOnGroundAnimationState` - 在水下接触海底时闲置的状态。
        - `idleOnGroundAnimationState` - 在地面（非水下）闲置的状态。
        - `playDeadAnimationState` - 装死的状态。
    - `RabbitRenderState`
        - `hopAnimationState` - 实体正在执行的跳跃状态。
        - `idleHeadTiltAnimationState` - 执行空闲动画时头部倾斜的状态。
- `net.minecraft.client.resources.model.EquipmentClientInfo$LayerType#HUMANOID_BABY` - 幼年类人生物装备层。
- `net.minecraft.sounds.SoundEvents#PIG_EAT_BABY` - 幼年猪进食时播放的声音。
- `net.minecraft.world.entity.AgeableMob`
    - `canUseGoldenDandelion` - 是否可以使用金蒲公英来锁定实体的年龄。
    - `setAgeLocked` - 将实体设置为年龄锁定。
    - `makeAgeLockedParticle` - 在锁定实体年龄时创建粒子。
    - `AGE_LOCK_DOWNWARDS_MOVING_PARTICLE_Y_OFFSET` - 粒子起始位置的 Y 偏移量。
- `net.minecraft.world.entity.animal.axolotl.Axolotl`
    - `swimAnimation` - 游泳的状态。
    - `walkAnimationState` - 在地面（非水下）行走的状态。
    - `walkUnderWaterAnimationState` - 在水下行走的状态。
    - `idleUnderWaterAnimationState` - 在水下但未在地面闲置的状态。
    - `idleUnderWaterOnGroundAnimationState` - 在水下接触海底时闲置的状态。
    - `idleOnGroundAnimationState` - 在地面（非水下）闲置的状态。
    - `playDeadAnimationState` - 装死的状态。
    - `$AnimationState` -> `$AxolotlAnimationState`
- `net.minecraft.world.entity.animal.chicken.ChickenVariant` 现在接受一个幼年纹理的资源
- `net.minecraft.world.entity.animal.cow.CowVariant` 现在接受一个幼年纹理的资源
- `net.minecraft.world.entity.animal.cat.CatVariant` 现在接受一个幼年纹理的资源
    - `CatVariant#assetInfo` - 根据实体是否为幼年获取实体纹理。
- `net.minecraft.world.entity.animal.equine.AbstractHorse#BABY_SCALE` - 幼年大小与成年相比的比例。
- `net.minecraft.world.entity.animal.frog.Tadpole`
    - `ageLockParticleTimer` - 年龄锁定实体的粒子应生成的计时器。
    - `setAgeLocked`, `isAgeLocked` - 处理蝌蚪的年龄锁定。
- `net.minecraft.world.entity.animal.goat.Goat`
    - `BABY_DEFAULT_X_HEAD_ROT` - 幼年变体的默认头部 X 旋转。
    - `MAX_ADDED_RAMMING_X_HEAD_ROT` - 最大头部 X 旋转。
    - `addHorns`, `removeHorns` 已移除
- `net.minecraft.world.entity.animal.pig.PigVariant` 现在接受一个幼年纹理的资源
- `net.minecraft.world.entity.animal.rabbit.Rabbit`
    - `hopAnimationState` - 实体正在执行的跳跃状态。
    - `idleHeadTiltAnimationState` - 执行空闲动画时头部倾斜的状态。
- `net.minecraft.world.entity.animal.wolf`
    - `WolfSoundVariant` -> `WolfSoundVariant$WolfSoundSet`
        - 该类本身现在持有成年狼和幼年狼的两个声音集。
    - `WolfSoundVariants$SoundSet#getSoundEventSuffix` -> `getSoundEventIdentifier`
- `net.minecraft.world.entity.animal.wolf.WolfVariant` 现在接受一个幼年变体的资源信息
- `net.minecraft.world.item.equipment.EquipmentAssets#TRADER_LLAMA_BABY` - 幼年流浪商羊驼的装备资源。

### interactAt 的移除

`Entity#interactAt` 已被移除，所有进一步的调用都已合并到 `Entity#interact` 中。最初，如果命中结果在实体的交互范围内，则调用 `Entity#interactAt`。如果 `interactAt` 没有消耗该操作（即 `InteractionResult#consumesAction` 返回 false），则调用 `Entity#interact`。现在，如果在实体的交互范围内，则调用 `Entity#interact`，并接受交互位置的 `Vec3`。

```java
// 在某个 Entity 子类中

@Override
public InteractionResult interact(Player player, InteractionHand hand, Vec3 location) {
    // 处理交互
    super.interact(player, hand, location);
}
```

`interactAt` 检查结果是否未消耗交互，如果没有则调用 `interact`
现在，使用实体命中调用 `interact`

- `net.minecraft.client.multiplayer.MultiPlayerGameMode`
    - `interact` 现在接受 `EntityHitResult`
    - `interactAt` 已移除
- `net.minecraft.world.entity.Entity`
    - `interact` 现在接受一个 `Vec3` 表示交互的位置
    - `interactAt` 已移除
- `net.minecraft.world.entity.player.Player#interactOn` 现在接受一个 `Vec3` 表示交互的位置

### ChunkPos，现在是一个记录

`ChunkPos` 现在是一个记录。`BlockPos` 构造函数已被 `ChunkPos#containing` 取代，而打包的 `long` 构造函数已被 `ChunkPose#unpack` 取代。

- `net.minecraft.world.level.ChunkPos` 现在是一个记录
    - `ChunkPos(BlockPos)` -> `containing`
    - `ChunkPos(long)` -> `unpack`
    - `toLong`, `asLong` -> `pack`

### 不再有绊线管线

绊线渲染管线已被完全移除。现在，绊线使用带有 `alpha_cutoff_bias` 为 0.1 的 `cutout` 用于纹理。

- `net.minecraft.client.renderer.RenderPipelines#TRIPWIRE_BLOCK`, `TRIPWIRE_TERRAIN` 已移除
- `net.minecraft.client.renderer.chunk`
    - `ChunkSectionLayer#TRIPWIRE` 已移除
    - `ChunkSectionLayerGroup#TRIPWIRE` 已移除
- `net.minecraft.client.renderer.rendertype.RenderTypes#tripwireMovingBlock` 已移除

### 活动与大脑

活动（Activity）定义了生物在特定阶段的行为方式，现在通过 `ActivityData` 存储和传递。这包含活动类型、要执行的行为及其优先级、活动激活的条件，以及活动停止时要擦除的记忆。`Brain#provider` 现在接受一个 `$ActivitySupplier` 来构造实体执行的一系列 `ActivityData`。

大脑也略有变化。首先，`Brain` 本身不能直接序列化。相反，大脑被 `$Packed` 到记录中，持有其当前记忆的映射。要获取使用的记忆类型，通常从 `Sensor#requires` 中提取。此外，`LivingEntity#brainProvider` 不再存在，而是选择将提供器存储在实体本身的静态常量中。这意味着大脑现在完全通过 `makeBrain` 方法构建，接受之前的 `$Packed` 数据：

```java
// 对于某个扩展 LivingEntity 的 ExampleEntity
// 假设扩展了 Mob 子类
private static final Brain.Provider<ExampleEntity> BRAIN_PROVIDER = Brain.provider(
    // 实体使用的传感器列表。
    ImmutableList.of(),
    // 一个接受实体并返回活动列表的函数。
    entity -> List.of(
        new ActivityData(
            // 活动类型
            Activity.CORE,
            // 优先级和行为对的列表
            ImmutableList.of(Pair.of(0, new MoveToTargetSink())),
            // 活动运行所需的记忆条件集
            // 例如，此记忆值必须存在
            ImmutableSet.of(Pair.of(MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_PRESENT)),
            // 活动停止时要擦除的记忆集
            ImmutableSet.of(MemoryModuleType.ATTACK_TARGET)
        )
    )
);

@Override
protected Brain.Provider<ExampleEntity> makeBrain(Brain.Packed packedBrain) {
    // 构建大脑，填充任何先前的记忆
    return BRAIN_PROVIDER.makeBrain(this, packedBrain);
}
```

- `net.minecraft.world.entity.LivingEntity`
    - `brainProvider` 已移除
    - `makeBrain` 现在接受一个 `Brain$Packed` 而不是 `Dynamic`
- `net.minecraft.world.entity.ai`
    - `ActivityData` - 一个记录，包含正在执行的活动、该活动中要执行的行为、任何记忆条件以及停止后要擦除的记忆。
    - `Brain` 现在是 protected 的，接受一个 `ActivityData` 列表、一个 `MemoryMap` 而不是不可变的记忆列表、一个 `RandomSource`，并且不提供 `Codec`
        - 公共构造函数不再接受任何参数
        - `provider` 现在有一个只接受传感器类型的重载，默认记忆类型为空列表
            - 一些 `provider` 方法也接受要执行的 `Brain$ActivitySupplier`
        - `codec`, `serializeStart` 被 `pack`, `Brain$Packed` 取代
        - `addActivityAndRemoveMemoryWhenStopped`, `addActivityWithConditions` 合并到 `addActivity` 中
            - 或者使用 `ActivityData#create`
        - `copyWithoutBehaviors` 已移除
        - `getMemories` 被 `forEach` 取代
        - `$ActivitySupplier` - 为实体创建活动列表。
        - `$MemoryValue` 已移除
        - `$Packed` - 一个包含序列化大脑到磁盘的数据的记录。
        - `$Provider#makeBrain` 现在接受实体和要反序列化记忆的 `Brain$Packed`
        - `$Visitor` - 访问大脑内的记忆，无论是已定义但为空、存在还是带有计时器存在。
- `net.minecraft.world.entity.ai.behavior.VillagerGoalPackages#get*Package` 不再接受 `VillagerProfession`
- `net.minecraft.world.entity.ai.memory`
    - `ExpirableValue` -> `MemorySlot`，不是一对一
        - 原始的 `ExpirableValue` 现在是一个记录，定义记忆何时过期，而不是自己更新
    - `MemoryMap` - 将记忆类型链接到其存储值的映射。
    - `MemoryModuleType` - 记忆是否可以序列化。
- `net.minecraf.tworld.entity.ai.sensing.Sensor#randomlyDelayStart` - 延迟传感器多长时间。
- `net.minecraft.world.entity.animal.allay.AllayAi`
    - `SENSOR_TYPES`, `MEMORY_TYPES` -> `BRAIN_PROVIDER`，现在是 private；不是一对一
    - `makeBrain` -> `getActivities`，不是一对一
- `net.minecraft.world.entity.animal.armadillo.ArmadilloAi#makeBrain`, `brainProvider` -> `getActivities`，现在是 `protected`，不是一对一
- `net.minecraft.world.entity.animal.axolotl`
    - `AxolotlSENSOR_TYPES` -> `BRAIN_PROVIDER`，现在是 private；不是一对一
    - `AxolotlAi`
        - `makeBrain` -> `getActivities`，不是一对一
        - `initPlayDeadActivity`，现在是 `protected`，不再接受任何参数
        - `initFightActivity`，现在是 `protected`，不再接受任何参数
        - `initCoreActivity`，现在是 `protected`，不再接受任何参数
        - `initIdleActivity`，现在是 `protected`，不再接受任何参数
- `net.minecraft.world.entity.animal.camel.CamelAi#makeBrain`, `brainProvider` -> `getActivities`，现在是 `protected`，不是一对一
- `net.minecraft.world.entity.animal.frog`
    - `Frog#SENSOR_TYPES` -> `BRAIN_PROVIDER`，现在是 private；不是一对一
    - `FrogAi#makeBrain` -> `getActivities`，不是一对一
    - `Tadpole#SENSOR_TYPES` -> `BRAIN_PROVIDER`，现在是 private；不是一对一
- `net.minecraft.world.entity.animal.frog.TadpoleAi#makeBrain` -> `getActivities`，现在是 `public`，不是一对一
- `net.minecraft.world.entity.animal.goat`
    - `Goat#SENSOR_TYPES` -> `BRAIN_PROVIDER`，现在是 private；不是一对一
    - `GoatAi#makeBrain` -> `getActivities`，不是一对一
- `net.minecraft.world.entity.animal.golem.CopperGolemAi#makeBrain`, `brainProvider` -> `getActivities`，现在是 `protected`，不是一对一
- `net.minecraft.world.entity.animal.happyghast.HappyGhastAi#makeBrain`, `brainProvider` -> `getActivities`，现在是 `protected`，不是一对一
- `net.minecraft.world.entity.animal.nautilus`
    - `NautilusAi`
        - `SENSOR_TYPES`,`MEMORY_TYPES` -> `Nautilus#BRAIN_PROVIDER`，现在是 private，不是一对一
        - `makeBrain`, `brainProvider` -> `getActivities`，现在是 `public`，不是一对一
    - `ZombieNautilusAi`
        - `SENSOR_TYPES`,`MEMORY_TYPES` -> `ZombieNautilus#BRAIN_PROVIDER`，现在是 private，不是一对一
        - `makeBrain`, `brainProvider` -> `getActivities`，现在是 `public`，不是一对一
- `net.minecraft.world.entity.animal.sniffer.SnifferAi#makeBrain` -> `getActivities`，现在是 `public`，不是一对一
- `net.minecraft.world.entity.monster.Zoglin`
    - `SENSOR_TYPES` -> `BRAIN_PROVIDER`，现在是 private，不是一对一
    - `getActivities` - 僵尸疣猪兽执行的活动。
- `net.minecraft.world.entity.monster.breeze.BreezeAi#makeBrain` -> `getActivities`，不是一对一
- `net.minecraft.world.entity.monster.creaking.CreakingAi#makeBrain`, `brainProvider` -> `getActivities`，现在是 `protected`，不是一对一
- `net.minecraft.world.entity.monster.hoglin`
    - `Hoglin#SENSOR_TYPES` -> `BRAIN_PROVIDER`，现在是 private；不是一对一
    - `HoglinAi#makeBrain` -> `getActivities`，不是一对一
- `net.minecraft.world.entity.monster.piglin`
    - `Piglin#SENSOR_TYPES`,`MEMORY_TYPES` -> `BRAIN_PROVIDER`，现在是 private，不是一对一
    - `PiglinAi#makeBrain` -> `getActivities`，现在是 `public`，不是一对一
    - `PiglinBrute#SENSOR_TYPES`,`MEMORY_TYPES` -> `BRAIN_PROVIDER`，现在是 private，不是一对一
    - `PiglinBruteAi#makeBrain` -> `getActivities`，现在是 `public`，不是一对一
- `net.minecraft.world.entity.monster.warden.WardenAi#makeBrain` -> `getActivities`，不是一对一

### 文件修复器

文件修复器是一个新系统，用于帮助在版本之间升级游戏文件，与数据修复器协同工作。类似于文件中的数据可以通过数据修复器在 Minecraft 版本之间修改或“升级”，文件修复器可以修改世界目录中的任何内容，从移动文件和目录到直接删除它们。因此，文件修复器总是在数据修复器之前应用。

与数据修复器升级时不同，文件修复器会改变世界文件夹的结构。因此，降级几乎不可能，因为文件名和位置很可能已更改位置。

文件修复器通过 `FileFix` 应用，它使用 `makeFixer` 定义要对文件执行的一些操作。通常通过 `addFileContentFix` 完成，通过 `FileAccess` 提供对所需文件的访问，然后像任何其他 `Dynamic` 实例一样修改数据。操作通常定义为 `FileFixOperation`，可以移动文件结构。

然后通过 `FileFixerUpper` 应用文件修复，它使用写时复制文件系统对文件进行操作。修复器使用 `$Builder` 构建，使用 `addSchema` 和 `addFixer` 为所需版本应用修复器。在升级过程中，文件在临时文件夹中创建，然后移动到世界文件夹。原始世界文件夹在删除之前被移动到另一个文件夹。

- `net.minecraft.client.gui.screens.FileFixerAbortedScreen` - 当文件修复被中止时显示的屏幕。
- `net.minecraft.client.gui.screens.worldselection.FileFixerProgressScreen` - 尝试显示升级和修复世界文件的进度时显示的屏幕。
- `net.minecraft.server.packs.linkfs`
    - `DummyFileAttributes` -> `.minecraft.util.DummyFileAttributes`
    - `LinkFSPath`
        - `DIRECTORY_ATTRIBUTES` -> `DummyFileAttributes#DIRECTORY`
        - `FILE_ATTRIBUTES` -> `DummyFileAttributes#FILE`
- `net.minecraft.util`
    - `ExtraCodecs`
        - `pathCodec` - 路径的编解码器，从字符串转换并使用 Unix 分隔符存储。
        - `relaiveNormalizedSubPathCodec` - 路径的编解码器，已标准化并验证以确保其是相对的。
        - `guardedPathCodec` - 路径的编解码器，从某个基础路径解析和相对化。
    - `FileUtil`
        - `isPathNormalized`, `createPathToResource` 已移除
        - `isEmptyPath` - 返回路径是否为空。
    - `Util#safeMoveFile` - 使用给定选项安全地将文件从某个源移动到目标。
- `net.minecraft.util.filefix`
    - `AbortedFileFixException` - 当文件修复已中止且无法还原移动时抛出的异常。
    - `AtmoicMoveNotSupportedFileFixException` - 当用户文件系统不支持原子移动时抛出的异常。
    - `CanceledFileFixException` - 当文件修复升级过程被取消时抛出的异常。
    - `FailedCleanupFileFixException` - 当文件修复无法移动或删除文件夹进行清理时抛出的异常。
    - `FileFix` - 对文件执行某些操作的修复器。
    - `FileFixerUpper` - 要执行操作的文件修复器。
    - `FileFixException` - 尝试通过文件修复器升级世界时抛出的异常。
    - `FileFixUtil` - 执行某些文件操作的工具。
    - `FileSystemCapabilities` - 目录中文件系统的能力。
- `net.minecraft.util.filefix.access`
    - `ChunkNbt` - 处理升级区块 nbt。
    - `CompressedNbt` - 处理升级压缩的 nbt 文件。
    - `FileAccess` - 提供对某些文件资源的引用，给定其关系。
    - `FileAccessProvider` - 文件访问的提供器，给定与源的关系。
    - `FileRelation` - 文件与某个源路径的关系的定义。
    - `FileResourceType` - 定义要访问的资源类型。
    - `FileResourceTypes` - 所有定义的文件资源类型。
    - `LevelDat` - 处理升级 level dat。
    - `PlayerData` - 处理升级玩家数据。
    - `SavedDataNbt` - 处理升级保存的数据。
- `net.minecraft.util.filefix.fixes.*` - 要应用到文件的原版修复。
- `net.minecraft.util.filefix.operations`
    - `ApplyInFolders` - 在相关文件夹内应用给定操作。
    - `DeleteFileOrEmptyDirectory` - 删除目标文件或空目录。
    - `FileFixOperation` - 在某个基础目录内执行的操作。
    - `FileFixOperations` - 所有原版文件修复操作。
    - `GroupMove` - 移动某个目录，对其内容应用任何移动操作。
    - `ModifyContent` - 修改文件的内容。
    - `Move` - 将文件从某个源移动到某个目标。
    - `RegexMove` - 移动所有匹配给定源模式的文件到目标，替换匹配的部分。
- `net.minecraft.util.filefix.virtualfilesystem`
    - `CopyOnWriteFileStore` - 使用写时复制原理的文件存储。
    - `CopyOnWriteFileSystem` - 使用写时复制原理的文件系统。
    - `CopyOnWriteFSPath` - 使用写时复制原理的路径。
    - `CopyOnWriteFSProvider` - 使用写时复制原理的文件系统提供器。
    - `DirectoryNode` - 某个写时复制文件系统路径的目录节点。
    - `FileMove` - 一个记录，包含文件被移动到的路径。
    - `FileNode` - 某个写时复制文件系统路径的文件节点。
    - `Node` - 某个写时复制文件系统路径的节点。
- `net.minecraft.util.filefix.virtualfilesystem.exception`
    - `CowFSCreationException` - 当无法创建文件系统时的 `CowFSFileSystemException`。
    - `CowFSDirectoryNotEmptyException` - 专门针对写时复制系统的 `DirectoryNotEmptyException`。
    - `CowFSFileAlreadyExistsException` - 专门针对写时复制系统的 `FileAlreadyExistsException`。
    - `CowFSFileSystemException` - 专门针对写时复制系统的 `FileSystemException`。
    - `CowFSIllegalArgumentException` - 尝试在写时复制系统上操作时的 `IllegalArgumentException`。
    - `CowFSNoSuchFileException` - 专门针对写时复制系统的 `NoSuchFileException`。
    - `CowFSNotDirectoryException` - 专门针对写时复制系统的 `NotDirectoryException`。
    - `CowFSSymlinkException` - 尝试将写时复制系统与符号链接一起使用时的 `CowFSCreationException`。
- `net.minecraft.util.worldupdate`
    - `UpgradeProgress`
        - `getTotalFiles` -> `getTotalFileFixState`，不是一对一
        - `addTotalFiles` -> `addTotalFileFixOperations`，不是一对一
        - `getTypeFileFixStats`, `getRunningFileFixerStats` - 获取特定文件组的修复器统计信息。
        - `incrementFinishedOperations`, `incrementFinishedOperationsBy` - 增加已完成操作的数量。
        - `setType`, `getType` - 获取升级进度的类型。
        - `setApplicableFixerAmount` - 设置运行中文件修复器的已完成操作总数。
        - `incrementRunningFileFixer` - 增加已完成操作的数量。
        - `logProgress` - 每秒记录一次升级进度。
        - `$FileFixStats` - 已执行/已完成操作的计数器。
        - `$Type` - 对世界数据执行的升级类型。
    - `WorldUpgrader` 不再接受 `WorldData`
        - `STATUS_*` 消息已合并到 `UpgradeStatusTranslator` 中
            - 这也包含特定的 datafix 类型
        - `running`, `finished`, `progress`, `totalChunks`, `totalFiles`, `converted`, `skipped`, `progressMap`, `status` 都已移至 `UpgradeProgress`，存储在 `upgradeProgress` 中
        - `getProgress` -> `getTotalProgress`，不是一对一
        - `$AbstractUpgrader`, `$SimpleRegionStorageUpgrader` -> `RegionStorageUpgrader`，不再接受提供的 `LegacyTagFixer`，不是一对一
            - `$ChunkUpgrader`, `$EntityUpgrader`, `$PoiUpgrader` 现在只是在 `WorldUpgrader#work` 中构造
            - `$Builder#setLegacyFixer` 已移除
        - `$ChunkUpgrader#tryProcessOnePosition` 已部分抽象为 `getDataFixContentTag`, `verifyChunkPosAndEraseCache`, `verifyChunkPos`
        - `$FileToUpgrade` -> `FileToUpgrade`
- `net.minecraft.world.level.ChunkPos#getRegionX`, `getRegionZ` - 获取区块所在的区域。
- `net.minecraft.world.level.chunk.ChunkGenerator#getTypeNameForDataFixer` 现在返回一个可选的 `Identifier` 而不是 `ResourceKey`
- `net.minecraft.world.level.chunk.storage`
    - `LegacyTagFixer` 接口已移除
    - `RecreatingSimpleRegionStorage` 不再接受提供的 `LegacyTagFixer`
    - `SimpleRegionStorage` 不再接受提供的 `LegacyTagFixer`
        - `markChunkDone` 已移除
- `net.minecraft.world.level.levelgen.structure`
    - `LegacyStructureDataHandler` 类已移除
    - `StructureFeatureIndexSavedData` 类已移除
- `net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager`
    - `STRUCTURE_RESOURCE_DIRECTORY_NAME` -> `STRUCTURE_DIRECTORY_NAME`，不是一对一
    - `WORLD_STRUCTURE_LISTER`, `RESOURCE_TEXT_STRUCTURE_LISTER` - 结构 nbt 的 ID 转换器。
    - `save` 现在有一个接受路径、`StructureTemplate` 和 `boolean`（是否将数据写为文本）的重载
    - `createAndValidatePathToGeneratedStructure` -> `TemplatePathFactory#createAndValidatePathToStructure`，不是一对一
    - `worldTemplates`, `testTemplates` - 模板路径工厂。
- `net.minecraft.world.level.levelgen.structure.templatesystem.loader`
    - `DirectoryTemplateSource` - 某个目录的模板源。
    - `ResourceManagerTemplateSource` - 资源管理器的模板源。
    - `TemplatePathFactory` - 获取某个结构路径的工厂。
    - `TemplateSource` - 结构模板的加载器。
- `net.minecraft.world.level.storage`
    - `LevelStorageSource`
        - `getLevelDataAndDimensions` 现在接受 `$LevelStorageAccess`
        - `readExistingSavedData` - 读取任何现有的保存数据。
        - `writeGameRules` - 将游戏规则写入保存数据。
        - `$LevelStorageAccess#releaseTemporarilyAndRun` - 释放访问并在重新创建锁之前运行。
            - `collectIssues` - 收集尝试升级数据时的任何问题。
            - `getSummary` -> `fixAndGetSummary`, `fixAndGetSummaryFromTag`；不是一对一
            - `getDataTag` -> `getUnfixedDataTag`，不是一对一
            - `getDataTagFallback` -> `getUnfixedDataTagWithFallback`，不是一对一
            - `saveDataTag` 不再接受 `RegistryAccess`
            - `saveLevelData` - 保存 level dat。
    - `LevelSummary` 现在接受是否需要文件修复
        - `UPGRADE_AND_PLAY_WORLD` - 告诉用户升级他们的世界并游玩的组件。
        - `requiresFileFixing` - 关卡是否需要文件修复。
        - `$BackupStatus#FILE_FIXING_REQUIRED` - 是否需要文件修复才能在此版本上玩此关卡。

### 聊天权限

聊天系统现在有一组相关的权限，指示玩家可以发送或接收哪些消息。`Permissions#CHAT_SEND_MESSAGES` 和 `CHAT_SEND_COMMANDS` 分别确定玩家是否可以发送消息或命令。同样，`CHAT_RECEIVE_PLAYER_MESSAGES` 和 `CHAT_RECEIVE_SYSTEM_MESSAGES` 确定玩家是否可以接收来自其他玩家或系统的消息。请注意，所有这些权限仅在客户端处理，不在服务器端验证。

- `net.minecraft.SharedConstants#DEBUG_CHAT_DISABLED` - 禁用聊天框的标志。
- `net.minecraft.client`
    - `GuiMessage` -> `.multiplayer.chat.GuiMessage`
    - `GuiMessageTag` -> `.multiplayer.chat.GuiMessageTag`
    - `Minecraft`
        - `getChatStatus` -> `computeChatAbilities`，不是一对一
        - `$ChatStatus` -> `ChatRestriction`，不是一对一
- `net.minecraft.client.gui.Gui#setChatDisabledByPlayerShown`, `isShowingChatDisabledByPlayer` - 处理聊天是否被显示的玩家禁用。
- `net.minecraft.client.gui.components`
    - `ChatComponent`
        - `GO_TO_RESTRICTIONS_SCREEN` - 重定向到限制屏幕的标识符。
        - `setVisibleMessageFilter` - 设置消息过滤函数。
        - `render`, `captureClickableText` 现在接受 `$DisplayMode` 而不是表示玩家是否在聊天的 `boolean`
        - `addMessage` 现在是 private
            - 拆分为 `addClientSystemMessage`, `addServerSystemMessage`, `addPlayerMessage`
        - `$DisplayMode` - 聊天应如何显示。
    - `CommandSuggestions`
        - `USAGE_FORMAT`, `USAGE_OFFSET_FROM_BOTTOM`, `LINE_HEIGHT` - 显示命令建议的常量。
        - `setRestrictions` - 设置可以键入的消息的限制。
        - `hasAllowedInput` - 聊天框是否允许输入。
- `net.minecraft.client.gui.screens.ChatScreen#USAGE_BACKGROUND_COLOR` - 命令建议框的背景颜色。
- `net.minecraft.client.gui.screens.multiplayer.RestrictionsScreen` - 用于设置玩家聊天框限制的屏幕。
- `net.minecraft.client.gui.screens.reporting.ReportPlayerScreen` 现在接受一个 `boolean` 表示聊天是否被禁用或阻止
- `net.minecraft.client.multiplayer.chat`
    - `ChatAbilities` - 玩家在聊天框上聊天的限制集。
    - `ChatListener`
        - `handleSystemMessage` 的 `boolean` 现在用于表示系统是否为远程而不是覆盖
            - 覆盖现在通过 `handleOverlay` 处理
    - `GuiMessageSource` - 消息的来源。
- `net.minecraft.client.player.LocalPlayer` 现在接受 `ChatAbilities`
    - `chatAbilities`, `refreshChatAbilities` - 处理聊天能力。
- `net.minecraft.server.permissions.Permissions`
    - `CHAT_SEND_MESSAGES` - 玩家是否可以发送聊天消息。
    - `CHAT_SEND_COMMANDS` - 玩家是否可以发送命令。
    - `CHAT_RECEIVE_PLAYER_MESSAGES` - 玩家是否可以接收其他玩家的消息。
    - `CHAT_RECEIVE_SYSTEM_MESSAGES` - 玩家是否可以接收系统消息。
    - `CHAT_PERMISSIONS` - 一组可用的聊天权限。
- `net.minecraft.world.entity.player.Player#displayClientMessage` 拆分为当覆盖消息为 `false` 时的 `sendSystemMessage`，以及当覆盖消息为 `true` 时的 `sendOverlayMessage`

### 更多实体声音变种注册表

猫、鸡、牛和猪现在有了声音变体：一个数据包注册表对象，指定实体播放的声音。这不需要直接与实际的实体变体相关联，因为它只定义实体播放的声音，通常在 `Mob#finalizeSpawn` 期间。

对于牛：

```json5
// 文件位于：
// - `data/examplemod/cow_sound_variant/example_cow_sound.json`
{
    // 空闲时随机播放的声音事件的注册表名称。
    "ambient_sound": "minecraft:entity.cow.ambient",
    // 被杀死时播放的声音事件的注册表名称。
    "death_sound": "minecraft:entity.cow.death",
    // 受伤时播放的声音事件的注册表名称。
    "hurt_sound": "minecraft:entity.cow.hurt",
    // 踩踏时播放的声音事件的注册表名称。
    "step_sound": "minecraft:entity.cow.step"
}
```

对于鸡和猪：

```json5
// 文件位于：
// - `data/examplemod/chicken_sound_variant/example_chicken_sound.json`
{
    // 实体年龄大于或等于 0（成年）时播放的声音。
    "adult_sounds": {
        // 空闲时随机播放的声音事件的注册表名称。
        "ambient_sound": "minecraft:entity.chicken.ambient",
        // 被杀死时播放的声音事件的注册表名称。
        "death_sound": "minecraft:entity.chicken.death",
        // 受伤时播放的声音事件的注册表名称。
        "hurt_sound": "minecraft:entity.chicken.hurt",
        // 踩踏时播放的声音事件的注册表名称。
        "step_sound": "minecraft:entity.chicken.step"
    },
    // 实体年龄小于 0（幼年）时播放的声音。
    "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"
    }
}
```

对于猪：

```json5
// 文件位于：
// - `data/examplemod/pig_sound_variant/example_pig_sound.json`
{
    // 实体年龄大于或等于 0（成年）时播放的声音。
    "adult_sounds": {
        // 空闲时随机播放的声音事件的注册表名称。
        "ambient_sound": "minecraft:entity.pig.ambient",
        // 被杀死时播放的声音事件的注册表名称。
        "death_sound": "minecraft:entity.pig.death",
        // 进食时播放的声音事件的注册表名称。
        "eat_sound": "minecraft:entity.pig.eat",
        // 受伤时播放的声音事件的注册表名称。
        "hurt_sound": "minecraft:entity.pig.hurt",
        // 踩踏时播放的声音事件的注册表名称。
        "step_sound": "minecraft:entity.pig.step"
    },
    // 实体年龄小于 0（幼年）时播放的声音。
    "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"
    }
}
```

对于猫：

```json5
// 文件位于：
// - `data/examplemod/cat_sound_variant/example_cat_sound.json`
{
    // 实体年龄大于或等于 0（成年）时播放的声音。
    "adult_sounds": {
        // 驯服后空闲时随机播放的声音事件的注册表名称。
        "ambient_sound": "minecraft:entity.cat.ambient",
        // 未驯服且被食物诱惑时播放的声音事件的注册表名称。
        "beg_for_food_sound": "minecraft:entity.cat.beg_for_food",
        // 被杀死时播放的声音事件的注册表名称。
        "death_sound": "minecraft:entity.cat.death",
        // 被喂食时播放的声音事件的注册表名称。
        "eat_sound": "minecraft:entity.cat.eat",
        // 发出嘶嘶声时播放的声音事件的注册表名称，通常针对追逐的幻翼。
        "hiss_sound": "minecraft:entity.cat.hiss",
        // 受伤时播放的声音事件的注册表名称。
        "hurt_sound": "minecraft:entity.cat.hurt",
        // 发出呼噜声时播放的声音事件的注册表名称，通常在恋爱或躺下时。
        "purr_sound": "minecraft:entity.cat.purr",
        // 驯服后 25% 空闲时随机播放的声音事件的注册表名称。
        "purreow_sound": "minecraft:entity.cat.purreow",
        // 未驯服时空闲时随机播放的声音事件的注册表名称。
        "stray_ambient_sound": "minecraft:entity.cat.stray_ambient"
    },
    // 实体年龄小于 0（幼年）时播放的声音。
    "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.Registries`
    - `CAT_SOUND_VARIANT` - 猫应发出的声音的注册表键。
    - `CHICKEN_SOUND_VARIANT` - 鸡应发出的声音的注册表键。
    - `COW_SOUND_VARIANT` - 牛应发出的声音的注册表键。
    - `PIG_SOUND_VARIANT` - 猪应发出的声音的注册表键。
- `net.minecraft.network.synched.EntityDataSerializers`
    - `CAT_SOUND_VARIANT` - 猫应发出的声音的实体序列化器。
    - `CHICKEN_SOUND_VARIANT` - 鸡应发出的声音的实体序列化器。
    - `COW_SOUND_VARIANT` - 牛应发出的声音的实体序列化器。
    - `PIG_SOUND_VARIANT` - 猪应发出的声音的实体序列化器。
- `net.minecraft.sounds.SoundEvents`
    - `CAT_*` 声音现在是 `Holder$Reference` 或存储在 `CAT_SOUNDS` 映射中
    - `CHICKEN_*` 声音现在是 `Holder$Reference` 或存储在 `CHICKEN_SOUNDS` 映射中
    - `COW_*` 声音存储在 `COW_SOUNDS` 映射中
    - `PIG_*` 声音现在是 `Holder$Reference` 或存储在 `PIG_SOUNDS` 映射中
- `net.minecraft.world.entity.animal.chicken`
    - `ChickenSoundVariant` - 鸡变体播放的声音。
    - `ChickenSoundVariants` - 所有原版鸡变体。
- `net.minecraft.world.entity.animal.cow`
    - `AbstractCow#getSoundSet` - 获取牛发出的声音。
    - `CowSoundVariant` - 牛变体播放的声音。
    - `CowSoundVariants` - 所有原版牛变体。
- `net.minecraft.world.entity.animal.feline`
    - `CatSoundVariant` - 猫变体播放的声音。
    - `CatSoundVariants` - 所有原版猫变体。
- `net.minecraft.world.entity.animal.chicken`
    - `ChickenSoundVariant` - 鸡变体播放的声音。
    - `ChickenSoundVariants` - 所有原版鸡变体。
- `net.minecraft.world.entity.animal.pig`
    - `PigSoundVariant` - 猪变体播放的声音。
    - `PigSoundVariants` - 所有原版猪变体。

### 音频变更

音频设备现在通过 `DeviceTracker` 处理，根据底层机器，允许机器在音频设备更改时发送系统事件，或使用标准轮询间隔重新查询可用设备列表。

- `com.mojang.blaze3d.audio`
    - `AbstractDeviceTracker` - 用于管理音频设备更改的抽象跟踪器。
    - `CallbackDeviceTracker` - 使用 SOFT 系统事件回调确定更改的设备跟踪器。
    - `DeviceList` - 所有音频设备的列表，包括默认设备（如果可用）。
    - `DeviceTracker` - 用于管理音频设备更改的接口。
    - `Library`
        - `NO_DEVICE` 现在是 `public` 而不是 `private`
        - `init` 现在接受 `DeviceList`
        - `getDefaultDeviceName` 移至 `DeviceList#defaultDevice`
        - `getCurrentDeviceName` -> `currentDeviceName`
        - `hasDefaultDeviceChanged` 移至 `AbstractDeviceTracker`，不是一对一
        - `getAvailableSoundDevices` 移至 `DeviceList`，不是一对一
        - `createDeviceTracker` - 创建用于管理音频设备更改的跟踪器。
        - `getDebugString` -> `getChannelDebugString`
    - `PollingDeviceTracker` - 使用轮询间隔确定更改的设备跟踪器。
    - `SoundBuffer`
        - `format` - 声音流的格式。
        - `size` - 声音流中的字节数。
        - `isValid` - 声音流是否处于有效状态。
- `net.minecraft.client.Options`
    - `DEFAULT_SOUND_DEVICE` 现在是 `private` 而不是 `public`
    - `isSoundDeviceDefault` - 检查设备是否为默认音频设备。
- `net.minecraft.client.gui.components.debug`
    - `DebugEntrySoundCache` - 显示已加载声音流当前缓存的调试条目。
    - `DebugScreenEntries#SOUND_CACHE` - 声音流缓存调试信息的标识符。
- `net.minecraft.client.sounds`
    - `SoundBufferLibrary`
        - `enumerate` - 循环所有缓存的声音，输出其 id、大小和格式。
        - `$DebugOutput` - 接受某些声音元数据的接口。
            - `$Counter` - 跟踪声音流数量和总大小的输出实现。
    - `SoundEngine`
        - `getDebugString` -> `getChannelDebugString`, `getSoundCacheDebugStats`; 不是一对一
        - `$DeviceCheckState` 已移除
    - `SoundManager#getDebugString` -> `getChannelDebugString`, `getSoundCacheDebugStats`; 不是一对一

### 输入消息编辑器支持

Minecraft 现在支持输入消息编辑器（IME），允许输入来自中文或印地语等语言的复杂字符，而不是临时的预编辑文本。预编辑文本在游戏内显示为覆盖层，而主机操作系统提供的任何其他 IME 功能。通过此添加，可以通过 `GuiEventListener#preeditUpdated` 在屏幕中添加支持，或使用实现该方法的现有原版小部件。

- `com.mojang.blaze3d.platform`
    - `InputConstants#setupKeyboardCallbacks` 现在接受 `GLFWCharCallbackI` 而不是 `GLFWCharModsCallbackI` 用于字符键入回调，`GLFWPreeditCallbackI` 用于通过输入方法编辑器处理复杂字符输入，以及 `GLFWIMEStatusCallbackI` 用于通知编辑器的状态
    - `MessageBox` - 用于创建操作系统原生消息框的工具。
    - `TextInputManager` - 用于处理游戏窗口中文本输入的管理器。
        - `setTextInputArea` - 设置预测文本光标应出现的区域。
        - `startTextInput`, `stopTextInput` - 处理切换输入消息编辑器。
- `net.minecraft.client`
    - `KeyboardHandler`
        - `resubmitLastPreeditEvent` - 重复发送的最后一个预编辑事件。
        - `submitPreeditEvent` - 告知监听器预编辑文本已更新。
    - `Minecraft`
        - `textInputManager` - 返回输入管理器。
        - `onTextInputFocusChange` - 根据文本输入是否聚焦更改编辑器输入状态。
- `net.minecraft.client.gui.GuiGraphics`
    - `setPreeditOverlay` - 设置绘制预编辑文本的覆盖层。
    - `renderDeferredElements` 现在接受鼠标位置的 `int` 和游戏时间增量刻 `float`
- `net.minecraft.client.gui.components`
    - `IMEPreeditOverlay` - 用于显示输入消息编辑器预编辑文本的覆盖层。
    - `TextCursorUtils` - 绘制文本光标的工具。
- `net.minecraft.client.gui.components.events.GuiEventListener#preeditUpdated` - 监听预编辑文本何时更改。
- `net.minecraft.client.input`
    - `CharacterEvent` 不再接受修饰符 `int` 集
    - `PreeditEvent` - 一个包含预编辑文本以及光标位置的事件。

### 炼药锅交互调度器

炼药锅的交互已进行了一些重组，所有注册已从 `CauldronInteraction` 移至 `CauldronInteractions`。此外，炼药锅类型的底层 `$InteractionMap` 已被 `$Dispatcher` 取代，它可以为标签和物品注册交互。标签在物品之前检查。

```java
CauldronInteractions.EMPTY.put(
    // 要使用的物品或 TagKey
    ItemTags.WOOL,
    // 要应用的炼药锅交互
    (state, level, pos, player, hand, itemInHand) -> InteractionResult.TRY_WITH_EMPTY_HAND
);
```

- `net.minecraft.core.cauldron`
    - `CauldronInteraction`
        - 所有关于将交互注册到映射的字段已移至 `CauldronInteractions`
            - `INTERACTIONS` -> `CauldronInteractions#ID_MAPPER`，现在是 `private`
        - `DEFAULT` - 与炼药锅的默认交互
        - `$InteractionMap` -> `$Dispatcher`，不是一对一
    - `CauldronInteractions` - 所有原版炼药锅交互。

### 基于规则的方块状态提供者

`RuleBasedStateProvider` 现在扩展了 `BlockStateProvider`，允许它在需要状态提供器的任何地方使用。其实现没有改变，现在只需要将 `rule_based_state_provider` 指定为 `type`。因此，所有使用 `RuleBasedBlockStateProvider` 的配置都已放宽，以允许任何 `BlockStateProvider`。

- `net.minecraft.world.level.levelgen.feature.configurations`
    - `DiskConfiguration` 现在接受一个 `BlockStateProvider` 而不是 `RuleBasedBlockStateProvider`
    - `TreeConfiguration` 现在接受一个 `BlockStateProvider` 而不是 `RuleBasedBlockStateProvider`
        - `belowTrunkProvider` 现在是 `BlockStateProvider` 而不是 `RuleBasedBlockStateProvider`
        - `$TreeConfigurationBuilder` 现在接受一个 `BlockStateProvider` 而不是 `RuleBasedBlockStateProvider`
- `net.minecraft.world.level.levelgen.feature.stateproviders`
    - `BlockStateProvider#getOptionalState` - 获取方块的状态，否则为 `null`。
    - `BlockStateProviderType#RULE_BASED_STATE_PROVIDER` - 基于规则的状态提供器的类型。
    - `RuleBasedBlockStateProvider` -> `RuleBasedStateProvider`，现在是一个类，实现 `BlockStateProvider`
        - 构造函数现在可以接受一个可空的回退 `BlockStateProvider`
        - `ifTrueThenProvide` - 如果谓词为真，则提供给定的方块。
        - `simple` -> `always`
        - `$Builder` - 用于构建放置方块规则的构建器。

### 流体逻辑重组

通用实体流体移动已移至单独的 `EntityFluidInteraction` 类中，其中所有跟踪的流体都会更新，然后在层时间可能被水流推动。

- `net.minecraft.world.entity`
    - `Entity`
        - `updateInWaterStateAndDoFluidPushing` -> `updateFluidInteraction`，不是一对一
        - `updateFluidHeightAndDoFluidPushing` -> `EntityFluidInteraction#update`
        - `getFluidInteractionBox` - 获取实体在流体交互期间的边界框。
        - `modifyPassengerFluidInteractionBox` - 返回实体骑乘在某些交通工具中时修改后的边界框。
    - `EntityFluidInteraction` - 用于管理实体流体交互和基本移动的处理程序。
- `net.minecraft.world.level.chunk.LevelChunkSection#hasFluid` - 区块部分是否包含流体方块。

### 移除随机斑块特征

随机斑块特征已被完全移除，转而使用像大多数其他特征一样的位置放置。要转换，配置中定义为 `ConfiguredFeature` 的部分应该是它自己的文件。然后，位置放置应指定 `CountPlacement`，后跟使用 `TrapezoidInt` 的 `RandomOffsetPlacement`，最后是 `BlockPredicateFilter`：

```json5
// 在 `data/examplemod/worldgen/configured_feature/example_configured_feature.json` 中
{
    // 之前 config.feature.feature
    "type": "minecraft:simple_block",
    "config": {
        "to_place": {
            "type": "minecraft:simple_state_provider",
            "state": {
                "Name": "minecraft:sweet_berry_bush",
                "Properties": {
                    "age": "3"
                }
            }
        }
    }
}

// 在 `data/examplemod/worldgen/placed_feature/example_placed_feature.json` 中
{
    "feature": "examplemod:example_configured_feature",
    "placement": [
        {
            // 之前 config.tries
            "type": "minecraft:count",
            "count": 96
        },
        {
            "type": "minecraft:random_offset",
            "xz_spread": {
                // 之前 config.xz_spread
                // min 和 max 是加法逆元
                "type": "minecraft:trapezoid",
                "max": 7,
                "min": -7,
                "plateau": 0
            },
            "y_spread": {
                // 之前 config.y_spread
                "type": "minecraft:trapezoid",
                "max": 3,
                "min": -3,
                "plateau": 0
            }
        },
        {
            // 之前 config.feature.placement
            // 这包含原始放置特征的位置放置
            "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.features`
    - `FeatureUtils#simpleRandomPatchConfiguration`, `simplePatchConfiguration` 已移除
        - 通常被 `Feature#SIMPLE_BLOCK` 替换，带有随机偏移和过滤器的位置放置
    - `NetherFeatures#PATCH_*` 字段不再有 `PATCH_*` 前缀
    - `VegetationFeatures`
        - `PATCH_*` 字段不再有 `PATCH_*` 前缀
        - `WILDFLOWERS_BIRCH_FOREST`, `WILDFLOWERS_MEADOW` -> `WILDFLOWER`，不是一对一
        - `PALE_FOREST_FLOWERS` -> `PALE_FOREST_FLOWER`
- `net.minecraft.world.level.biome.BiomeGenerationSettings#getFlowerFeatures` -> `getBoneMealFeatures`
- `net.minecraft.world.level.levelgen.feature`
    - `ConfiguredFeature#getFeatures` -> `getSubFeatures`，现在返回一个持有者包装的 `ConfiguredFeature` 流，不包含此特征
    - `Feature`
        - `FLOWER`, `NO_BONEMEAL_FLOWER` 已移除
        - `RANDOM_PATCH` 已移除
    - `RandomPatchFeature` 类已移除
- `net.minecraft.world.level.levelgen.feature.configurations`
    - `FeatureConfiguration#getFeatures` -> `getSubFeatures`，现在返回一个持有者包装的 `ConfiguredFeature` 流
    - `RandomPatchConfiguration` 记录已移除
- `net.minecraft.world.level.levelgen.placement.PlacedFeature#getFeatures` 现在返回一个持有者包装的 `ConfiguredFeature` 流，并连接了此特征

### 特定逻辑变更

- 画中画提交调用现在使用 `0xF000F0` 而不是 `0x000000` 作为光照坐标。
- `net.minecraft.client.multiplayer.RegistryDataCollector#collectGameRegistries` 的 `boolean` 参数现在仅处理从同步注册表以及标签更新组件。
- `net.minecraft.client.renderer.RenderPipelines#VIGNETTE` 现在将 alpha 与源为零和目标为一混合。
- `net.minecraft.server.packs.PathPackResources#getResource`, `listPath`, `listResources` 使用标识符的命名空间首先解析路径。
- `net.minecraft.world.entity.EntitySelector#CAN_BE_PICKED` 现在可以找到旁观者模式下的实体，假设 `Entity#isPickable` 为 true。
- `net.minecraft.world.entity.ai.sensing.NearestVisibleLivingEntitySensor#requires` 默认不再实现。
- `net.minecraft.world.level.levelgen.WorldOptions#generate_features` JSON 中的字段已重命名为 `generate_structures` 以匹配其 Java 字段名称。
- `net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate#ONLY_IN_AIR_PREDICATE` 现在匹配空气标签而不是仅仅空气方块。
- `net.minecraft.world.level.timers`
    - `FunctionCallback`, `FunctionTagCallback` 现在在序列化时使用 `id` 而不是 `Name`
    - `TimerCallbacks` 现在在序列化时使用 `type` 而不是 `Type`

### 数据组件新增

- `dye` - 将物品设置为染料材料，在特定情况下使用。
- `additional_trade_cost` - 按指定金额偏移交易成本的修饰符。
- `pig/sound_variant` - 猪应发出的声音。
- `cow/sound_variant` - 牛应发出的声音。
- `chicken/sound_variant` - 鸡应发出的声音。
- `cat/sound_variant` - 猫应发出的声音。

### 环境属性新增

- `visual/block_light_tint` - 着色方块发出的光的颜色。
- `visual/night_vision_color` - 夜视激活时的颜色。
- `visual/ambient_light_color` - 环境中环境光的颜色。

### 标签更改

- `minecraft:block`
    - `bamboo_plantable_on` -> `supports_bamboo`
    - `mushroom_grow_block` -> `overrides_mushroom_light_requirement`
    - `small_dripleaf_placeable` -> `supports_small_dripleaf`
    - `big_dripleaf_placeable` -> `supports_big_dripleaf`
    - `dry_vegetation_may_place_on` -> `supports_dry_vegetation`
    - `snow_layer_cannot_survive_on` -> `cannot_support_snow_layer`
    - `snow_layer_can_survive_on` -> `support_override_snow_layer`
    - `enables_bubble_column_drag_down`
    - `enables_bubble_column_push_up`
    - `supports_vegetation`
    - `supports_crops`
    - `supports_stem_crops`
    - `supports_stem_fruit`
    - `supports_pumpkin_stem`
    - `supports_melon_stem`
    - `supports_pumpkin_stem_fruit`
    - `supports_melon_stem_fruit`
    - `supports_sugar_cane`
    - `supports_sugar_cane_adjacently`
    - `supports_cactus`
    - `supports_chorus_plant`
    - `supports_chorus_flower`
    - `supports_nether_sprouts`
    - `supports_azalea`
    - `supports_warped_fungus`
    - `supports_crimson_fungus`
    - `supports_mangrove_propagule`
    - `supports_hanging_mangrove_propagule`
    - `supports_nether_wart`
    - `supports_crimson_roots`
    - `supports_warped_roots`
    - `supports_wither_rose`
    - `supports_cocoa`
    - `supports_lily_pad`
    - `supports_frogspawn`
    - `support_override_cactus_flower`
    - `cannot_support_seagrass`
    - `cannot_support_kelp`
    - `grows_crops`
    - `mud`
    - `moss_blocks`
    - `grass_blocks`
    - `substrate_overworld`
    - `beneath_tree_podzol_replaceable`
    - `beneath_bamboo_podzol_replaceable`
    - `cannot_replace_below_tree_trunk`
    - `ice_spike_replaceable`
    - `forest_rock_can_place_on`
    - `huge_brown_mushroom_can_place_on`
    - `huge_red_mushroom_can_place_on`
    - `prevents_nearby_leaf_decay`
- `minecraft:enchantment`
    - `trades/desert_special` 已移除
    - `trades/jungle_special` 已移除
    - `trades/plains_special` 已移除
    - `trades/savanna_special` 已移除
    - `trades/snow_special` 已移除
    - `trades/swamp_special` 已移除
    - `trades/taiga_special` 已移除
- `minecraft:entity_type`
    - `cannot_be_age_locked`
- `minecraft:fluid`
    - `supports_sugar_cane_adjacently`
    - `supports_lily_pad`
    - `supports_frogspawn`
    - `bubble_column_can_occupy`
- `minecraft:item`
    - `metal_nuggets`
    - `dyeable` 已移除，拆分为：
        - `dyes`
        - `loom_dyes`
        - `loom_patterns`
        - `cauldron_can_remove_due`
        - `cat_collar_dyes`
        - `wolf_collar_dyes`
    - `mud`
    - `moss_blocks`
    - `grass_blocks`
- `minecraft:potion`
    - `tradable`
- `minecraft:worldgen/configured_feature`
    - `can_spawn_from_bone_meal`

### 添加列表

- `net.minecraft.advancements.criterion`
    - `FoodPredicate` - 可以检查食物水平和饱和度的标准谓词。
    - `MinMaxBounds`
        - `validateContainedInRange` - 返回一个验证目标范围并将结果作为数据结果返回的函数。
        - `$Bounds#asRange` - 将边界转换为 `Range`。
- `net.minecraft.client`
    - `Minecraft#sendLowDiskSpaceWarning` - 发送系统通知以提示磁盘空间不足。
    - `Options#keyDebugLightmapTexture` - 显示光照图纹理的键映射。
- `net.minecraft.client.gui.components`
    - `AbstractScrollArea`
        - `scrollbarWidth` - 滚动条的宽度。
        - `defaultSettings` - 根据滚动速率构建默认滚动条设置。
        - `$ScrollbarSettings` - 包含滚动条元数据的记录。
    - `DebugScreenOverlay`
        - `showLightmapTexture` - 是否在覆盖层上渲染光照图纹理。
        - `toggleLightmapTexture` - 切换是否应渲染光照图纹理。
    - `ScrollableLayout`
        - `setMinHeight` - 设置容器布局的最小高度。
        - `$ReserveStrategy` - 在布局内保留滚动条宽度时使用的策略。
    - `Tooltip`
        - `component` - 要显示的工具提示的组件。
        - `style` - 用于计算工具提示背景和框架的标识符。
- `net.minecraft.client.gui.components.debug`
    - `DebugEntryDetailedMemory` - 显示详细内存使用情况的调试条目。
    - `DebugEntryLookingAt#getHitResult` - 获取相机实体的命中结果。
    - `DebugEntryLookingAtEntityTags` - 用于显示实体标签的调试条目。
    - `DebugScreenEntries`
        - `DETAILED_MEMORY` - 详细内存使用调试条目的标识符。
        - `LOOKING_AT_ENTITY_TAGS` - 实体标签调试条目的标识符。
- `net.minecraft.client.gui.navigation.FocusNavigationEvent$ArrowNavigation#with` - 设置导航的上一个焦点。
- `net.minecraft.client.gui.screens.GenericWaitingScreene#createWaitingWithoutButton` - 创建一个不显示取消按钮的等待屏幕。
- `net.minecraft.client.gui.screens.options`
    - `DifficultyButtons` - 一个包含创建难度按钮的布局元素的类。
    - `HasGamemasterPermissionReaction` - 标记选项屏幕能够响应游戏管理员权限更改的接口。
    - `OptionsScreen#getLastScreen` - 返回导航到此屏幕的上一个屏幕。
    - `WorldOptionsScreen` - 包含玩家所在当前世界的选项的屏幕。
- `net.minecraft.client.gui.screens.worldselection.EditWorldScreen#conditionallyMakeBackupAndShowToast` - 仅在传入的 `boolean` 为 true 时制作备份并显示提示；否则返回一个 `false` 的 future。
- `net.minecraft.client.multiplayer.MultiPlayerGameMode#spectate` - 向服务器发送数据包，表示玩家将旁观给定的实体。
- `net.minecraft.client.multiplayer.prediction.BlockStatePredictionHandler#onTeleport` - 当玩家在服务器上移动时运行，通常来自某种传送（例如命令、骑乘实体）。
- `net.minecraft.client.renderer`
    - `LightmapRenderStateExtractor` - 提取光照图的渲染状态。
    - `UiLightmap` - 用户界面中的光照图。
    - `RenderPipelines`
        - `LINES_DEPTH_BIAS` - 一个将多边形深度偏移因子设置为 -1 并将单位设置为 -1 的渲染管线。
        - `ENTITY_CUTOUT_DISSOLVE` - 一个使用蒙版采样器将实体模型溶解到背景中的渲染管线。
- `net.minecraft.client.renderer.rendertype.RenderType#hasBlending` - 管线是否定义了混合函数。
- `net.minecraft.commands.ArgumentVisitor` - 用于访问命令参数的辅助类。
- `net.minecraft.commands.arguments.selector.EntitySelector#COMPILABLE_CODEC` - 包装在 `EntitySelectorParser` 周围的 `CompilableString` 编解码器。
- `net.minecraft.core.component.predicates`
    - `DataComponentPredicates#VILLAGER_VARIANT` - 检查村民类型的谓词。
    - `VillagerTypePredicate` - 检查村民类型的谓词。
- `net.minecraft.core.dispenser.SpawnEggItemBehavior` - 刷怪蛋的发射器行为。
- `net.minecraft.core.registries.ConcurrentHolderGetter` - 从本地缓存读取引用的获取器，必要时同步到原始数据。
- `net.minecraft.data`
    - `BlockFamilies`
        - `END_STONE` - 末地石变体的家族。
        - `getFamily` - 获取基础方块的家族（如果存在）。
    - `BlockFamily`
        - `$Builder#tiles`, `$Variant#TILES` - 作为某个基础方块的瓷砖变体的方块。
        - `$Builder#bricks`, `$Variant#BRICKS` - 作为某个基础方块的砖块变体的方块。
        - `$Builder#cobbled`, `$Variant#COBBLED` - 作为某个基础方块的圆石变体的方块。
    - `DataGenerator$Uncached` - 不缓存任何关于生成文件信息的数据生成器。
- `net.minecraft.data.recipes.RecipeProvider`
    - `bricksBuilder`, `tilesBuilder` - 用于砖块和瓷砖方块变体的构建器。
    - `generateCraftingRecipe`, `generateStonecutterRecipe` - 为给定的方块家族生成适当的配方。
    - `getBaseBlock` -> `getBaseBlockForCrafting`
    - `bredAnimal` - 如果玩家已使两只动物繁殖，则解锁配方。
- `net.minecraft.gametest.framework`
    - `GameTestEvent#createWithMinimumDelay` - 创建一个具有最小延迟的测试事件。
    - `GameTestHelper`
        - `getBoundsWithPadding` - 获取带有指定填充的测试区域的边界框。
        - `runBeforeTestEnd` - 在测试结束前一 tick 运行 runnable。
        - `despawnItem` - 清除位置距离内的所有物品实体。
        - `discard` - 丢弃实体。
        - `setTime` - 设置维度默认时钟的时间。
        - `placeBlock` - 在相对位置和方向上放置给定的方块。
    - `GameTestInstance#padding` - 每个游戏测试周围间隔的方块数。
    - `GameTestSequence#thenWaitAtLeast` - 在运行 runnable 之前至少等待指定的 tick 数。
- `net.minecraft.nbt.TextComponentTagVisitor`
    - `$PlainStyling` - 将 nbt 存储在组件字面量映射中的样式。
    - `$RichStyling` - 带有语法高亮和格式化的 nbt 样式。
    - `$Styling` - 定义读取标签应如何样式的接口。
    - `$Token` - 用于更丰富地表示标签数据的令牌。
- `net.minecraft.network.chat.ResolutionContext` - 组件被解析为字符串的上下文。
- `net.minecraft.network.chat.contents.NbtContents#NBT_PATH_CODEC` - 包装在 `NbtPathArgument$NbtPath` 周围的 `CompilableString` 编解码器。
- `net.minecraft.network.chat.contents.data.BlockDataSource#BLOCK_POS_CDEC` - 包装在 `Coordinates` 周围的 `CompilableString` 编解码器。
- `net.minecraft.network.protocol.game`
    - `ClientboundGameRuleValuesPacket` - 以字符串形式向客户端发送游戏规则值的数据包。
    - `ClientboundGamePacketListener#handleGameRuleValues` - 处理从服务器发送的游戏规则值。
    - `ClientboundLowDiskSpaceWarningPacket` - 发送给客户端警告机器磁盘空间不足的数据包。
    - `ClientGamePacketListener#handleLowDiskSpaceWarning` - 处理关于磁盘空间不足的警告数据包。
    - `ServerboundAttackPacket` - 发送给服务器关于玩家攻击了哪个实体的数据包。
    - `ServerboundClientCommandPacket$Action#REQUEST_GAMERULE_VALUES` - 从服务器请求游戏规则值。
    - `ServerboundSetGameRulePacket` - 从客户端发送设置游戏规则条目的数据包。
    - `ServerboundSpectateEntityPacket` - 发送给服务器关于玩家想要旁观哪个实体的数据包。
    - `ServerGamePacketListener`
        - `handleAttack` - 处理玩家对实体的攻击。
        - `handleSpectateEntity` - 处理玩家想要旁观实体。
        - `handleSetGameRule` - 处理从客户端设置游戏规则。
- `net.minecraft.resources`
    - `FileToIdConverter#extensionMatches` - 检查标识符是否以指定的扩展名结尾。
    - `Identifier`
        - `ALLOWED_NAMESPACE_CHARACTERS` - 标识符命名空间中允许的字符。
        - `resolveAgainst` - 通过检查 `/<namespace>/<path>` 从给定根解析路径。
- `net.minecraft.server`
    - `Bootstrap#shutdownStdout` - 关闭 stdout 流。
    - `MinecraftServer`
        - `DEFAULT_GAME_RULES` - 服务器的默认游戏规则。
        - `warnOnLowDiskSpace` - 如果磁盘空间低于 64 MiB，则发送警告。
        - `sendLowDiskSpaceWarning` - 发送磁盘空间不足的警告。
- `net.minecraft.server.commands.SwingCommand` - 调用所有目标的 `LivingEntity#swing` 的命令。
- `net.minecraft.server.level.ServerPlayer`
    - `sendBuildLimitMessage` - 如果玩家在相应的 Y 方向上无法再建造，则发送覆盖消息。
    - `sendSpawnProtectionMessage` - 如果玩家因生成保护而无法修改地形，则发送覆盖消息。
- `net.minecraft.server.packs.AbstractPackResources#loadMetadata` - 加载根目录的 `pack.mcmeta`。
- `net.minecraft.server.packs.resources.ResourceMetadata$MapBased` - 将节存储在映射中的资源元数据。
- `net.minecraft.tags.TagLoader$ElementLookup#fromGetters` - 根据元素是否需要，从给定的 `HolderGetter` 构造元素查找。
- `net.minecraft.util`
    - `ARGB#gray` - 根据给定的亮度获取灰度颜色。
    - `CompilableString` - 用于获取某些字符串模式并通过某些解析器将其编译为对象的工具。
    - `LightCoordsUtil` - 用于从光照值确定光照坐标的工具。
    - `ProblemReporter$MapEntryPathElement` - 映射中某个条目的路径元素。
    - `Util#allOfEnumExcept` - 获取除提供的值之外的所有枚举的集合。
- `net.minecraft.util.thread.BlockableEventLoop#hasDelayedCrash` - 是否有排队的崩溃报告。
- `net.minecraft.util.valueproviders.TrapezoidInt` - 使用梯形分布采样随机值。
- `net.minecraft.world.InteractionHand#STREAM_CODEC` - 交互手的网络编解码器。
- `net.minecraft.world.attribute`
    - `AttributeType#toFloat` - 将属性值作为 `float` 获取，如果未定义则抛出异常。
    - `AttributeTypes#INTEGER` - 一个整数属性类型。
    - `LerpFunction#ofInteger` - 用于整数值的 lerp 函数。
- `net.minecraft.world.attribute.modifier`
    - `AttributeModifier#INTEGER_LIBRARY` - 用于整数的操作符库。
    - `IntegerModifier` - 将某些参数应用于整数值的修饰符。
- `net.minecraft.world.entity`
    - `AgeableMob`
        - `AGE_LOCK_COOLDOWN_TICKS` - 在实体可以年龄锁定/解锁之前等待的 tick 数。
        - `ageLockParticleTimer` - 年龄锁定/解锁时显示粒子的时间。
    - `Entity`
        - `applyEffectsFromBlocksForLastMovements` - 对实体应用上一次移动的方块效果，由物品使用。
        - `$Flags` - 一个注解，标记特定值为实体的标志位集。
    - `LivingEntity#getLiquidCollisionShape` - 返回实体尝试与液体碰撞时的边界。
    - `Mob`
        - `asValidTarget` - 检查实体是否为该实体的有效目标（可以攻击）。
        - `getTargetUnchecked` - 获取原始目标而不检查其有效性。
        - `canAgeUp` - 实体是否可以成长为更成熟的变体。
        - `setAgeLocked`, `isAgeLocked` - 实体是否不能成长。
    - `NeutralMob#getTargetUnchecked` - 获取原始目标而不检查其有效性。
    - `TamableAnimal#feed` - 玩家将物品作为食物给予，根据存储的组件或某些默认值治愈它们。
- `net.minecraft.world.entity.ai.behavior`
    - `BehaviorControl#getRequiredMemories` - 行为所需的记忆列表。
    - `GoAndGiveItemsToTarget$ItemThrower` - 一个处理如果因该实体的行为而抛出物品时应发生什么的接口。
- `net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder$TriggerWithResult#memories` - 行为所需的记忆列表。
- `net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities#nearbyEntities` - 在该实体的跟随范围内的实体列表。
- `net.minecraft.world.entity.decoration.LeashFenceKnotEntity`
    - `getKnot` - 在给定位置找到结，否则返回空的可选值。
    - `createKnot` - 创建一个新结并将其添加到关卡中。
- `net.minecraft.world.entity.monster.piglin`
    - `PiglinAi`
        - `MAX_TIME_BETWEEN_HUNTS` - 猪灵再次开始狩猎前的最大秒数。
        - `findNearbyAdultPiglins` - 返回此猪灵记忆中所有成年猪灵的列表。
- `net.minecraft.world.entity.raid.Raid`
    - `getBannerComponentPatch` - 获取旗帜图案的组件。
    - `getOminousBannerTemplate` - 获取不祥旗帜的堆叠模板。
- `net.minecraft.world.inventory.SlotRanges`
    - `MOB_INVENTORY_SLOT_OFFSET` - 生物物品栏的起始索引。
    - `MOB_INVENTORY_SIZE` - 生物物品栏的大小。
- `net.minecraft.world.item.component.BundleContents#BEEHIVE_WEIGHT` - 蜂箱的重量。
- `net.minecraft.world.item.enchantment.EnchantmentTarget#NON_DAMAGE_CODEC` - 仅允许攻击者和受害者附魔目标的编解码器。
- `net.minecraft.world.level.block.BigDripleafBlock#canGrowInto` - 大垂滴叶是否可以生长到指定位置。
- `net.minecraft.world.level.block.grower.TreeGrower#getMinimumHeight` - 如果存在，获取树干放置器的基本高度。
- `net.minecraft.world.level.block.state`
    - `BlockBehaviour$PostProcess` - 一个获取要标记为后处理的位置的接口。
    - `StateDefinition`
        - `propertiesCodec` - 状态属性的映射编解码器。
        - `isSingletonState` - 定义是否只包含一个状态。
    - `StateHolder#isSingletonState` - 持有者是否只包含一个状态。
- `net.minecraft.world.level.block.state.properties`
    - `NoteBlockInstrument`
        - `TRUMPET` - 铜块放置在音符盒下时发出的声音。
        - `TRUMPET_EXPOSED` - 斑驳的铜块放置在音符盒下时发出的声音。
        - `TRUMPET_OXIDIZED` - 氧化的铜块放置在音符盒下时发出的声音。
        - `TRUMPET_WEATHERED` - 锈蚀的铜块放置在音符盒下时发出的声音。
    - `Property$Value#valueName` - 获取值的名称。
- `net.minecraft.world.level.dimension.DimensionDefaults`
    - `BLOCK_LIGHT_TINT` - 方块光的默认着色。
    - `NIGHT_VISION_COLOR` - 夜视激活时的默认颜色。
    - `TURTLE_EGG_HATCH_CHANCE` - 海龟蛋在随机 tick 中孵化的几率。
- `net.minecraft.world.level.gamerules.GameRule#getIdentifierWithFallback` - 获取游戏规则的标识符，否则获取未注册的标识符。
- `net.minecraft.world.level.levelgen`
    - `NoiseBasedChunkGenerator#getInterpolatedNoiseValue` - 获取给定位置的插值密度，如果 Y 超出噪声设置范围，则返回非数字值。
    - `NoiseChunk#getInterpolatedDensity` - 计算完整的噪声密度。
- `net.minecraft.world.level.levelgen.feature.AbstractHugeMushroomFeature#MIN_MUSHROOM_HEIGHT` - 蘑菇的最小高度。
- `net.minecraft.world.level.levelgen.feature.configurations.BlockBlobConfiguration` - 块团块特征的配置。
- `net.minecraft.world.level.levelgen.feature.trunkplacers.TrunkPlacer#getBaseHeight` - 返回树干的最小高度。
- `net.minecraft.world.level.levelgen.placement.RandomOffsetPlacement#ofTriangle` - 创建一个梯形分布，用于选择 XZ 和 Y 范围。
- `net.minecraft.world.level.material`
    - `FluidState#isFull` - 流体量是否为八。
    - `LavaFluid#LIGHT_EMISSION` - 熔岩流体发出的光量。
- `net.minecraft.world.level.pathfinder.PathType#BIG_MOBS_CLOSE_TO_DANGER` - 对于实体宽度大于一个方块的生物的路径惩罚。
- `net.minecraft.world.level.storage.LevelStorageSource#writeWorldGenSettings` - 将世界生成设置写入其保存数据位置。
- `net.minecraft.world.level.storage.loot.functions`
    - `EnchantRandomlyFunction$Builder#withOptions` - 指定可用于随机附魔此物品的附魔。
    - `SetRandomDyesFunction` - 一个物品函数，从提供的列表中应用随机染料（如果物品在 `dyeable` 标签中）到 `DYED_COLOR` 组件。
    - `SetRandomPotionFunction` - 一个物品函数，从提供的列表中应用随机药水到 `POTION_CONTENTS` 组件。
- `net.minecraft.world.level.storage.loot.parameters.LootContextParams#ADDITIONAL_COST_COMPONENT_ALLOWED` - 允许交易在所需堆叠或修饰符需要时产生额外成本。
- `net.minecraft.world.level.storage.loot.predicates.EnvironmentAttributeCheck` - 检查给定属性是否与提供的值匹配的战利品条件。
- `net.minecraft.world.level.storage.loot.providers.number`
    - `EnvironmentAttributeValue` - 以浮点数形式获取属性值的提供器。
    - `Sum` - 对所有提供的数字提供器的值求和的提供器。
- `net.minecraft.world.phys.AABB$Builder#isDefined` - 检查是否至少有一个点构成边界框。

### 更改列表

- `net.minecraft.advancements.criterion`
    - `EntityTypePredicate#matches` 现在接受一个持有者包装的 `EntityType` 而不是原始类型本身
    - `KilledTrigger$TriggerInstance#entityPredicate` -> `entity`
    - `PlayerPredicate` 现在接受一个 `FoodPredicate`
        - 可以使用 `PlayerPredicate$Builder#setFood` 设置
- `net.minecraft.client.gui`
    - `GuiGraphics`
        - `blit` 现在有一个接受 `GpuTextureView` 和 `GpuSampler` 的重载
        - `setTooltipForNextFrame` 现在有一个接受工具提示的 `FormattedCharSequence` 列表以及是否替换任何现有工具提示的重载
    - `ItemSlotMouseAction#onSlotClicked` 现在接受一个 `ContainerInput` 而不是 `ClickType`
- `net.minecraft.client.gui.components`
    - `AbstractContainerWidget` 现在接受一个 `AbstractScrollArea$ScrollbarSettings`
    - `AbstractScrollArea` 现在接受一个 `AbstractScrollArea$ScrollbarSettings`
        - `scrollbarVisible` -> `scrollable`
        - `scrollBarY` 现在是 public
        - `scrollRate` 不再是抽象的
    - `AbstractTextAreaWidget` 现在接受一个 `AbstractScrollArea$ScrollbarSettings`
    - `PopupScreen$Builder#setMessage` -> `addMessage`，不是一对一
    - `ScrollableLayout$Container` 现在接受一个 `AbstractScrollArea$ScrollbarSettings`
    - `Tooltip#create` 现在有一个接受可选的 `TooltipComponent` 和样式 `Identifier` 的重载
- `net.minecraft.client.gui.components.debug`
    - `DebugEntryLookingAtBlock`, `DebugEntryLookingAtFluid` -> `DebugEntryLookingAt`
        - 更具体地说，`$BlockStateInfo`, `$BlockTagInfo`, `$FluidStateInfo`, `$FluidTagInfo`
    - `DebugEntryLookingAtEntity#GROUP` 现在是 public
    - `DebugScreenEntries`
        - `LOOKING_AT_BLOCK` -> `LOOKING_AT_BLOCK_STATE`, `LOOKING_AT_BLOCK_TAGS`
        - `LOOKING_AT_FLUID` -> `LOOKING_AT_FLUID_STATE`, `LOOKING_AT_FLUID_TAGS`
    - `DebugScreenEntryList` 现在接受一个 `DataFixer`
- `net.minecraft.client.gui.components.tabs.TabNavigationBar#setWidth` -> `updateWidth`，不是一对一
- `net.minecraft.client.gui.navigation.FocusNavigationEvent$ArrowNavigation` 现在接受一个可空的 `ScreenRectangle` 用于上一个焦点
- `net.minecraft.client.gui.screens`
    - `ConfirmScreen#layout` 现在是 final
    - `DemoIntroScreen` 被 `ClientPacketListener#openDemoIntroScreen` 取代，现在是 private
    - `GenericWaitingScreen` 现在接受三个 `boolean`，分别表示是否显示加载点、取消按钮以及屏幕是否应在按下 ESC 时关闭
- `net.minecraft.client.gui.screens.inventory.AbstractMountInventoryScreen#mount` 现在是 final
- `net.minecraft.client.gui.screens.options`
    - `OptionsScreen` 现在实现 `HasGamemasterPermissionReaction`
        - 构造函数现在接受一个 `boolean` 表示玩家是否当前在世界中
        - `createDifficultyButton` 现在在 `WorldOptionsScreen#createDifficultyButtons` 中处理，不是一对一
    - `WorldOptionsScreen` 现在实现 `HasGamemasterPermissionReaction`
        - `createDifficultyButtons` -> `DifficultyButtons#create`，现在是 public
- `net.minecraft.client.multiplayer`
    - `ClientLevel#syncBlockState` 现在可以接受一个可空的玩家位置
    - `MultiPlayerGameMode#handleInventoryMouseClick` 现在接受一个 `ContainerInput` 而不是 `ClickType`
    - `WeatherEffectRenderer#render` 不再接受 `MultiBufferSource`
- `net.minecraft.client.renderer.block.ModelBlockRenderer$Cache#getLightColor` -> `getLightCoords`
- `net.minecraft.client.renderer.blockentity.state`
    - `BrushableBlockRenderState#itemState` 现在是 final
    - `EndPortalRenderState` 现在是一个 final 的 `Direction` 集而不是 `EnumSet`
    - `ShelfRenderState#items` 现在是 final
- `net.minecraft.client.renderer.entity.state`
    - `FallingBlockRenderState#movingBlockRenderState` 现在是 final
    - `HumanoidRenderState#attackArm` -> `ArmedEntityRenderState#attackArm`
    - `WitherRenderState#xHeadRots`, `yHeadRots` 现在是 final
- `net.minecraft.client.resources.sounds.AbstractSoundInstance#random` 现在是 final
- `net.minecraft.commands.SharedSuggestionProvider#getCustomTabSugggestions` -> `getCustomTabSuggestions`
- `net.minecraft.commands.arguments.ComponentArgument#getResolvedComponent` 现在接受一个非空的 `Entity`
- `net.minecraft.commands.arguments.selector.SelectorPattern` 被 `CompilableString` 取代
- `net.minecraft.core.HolderGetter$Provider#get`, `getOrThrow` 现在有接受 `TagKey` 的重载
- `net.minecraft.data`
    - `BlockFamily`
        - `shouldGenerateRecipe` -> `shouldGenerateCraftingRecipe`, `shouldGenerateStonecutterRecipe`
        - `$Builder#dontGenerateRecipe` -> `dontGenerateCraftingRecipe`, `generateStonecutterRecipe`
    - `DataGenerator` 现在是抽象的
        - 构造函数现在只接受 `Path` 输出，不接受 `WorldVersion` 或是否总是生成
            - 原始实现可以在 `DataGenerator$Cached` 中找到
        - `run` 现在是抽象的
    - `Main#addServerProviders` -> `addServerDefinitionProviders`，不再接受 dev `boolean`，不是一对一
    - 其余逻辑已放入 `addServerConverters`，接受 dev `boolean` 但不接受报告 `boolean`
- `net.minecraft.data.loot.BlockLootSubProvider`
    - `explosionResistant` 现在是 private
    - `enabledFeatures` 现在是 private
    - `map` 现在是 private
- `net.minecraft.data.recipes`
    - `RecipeProvider$FamilyRecipeProvider` -> `$FamilyCraftingRecipeProvider`, `$FamilyStonecutterRecipeProvider`
    - `SingleItemRecipeBuilder#stonecutting` 移至 `BlockFamily` 上的参数
- `net.minecraft.data.structures.SnbtToNbt` 现在有一个接受单个输入文件夹路径的重载
- `net.minecraft.gametest.framework`
    - `GameTestHelper`
        - `assertBlockPresent` 现在有一个只接受要检查的块的重载
        - `moveTo` 现在有接受 `BlockPos` 和 `Vec3` 作为位置的重载
        - `assertEntityInstancePresent` 现在有一个通过 `double` 膨胀边界框以检查内部实体的重载
    - `GameTestServer#create` 现在接受一个 `int` 表示运行所有匹配测试的次数
    - `StructureUtils#testStructuresDir` 拆分为 `testStructuresTargetDir`, `testStructuresSourceDir`
    - `TestData` 现在接受一个 `int` 表示测试周围填充的方块数
- `net.minecraft.nbt`
    - `NbtUtils`
        - `addDataVersion` 现在使用泛型 `Dynamic` 而不是显式的 nbt 标签
        - `getDataVersion` 现在有一个默认值为 -1 的重载（如果未指定版本）
    - `TextComponentTagVisitor` 现在可以接受一个 `$Styling` 和一个 `boolean` 表示是否对键进行排序
        - `handleEscapePretty` 现在是一个 `private` 实例方法，而不是 `protected` static
- `net.minecraft.network.FriendlyByteBuf`
    - `readVec3`, `writeVec3` 被 `Vec3#STREAM_CODEC` 取代
    - `readLpVec3`, `writeLpVec3` 被 `Vec3#LP_STREAM_CODEC` 取代
- `net.minecraft.network.chat`
    - `Component`
        - `nbt` 现在接受一个 `CompilableString` 而不是 `String`
        - `object` 现在有一个接受 `Component` 回退的重载
    - `ComponentContents#resolve` 现在接受一个 `ResolutionContext` 而不是 `CommandSourceStack` 和 `Entity`
    - `ComponentUtils#updateForEnttiy` -> `resolve`，接受 `ResolutionContext` 而不是 `CommandSourceStack` 和 `Entity`
    - `LastSeenMessages#EMPTY` 现在是 final
- `net.minecraft.network.chat.contents`
    - `NbtContents` 现在是一个记录，构造函数接受一个 `CompilableString` 而不是 `String`
    - `ObjectContents` 现在接受一个可选的 `Component` 作为回退，如果其内容无法验证
- `net.minecraft.network.chat.contents.data`
    - `BlockDataSource` 现在接受一个 `CompilableString` 用于 `Coordinates`，而不是模式和编译后的位置
    - `EntityDataSource` 现在接受一个 `CompilableString` 用于 `EntitySelector`，而不是模式和编译后的选择器
- `net.minecraft.network.chat.contents.objects.ObjectInfo#description` -> `defaultFallback`
- `net.minecraft.network.protocol.game`
    - `ClientboundSetEntityMotionPacket` 现在是一个记录
    - `ServerboundContainerClickPacket` 现在接受一个 `ContainerInput` 而不是 `ClickType`
    - `ServerboundInteractPacket` 现在是一个记录，现在接受交互位置的 `Vec3`
- `net.minecraft.references`
    - `Blocks` -> `BlockIds`
    - `Items` -> `ItemIds`
- `net.minecraft.resources`
    - `FileToIdConverter` 现在是一个记录
    - `RegistryDataLoader#load` 现在返回一个 `CompletableFuture` 的冻结注册表访问
- `net.minecraft.server.MinecraftServer` 现在接受一个 `boolean` 表示是否传播崩溃，通常用于抛出延迟崩溃
    - `throwIfFatalException` -> `BlockableEventLoop#throwDelayedException`，现在是 private，不是一对一
    - `setFatalException` -> `BlockableEventLoop#delayCrash`, `relayDelayCrash`；不是一对一
- `net.minecraft.server.commands.ChaseCommand#DIMENSION_NAMES` 现在是 final
- `net.minecraft.server.dedicated.DedicatedServerProperties#acceptsTransfers` 现在是 final
- `net.minecraft.server.packs`
    - `BuiltInMetadata` 已合并到 `ResourceMetadata` 中
        - `get` -> `ResourceMetadata#getSection`
        - `of` -> `ResourceMetadata#of`
    - `PathPackResources#getNamespaces` 现在有一个接受根目录 `Path` 的静态重载
    - `VanillaPackResourcesBuilder#setMetadata` 现在接受一个 `ResourceMetadata` 而不是 `BuiltInMetadata`
- `net.minecraft.server.players.OldUsersConverter#serverReadyAfterUserconversion` 被 `areOldUserListsRemoves` 取代，现在是 `public`
- `net.minecraft.tags.TagLoader`
    - `loadTagsFromNetwork` 现在接受一个 `Registry` 而不是 `WritableRegistry`，返回标签键到持有者条目列表的映射
    - `loadTagsForRegistry` 现在有一个接受注册表键以及元素查找的重载，返回标签键到持有者条目列表的映射
- `net.minecraft.util`
    - `Brightness`
        - `pack` -> `LightCoordsUtil#pack`
        - `block` -> `LightCoordsUtil#block`
        - `sky` -> `LightCoordsUtil#sky`
    - `RandomSource#createNewThreadLocalInstance` -> `createThreadLocalInstance`
        - 现在有一个指定种子的重载
    - `Util#copyAndAdd` 现在有一个接受可变参数元素的重载
- `net.minecraft.util.thread`
    - `BlockableEventLoop` 现在接受一个 `boolean` 表示是否传播崩溃，通常用于抛出延迟崩溃
    - `ReentrantBlockableEventLoop` 现在接受一个 `boolean` 表示是否传播崩溃，通常用于抛出延迟崩溃
- `net.minecraft.world.InteractionResult$ItemContext#NONE`, `DEFAULT` 现在是 final
- `net.minecraft.world.attribute`
    - `AttributeType` 现在接受一个 `ToFloatFunction` 用于数字提供器
        - `ofInterpolated` 现在接受一个 `ToFloatFunction`
    - `EnvironmentAttributeReader#getValue` 现在有一个接受 `LootContext` 的重载
- `net.minecraft.world.entity`
    - `Avatar` 现在是抽象的
    - `Entity`
        - `fluidHeight` 现在是 final
        - `getTags` -> `entityTags`
        - `getRandomY` 现在有一个指定扩展 `double` 的重载
    - `Leashable$Wrench#ZERO` 现在是 final
    - `LivingEntity`
        - `interpolation` 现在是 final
        - `swingingArm` 现在是可空的
        - `canAttackType` -> `canAttack`，不是一对一，接受 `LivingEntity` 而不是 `EntityType`
        - `lungeForwardMaybe` -> `postPiercingAttack`
        - `entityAttackRange` -> `getAttackRangeWith`，现在接受用于攻击的 `ItemStack`
- `net.minecraft.world.entity.ai.behavior`
    - `GoAndGiveItemsToTarget` 现在接受 `$ItemThrower`
        - `throwItem` -> `BehaviorUtils#throwItem`，不是一对一
    - `SpearAttack` 不再接受接近距离 `float`
    - `TryLaySpawnOnWaterNearLand` -> `TryLaySpawnOnFluidNearLand`，不是一对一
- `net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder#sequence` 现在接受一个 `Oneshot` 作为第二个条目，而不是 `Trigger`
- `net.minecraft.world.entity.ai.goal`
    - `BoatGoals` -> `FollowPlayerRiddenEntityGoal$FollowEntityGoal`
        - `BOAT` 被 `ENTITY` 取代
    - `FollowBoatGoal` -> `FollowPlayerRiddenEntityGoal`，不是一对一
- `net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal#targetConditions` 现在是 final
- `net.minecraft.world.entity.ai.sensing.NearestVisibleLivingEntitySensor#getMemory` -> `getMemoryToSet`
- `net.minecraft.world.entity.decoration.Mannequin#getProfile` -> `Avatar#getProfile`，现在是 `public` 和 `abstract`
    - 仍在 `Mannequin` 中实现
- `net.minecraft.world.entity.item.ItemEntity#DEFAULT_HEALTH` 现在是 `public` 而不是 `private`
- `net.minecraft.world.entity.monster.breeze.Breeze#idle`, `slide`, `slideBack`, `longJump`, `shoot`, `inhale` 现在是 final
- `net.minecraft.world.entity.monster.piglin.PiglinAi#isZombified` 现在接受 `Entity` 而不是 `EntityType`
- `net.minecraft.world.entity.monster.warden.Warden#roarAnimationState`, `sniffAnimationState`, `emergeAnimationState`, `diggingAnimationState`, `attackAnimationState`, `sonicBoomAnimationState` 现在是 final
- `net.minecraft.world.entity.monster.zombie.Zombie#handleAttributes` 现在接受 `EntitySpawnReason`
- `net.minecraft.world.entity.player`
    - `Input#EMPTY` 现在是 final
    - `Player`
        - `currentImpulseImpactPos` -> `LivingEntity#currentImpulseImpactPos`
        - `currentExplosionCause` -> `LivingEntity#currentExplosionCause`
        - `setIgnoreFallDamageFromCurrentImpulse` -> `LivingEntity#setIgnoreFallDamageFromCurrentImpulse`
        - `applyPostImpulseGraceTime` -> `LivingEntity#applyPostImpulseGraceTime`
        - `isIgnoringFallDamageFromCurrentImpulse` -> `LivingEntity#isIgnoringFallDamageFromCurrentImpulse`
        - `tryResetCurrentImpulseContext` -> `LivingEntity#tryResetCurrentImpulseContext`
        - `resetCurrentImpulseContext` -> `LivingEntity#resetCurrentImpulseContext`
        - `isInPostImpulseGraceTime` -> `LivingEntity#isInPostImpulseGraceTime`
        - `isWithinAttackRange` 现在接受用于攻击的 `ItemStack`
- `net.minecraft.world.entity.vehicle.minecart.NewMinecartBehavior$MinecartStep#EMPTY` 现在是 final
- `net.minecraft.world.inventory.AbstractContainerMenu#getQuickCraftPlaceCount` 现在接受快速制作槽位的数量而不是槽位集本身
- `net.minecraft.world.item`
    - `BundleItem#getSelectedItem` -> `getSelectedItemIndex`
    - `CreativeModeTab$Output` 现在是 `protected` 而不是 `public`
    - `EnderpearlItem#PROJECTILE_SHOOT_POWER` 现在是 final
    - `Item$Properties#requiredFeatures` 现在有一个接受 `FeatureFlagSet` 的重载
    - `Items#register*` 方法现在是 `private` 而不是 `public`
    - `ItemUtils#onContainerDestroyed` 现在接受一个 `Stream` 的 `ItemStack` 而不是 `Iterable`
    - `SignApplicator#tryApplyToSign`, `canApplyToSign` 现在接受正在使用的 `ItemStack`
    - `SnowballItem#PROJECTILE_SHOOT_POWER` 现在是 final
    - `ThrowablePotionItem#PROJECTILE_SHOOT_POWER` 现在是 final
    - `WindChargeItem#PROJECTILE_SHOOT_POWER` 现在是 final
- `net.minecraft.world.item.alchemy.Potions` 现在处理 `Holder$Reference` 而不是超类 `Holder`
- `net.minecraft.world.item.component`
    - `AttackRange`
        - `minRange` -> `minReach`
        - `maxRange` -> `maxReach`
        - `minCreativeRange` -> `minCreativeReach`
        - `maxCreativeRange` -> `maxCreativeReach`
    - `BundleContents`
        - `weight` 现在返回一个 `DataResult` 包装的 `Fraction` 而不是原始对象
        - `getSelectedItem` -> `getSelectedItemIndex`
    - `WrittenBookContent`
        - `tryCraftCopy` -> `craftCopy`
        - `resolveForItem`, `resolve` 现在接受 `ResolutionContext` 和 `HolderLookup$Provider` 而不是 `CommandSourceStack` 和 `Player`
- `net.minecraft.world.item.enchantment`
    - `ConditionalEffect#codec` 不再接受 `ContextKeySet`
    - `Enchantment#doLunge` -> `doPostPiercingAttack`
    - `EnchantmentHelper#doLungeEffects` -> `doPostPiercingAttackEffects`
    - `TargetedConditionalEffect#codec`, `equipmentDropsCodec` 不再接受 `ContextKeySet`
- `net.minecraft.world.item.enchantment.effects.EnchantmentAttributeEffect#CODEC` -> `MAP_CODEC`
- `net.minecraft.world.item.equipment.Equippable#canBeEquippedBy` 现在接受一个持有者包装的 `EntityType` 而不是原始类型本身
- `net.minecraft.world.item.trading.VillagerTrades#LIBRARIAN_5_EMERALD_NAME_TAG` 被 `LIBRARIAN_5_EMERALD_YELLOW_CANDLE`, `LIBRARIAN_5_EMERALD_RED_CANDLE` 取代，不是一对一
    - 原始交易已移至 `WANDERING_TRADER_EMERALD_NAME_TAG`
- `net.minecraft.world.level`
    - `LevelAccessor` 不再实现 `LevelReader`
    - `LevelHeightAccessor#isInsideBuildHeight` 现在有一个接受 `BlockPos` 的重载
- `net.minecraft.world.level.block`
    - `BigDripleafBlock#canPlaceAt` 现在接受 `LevelReader` 而不是 `LevelHeightAccessor`，并且不再接受旧状态
    - `BubbleColumnBlock#updateColumn` 现在接受气泡柱 `Block`
    - `FireBlock#setFlammable` 现在是 `private` 而不是 `public`
    - `MultifaceSpreader$DefaultSpreaderConfig#block` 现在是 final
    - `SnowyDirtBlock` -> `SnowyBlock`
    - `SpreadingSnowyDirtBlock` -> `SpreadingSnowyBlock`
        - 构造函数现在接受 `ResourceKey` 表示“基础”方块，或当雪或任何其他装饰（例如草）被移除时的方块
- `net.minecraft.world.level.block.entity.TestInstanceBlockEntity`  
    - `getTestBoundingBox` - 测试的边界框，按其填充膨胀。
    - `getTestBounds` - 测试的轴对齐边界框，按其填充膨胀。
- `net.minecraft.world.level.block.entity.vault`
    - `VaultConfig#DEFAULT`, `CODEC` 现在是 final
    - `VaultServerData#CODEC` 现在是 final
    - `VaultSharedData#CODEC` 现在是 final
- `net.minecraft.world.level.block.state`
    - `BlockBehaviour`
        - `$BlockStateBase` 现在接受一个 `Property` 和 `Comparable` 值的数组，而不是一个值映射，并且不再接受 `MapCodec`
            - `hasPostProcess` -> `getPostProcessPos`，不是一对一
        - `$Properties#hasPostProcess` -> `getPostProcessPos`，不是一对一
    - `BlockState` 现在接受一个 `Property` 和 `Comparable` 值的数组，而不是一个值映射，并且不再接受 `MapCodec`
    - `StateHolder` 现在接受一个 `Property` 和 `Comparable` 值的数组，而不是一个值映射，并且不再接受 `MapCodec`
        - `populateNeighbours` -> `initializeNeighbors`，现在是包私有而不是 `public`；不是一对一
        - `getValues` 现在返回一个 `Property$Value` 流
        - `codec` 现在接受从某个对象获取状态定义的函数
- `net.minecraft.world.level.chunk.ChunkAccess#blendingData` 现在是 final
- `net.minecraft.world.level.chunk.storage.SimpleRegionStorage#upgradeChunkTag` 现在接受一个 `int` 表示目标版本
- `net.minecraft.world.level.gameevent.vibrations.VibrationSystem$Data#CODEC` 现在是 final
- `net.minecraft.world.level.gamerules.GameRules` 现在有一个接受 `GameRule` 列表的重载
- `net.minecraft.world.level.levelgen`
    - `NoiseRouterData#caves` 不再接受 `NormalNoise$NoiseParameters` 的 `HolderGetter`
    - `WorldDimensions#keysInOrder` 现在接受一个 `LevelStem` 键的集合而不是一个流
- `net.minecraft.world.level.levelgen.blockpredicates`
    - `TrueBlockPredicate#INSTANCE` 现在是 final
    - `UnobstructedPredicate#INSTANCE` 现在是 final
- `net.minecraft.world.level.levelgen.feature`
    - `AbstractHugeMushrromFeature`
        - `isValidPosition` 现在接受一个 `WorldGenLevel` 而不是 `LevelAccessor`
        - `placeTrunk` 现在接受一个 `WorldGenLevel` 而不是 `LevelAccessor`
        - `makeCap` 现在接受一个 `WorldGenLevel` 而不是 `LevelAccessor`
    - `BlockBlobFeature` 现在使用 `BlockBlobConfiguration` 泛型
    - `Feature`
        - `FOREST_ROCK` 被 `BLOCK_BLOB` 取代
        - `ICE_SPIKE` 被 `SPIKE` 取代
    - `IceSpikeFeature` -> `SpikeFeature`，不是一对一
        - `SpikeFeature` 现在是 `EndSpikeFeature`，不是一对一
            - `NUMBER_OF_SPIKES` -> `EndSpikeFeature#NUMBER_OF_SPIKES`
            - `getSpikesForLevel` -> `EndSpikeFeature#getSpikesForLevel`
- `net.minecraft.world.level.levelgen.feature.configurations`
    - `HugeMushroomFeatureConfiguration` 现在是一个记录，接受一个可放置的 `BlockPredicate`
    - `SpikeConfiguration` -> `EndSpikeConfiguration` 现在是一个记录
        - 原始的 `SpikeConfiguration` 现在用于冰刺，接受要使用的方块，以及放置位置的谓词和是否可以替换存在的方块
    - `TreeConfiguration`
        - `dirtProvider`, `forceDirt` 已被 `belowTrunkProvider` 取代
            - `dirtProvider` 通常使用 `CAN_PLACE_BELOW_OVERWORLD_TRUNKS`
            - `forceDirt` 通常使用 `PLACE_BELOW_OVERWORLD_TRUNKS`
        - `$TreeConfigurationBuilder`
            - `dirtProvider`, `dirt`, `forceDirt` 已被 `belowTrunkProvider` 取代
- `net.minecraft.world.level.levelgen.feature.foliageplacers.FoliagePlacer`
    - `createFoliage` 现在接受一个 `WorldGenLevel` 而不是 `LevelSimulatedReader`
    - `placeLeavesRow`, `placeLeavesRowWithHangingLeavesBelow` 现在接受一个 `WorldGenLevel` 而不是 `LevelSimulatedReader`
    - `tryPlaceExtension`, `tryPlaceLeaf` 现在接受一个 `WorldGenLevel` 而不是 `LevelSimulatedReader`
- `net.minecraft.world.level.levelgen.feature.rootplacers.RootPlacer#placeRoots`, `placeRoot` 现在接受一个 `WorldGenLevel` 而不是 `LevelSimulatedReader`
- `net.minecraft.world.level.levelgen.feature.stateproviders`
    - `BlockStateProvider#getState` 现在接受 `WorldGenLevel`
- `net.minecraft.world.level.levelgen.feature.treedecorators`
    - `TreeDecorator$Context` 现在接受一个 `WorldGenLevel` 而不是 `LevelSimulatedReader`
        - `level` 现在返回 `WorldGenLevel` 而不是 `LevelSimulatedReader`
- `net.minecraft.world.level.levelgen.feature.trunkplacers.TrunkPlacer`
    - `placeTrunk` 现在接受一个 `WorldGenLevel` 而不是 `LevelSimulatedReader`
    - `setDirtAt` -> `placeBelowTrunkBlock`，现在接受一个 `WorldGenLevel` 而不是 `LevelSimulatedReader`
    - `placeLog` 现在接受一个 `WorldGenLevel` 而不是 `LevelSimulatedReader`
    - `placeLogIfFree` 现在接受一个 `WorldGenLevel` 而不是 `LevelSimulatedReader`
    - `validTreePos` 现在接受一个 `WorldGenLevel` 而不是 `LevelSimulatedReader`
    - `isFree` 现在接受一个 `WorldGenLevel` 而不是 `LevelSimulatedReader`
- `net.minecraft.world.level.levelgen.placement.BiomeFilter#CODEC` 现在是 final
- `net.minecraft.world.level.levelgen.structure.TemplateStructurePiece#template`, `placeSettings` 现在是 final
- `net.minecraft.world.level.levelgen.structure.pools.alias`
    - `DirectPoolAlias#CODEC` 现在是 final
    - `RandomGroupPoolAlias#CODEC` 现在是 final
    - `RandomPoolAlias#CODEC` 现在是 final
- `net.minecraft.world.level.levelgen.structure.templatesystem.LiquidSettings#CODEC` 现在是 final
- `net.minecraft.world.level.levelgen.synth.PerlinNoise#getValue` 不再接受 `boolean` 表示是否展平 Y 值而不是应用频率因子
- `net.minecraft.world.level.material.FluidState` 现在接受一个 `Property` 和 `Comparable` 值的数组，而不是一个值映射，并且不再接受 `MapCodec`
- `net.minecraft.world.level.pathfinder.PathType`
    - `DANGER_POWDER_SNOW` -> `ON_TOP_OF_POWDER_SNOW`
    - `DANGER_FIRE` -> `FIRE_IN_NEIGHBOR`
    - `DAMAGE_FIRE` -> `FIRE`
    - `DANGER_OTHER` -> `DAMAGING_IN_NEIGHBOR`
    - `DAMAGE_OTHER` -> `DAMAGING`,
    - `DANGER_TRAPDOOR` -> `ON_TOP_OF_TRAPDOOR`
- `net.minecraft.world.level.saveddata.maps.MapItemSavedData#tickCarriedBy` 现在接受一个可空的 `ItemFrame`
- `net.minecraft.world.level.storage.loot.functions`
    - `EnchantRandomlyFunction` 现在接受一个 `boolean` 表示是否包含来自被附魔堆叠的额外交易成本组件
        - 通过 `$Builder#includeAdditionalCostComponent` 设置
    - `EnchantWithLevelsFunction` 现在接受一个 `boolean` 表示是否包含来自被附魔堆叠的额外交易成本组件
        - 通过 `$Builder#includeAdditionalCostComponent` 设置
        - `$Builder#fromOptions` -> `withOptions`，现在有一个接受可选的 `HolderSet` 的重载

### 移除列表

- `net.minecraft.SharedConstants#USE_WORKFLOWS_HOOKS`
- `net.minecraft.client.data.models.BlockModelGenerators#createGenericCube`
- `net.minecraft.client.Minecraft#delayCrashRaw`
- `net.minecraft.client.gui.components.EditBox#setFilter`
- `net.minecraft.client.multiplayer.ClientPacketListener#getId`
- `net.minecraft.client.renderer.Sheets`
    - `shieldSheet`
    - `bedSheet`
    - `shulkerBoxSheet`
    - `signSheet`
    - `hangingSignSheet`
    - `chestSheet`
- `net.minecraft.client.renderer.rendertype.RenderTypes#weather`
- `net.minecraft.data.loot.BlockLootSubProvider(Set, FeatureFlagSet, Map, HolderLookup$Provider)`
- `net.minecraft.gametest.framework.StructureUtils#DEFAULT_TEST_STRUCTURES_DIR`
- `net.minecraft.nbt.NbtUtils`
    - `addCurrentDataVersion`
    - `prettyPrint(Tag)`
- `net.minecraft.server.packs.AbstractPackResources#getMetadataFromStream`
- `net.minecraft.server.players.PlayerList#getSingleplayerData`
- `net.minecraft.util`
    - `Mth#createInsecureUUID`
    - `LightCoordsUtil#UI_FULL_BRIGHT`
- `net.minecraft.world`
    - `ContainerListener`
    - `Difficulty#getKey`
    - `SimpleContainer#addListener`, `removeListener`
- `net.minecraft.world.entity.ai.memory.MemoryModuleType#INTERACTABLE_DOORS`
- `net.minecraft.world.entity.monster.Zoglin#MEMORY_TYPES`
- `net.minecraft.world.entity.monster.creaking.Creaking#MEMORY_TYPES`
- `net.minecraft.world.entity.monster.hogling.Hoglin#MEMORY_TYPES`
- `net.minecraft.world.item`
    - `BundleItem#hasSelectedItem`
    - `Item#getName()`
    - `ItemStack`
        - `isFramed`, `getFrame`
        - `setEntityRepresentation`, `getEntityRepresentation`
- `net.minecraft.world.item.component`
    - `BundleContents`
        - `getItemUnsafe`
        - `hasSelectedItem`
    - `WrittenBookContent#MAX_CRAFTABLE_GENERATION`
- `net.minecraft.world.level.block.LiquidBlock#SHAPE_STABLE`
- `net.minecraft.world.level.levelgen.feature`
    - `Feature#isStone`, `isDirt`, `isGrassOrDirt`
- `net.minecraft.world.level.levelgen.material.WorldGenMaterialRule`
- `net.minecraft.world.level.storage.loot.functions.SetOminousBottleAmplifierFunction#amplifier`
