Datapacks
Server data lives under two different places in config/pkl4mc/. Both places get injected as a virtual datapack on world load and reload with /pkl reload or just /reload. Both support every schema and behavior identically.
- shaped.pkl
config/pkl4mc/data
In this place you can drop in loose .pkl files in the KubeJS style. Like in kube you don’t need a pack.mcmeta or zip. The path is the resource location already.
- <name>.pkl
- shaped.pkl
config/pkl4mc/datapacks
This location has the same structure as the vanilla world/datapacks/, which you can use for self contained or shareable packs in .zip format. You can also create a folder pack instead of a .zip.
- shaped.pkl
- pack.mcmeta
Multi output
When we use recipes as a example, they can output multiple .json files by its name field. One .pkl file is enough for serving multiple recipe files.
// config/pkl4mc/data/minecraft/recipes/blasting.pkl
amends "@pkl4mc/recipes.pkl"
blasting {
new {
// The name decidies the json output name:
// minecraft/recipes/iron_block_from_blasting.json
name = "iron_block_from_blasting"
input { item = "minecraft:raw_iron_block" }
output { item = "minecraft:iron_block" }
experience = 6.3
cookingTime = 800
}
new {
// minecraft/recipes/gold_block_from_blasting.json
name = "gold_block_from_blasting"
input { item = "minecraft:raw_gold_block" }
output { item = "minecraft:gold_block" }
experience = 6.3
cookingTime = 800
}
new {
// minecraft/recipes/copper_block_from_blasting.json
name = "copper_block_from_blasting"
input { item = "minecraft:raw_copper_block" }
output { item = "minecraft:copper_block" }
experience = 6.3
cookingTime = 800
}
}Serving nothing
A file can also generate nothing at all. If every when condition inside it evals to false pkl4mc just serves no json and does not error. In this example the blasting recipe only loads, when Tinkers’ Construct is loaded.
// config/pkl4mc/data/tconstruct/recipes/blasting.pkl
amends "@pkl4mc/recipes.pkl"
local loadedMods = read("prop:pkl4mc.loadedMods").split(",")
local hasTinkersConstruct = loadedMods.contains("tconstruct")
blasting {
when (hasTinkersConstruct) {
new {
// tconstruct/recipes/cobalt_block_from_blasting.json
name = "cobalt_block_from_blasting"
input { item = "tconstruct:raw_cobalt_block" }
output { item = "tconstruct:cobalt_block" }
experience = 6.3
cookingTime = 800
}
}
}When an entry is still there but has an empty output for some reason, the cobalt_block_from_blasting.json would get served, just without a item in result. That recipe would be get rejected on datapack load by Minecraft.
This case will get improved probably in the future.
// config/pkl4mc/data/tconstruct/recipes/blasting.pkl
amends "@pkl4mc/recipes.pkl"
blasting {
new {
// tconstruct/recipes/cobalt_block_from_blasting.json
name = "cobalt_block_from_blasting"
input { item = "tconstruct:raw_cobalt_block" }
output {}
experience = 6.3
cookingTime = 800
}
}Special folders
data/<namespace>/recipe_removals/can include custom.pklfiles for recipe removals in different ways. These will apply at recipe load instead of served as datapack content.config/pkl4mc/assets/serves client resources, such as EMI customizations. Client assets reload with F3+T and not with/pkl reload.