Crafting Recipe Configuration

Define crafting recipes that turn ingredients into a result item — a server-only config.

Crafting recipes turn a set of ingredients into a result item. They’re server-only config — the client never reads this file, it just receives the resolved recipe list from the server over the network.


File Location

Register the file in your mod’s manifest (mods/<YourMod>/<YourMod>.yaml):

crafting-config: crafting-config.yaml

Then create the file it points to, relative to your mod’s folder:

mods/<YourMod>/crafting-config.yaml

A large mod can split its recipes across several files by giving crafting-config a list instead of a single path:

crafting-config:
  - crafting/tools.yaml
  - crafting/smelting.yaml

The files load in the order listed, and that order sets precedence: a later file’s recipe with the same id overrides an earlier one, and remove-recipes applies to everything loaded before it — the same way ordering works within a single file.

The file is a single list of recipes:

recipes:
  - crafting-station:
      type: crafting
    result:
      item: my_item
      amount: 1
    ingredients:
      - item: dirt
        amount: 1

Minimal Example

recipes:
  - crafting-station:
      type: crafting
    result:
      item: oak_planks
      amount: 4
    ingredients:
      - item: oak_log
        amount: 1

Fields

FieldDefaultDescription
crafting-station.type(required)The crafting category this recipe belongs to — an open, case-insensitive tag. Crafting is the built-in baseline (craftable by hand, no station); Smelting is used by the base game’s furnace. Any other tag (e.g. Anvil, Loom) is valid too, as long as a station provides it — see Custom station types.
crafting-station.tier(base tier)The named tier a crafting station must provide for this recipe to be craftable there — one of the names declared for this type in a crafting-types block. Omit it to require the type’s base (first) tier. A station satisfies the recipe when its own tier is at least as high, by list position.
name(none)Optional stable identifier for the recipe, enabling override and removal — see Overriding and removing recipes. Anonymous recipes (no name) are additive-only.
result(required)The item produced — see Result and Ingredients.
ingredients(required)A list of required inputs — see Result and Ingredients.

Every amount defaults to 1, and crafting-station.tier defaults to the type’s base tier, so you can omit them when that’s what you want.


Crafting types and tiers

Each crafting type declares an ordered list of named tiers in a top-level crafting-types block. A recipe or station names a tier; a recipe is craftable when an in-range station of the same type provides a tier at least as high by list position. The names are the ordering — there is no separate number to guess, and the craft menu can tell the player exactly which station a recipe needs (“Needs: bench”).

crafting-types:
  - type: crafting
    tiers: [hand, bench]   # index 0 = hand (no station), 1 = bench
  - type: smelting
    tiers: [furnace]       # index 0 = furnace

recipes:
  - crafting-station: { type: crafting, tier: bench }   # needs a bench-tier station
    result: { item: iron_pickaxe, amount: 1 }
    ingredients: [ { item: iron_bar, amount: 3 } ]
  • The first tier of the Crafting type is the hand-crafting baseline — always available with no station. The first tier of any other type still requires a station providing it.
  • A type may be declared once across all mods (a redefinition is ignored with a warning), so a later mod can’t silently reorder — and thus rebalance — another’s tiers. Mods add their own new types freely.
  • Tier names are matched case-insensitively; a recipe or station naming a tier that isn’t declared for its type is dropped with a warning.

Result and Ingredients

result is a single entry or a list of them (see Multiple results); ingredients is always a list. Each entry is one of these shapes:

By item name

- item: wooden_stick
  amount: 2

item is mod-prefixed automatically if you don’t include a colon yourself. amount defaults to 1. This is the same item: key that loot-table-config.yaml and block/mob drop tables use to reference an item.

By item name (shorthand)

When the amount is 1, an entry can be written as a plain string instead of a map — for both ingredients and result:

result: grass
ingredients:
  - dirt
  - coal

This is exactly equivalent to { item: dirt, amount: 1 }. For any amount above 1, use the map form.

By material type

- material-types: PLANKS
  amount: 3

Matches any item carrying the given tag in its material-types (set in item-config.yaml) — useful for recipes that should accept several interchangeable items (any plank, any log, etc.) instead of one specific item. The match is case-insensitive. amount defaults to 1. This shape can’t be used for result, only for ingredients.

A list accepts any of several tags. Write a list to satisfy the ingredient with whichever tag the player happens to have:

- material-types: [PLANKS, LOG]
  amount: 3

Both sides are tag sets, so the match is an intersection: the ingredient is satisfied when the item carries any one of the listed tags. Before the list form existed, accepting either of two tags meant inventing a third shared tag and re-tagging every item that should qualify.

Multiple results (byproducts)

