Examples
A first recipe, then the PKL language features you actually need. Full language docs live in the PKL language reference.
Your first recipe
Create config/pkl4mc/data/mypack/recipes/stick_frenzy.pkl:
amends "@pkl4mc/recipes.pkl"
shaped {
new {
name = "stick_frenzy"
category = "misc"
key {
["S"] { item = "minecraft:stick" }
}
pattern { "S S"; " S "; "S S" }
output { item = "minecraft:stick"; count = 4 }
}
}Run /pkl reload in-game (op required). Craft 5 sticks into 4. Your recipe is live.
Now break it on purpose: change pattern to patern, reload, and run /pkl errors. You get the file, line, column, and error message. With IDE setup done, the same error shows as a red squiggle before you ever launch the game.
Amending a schema
amends means “this file fills in the fields of that schema”:
amends "@pkl4mc/recipes.pkl"The schema defines fields, types, and JSON rendering. You set values. The schema catalog lists everything you can amend.
Objects and collections
// object: braces, fields separated by newlines or ;
output { item = "minecraft:stick"; count = 4 }
// listing: elements one per line
pattern {
"S S"
" S "
"S S"
}
// listing of objects: each element wrapped in new { }
shaped {
new { name = "recipe_one" /* ... */ }
new { name = "recipe_two" /* ... */ }
}
// mapping: string keys in brackets
key {
["S"] { item = "minecraft:stick" }
}Variables and reuse
local declares a file-private value. Define once, use everywhere:
amends "@pkl4mc/recipes.pkl"
local steel = "gtceu:steel_ingot"
smelting {
new {
name = "steel_from_iron"
input { item = "minecraft:iron_ingot" }
output { item = steel }
experience = 0.7
cookingTime = 200
}
}String interpolation uses \(expr):
local mod = "mypack"
name = "\(mod)_steel_recipe"Mod conditions
The loaded Forge mod list is available to every file. Branch on mod presence:
local loadedMods = read("prop:pkl4mc.loadedMods").split(",")
local hasProjectE = loadedMods.contains("projecte")
shapeless {
new {
name = "conditional_example"
inputs {
new { item = if (hasProjectE) "minecraft:diamond" else "minecraft:coal" }
}
output { item = "minecraft:emerald" }
}
}when inserts elements conditionally inside collections:
inputs {
new { item = "minecraft:coal" }
when (hasProjectE) {
new { item = "minecraft:diamond" }
}
}Types catch your typos
Schema fields are typed. A misspelled field or count = "four" is an evaluation error and a red squiggle in your editor, not a silent in-game failure. After running the dump command, item id strings validate against your modpack’s real registries too.
Raw modules
Modules written from scratch, without amending a schema, must declare JSON output themselves:
output { renderer = new JsonRenderer {} }Schemas declare this for you. Mods without a dedicated schema are covered by the generic recipes schema.