Skip to content

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 .pkl files 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.