内置配方类型

内置配方类型

Minecraft 内置了多种可直接使用的配方类型和序列化器。本文介绍各配方类型及其数据生成方法。

合成

合成配方通常在工作台、合成器,或模组工作台、机器中使用。其配方类型为 minecraft:crafting。

有序合成

工作台、木棍、大多数工具等重要配方都通过有序合成创建。这些配方定义了必须按其摆放物品的图案或形状,因此称为“有序”。示例如下:

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

逐行解释如下:

  • type:有序配方序列化器 ID,即 minecraft:crafting_shaped。

  • category:可选字段,定义配方书中的 CraftingBookCategory。

  • key 和 pattern:共同定义物品在合成网格中的摆放方式。

    • pattern 最多定义三行字符串,每行最多三个字符,表示配方形状。所有行长度必须相同,即图案必须为矩形。空格表示应留空的槽位。
    • key 将图案中使用的字符关联到原料。上例中,所有 X 必须是铁锭,所有 # 必须是木棍。
  • result:配方结果,采用物品堆叠模板的 JSON 表示。

  • 示例中未展示 group 键。这个可选字符串属性用于在配方书中创建分组;同组配方会在配方书中合并显示。

  • 示例中未展示 show_notification。此可选布尔值为 false 时,会禁用首次使用或解锁配方时右上角出现的提示。

下面是在 RecipeProvider#buildRecipes 中生成该配方的方法:

// We use a builder pattern, therefore no variable is created. Create a new builder by calling
// ShapedRecipeBuilder#shaped with the recipe category (found in the RecipeCategory enum)
// and a result item, a result item and count, or a result item stack template.
ShapedRecipeBuilder.shaped(this.registries.lookupOrThrow(Registries.ITEM), RecipeCategory.TOOLS, Items.IRON_PICKAXE)
        // Create the lines of your pattern. Each call to #pattern adds a new line.
        // Patterns will be validated, i.e. their shape will be checked.
        .pattern("XXX")
        .pattern(" # ")
        .pattern(" # ")
        // Create the keys for the pattern. All non-space characters used in the pattern must be defined.
        // This can either accept Ingredients, TagKey<Item>s or ItemLikes, i.e. items or blocks.
        .define('X', Items.IRON_INGOT)
        .define('#', Items.STICK)
        // Creates the recipe advancement. While not mandated by the consuming background systems,
        // the recipe builder will crash if you omit this. The first parameter is the advancement name,
        // and the second one is the condition. Normally, you want to use the has() shortcut for the condition.
        // Multiple advancement requirements can be added by calling #unlockedBy multiple times.
        .unlockedBy("has_iron_ingot", this.has(Items.IRON_INGOT))
        // Stores the recipe in the passed RecipeOutput, to be written to disk.
        // If you want to add conditions to the recipe, those can be set on the output.
        .save(this.output);

还可以分别调用 #group 和 #showNotification 设置配方书分组、切换弹出提示。

无序合成

与有序配方不同,无序配方不关心原料的摆放顺序。因此没有 pattern 和 key,只有原料列表:

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

同样逐行解释:

  • type:无序配方序列化器 ID,即 minecraft:crafting_shapeless。
  • category:可选字段,定义配方书中的分类。
  • ingredients:原料列表。代码会保留列表顺序以供配方展示使用,但配方本身接受任意顺序的原料。
  • result:配方结果,采用物品堆叠模板的 JSON 表示。
  • 示例中未展示 group 键。这个可选字符串属性用于在配方书中创建分组;同组配方会合并显示。

下面是在 RecipeProvider#buildRecipes 中生成该配方的方法:

// We use a builder pattern, therefore no variable is created. Create a new builder by calling
// ShapelessRecipeBuilder#shapeless with the recipe category (found in the RecipeCategory enum)
// and a result item, a result item and count, or a result item stack template.
ShapelessRecipeBuilder.shapeless(this.registries.lookupOrThrow(Registries.ITEM), RecipeCategory.MISC, Items.MUSHROOM_STEW)
        // Add the recipe ingredients. This can either accept Ingredients, TagKey<Item>s or ItemLikes.
        // Overloads also exist that additionally accept a count, adding the same ingredient multiple times.
        .requires(Blocks.BROWN_MUSHROOM)
        .requires(Blocks.RED_MUSHROOM)
        .requires(Items.BOWL)
        // Creates the recipe advancement. While not mandated by the consuming background systems,
        // the recipe builder will crash if you omit this. The first parameter is the advancement name,
        // and the second one is the condition. Normally, you want to use the has() shortcut for the condition.
        // Multiple advancement requirements can be added by calling #unlockedBy multiple times.
        .unlockedBy("has_mushroom_stew", this.has(Items.MUSHROOM_STEW))
        .unlockedBy("has_bowl", this.has(Items.BOWL))
        .unlockedBy("has_brown_mushroom", this.has(Blocks.BROWN_MUSHROOM))
        .unlockedBy("has_red_mushroom", this.has(Blocks.RED_MUSHROOM))
        // Stores the recipe in the passed RecipeOutput, to be written to disk.
        // If you want to add conditions to the recipe, those can be set on the output.
        .save(this.output);

还可以调用 #group 设置配方书分组。

说明 只有一种输入物品的配方(例如拆解储存方块)应使用无序配方,以遵循原版惯例。

物品浸染

浸染配方是一种特殊的单物品合成配方,会将材料堆叠的药水内容复制到结果堆叠。例如:

{
    "type": "minecraft:crafting_imbue",
    "category": "misc",
    "material": "minecraft:arrow",
    "result": {
        "count": 8,
        "id": "minecraft:tipped_arrow"
    },
    "source": "minecraft:lingering_potion"
}

同样逐行解释:

  • type:配方序列化器 ID,即 minecraft:crafting_imbue。
  • category:可选字段,定义配方书中的分类。
  • group:可选字符串属性,用于在配方书中创建分组。同组配方会合并显示,这通常适合转换配方。
  • source:包含要浸染的药水内容的原料。
  • material:用于浸染 source 的原料。
  • result:配方结果,采用物品堆叠模板的 JSON 表示。

下面是在 RecipeProvider#buildRecipes 中生成此配方的方法:

// We use a builder pattern, therefore no variable is created. Create a new builder by calling
// CustomCraftingRecipeBuilder#customCrafting with the recipe category (found in the RecipeCategory enum)
// and a factory function that takes in the `Recipe.CommonInfo` and `CraftingRecipe.CraftingBookInfo`
// to return the `Recipe` instance.
CustomCraftingRecipeBuilder.customCrafting(
    RecipeCategory.MISC,
    // The function used to construct the recipe instance.
    (commonInfo, bookInfo) -> new ImbueRecipe(
        commonInfo, bookInfo,
        // The source that contains the potion contents.
        Ingredient.of(Items.LINGERING_POTION),
        // The material used to imbue the source.
        Ingredient.of(Items.ARROW),
        // The resulting template with the potion contents.
        new ItemStackTemplate(Items.TIPPED_ARROW, 8)
    )
)
    // Creates the recipe advancement. While not mandated by the consuming background systems,
    // the recipe builder will crash if you omit this. The first parameter is the advancement name,
    // and the second one is the condition. Normally, you want to use the has() shortcut for the condition.
    // Multiple advancement requirements can be added by calling #unlockedBy multiple times.
    .unlockedBy("has_lingering_potion", this.has(Items.LINGERING_POTION))
    // Stores the recipe in the passed RecipeOutput, to be written to disk.
    // If you want to add conditions to the recipe, those can be set on the output.
    .save(this.output, "tipped_arrow");

还可以调用 #group 设置配方书分组。

转换合成

转换配方是一种特殊的单物品合成配方,会将输入堆叠的数据组件完整复制到结果堆叠。转换通常发生在两种不同物品之间,其中一种是另一种的染色版本。例如:

{
    "type": "minecraft:crafting_transmute",
    "category": "misc",
    "group": "shulker_box_dye",
    "input": "#minecraft:shulker_boxes",
    "material": "minecraft:blue_dye",
    "material_count": 1,
    "add_material_count_to_result": false,
    "result": {
        "id": "minecraft:blue_shulker_box"
    }
}

