Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

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

本指南采用知识共享署名4.0国际许可协议授权,欢迎作为参考资料使用,使用时请保留原文链接以便其他读者查阅。

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

特别鸣谢:

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

资源包变更

原版还存在许多面向用户的改动未在本文讨论,这些内容可能对模组开发者具有参考价值。具体变更清单可查看Misode的版本更新日志

Java 25 与反混淆

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

首先,Java 开发工具包已从 21 升级到 25。原版使用了这些新特性,例如 JEP 447,它允许在构造函数中在 super 之前使用语句。对于模组开发社区的用户,请确保相应更新,或利用您的 IDE 或构建工具功能。Microsoft 的 OpenJDK 可以在此处找到。

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

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

战利品类型展开

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

// 以下是一个 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.BuiltInRegistriesRegistries
    • 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,详细说明具体问题。

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

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

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

// 对于某个实现 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 字段的静态实用程序。

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

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

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

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

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

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

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

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 -> ValidationContextSourceValidatable
      • Validatable 包含 validate* 方法
      • ValidationContextSource 持有上下文和报告器
  • net.minecraft.world.item.enchantment
    • ConditionalEffect 现在实现 Validatable
      • conditionCodec 被加载后调用 validate 取代
    • TargetedConditionalEffect 现在实现 Validatable
  • net.minecraft.world.level.storage.loot
    • IntRange 现在实现 LootContextUser
      • getReferencedContextParamsvalidate 取代
    • LootContext$VisitedEntry 泛型现在必须扩展 Validatable
    • LootContextUser 现在实现 Validatable
    • LootDataType 泛型现在必须扩展 Validatable
      • 构造函数现在接受 $ContextGetter 而不是 $Validator
      • runValidation 现在接受 ValidationContextSource 而不是 ValidationContext
        • 还有一个接受 HolderLookup 而不是键值对的重载
      • createSimpleValidatorcreateLootTableValidator$ValidatorValidatable 取代
      • $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(给予)什么作为回报。每个交易还可以提供对物品本身或其成本的修改器,或者根据给定条件决定是否可以达成特定交易。每个交易还指定可以进行的交易次数、给予多少经验值,或者与用户声誉相乘的价格倍数。然后通过 getOfferVillagerTrade 转换为 MerchantOffer,接受 LootContext,通常带有上下文参数 LootContextParamSets#VILLAGER_TRADE,提供商人本身(THIS_ENTITY)及其位置(ORIGIN)。

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

// 对于某个村民交易 '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#addOffersFromItemListingsAbstractVillager#addOffersFromItemListingsWithoutDuplicates 来选择要使用的报价。

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

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

// 对于某个交易集 '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"
}

村民交易标签可以是:

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

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

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

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

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"))
            )
        )
    )
);

物品列表转换

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

绿宝石 <-> 物品

对于以下交易:

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
);

它们的等价形式为:

// 对于某个村民交易 '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
}

物品和绿宝石 -> 物品

对于以下交易:

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

等价形式为:

// 对于某个村民交易 '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
}

绿宝石 -> 染色盔甲

对于以下交易:

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

等价形式为:

// 对于某个村民交易 '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
}

绿宝石 -> 附魔物品

对于以下交易:

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
);

等价形式为:

// 对于某个村民交易 '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
}

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

对于以下交易:

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
);

等价形式为:

// 对于某个村民交易 '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
}

绿宝石 -> 宝藏地图

对于以下交易:

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
);

等价形式为:

// 对于某个村民交易 '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 来检查是否可以向特定村民类型提供报价:

