Skip to content

内置配方类型

字数
3361 字
阅读时间
14 分钟

内置配方类型

Minecraft 提供了多种配方类型和序列化器供你使用。本文将解释每种配方类型,以及如何生成它们。


合成配方

合成配方通常在合成台、合成器或模组中的合成台或机器中制作。它们的配方类型是 minecraft:crafting​。

形状合成

一些最重要的配方——例如合成台、木棍或大多数工具——都是通过形状配方创建的。这些配方由必须插入物品的合成图案或形状定义(因此称为“形状”)。让我们看一个示例:

json
{
    "type": "minecraft:crafting_shaped",
    "category": "equipment",
    "pattern": [
        "XXX",
        " # ",
        " # "
    ],
    "key": {
        "#": {
            "item": "minecraft:stick"
        },
        "X": {
            "item": "minecraft:iron_ingot"
        }
    },
    "result": {
        "count": 1,
        "id": "minecraft:iron_pickaxe"
    }
}

让我们逐行解析:

  • type:这是形状配方序列化器的 ID,minecraft:crafting_shaped​。

  • category:此可选字段定义合成书中的类别。

  • key 和 pattern:这些一起定义了物品必须如何放入合成网格。

    • pattern​ 定义了最多三行,每行最多三个字符的字符串,用于定义形状。所有行必须具有相同的长度,即图案必须形成矩形。空格可用于表示应保持为空的槽位。
    • key​ 将图案中使用的字符与成分关联起来。在上面的示例中,图案中的所有 X​ 必须是铁锭,所有 #​ 必须是木棍。
  • result:配方结果。这是物品堆栈的 JSON 表示。

示例中未显示的是 group​ 键。此可选字符串属性在配方书中创建一个组。同一组中的配方将在配方书中显示为一个。

然后,让我们看看如何生成此配方:

java
// 我们使用构建器模式,因此不创建变量。通过调用 ShapedRecipeBuilder#shaped 创建一个新的构建器,
// 传入配方类别(在 RecipeCategory 枚举中找到)和结果物品、结果物品和数量,或结果物品堆栈。
ShapedRecipeBuilder.shaped(RecipeCategory.TOOLS, Items.IRON_PICKAXE)
        // 创建图案的行。每次调用 #pattern 都会添加新的一行。
        // 图案将被验证,即检查其形状。
        .pattern("XXX")
        .pattern(" # ")
        .pattern(" # ")
        // 为图案创建键。图案中使用的所有非空格字符都必须定义。
        // 这可以接受 Ingredients、TagKey<Item>s 或 ItemLikes,即物品或方块。
        .define('X', Items.IRON_INGOT)
        .define('#', Items.STICK)
        // 创建配方进度。虽然消费背景系统不强制要求,
        // 但如果你省略此步骤,配方构建器将崩溃。第一个参数是进度名称,
        // 第二个参数是条件。通常,你希望使用 has() 快捷方式作为条件。
        // 可以通过多次调用 #unlockedBy 来添加多个进度要求。
        .unlockedBy("has_iron_ingot", has(Items.IRON_INGOT))
        // 将配方存储在传递的 RecipeOutput 中,以便写入磁盘。
        // 如果你想为配方添加条件,可以在输出上设置它们。
        .save(output);

此外,你可以调用 #group​ 来设置配方书组。

无形状合成

与形状合成配方不同,无形状合成配方不关心成分的传递顺序。因此,没有图案和键,而是只有一个成分列表:

json
{
    "type": "minecraft:crafting_shapeless",
    "category": "misc",
    "ingredients": [
        {
            "item": "minecraft:brown_mushroom"
        },
        {
            "item": "minecraft:red_mushroom"
        },
        {
            "item": "minecraft:bowl"
        }
    ],
    "result": {
        "count": 1,
        "id": "minecraft:mushroom_stew"
    }
}

