Skip to main content
A recipe turns ingredients (consumed from the bag) into an output item. forge-crafting orchestrates the job; the items come from forge-items and live in forge-inventory.

Register a definition

local fc = exports["forge-crafting"]

fc:RegisterRecipe({
  id          = "recipe:health_tonic",
  label       = "Health Tonic",
  ingredients = {
    { item = "item:kingsfoil", count = 2, consume = true },
    { item = "item:water",     count = 1, consume = true },
  },
  output       = { item = "item:health_tonic", qty = 1 },
  craftTimeSec = 3,
  xp           = { amount = 5 },        -- optional: GainXP on completion
  requires     = { unlock = false },    -- common knowledge: craftable without learning
})

Fields

FieldNotes
idRequired. recipe:<name>.
ingredientsList of { item, count, consume? }. Consumed at completion.
outputEither { item, qty } or { table } (a loot table for variable output).
stationOptional station id; omit for handcraft-anywhere.
craftTimeSecJob duration.
xpOptional { amount } granted via forge-progression on completion.
requiresOptional gating: unlock, level.min, identity, equippedTag.

Knowledge: who can craft it

By default a character must learn a recipe before crafting it:
exports["forge-crafting"]:LearnRecipe(characterId, "recipe:health_tonic", "trainer")
Set requires = { unlock = false } to make a recipe common knowledge, anyone can craft it with no learning step. (The shipped recipe:bandage uses this so a fresh character can craft immediately.)

Craft it

exports["forge-crafting"]:CraftRequest(characterId, "recipe:health_tonic", 1)
The job validates ingredients, runs for craftTimeSec, and consumes ingredients at completion, so cancelling, disconnecting, or walking away mid-craft is lossless (no ingredients lost, no output minted). On success the output is added to the bag (overflow spills to a world drop) and any xp is granted.
To ship your own neutral default recipe, add it to forge-crafting’s shared/data/recipes.lua with ShipDefaults = true.

Back to the packages