result can be a list instead of a single entry, so one craft yields several outputs (a bar plus slag, an ore that splits into multiple items). Each entry uses the same shapes as a single result (by item name, shorthand, or override):

result:
  - { item: iron_bar, amount: 1 }
  - { item: slag, amount: 2 }

The first entry is the primary result — it’s the recipe’s icon in the craft menu. Placement is all-or-nothing: if the inventory can’t hold every output, the craft fails and nothing is consumed or produced (no items are dropped on the ground or lost). A single-entry result (map, shorthand string, or override) still works exactly as before.

Catalysts (consumed: false)

An ingredient can be marked consumed: false to make it a catalyst: it must be present in the crafting inventory in the required amount, but the craft does not use it up — a mold, a blueprint, a required tool. It defaults to true (consumed), so leaving it off keeps the normal behavior.

ingredients:
  - { item: casting_mold, amount: 1, consumed: false }   # required, kept
  - { item: iron_ingot, amount: 4 }                       # consumed as usual
  - material-types: [PLANKS, LOG]
    amount: 2
    consumed: false                                       # any plank/log, kept

consumed is only accepted on the map forms{ item: …, consumed: false } and the material-types form. The bare-string shorthand can’t carry it (it’s always consumed), and it’s meaningless on result. A catalyst still counts toward affordability: the recipe won’t craft unless the catalyst is present in the required amount, it just isn’t spent when it does.

Advanced: overriding item properties

An entry can optionally override that item’s own catalog properties, using the same fields documented in item-config.md. This advanced form is a full inline item definition, so it identifies the item with the item catalog’s own name field (not item):

Two different names, at two different levels. A name directly on a recipe is the recipe’s own identifier (used for override and removal). A name inside an ingredients: or result: entry names the item, and only in this full inline form — the ordinary shorthand for an item is item:. They never appear at the same level, so there’s no ambiguity in practice, but they are unrelated fields.

- name: wooden_short_sword
  amount: 1
  max-stack-size: 1
  tool-types: [shears]
  interact-range: 5
  type-override: weapon
  weapon-info:
    type: melee
    class-name: Short Sword
    damage: 999.0

type-override (plus a matching *-info block sitting directly alongside it) replaces the item’s behavior entirely for this specific recipe result/ingredient — a rarely-needed escape hatch for a one-off variant. Everything else on this entry still falls back to the item’s normal catalog values if omitted. Use the plain item: form above for the common case; reach for name: + overrides only when you need a one-off variant.

The keys this form accepts are exactly name, amount, max-stack-size, tool-types, interact-range, type-override, damage (for type-override: empty), and one *-info block. Anything else — including a misspelling of one of those — fails the recipe at load, the same as any other unknown field. The same rule and the same key set apply wherever this form appears: a drop table entry’s item: block and a loot table entry’s item: block are the identical shape.

tool-types here takes a single value or a list, matching the item catalog entry it overrides. Note that name: is what marks an entry as this full form; an entry without it is read as the item: shorthand.


Fuel (fuel:)

A recipe can require fuel — a consumed resource separate from its ingredients (furnace smelting is the usual case). Add an optional fuel block:

  - name: iron_bar
    crafting-station: { type: smelting, tier: furnace }
    result: { item: iron_bar, amount: 1 }
    ingredients:
      - { item: raw_iron, amount: 1 }
    fuel:
      type: coal      # the fuel grade required (an item's `fuel-types` tag)
      amount: 8       # total fuel value this craft costs

At craft time the server gathers every item carrying the type grade in its fuel-types and consumes the minimum whole items whose summed fuel-value covers amount (highest-value items first). Smelting is still instant — fuel is a cost, not a timer, and there is no burn-pool: any leftover fuel value on the last item consumed is lost. If the player doesn’t have enough fuel of the right grade, the craft fails (nothing is consumed). Both type and amount are required inside the block, and amount must be above 0.

For example, with coal at fuel-value: 8 and the recipe above (amount: 8), one coal smelts one bar. A recipe costing amount: 4 would still consume a whole coal (value 8), wasting 4 — size your fuel values and costs together.


Overriding and removing recipes

By default recipes are additive — loading another mod’s crafting config adds its recipes alongside yours. To let a recipe be changed or deleted later (by your own mod or by a mod that loads after yours), give it a name:

recipes:
  - name: iron_pickaxe        # becomes YourMod:iron_pickaxe
    crafting-station:
      type: crafting
      tier: bench
    result: Creation:iron_pickaxe
    ingredients:
      - item: Creation:iron_bar
        amount: 3
      - item: Creation:wooden_stick
        amount: 2

A name is mod-prefixed just like an item name, so a bare iron_pickaxe becomes YourMod:iron_pickaxe; use an explicit Mod:name to reference a recipe from a different mod.