像以前一样,让我们逐行解析:

  • type:这是无形状配方序列化器的 ID,minecraft:crafting_shapeless​。
  • category:此可选字段定义合成书中的类别。
  • ingredients:成分列表。列表顺序在代码中保留用于配方查看目的,但配方本身接受任何顺序的成分。
  • result:配方结果。这是物品堆栈的 JSON 表示。

示例中未显示的是 group​ 键。此可选字符串属性在配方书中创建一个组。同一组中的配方将在配方书中显示为一个。

然后,让我们看看如何生成此配方:

java
// 我们使用构建器模式,因此不创建变量。通过调用 ShapelessRecipeBuilder#shapeless 创建一个新的构建器,
// 传入配方类别(在 RecipeCategory 枚举中找到)和结果物品、结果物品和数量,或结果物品堆栈。
ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, Items.MUSHROOM_STEW)
        // 添加配方成分。这可以接受 Ingredients、TagKey<Item>s 或 ItemLikes。
        // 还存在接受数量的重载,多次添加相同的成分。
        .requires(Blocks.BROWN_MUSHROOM)
        .requires(Blocks.RED_MUSHROOM)
        .requires(Items.BOWL)
        // 创建配方进度。虽然消费背景系统不强制要求,
        // 但如果你省略此步骤,配方构建器将崩溃。第一个参数是进度名称,
        // 第二个参数是条件。通常,你希望使用 has() 快捷方式作为条件。
        // 可以通过多次调用 #unlockedBy 来添加多个进度要求。
        .unlockedBy("has_mushroom_stew", has(Items.MUSHROOM_STEW))
        .unlockedBy("has_bowl", has(Items.BOWL))
        .unlockedBy("has_brown_mushroom", has(Blocks.BROWN_MUSHROOM))
        .unlockedBy("has_red_mushroom", has(Blocks.RED_MUSHROOM))
        // 将配方存储在传递的 RecipeOutput 中,以便写入磁盘。
        // 如果你想为配方添加条件,可以在输出上设置它们。
        .save(output);

此外,你可以调用 #group​ 来设置配方书组。

注意:单物品配方(例如存储方块解包)应是无形状配方,以遵循原版标准。

特殊合成

在某些情况下,输出必须从输入动态创建。大多数情况下,这是为了通过复制或计算输入堆栈的值来设置输出上的数据组件。这些配方通常只指定类型并硬编码其他所有内容。例如:

json
{
    "type": "minecraft:crafting_special_armordye"
}

此配方用于染色皮革盔甲,仅指定类型并硬编码其他所有内容——最显著的是颜色计算,这在 JSON 中很难表达。Minecraft 将所有特殊合成配方前缀为 crafting_special_​,但此做法不必遵循。

生成此配方如下所示:

java
// #special 的参数是 Function<CraftingBookCategory, Recipe<?>>。
// 所有原版特殊配方都使用带有一个 CraftingBookCategory 参数的构造函数。
SpecialRecipeBuilder.special(ArmorDyeRecipe::new)
        // 此 #save 重载允许我们指定名称。它也可以用于形状或无形状构建器。
        .save(output, "armor_dye");

原版提供了以下特殊合成序列化器(模组可能会添加更多):

  • minecraft:crafting_special_armordye​:用于染色皮革盔甲和其他可染色物品。
  • minecraft:crafting_special_bannerduplicate​:用于复制旗帜。
  • minecraft:crafting_special_bookcloning​:用于复制成书。这将使结果书的生成属性增加一。
  • minecraft:crafting_special_firework_rocket​:用于制作烟花火箭。
  • minecraft:crafting_special_firework_star​:用于制作烟花星。
  • minecraft:crafting_special_firework_star_fade​:用于为烟花星应用褪色。
  • minecraft:crafting_special_mapcloning​:用于复制已填充地图。也适用于宝藏地图。
  • minecraft:crafting_special_mapextending​:用于扩展已填充地图。
  • minecraft:crafting_special_repairitem​:用于将两个损坏的物品修复为一个。
  • minecraft:crafting_special_shielddecoration​:用于将旗帜应用于盾牌。
  • minecraft:crafting_special_shulkerboxcoloring​:用于为潜影盒着色,同时保留其内容。
  • minecraft:crafting_special_suspiciousstew​:用于根据输入花朵制作可疑的炖菜。
  • minecraft:crafting_special_tippedarrow​:用于根据输入药水制作 tipped 箭。
  • minecraft:crafting_decorated_pot​:用于从碎片制作装饰罐。