同样逐行解释:

  • type:配方序列化器 ID,即 minecraft:crafting_transmute。
  • category:可选字段,定义配方书中的分类。
  • group:可选字符串属性,用于在配方书中创建分组。同组配方会合并显示,这通常适合转换配方。
  • input:要转换的原料。
  • material:使输入堆叠转换为结果的原料。
  • material_count:将输入堆叠转换为结果所需的 material 数量。
  • result:配方结果,采用物品堆叠模板的 JSON 表示。
  • add_material_count_to_result:是否将所用材料数量加到结果物品数量上,常用于地图等物品的数据复制。

下面是在 RecipeProvider#buildRecipes 中生成此配方的方法:

// We use a builder pattern, therefore no variable is created. Create a new builder by calling
// TransmuteRecipeBuilder#transmute with the recipe category (found in the RecipeCategory enum),
// the ingredient input, the ingredient material, and the resulting item.
TransmuteRecipeBuilder.transmute(RecipeCategory.MISC, this.tag(ItemTags.SHULKER_BOXES),
    Ingredient.of(DyeItem.byColor(DyeColor.BLUE)), ShulkerBoxBlock.getBlockByColor(DyeColor.BLUE).asItem())
        // Sets the group of the recipe to display in the recipe book.
        .group("shulker_box_dye")
        // Sets the number of materials required to transmute the stack.
        .setMaterialCount(TransmuteRecipe.DEFAULT_MATERIAL_COUNT)
        // Creates the recipe advancement. While not mandated by the consuming background systems,
        // the recipe builder will crash if you omit this. The first parameter is the advancement name,
        // and the second one is the condition. Normally, you want to use the has() shortcut for the condition.
        // Multiple advancement requirements can be added by calling #unlockedBy multiple times.
        .unlockedBy("has_shulker_box", this.has(ItemTags.SHULKER_BOXES))
        // Stores the recipe in the passed RecipeOutput, to be written to disk.
        // If you want to add conditions to the recipe, those can be set on the output.
        .save(this.output);

还可以使用 #addMaterialCountToOutput,将所用材料数量加到结果数量上。

物品染色

染色配方是一种特殊的单物品合成配方,会将染料堆叠的 DataComponents#DYE 合并为一个 DataComponents#DYED_COLOR,并应用到目标堆叠以构造结果。与转换合成类似,目标堆叠的所有其他组件都会复制到结果堆叠。例如:

{
    "type": "minecraft:crafting_dye",
    "category": "misc",
    "dye": "#minecraft:dyes",
    "group": "dyed_armor",
    "result": {
        "id": "minecraft:leather_boots"
    },
    "target": "minecraft:leather_boots"
}

同样逐行解释:

  • type:配方序列化器 ID,即 minecraft:crafting_transmute。
  • category:可选字段,定义配方书中的分类。
  • group:可选字符串属性,用于在配方书中创建分组。同组配方会合并显示,这通常适合染色配方。
  • target:要应用染料的目标原料。
  • dye:用于染色的原料,都必须具有 DataComponents#DYE 数据组件。
  • result:配方结果,采用物品堆叠模板的 JSON 表示。

下面是在 RecipeProvider#buildRecipes 中生成此配方的方法:

// We use a builder pattern, therefore no variable is created. Create a new builder by calling
// CustomCraftingRecipeBuilder#customCrafting with the recipe category (found in the RecipeCategory enum)
// and a factory function that takes in the `Recipe.CommonInfo` and `CraftingRecipe.CraftingBookInfo`
// to return the `Recipe` instance.
CustomCraftingRecipeBuilder.customCrafting(
    RecipeCategory.MISC,
    // The function used to construct the recipe instance.
    (commonInfo, bookInfo) -> new DyeRecipe(
        commonInfo, bookInfo,
        // The target to apply the dyes to.
        Ingredient.of(Items.LEATHER_BOOTS),
        // The dyes that can be applied to the target.
        this.tag(ItemTags.DYES),
        // The resulting template with the applied dye color.
        new ItemStackTemplate(Items.LEATHER_BOOTS)
    )
)
    // Sets the group of the recipe to display in the recipe book.
    .group("dyed_armor")
    // Creates the recipe advancement. While not mandated by the consuming background systems,
    // the recipe builder will crash if you omit this. The first parameter is the advancement name,
    // and the second one is the condition. Normally, you want to use the has() shortcut for the condition.
    // Multiple advancement requirements can be added by calling #unlockedBy multiple times.
    .unlockedBy("has_leather_boots", this.has(Items.LEATHER_BOOTS))
    // Stores the recipe in the passed RecipeOutput, to be written to disk.
    // If you want to add conditions to the recipe, those can be set on the output.
    .save(this.output, "dyed_leather_boots");