// 对于某个村民交易 '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 已被拆分为许多不同的类和实现
      • TRADESEXPERIMENTAL_TRADESWANDERING_TRADER_TRADES 现在由 VillagerProfession#tradeSetsByLevel 表示
        • 由于它们现在是数据包条目,因此存储在其各自的数据包中
        • TRADESEXPERIMENTAL_TRADESdata/minecraft/trade_set/<profession>/* 表示
        • WANDERING_TRADER_TRADESdata/minecraft/trade_set/wandering_trader/* 表示
      • $DyedArmorForEmeralds -> VillagerTrades#dyedItemaddRandomDye;不是一对一
      • $EmeraldForItems -> VillagerTrade,不是一对一
      • $EmeraldsForVillagerTypeItem -> VillagerTrades#registerBoatTrades,参见用法,不是一对一
      • $EnchantBookForEmeralds -> VillagerTrades#enchantedBook,不是一对一
      • $EnchantedItemForEmeralds -> VillagerTrades#enchantedItem,不是一对一
      • $ItemListing -> VillagerTrade
      • $ItemsAndEmeraldsToItems -> 带有 additionalWantsVillagerTrade
      • $ItemsForEmeralds -> VillagerTrade,不是一对一
      • $SuspiciousStewForEmerald -> 带有 SetStewEffectFunctionVillagerTrade
      • $TippedArrowForItemsAndEmeralds -> 带有 SetRandomPotionFunctionVillagerTrade
      • $TreasureMapForEmeralds -> VillagerTrades$VillagerExplorerMapEntry,参见用法,不是一对一
      • $TypeSpecificTrade -> VillagerTrades#villagerTypeRestrictionvillagerTypeHolderSet;不是一对一
  • net.minecraft.world.item.enchantment.providers.TradeRebalanceEnchantmentProviders 接口已移除
    • TradeRebalanceVillagerTradesTradeRebalanceRegistries 取代
  • 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 方法。

// 对于某个 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 轻松添加组件。

// 对于某个自定义注册表对象
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 收集组件。

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

物品

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

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。它们为网络通信提供了常规的 CODECMAP_CODECSTREAM_CODEC

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 作为类型。

// 两者都是物品实例
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,如下所示:

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
      • oreSmeltingoreBlasting 现在接受 CookingBookCategory
      • oreCooking 不再接受 RecipeSerializer,现在接受 CookingBookCategory
      • cookRecipessimpleCookingRecipe 不再接受 RecipeSerializer
      • shapeless 现在接受 ItemStackTemplate 而不是 ItemStack
    • ShapedRecipeBuilder 现在接受 ItemStackTemplate 作为结果,ItemLike 移至重载
      • 两个构造函数都是 private
    • ShapelessRecipeBuilder 现在接受 ItemStackTemplate 作为结果而不是 ItemStack
    • SimpleCookingRecipeBuilder 现在接受 ItemStackTemplate 作为结果,ItemLike 移至重载
      • generic 不再接受 RecipeSerializer,现在接受 CookingBookCategory
      • blastingsmelting 现在接受 CookingBookCategory
    • SingleItemRecipeBuilder 现在接受 ItemStackTemplate 作为结果,ItemLike 移至重载
      • ItemStackTemplate 构造函数是 private
    • SmithingTransformRecipeBuilder 现在接受 ItemStackTemplate 作为结果而不是 Item
    • TransmuteRecipeBuilder 现在接受 ItemStackTemplate 作为结果而不是 Holder<Item>
      • 构造函数是 private
      • transmute 现在有一个接受 ItemStackTemplate 作为结果的重载
      • addMaterialCountToOutputsetMaterialCount - 根据使用的材料数量处理结果堆栈的大小。
  • 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_CODECSTRICT_CODECSTRING_SINGLE_ITEM_CODECSIMPLE_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
      • nonEmptyItemsnonEmptyItemsCopy -> 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 现在是一个记录,接受用于序列化和反序列化配方的 MapCodecStreamCodec。因此,Serializer 类已被完全移除,取而代之的是在注册期间向记录提供编解码器:

// 假设某个 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 接口中定义的方法访问。因此,可以使用 NormalCraftingRecipeCustomRecipeSimpleSmithingRecipeSingleItemRecipeAbstractCookingRecipe 等类通过实现几个方法来创建新的配方实现。

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

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

染料组件

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

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

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

实体和告示牌

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

另一方面,给狼和猫的项圈染色可以是任何物品,只要它具有 DYE 组件即可。此外,该物品必须分别位于 ItemTags#WOLF_COLLAR_DYESItemTags#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
      • getAllBundleItemColorsgetByColor 已移除
    • DyeColor#VALUES - 所有染料颜色的列表。
    • DyeItem 不再接受 DyeColor
      • getDyeColorbyColor 已移除
  • 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#getBlockByColorgetColoredItemStack 已移除

世界时钟与时间标记

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

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

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

然后,您可以通过 ClockManager 通过 Level#clockManagerMinecraftServer#clockManager 查询时钟状态:

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

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

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

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

// 对于某个 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 字段来跟踪它们的时间。所有时间线都必须定义它使用的时钟;但是,请注意,时钟默认不支持任何同步,这意味着更新一个时钟的时间不会影响另一个时钟。

// 对于某个时间线 '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 中显示。由于时间标记由其世界时钟标识,因此使用相同世界时钟的时间线不能定义相同的时间标记。

// 对于某个时间线 '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 使用。

// 对于某个 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 现在接受一个时钟到其网络状态的映射,而不是白天时间 longboolean
  • net.minecraft.server
    • MinecraftServer
      • forceTimeSynchronization -> forceGameTimeSynchronization,不是一对一
      • clockManager - 服务器时钟管理器。
  • net.minecraft.server.level.ServerLevel
    • setDayTimegetDayCount 已移除
    • 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 已移除
      • setClockStatesclockStates - 处理世界时钟的当前状态。
  • 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,该标识符针对数据文件夹进行解析。此更改允许数据文件夹内的子目录,因为数据存储将在尝试写入文件之前首先创建所有缺失的父目录。

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 实例现在除了等级之外,还有自己的用于全局实例的数据存储。这意味着任何全局保存的数据都应存储在服务器实例上,而不是主世界。

// 给定一个 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.InWorldGameRulesScreenWorldCreationGameRulesScreen
    • 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
      • saveload -> 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_ENDgetType 已移除
  • 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
    • encodedecodeTYPE 取代
    • of - 构造生成设置。
  • net.minecraft.world.level.saveddata
    • SavedDataType 现在接受 Identifier 而不是字符串作为 id
    • WanderingTraderData - 流浪商人的保存数据。
    • WeatherData - 天气的保存数据。
  • net.minecraft.world.level.storage
    • DimensionDataStorage -> SavedDataStorage,不是一对一
    • LevelData#isThunderingisRainingsetRaining 现在在 WeatherData
    • LevelDataAndDimensions 现在接受 $WorldDataAndGenSettings 而不是 WorldData
      • $WorldDataAndGenSettings - 保存世界数据和生成设置。
    • LevelResource 现在是一个记录
    • PrimaryLevelData 字段已移至各自的保存数据类
      • PLAYER -> OLD_PLAYER
      • SINGLEPLAYER_UUID - 一个表示单机世界中玩家 UUID 的字符串。
      • WORLD_GEN_SETTINGS -> OLD_WORLD_GEN_SETTINGS
      • writeLastPlayed - 写入最后玩的玩家。
      • writeVersionTag - 写入数据版本标签。
    • ServerLevelData
      • setThunderinggetRainTimesetRainTimesetThunderTimegetThunderTimegetClearWeatherTimesetClearWeatherTime 移至 WeatherData
      • getWanderingTraderSpawnDelaysetWanderingTraderSpawnDelaygetWanderingTraderSpawnChancesetWanderingTraderSpawnChancegetWanderingTraderIdsetWanderingTraderId 移至 WanderingTraderData
      • getLegacyWorldBorderSettingssetLegacyWorldBorderSettingsWorldBorder 取代
      • getScheduledEvents -> MinecraftServer#getScheduledEvents
      • getGameRulesGameRuleMap 取代
    • WorldData
      • getCustomBossEventssetCustomBossEventsCustomBossEvents 取代
      • createTag 不再接受 RegistryAccess
      • getGameRulesGameRuleMap 取代
      • getLoadedPlayerTag -> getSinglePlayerUUID,不是一对一
      • endDragonFightDatasetEndDragonFightDataEnderDragonFight 取代
      • worldGenOptionsWorldGenSettings 保存数据取代
  • net.minecraft.world.level.timers.TimerQueue 现在扩展 SavedData
    • 构造函数现在接受 $Packed 事件,而不是 TimerCallbacks 和事件数据的 Stream
    • storeCODECTYPEcodec 取代
    • loadEventstoreEvent$Event$Packed#codec 取代
    • $Event 现在是一个记录
      • $Packed - 打包的事件数据。
    • $Packed - 打包的时间队列。

更多渲染变更

材质与动态层选择

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

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

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

// 对于某个模型 `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 重命名为 SpriteIdMaterialSet 重命名为 SpriteGetter

四边形粒子层

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

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 -> CuboidModelBlockModelWrapper -> CuboidItemModelWrapper)。此外,引用方块状态 JSON 内定义的渲染过程部分已从“block”更改为“block state”(例如,BlockModelPart -> BlockStateModelPartBlockModelDefinition -> BlockStateModelDispatcher)。您可以认为大多数“block model”类是新的,而那些重命名的类取代了 SpecialBlockModelRenderer 系统。

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

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

// 由于方块模型系统通过其代码内引导程序进行硬编码,
// 此示例将假设存在某种方法来访问 `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
);

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

// 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 用于粒子上下文,由下落的灰尘和地形粒子使用

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

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

// 假设可以访问 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
);

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

由于 ItemModelBlockModel 现在完全通过它们自己的功能提交管道处理,BlockRenderDispatcherItemRenderer 已被完全移除,被相应的系统取代。

对象定义变换

ItemModelBlockModel 现在可以接受一个可选的 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 -> extractRenderStateAbstractContainerScreen#renderLabels -> extractLabelsAbstractWidget#renderWidget -> extractWidgetRenderState)。一些缩写也被扩展,要么通过重命名,要么用另一个方法替换(例如,AbstractContainerScreen#renderBgScreen#extractBackground 取代)。

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

流体模型

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

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

// 由于流体模型系统在其烘焙中被硬编码,此示例
// 将假设存在某种方法可以修改访问
// `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_TESTCompareOp#ALWAYS_PASS 取代。深度信息可以通过 RenderPipeline$Builder#withDepthStencilState 添加到管道中。

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

public static final RenderPipeline EXAMPLE_PIPELINE = RenderPipeline.builder()
    .withLocation(ResourceLocation.fromNamespaceAndPath("examplemod", "pipeline/example"))
    .withVertexShader(ResourceLocation.fromNamespaceAndPath("examplemod", "example"))
    .withFragmentShader(ResourceLocation.fromNamespaceAndPath("examplemod", "example"))
    .withVertexFormat(DefaultVertexFormat.POSITION_TEX_COLOR, VertexFormat.Mode.QUADS)
    .withShaderDefine("ALPHA_CUTOUT", 0.5)
    .withSampler("Sampler0")
    .withUniform("ModelOffset", UniformType.VEC3)
    .withUniform("CustomUniform", UniformType.INT)
    .withPolygonMode(PolygonMode.FILL)
    .withCull(false)
    // 在写入缓冲区数据时设置颜色目标。
    .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 后端

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

实体和半透明功能

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

相机状态

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_alpharendertype_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_UNIFORMSINVALID_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,不是一对一
      • isResizedresetIsResized - 处理窗口是否已调整大小。
      • backend - 返回 GpuBackend
      • $WindowInitFailed 构造函数现在从 private 变为 public
    • WindowEventHandler#resizeDisplay -> resizeGui
  • com.mojang.blaze3d.pipeline
    • ColorTargetState - 一个包含颜色混合函数和掩码的记录。
    • DepthStencilState - 一个包含深度模板数据的记录。
    • RenderPipeline 现在接受 ColorTargetState 而不是可选的 BlendFunction、颜色和 alpha boolean 以及 LogicOp;以及 DepthStencilState 而不是 DepthTestFunction、深度 boolean 和偏置 float
      • getDepthTestFunctionisWriteDepthgetDepthBiasScaleFactorgetDepthBiasConstant -> getDepthStencilState,不是一对一
      • getColorLogicgetBlendFunctionisWriteColorisWriteAlpha -> getColorTargetState,不是一对一
      • $Builder
        • withDepthTestFunctionwithDepthWritewithDepthBias -> withDepthStencilState,不是一对一
        • withBlendwithColorWritewithColorLogic -> 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 - true1false0
    • 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 -> putBlockBakedQuadputBakedQuad;不是一对一
        • 亮度 float 数组、颜色 float、光照图 int 数组和覆盖 intQuadInstance 取代
        • putBlockBakedQuadPoseStack$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#advanceTimeadvanceGameTime(当 booleantrue 时)和 advanceRealTime 取代
      • advanceGameTimeadvanceRealTime 以前是 private,现在是 public
    • FramerateLimiter - 一个用于限制客户端帧率的实用程序。
    • Minecraft
      • noRender 已移除
      • useAmbientOcclusion 已移除
      • getBlockRenderer 已移除
      • getItemRenderer 已移除
    • Options
      • getCloudsType -> getCloudStatus
      • exclusiveFullscreen - 当为 true 时,全屏模式完全控制显示器。
  • net.minecraft.client.color.block
    • BlockColorBlockTintSource 取代,不是一对一
      • getColor -> colorInWorld, colorAsTerrainParticle; 不是一对一
    • BlockColors
      • getColorgetTintSourcesgetTintSource 取代;不是一对一
      • register 现在接受一个 BlockTintSource 列表而不是一个 BlockColor
    • BlockTintSource - 一个用于确定如何对 BlockState 进行单独或上下文着色的源。
    • BlockTintSources - 通用块着色源的实用程序。
  • net.minecraft.client.data.models
    • BlockModelGenerators
      • createSuffixedVariant 现在接受一个从 MaterialTextureMapping 的函数用于纹理,而不仅仅是 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
      • putputForced 现在接受一个 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
      • renderBgScreen#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、用于难度的 CycleButtonLockIconButton 和当前 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; 不是一对一
      • getLevelRenderStategetGameRenderState 取代,返回 GameRenderState 而不是 LevelRenderState
      • pick -> Minecraft#pick,现在为 private 而不是 public
      • render 拆分为 updateextractrenderboolean 现在表示是否推进游戏时间而不是渲染关卡
    • GlobalSettingsUniform 现在接受 Vec3 相机位置而不是主 Camera 本身
    • ItemBlockRenderTypes 已移除
      • getChunkRenderTypegetMovingBlockRenderType 现在存储在 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 或带有 SpriteGetterSpriteId 以及一个 int 色调颜色的重载
      • submitBreakingBlockModel - 提交方块破坏覆盖层。
    • PanoramaRendererPanorama 取代
      • registerTextures -> GuiRenderer#registerPanoramaTextures
      • render -> extractRenderState
    • PanoramicScreenshotParameters 记录已移除
    • PostChain 现在接受一个 ProjectionProjectionMatrixBuffer 而不是 CachedOrthoProjectionMatrixBuffer
      • load 现在接受一个 ProjectionProjectionMatrixBuffer 而不是 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_OUTLINEENTITY_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_BLOCKTRANSLUCENT_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
    • SpecialBlockModelRendererBuiltInBlockModels 取代,不是一对一
      • 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 作为姿态
    • VirtualScreenGpuBackend 取代
  • 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,不是一对一
      • renderBreakingTextureSubmitNodeCollector#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 - 获取用于 ChunkSectionLayerVertexConsumer
    • ModelBlockRenderer 现在接受 boolean 用于环境光遮蔽和剔除
      • tesselateBlock 现在接受一个 BlockQuadOutput 而不是 VertexConsumer,XYZ float 而不是 PoseStackBlockStateModel 而不是 BlockModelPart 列表,不再接受剔除 booleanint 覆盖,并接受种子 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
      • $AmbientOcclusionRenderStorageBlockModelLighter 取代,不是一对一
      • $AmbientVertexRemap -> BlockModelLighter$AmbientVertexRemap
      • $Cache -> BlockModelLighter$Cache
      • $CommonRenderStorageBlockModelLighter 取代,不是一对一
      • $SizeInfo -> BlockModelLighter$SizeInfo
    • MovingBlockRenderState#level -> cardinalLighting, lightEngine; 不是一对一
    • SelectBlockModel - 一个由其解析属性确定或选择的方块模型。
  • net.minecraft.client.renderer.block.model
    • BakedQuad -> .client.resources.model.geometry.BakedQuad
      • 构造函数现在接受一个 $MaterialInfo 而不是 TextureAtlasSpriteint 色调索引、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,现在为 protectedstatic 而不是 private
      • submitSpecial - 提交末地传送门立方体,由特殊渲染器使用。
      • getExtents - 获取每个面的顶点。
      • getOffsetUp, getOffsetDown 已移除
      • renderType 已移除
    • AbstractSignRenderer 现在接受一个泛型用于 SignRenderState
      • getSignModel 现在接受 SignRenderState 泛型而不是 BlockStateWoodType
      • getSignModelRenderScale, getSignTextRenderScale, getTextOffset, translateSignSignRenderState#transformationsSignRenderState$SignTransformations 取代
      • getSignMaterial -> getSignSprite
    • BannerRenderer
      • TRANSFORMATIONS - 当在墙上或地上时要应用的变换。
      • submitPatterns 不再接受基础 SpriteId、图案是否有箔以及轮廓颜色
      • submitSpecial 现在接受 BannerBlock$AttachmentType
    • BedRenderer
      • submitSpecial 已移除
        • 这被调用两次 submitPiece 或通过 BedSpecialRenderer 为每个床部件制作组合体所取代
      • submitPiece 现在是 public 而不是 private,接受 BedPart 而不是 Model$SimpleDirection 或是否在 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 不再接受 Directionfloat 旋转
    • 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
      • uploadMeshLayerisVertexBufferUploadedsetVertexBufferUploaded 取代
      • uploadLayerIndexBufferisIndexBufferUploadedsetIndexBufferUploaded 取代
    • RenderRegionCache#createRegion 现在接受 ClientLevel 而不是 Level
    • SectionBuffers -> SectionRenderDispatcher$RenderSectionBufferSlice,不是一对一
    • SectionCompiler 现在接受 boolean 用于环境光遮蔽和 cutout 树叶、BlockStateModelSetFluidStateModelSetBlockColors 而不是 BlockRenderDispatcher
    • SectionMesh
      • getBuffers -> getSectionDraw,不是一对一
      • $SectionDraw - 部分的绘图信息。
    • SectionRenderDispatcher 现在接受 SectionCompiler 而不是 BlockRenderDispatcherBlockEntityRenderDispatcher
      • 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
      • getBlockRenderDispatchergetBlockModelResolver 取代
    • 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 现在接受 GameRenderStateModelManager
      • renderAllFeatures 已拆分为 renderSolidFeaturesrenderTranslucentFeatures
        • 原始方法现在调用这两个方法,先 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_SAMPLERcreateMovingBlockSetup 取代,现在是 private
      • entityCutoutNoCull -> entityCutout
        • 原来的带剔除的 cutout 被 entityCutoutCull 取代
      • entityCutoutNoCullZOffset -> entityCutoutZOffset
      • entitySmoothCutout -> endCrystalBeam
      • entityNoOutline -> entityTranslucentaffectsOutlinefalse
      • 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
        • $SimpleBlockModel$BakingContextItemModel$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
      • 构造函数接受 BlockPosBlockState 和当前进度 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_* 开头,后跟方块(例如 bamboocactus)或组(例如 cropsdry_vegetation)。这由相关的方块子类通过重写 Block#canSurvive 或对于植被 VegetationBlock#mayPlaceOn 来处理。

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

容器屏幕变更

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

// 假设存在某个 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 上,原始状态将恢复到关卡中,以供下一个测试用例使用。

// 泛型应表示存储在关卡上的原始数据
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 是一个附加到某些对象的接口,这些对象表示某个其他“类型”对象的实例。例如,EntityEntityType 的类型化实例,或者 BlockStateBlock 的类型化实例。此接口旨在作为一种标准方法,提供对类型 Holder 的访问,并通过 is 检查后备类型(因此也是实例)是否等同于某个标识符、标签或原始对象。

// 对于某个 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,不是一对一
      • 实现为 AdultFelineModelBabyFelineModel
    • 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 - 猪灵耳朵的角度。
      • createMeshAdultPiglinModel#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$LayerTypeModelLayerLocation 用于鞍层和模型,并将 DonkeyRenderer$Type 拆分为成年类型和幼年类型
      • $Type
        • DONKEY_BABY - 驴的幼年变体。
        • MULE_BABY - 骡的幼年变体。
    • OcelotRenderer 现在接受一个 AbstractFelineModel 作为其泛型
    • UndeadHorseRenderer 现在接受一个 EquipmentClientInfo$LayerTypeModelLayerLocation 用于鞍层和模型,并将 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

// 在某个 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 数据:

// 对于某个扩展 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, serializeStartpack, Brain$Packed 取代
      • addActivityAndRemoveMemoryWhenStopped, addActivityWithConditions 合并到 addActivity
        • 或者使用 ActivityData#create
      • copyWithoutBehaviors 已移除
      • getMemoriesforEach 取代
      • $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 构建,使用 addSchemaaddFixer 为所需版本应用修复器。在升级过程中,文件在临时文件夹中创建,然后移动到世界文件夹。原始世界文件夹在删除之前被移动到另一个文件夹。

  • 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 现在有一个接受路径、StructureTemplateboolean(是否将数据写为文本)的重载
    • 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_MESSAGESCHAT_SEND_COMMANDS 分别确定玩家是否可以发送消息或命令。同样,CHAT_RECEIVE_PLAYER_MESSAGESCHAT_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
      • handleSystemMessageboolean 现在用于表示系统是否为远程而不是覆盖
        • 覆盖现在通过 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 期间。

对于牛:

// 文件位于:
// - `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"
}

对于鸡和猪:

// 文件位于:
// - `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"
    }
}

对于猪:

// 文件位于:
// - `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"
    }
}

对于猫:

// 文件位于:
// - `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 取代,它可以为标签和物品注册交互。标签在物品之前检查。

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,后跟使用 TrapezoidIntRandomOffsetPlacement,最后是 BlockPredicateFilter

// 在 `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#collectGameRegistriesboolean 参数现在仅处理从同步注册表以及标签更新组件。
  • 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 现在有一个接受 GpuTextureViewGpuSampler 的重载
      • 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
    • DemoIntroScreenClientPacketListener#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.SelectorPatternCompilableString 取代
  • 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 现在有接受 BlockPosVec3 作为位置的重载
      • 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, writeVec3Vec3#STREAM_CODEC 取代
    • readLpVec3, writeLpVec3Vec3#LP_STREAM_CODEC 取代
  • net.minecraft.network.chat
    • Component
      • nbt 现在接受一个 CompilableString 而不是 String
      • object 现在有一个接受 Component 回退的重载
    • ComponentContents#resolve 现在接受一个 ResolutionContext 而不是 CommandSourceStackEntity
    • ComponentUtils#updateForEnttiy -> resolve,接受 ResolutionContext 而不是 CommandSourceStackEntity
    • 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#serverReadyAfterUserconversionareOldUserListsRemoves 取代,现在是 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
      • BOATENTITY 取代
    • 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,现在是 publicabstract
    • 仍在 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 现在接受一个 StreamItemStack 而不是 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 现在接受 ResolutionContextHolderLookup$Provider 而不是 CommandSourceStackPlayer
  • 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_TAGLIBRARIAN_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 现在接受一个 PropertyComparable 值的数组,而不是一个值映射,并且不再接受 MapCodec
        • hasPostProcess -> getPostProcessPos,不是一对一
      • $Properties#hasPostProcess -> getPostProcessPos,不是一对一
    • BlockState 现在接受一个 PropertyComparable 值的数组,而不是一个值映射,并且不再接受 MapCodec
    • StateHolder 现在接受一个 PropertyComparable 值的数组,而不是一个值映射,并且不再接受 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$NoiseParametersHolderGetter
    • 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_ROCKBLOCK_BLOB 取代
      • ICE_SPIKESPIKE 取代
    • 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 现在接受一个 PropertyComparable 值的数组,而不是一个值映射,并且不再接受 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