熔炉类配方

第二组最重要的配方是通过熔炼或类似过程制作的配方。所有在熔炉(类型 minecraft:smelting​)、烟熏炉(minecraft:smoking​)、高炉(minecraft:blasting​)和营火(minecraft:campfire_cooking​)中制作的配方都使用相同的格式:

json
{
    "type": "minecraft:smelting",
    "category": "food",
    "cookingtime": 200,
    "experience": 0.1,
    "ingredient": {
        "item": "minecraft:kelp"
    },
    "result": {
        "id": "minecraft:dried_kelp"
    }
}

让我们逐行解析:

  • type:这是配方序列化器的 ID,minecraft:smelting​。根据你制作的熔炉类配方的类型,这可能会有所不同。
  • category:此可选字段定义合成书中的类别。
  • cookingtime:此字段确定配方需要处理的时间,以刻为单位。所有原版熔炉配方使用 200,烟熏炉和高炉使用 100,营火使用 600。但是,这可以是任何你想要的值。
  • experience:确定制作此配方时奖励的经验值。此字段是可选的,如果省略,则不会奖励经验。
  • ingredient:配方的输入成分。
  • result:配方结果。这是物品堆栈的 JSON 表示。

这些配方的数据生成如下所示:

java
// 使用 #smoking 用于烟熏配方,#blasting 用于高炉配方,#campfireCooking 用于营火配方。
// 所有这些构建器在其他方面的工作方式相同。
SimpleCookingRecipeBuilder.smelting(
        // 我们的输入成分。
        Ingredient.of(Items.KELP),
        // 我们的配方类别。
        RecipeCategory.FOOD,
        // 我们的结果物品。也可以是 ItemStack。
        Items.DRIED_KELP,
        // 我们的经验奖励。
        0.1f,
        // 我们的烹饪时间。
        200
)
        // 配方进度,与上面的合成配方相同。
        .unlockedBy("has_kelp", has(Blocks.KELP))
        // 此 #save 重载允许我们指定名称。
        .save(p_301191_, "dried_kelp_smelting");

注意:这些配方的配方类型与其配方序列化器相同,即熔炉使用 minecraft:smelting​,烟熏炉使用 minecraft:smoking​,依此类推。


切石机配方

切石机配方使用 minecraft:stonecutting​ 配方类型。它们非常简单,只有类型、输入和输出:

json
{
    "type": "minecraft:stonecutting",
    "ingredient": {
        "item": "minecraft:andesite"
    },
    "result": {
        "count": 2,
        "id": "minecraft:andesite_slab"
    }
}

type​ 定义配方序列化器(minecraft:stonecutting​)。ingredient​ 是一个成分,result​ 是一个基本的物品堆栈 JSON。与合成配方一样,它们还可以选择性地指定一个组以在配方书中进行分组。

数据生成也很简单:

java
SingleItemRecipeBuilder.stonecutting(Ingredient.of(Items.ANDESITE), RecipeCategory.BUILDING_BLOCKS, Items.ANDESITE_SLAB, 2)
        .unlockedBy("has_andesite", has(Items.ANDESITE))
        .save(output, "andesite_slab_from_andesite_stonecutting");

请注意,单物品配方构建器不支持实际的 ItemStack​ 结果,因此不支持带有数据组件的结果。然而,配方编解码器支持它们,因此如果需要此功能,则需要实现自定义构建器。


锻造配方