特殊配方

还有许多合成配方专门用于某一种用途(例如复制书籍、制作烟花),而非通用转换。多数情况下,这是为了根据输入堆叠计算数据组件的值,再设置到输出上。这些配方仍然可以配置,通常接收输入原料和结果模板。例如:

{
    "type": "minecraft:crafting_special_firework_rocket",
    "fuel": "minecraft:gunpowder",
    "result": {
        "count": 3,
        "id": "minecraft:firework_rocket"
    },
    "shell": "minecraft:paper",
    "star": "minecraft:firework_star"
}

这个制作烟花火箭的配方指定用于创建结果的燃料、外壳和烟火之星原料。不过,它假定烟火之星原料具有 DataComponents#FIREWORK_EXPLOSION 组件,否则不会添加爆炸效果。

Minecraft 为多数特殊合成配方使用 crafting_special_ 前缀,但无需强制遵循。

在 RecipeProvider#buildRecipes 中生成此配方的方法如下:

// The parameter of #special is a Supplier<Recipe<?>>.
SpecialRecipeBuilder.special(
    () -> new FireworkRocketRecipe(
        Ingredient.of(Items.PAPER),
        Ingredient.of(Items.GUNPOWDER),
        Ingredient.of(Items.FIREWORK_STAR),
        new ItemStackTemplate(Items.FIREWORK_ROCKET, 3)
    )
)
    // This overload of #save allows us to specify a name. It can also be used on other recipe builders.
    .save(this.output, "firework_rocket");

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

  • minecraft:crafting_special_bannerduplicate:复制旗帜。
  • minecraft:crafting_special_bookcloning:复制成书,使结果书的 generation 属性增加一。
  • minecraft:crafting_special_firework_rocket:合成烟花火箭。
  • minecraft:crafting_special_firework_star:合成烟火之星。
  • minecraft:crafting_special_firework_star_fade:为烟火之星添加淡出颜色。
  • minecraft:crafting_special_mapextending:扩展已有内容的地图。
  • minecraft:crafting_special_repairitem:将两个损坏物品修复为一个。
  • minecraft:crafting_special_shielddecoration:将旗帜应用到盾牌上。
  • minecraft:crafting_decorated_pot:使用陶片合成饰纹陶罐。

熔炉类配方

第二类重要配方是通过熔炼或类似过程完成的配方。熔炉(类型 minecraft:smelting)、烟熏炉(minecraft:smoking)、高炉(minecraft:blasting)和营火(minecraft:campfire_cooking)使用相同格式:

{
    "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 表示。

这些配方在 RecipeProvider#buildRecipes 中的数据生成如下:

// Use #smoking for smoking recipes, #blasting for blasting recipes, and #campfireCooking for campfire recipes.
// All of these builders work the same otherwise.
SimpleCookingRecipeBuilder.smelting(
        // Our input ingredient.
        Ingredient.of(Items.KELP),
        // Our recipe category.
        RecipeCategory.FOOD,
        CookingBookCategory.FOOD
        // Our result item. May also be an ItemStackTemplate.
        Items.DRIED_KELP,
        // Our experience reward
        0.1f,
        // Our cooking time.
        200
)
        // The recipe advancement, like with the crafting recipes above.
        .unlockedBy("has_kelp", this.has(Blocks.KELP))
        // This overload of #save allows us to specify a name.
        .save(this.output, "dried_kelp_smelting");

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

切石

切石机配方使用 minecraft:stonecutting 配方类型。其结构很简单,只有类型、输入和输出:

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

type 定义配方序列化器(minecraft:stonecutting)。ingredient 是原料,result 是基本的物品堆叠模板 JSON。与合成配方一样,也可以指定可选的 group,用于配方书分组。

在 RecipeProvider#buildRecipes 中生成数据同样简单:

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

注意,单物品配方构建器不支持实际的 ItemStack 结果,因此也不支持带数据组件的结果。不过,配方 codec 支持这种结果;需要该功能时,必须实现自定义构建器。

锻造

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

转换锻造

此序列化器将两个输入物品转换成一个,保留第一个输入的数据组件。原版主要用于下界合金装备,不过这里可以使用任意物品:

{
    "type": "minecraft:smithing_transform",
    "addition": "#minecraft:netherite_tool_materials",
    "base": "minecraft:diamond_axe",
    "result": {
        "id": "minecraft:netherite_axe"
    },
    "template": "minecraft:netherite_upgrade_smithing_template"
}

逐行解释如下:

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

数据生成时,在 RecipeProvider#buildRecipes 中调用 SmithingTransformRecipeBuilder#smithing 添加配方:

SmithingTransformRecipeBuilder.smithing(
        // The template ingredient.
        Ingredient.of(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE),
        // The base ingredient.
        Ingredient.of(Items.DIAMOND_AXE),
        // The addition ingredient.
        this.tag(ItemTags.NETHERITE_TOOL_MATERIALS),
        // The recipe book category.
        RecipeCategory.TOOLS,
        // The result item. Note that while the recipe codec accepts an item stack template here, the builder does not.
        // If you need an item stack template output, you need to use your own builder.
        Items.NETHERITE_AXE
)
        // The recipe advancement, like with the other recipes above.
        .unlocks("has_netherite_ingot", this.has(ItemTags.NETHERITE_TOOL_MATERIALS))
        // This overload of #save allows us to specify a name.
        .save(this.output, "netherite_axe_smithing");

纹饰锻造

纹饰锻造是向盔甲应用盔甲纹饰的过程:

{
    "type": "minecraft:smithing_trim",
    "addition": "#minecraft:trim_materials",
    "base": "#minecraft:trimmable_armor",
    "pattern": "minecraft:spire",
    "template": "minecraft:bolt_armor_trim_smithing_template"
}

同样逐项解释:

  • type:配方序列化器 ID,即 minecraft:smithing_trim。

  • base:基础原料。原版所有用例均使用 minecraft:trimmable_armor 标签。

  • template:模板原料。原版所有用例均使用盔甲纹饰锻造模板。

  • addition:附加原料。原版所有用例均使用 minecraft:trim_materials 标签。

  • pattern:应用于基础原料的纹饰图案。

此序列化器没有结果字段,因为它使用基础输入,并将模板和附加物品“应用”其上:根据其他输入设置基础物品的组件,再将操作结果作为配方结果。

数据生成时,在 RecipeProvider#buildRecipes 中调用 SmithingTrimRecipeBuilder#smithingTrim 添加配方:

SmithingTrimRecipeBuilder.smithingTrim(
        // The template ingredient.
        Ingredient.of(Items.BOLT_ARMOR_TRIM_SMITHING_TEMPLATE),
        // The base ingredient.
        this.tag(ItemTags.TRIMMABLE_ARMOR),
        // The addition ingredient.
        this.tag(ItemTags.TRIM_MATERIALS),
        // The trim pattern to apply to the base.
        this.registries.lookupOrThrow(Registries.TRIM_PATTERN).getOrThrow(TrimPatterns.SPIRE),
        // The recipe book category.
        RecipeCategory.MISC
)
        // The recipe advancement, like with the other recipes above.
        .unlocks("has_smithing_trim_template", this.has(Items.BOLT_ARMOR_TRIM_SMITHING_TEMPLATE))
        // This overload of #save allows us to specify a name. Yes, this name is copied from vanilla.
        .save(this.output, "bolt_armor_trim_smithing_template_smithing_trim");

来源: NeoForged/Documentation(26.1)。中文翻译依据提交 4a680cdd4d15。