Override — define a recipe with a name that already exists (from an earlier-loaded mod, or earlier in the same file). The later definition wins, keeping the original’s slot and identity. This is how you rebalance a base-game recipe:

recipes:
  # Make iron pickaxes cheaper than Creation's default.
  - name: Creation:iron_pickaxe
    crafting-station:
      type: crafting
      tier: bench
    result: Creation:iron_pickaxe
    ingredients:
      - item: Creation:iron_bar
        amount: 2

Remove — list ids under a top-level remove-recipes key to delete them outright, no replacement:

remove-recipes:
  - Creation:iron_pickaxe

recipes:
  - ...

Removals are applied before this file’s own recipes are added, so a mod can clear out recipes it doesn’t want and then define its own. Only recipes that declared a name can be overridden or removed — anonymous recipes have no handle to reference.

Every recipe Creation ships is named after the item it producesCreation:oak_planks, Creation:iron_pickaxe, and so on — so any of them can be overridden or removed by name. The two that produce a bulk debug stack are suffixed _bulk (Creation:torch_bulk, Creation:grass_bulk), since a name has to be unique: define a second recipe with an existing name and it replaces the first rather than adding to it. Name your own recipes for the same reason — an anonymous recipe can never be patched by anyone, including you.


Custom station types

crafting-station.type is an open registry, so a mod can invent its own crafting categories rather than being limited to Crafting/Smelting. A recipe tagged with a custom type only becomes craftable when the player is near an interactable whose crafting-station provides that same type:

# In crafting-config.yaml
recipes:
  - crafting-station:
      type: anvil
      tier: forged
    result: reinforced_plate
    ingredients:
      - item: iron_bar
        amount: 4
# In the station's interactable-config, so an ANVIL block grants the Anvil type at power 2
crafting-station:
  type: anvil
  tier: forged

Type matching is case-insensitive. The Crafting type is special only in that it needs no station (baseline hand-crafting); every other type — including Smelting — requires a station in range that provides it. See interactable-config.md for the crafting-station block.

The craft menu aggregates every station in range

Opening the craft menu shows the union of every recipe provided by all crafting stations within range of the player at once, not just one station’s list. Standing where a workbench and a furnace overlap gives you both Crafting and Smelting recipes in a single menu; hand-crafting (Crafting base tier) is always present. For each type, the highest tier among the in-range stations of that type applies, so a recipe is craftable when any nearby station of its type provides a high-enough tier, and recipes needing a tier no nearby station reaches are shown greyed with the tier they need. The list updates live as you move — walk away from a station and its recipes drop out; step back and they return.


Validation

Recipes are checked as they load. A recipe that fails a hard check is skipped (with a warning naming the recipe by its name or result), and the rest of the file still loads:

  • Empty or missing ingredients — a recipe must consume at least one item; one that produces its result from nothing is rejected.

  • An amount of 0 on any ingredient or on the result — rejected (usually a forgotten or mistyped amount).

  • material-types used for a result — rejected, since a tag matches many items and can’t name one output.

  • An empty material-types list — rejected, since it could never match anything.

The key is material-types, plural, on both sides. The item declares the tags it carries and the ingredient declares the tags it accepts, using the same key name. This used to be a singular material-type on the ingredient side; see Schema Conventions → Tag pairs.

  • Unknown item names on an ingredient or result — rejected, with the offending name in the message.

Some things load but emit a warning to look at:

  • A recipe whose result is the same item it consumes (e.g. DIRT → DIRT) — almost always a mistake or a duplication exploit.
  • A remove-recipes entry naming an id that doesn’t exist (already removed, undeclared, or misspelled).

Complete Example

recipes:
  # Simple recipe, by-name ingredient
  - name: oak_planks
    crafting-station:
      type: crafting
    result:
      item: oak_planks
      amount: 4
    ingredients:
      - item: oak_log
        amount: 1

  # Material-type ingredient — any PLANKS-tagged item works
  - name: wooden_stick
    crafting-station:
      type: crafting
    result:
      item: wooden_stick
      amount: 4
    ingredients:
      - material-types: PLANKS
        amount: 2

  # Mixed ingredients, higher power requirement
  - name: stone_pickaxe
    crafting-station:
      type: crafting
      tier: bench
    result:
      item: stone_pickaxe
      amount: 1
    ingredients:
      - item: stone
        amount: 3
      - item: wooden_stick
        amount: 2

  # Smelting recipe
  - name: iron_bar
    crafting-station:
      type: smelting
      tier: furnace
    result:
      item: iron_bar
      amount: 1
    ingredients:
      - item: raw_iron
        amount: 1
      - item: coal
        amount: 1

Last updated