锻造台支持两种不同的配方序列化器。一种用于将输入转换为输出,复制输入的组件(例如附魔),另一种用于将组件应用于输入。两者都使用 minecraft:smithing​ 配方类型,并且需要三个输入,分别称为基础、模板和附加物品。

转换锻造

此配方序列化器用于将两个输入物品转换为一个,保留第一个输入的组件。原版主要将此用于下界合金装备,但任何物品都可以在此使用:

json
{
    "type": "minecraft:smithing_transform",
    "base": {
        "item": "minecraft:diamond_axe"
    },
    "template": {
        "item": "minecraft:netherite_upgrade_smithing_template"
    },
    "addition": {
        "item": "minecraft:netherite_ingot"
    },
    "result": {
        "count": 1,
        "id": "minecraft:netherite_axe"
    }
}

让我们逐行解析:

  • type:这是配方序列化器的 ID,minecraft:smithing_transform​。
  • base:配方的基础成分。通常,这是某种装备。
  • template:配方的模板成分。通常,这是锻造模板。
  • addition:配方的附加成分。通常,这是某种材料,例如下界合金锭。
  • result:配方结果。这是物品堆栈的 JSON 表示。

在数据生成期间,调用 SmithingTransformRecipeBuilder#smithing​ 来添加你的配方:

java
SmithingTransformRecipeBuilder.smithing(
        // 模板成分。
        Ingredient.of(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE),
        // 基础成分。
        Ingredient.of(Items.DIAMOND_AXE),
        // 附加成分。
        Ingredient.of(Items.NETHERITE_INGOT),
        // 配方书类别。
        RecipeCategory.TOOLS,
        // 结果物品。请注意,虽然配方编解码器在此处接受物品堆栈,但构建器不接受。
        // 如果你需要物品堆栈输出,则需要使用自己的构建器。
        Items.NETHERITE_AXE
)
        // 配方进度,与上面的其他配方相同。
        .unlocks("has_netherite_ingot", has(Items.NETHERITE_INGOT))
        // 此 #save 重载允许我们指定名称。
        .save(output, "netherite_axe_smithing");

修剪锻造

修剪锻造是将盔甲修剪应用于盔甲的过程:

json
{
    "type": "minecraft:smithing_trim",
    "addition": {
        "tag": "minecraft:trim_materials"
    },
    "base": {
        "tag": "minecraft:trimmable_armor"
    },
    "template": {
        "item": "minecraft:bolt_armor_trim_smithing_template"
    }
}

再次,让我们逐行解析:

  • type:这是配方序列化器的 ID,minecraft:smithing_trim​。
  • base:配方的基础成分。所有原版用例在此处使用 minecraft:trimmable_armor​ 标签。
  • template:配方的模板成分。所有原版用例在此处使用锻造修剪模板。
  • addition:配方的附加成分。所有原版用例在此处使用 minecraft:trim_materials​ 标签。

此配方序列化器明显缺少 result​ 字段。这是因为它使用基础输入并“应用”模板和附加物品,即根据其他输入设置基础的组件,并使用该操作的结果作为配方结果。

在数据生成期间,调用 SmithingTrimRecipeBuilder#smithingTrim​ 来添加你的配方:

java
SmithingTrimRecipeBuilder.smithingTrim(
        // 基础成分。
        Ingredient.of(ItemTags.TRIMMABLE_ARMOR),
        // 模板成分。
        Ingredient.of(Items.BOLT_ARMOR_TRIM_SMITHING_TEMPLATE),
        // 附加成分。
        Ingredient.of(ItemTags.TRIM_MATERIALS),
        // 配方书类别。
        RecipeCategory.MISC
)
        // 配方进度,与上面的其他配方相同。
        .unlocks("has_smithing_trim_template", has(Items.BOLT_ARMOR_TRIM_SMITHING_TEMPLATE))
        // 此 #save 重载允许我们指定名称。是的,此名称是从原版复制的。
        .save(output, "bolt_armor_trim_smithing_template_smithing_trim");

贡献者

The avatar of contributor named as 小飘 小飘

文件历史