Skip to content

Datapacks

Warlon Mhite edited this page Nov 8, 2026 · 3 revisions

Home › Servers & modpacks › Datapacks

Every shape of data Hempdustry 2 reads from a datapack, field by field: strains, the smoking devices, the edibles, the green-out, the recipe types, a loot entry, a worldgen filter, two advancement triggers and the item components you can match. For datapack authors and pack makers. A step-by-step walk-through of adding a strain is on Custom Strains; the tags are on Tags.

On this page: Before you start · Strains · Devices · Edibles · Green-outs · Recipe types · Loot tables · World generation · Advancement triggers · Data components · NeoForge-only data · Differences on Minecraft 26.2 and 26.3 · Differences on Minecraft 1.21.1 · Minecraft 1.16.5 and 1.18.2

Before you start

The mod's own files are the best reference. Every file this page describes ships inside the mod's jar under data/hempdustry/. Copy one into your datapack at the same path, change the numbers, and you have an override. All the examples below are copied from those files.

Where a datapack goes: a folder (or zip) in <world>/datapacks/ with a pack.mcmeta beside its data/ folder. On a dedicated server that is world/datapacks/. The pack.mcmeta for each Minecraft version is on Custom Strains.

Two kinds of folder

Vanilla's own data types live directly under your namespace: data/<namespace>/recipe/, loot_table/, tags/, advancement/, worldgen/. The four registries Hempdustry adds live one level deeper, under a hempdustry/ folder, because Minecraft files a registry that is not its own under the registry's namespace:

Registry Folder Which files are read
hempdustry:strain data/<namespace>/hempdustry/strain/<id>.json every file, in any namespace: each is a strain
hempdustry:device data/hempdustry/hempdustry/device/<id>.json only the four ids below, in the hempdustry namespace
hempdustry:edible data/hempdustry/hempdustry/edible/default.json only this one
hempdustry:green_out data/hempdustry/hempdustry/green_out/default.json only this one

So the mod's own Purple Kush is data/hempdustry/hempdustry/strain/indica.json — hempdustry twice, and that is correct — and a strain of yours is data/yourpack/hempdustry/strain/whatever.json.

When a change takes effect

What Re-read by /reload?
Strains, devices, edibles, green-out No. They are read once, when the world opens. Restart the server, or leave a single-player world and open it again. (Minecraft 1.16.5 and 1.18.2 re-read them: below.)
Worldgen (placed and configured features, biome tags for generation) No — restart, and only chunks generated afterwards change
Recipes, loot tables, advancements, item and block tags Yes

When something is wrong

  • A malformed file stops the world loading, as any broken datapack entry does: a missing required field, a value out of range, an item or effect id that does not exist. The server's logs/latest.log says Registry loading errors:, then the registry (> Errors in registry hempdustry:strain:), the entry (>> Errors in element yourpack:whatever:) and what was wrong with it.
  • A file in the wrong place is silently ignored. A strain at data/yourpack/strain/ (no hempdustry/ folder) is never read, and nothing is logged; neither is a device file outside the hempdustry namespace. If a change seems to do nothing, check the path first.
  • A missing device, edible or green-out file (for instance, if the mod's own data pack has been switched off) falls back to the numbers the mod shipped, with one warning in the log.

Who needs the datapack

Only the server. Strains, devices, edibles and green-outs are sent to every player who joins, so players install nothing extra. Everything on this page works the same on Fabric and NeoForge; the last sections list what is different on Minecraft 26.2 and 26.3, 1.21.1, and 1.16.5 and 1.18.2.

The server config has the last word

The settings in config/hempdustry.json apply on top of whatever a datapack asks for: duration, cooldown, green-out and onset multipliers, the level caps (maxLevel, maxBuffLevel) and the switches for effects, debuffs, Hunger, Nausea and green-outs. See Configuration. What neither layer reaches: a device's durability and enchantability, which are part of the item.

Strains

seeds and flower optional, and seven new optional fields: new in 2.1.

A strain is anything that packs into a spliff, pipe, bong or vaporizer: its name, its colour, and what one hit does. The three plants are strains, and so are hashish, charas, filtered hashish, rosin, scorched hemp and schwag — strains with no seeds and no wild plant. A datapack can rebalance any of them by overriding its file, or add new ones that reuse existing items.

Path: data/<namespace>/hempdustry/strain/<id>.json. The strain's id is <namespace>:<id>.

Fields

Field Type Required? Default Meaning
translation_key string yes — Lang key of the name shown on loaded items ("%s Pipe", "%s Spliff"…). A datapack cannot add lang lines, so a key no lang file has shows raw; reuse an existing one (an item's own name key works) or ship the line in a resource pack.
color integer yes — The tint of the load on every pipe, bong, vaporizer and moon rock, and on the shared spliff art, as a plain number: 0xRRGGBB written in decimal (0xB57BFF is 11893759). Tinting multiplies, so the colour is the brightest the load can look.
buds item id yes — The item that packs. One of it in a packing recipe is dose_per_item worth of dose.
seeds item id no none The seed that plants this strain. Any strain with seeds has them added to the hemp-seed pools in grass and chests, and listed in the creative tab.
flower block id no none Its wild plant. Having a flower is what makes a strain "a plant" (see below).
model_index integer no 0 Which bespoke spliff art it wears. 0 = none of its own: the shared art, tinted with color. 1–99 are reserved for the mod; see model_index.
dose_per_item integer no 1 How much dose one buds item is worth. Rosin is 3: one piece is a whole bowl.
green_out_factor number no 1.0 Widens the green-out odds: 2.0 halves the risk; 0 or below means this strain never greens you out.
cough_factor number no 1.0 Widens the cough odds the same way: 2.0 halves them, 0.5 doubles them; 0 or below, never. The cough is only a sound.
effects list of effects no empty What one hit does, below. An empty list is allowed: the hit does nothing.

Each effect:

Field Type Required? Default Meaning
effect effect id yes — Any status effect, e.g. minecraft:speed.
base_amplifier integer no 0 The amplifier at dose 1 (0 is level I).
scales boolean no true Whether dose raises it: one level per item of dose after the first. false keeps it at base_amplifier.
duration_factor number no 1.0 Its share of the device's duration. 0.25 lasts a quarter as long. Never less than one tick.
on_exhale boolean no false Lands with the exhale, 38 ticks (about 2 s) after the hit, instead of on the hit.
chance number, 0–1 no 1.0 The odds it lands at all, rolled on every hit.
max_amplifier integer, 0–255 no 255 The highest amplifier dose may push it to.

So the shortest useful effect is {"effect": "minecraft:speed"}: level I, rising with dose, for the device's whole duration, on every hit.

How the numbers combine

  • Level: base_amplifier + (dose − 1) for an effect that scales, capped at max_amplifier; then the server's caps — helpful effects stop at maxBuffLevel (level II by default), everything at maxLevel. Dose counts per strain: in a load of two buds and one hash, each applies its own effects at its own count.
  • Length: the device's duration_ticks × duration_factor × the config's durationMultiplier. Each item of dose past the buff cap adds half the device's duration (the buffs have stopped rising; the costs have not), so a bong of three lasts half as long again.
  • A bud paired with a concentrate goes one level past the cap. A "concentrate" here is any strain with no flower and at least one helpful effect — so a resin strain you add counts too.
  • Green-out odds for a hit: the green-out file's odds for the dose, widened by the device's green_out_factor and by the load's main strain's green_out_factor (the entry with the largest count; a tie goes to the plant). Cough odds: the device's cough_one_in widened by the main strain's cough_factor.

What flower decides

A strain with a flower is a plant; one without is resin (or something stranger). The mod keys several things on it:

With flower Without
Creative tab its buds and flower join the plant run its buds appear only where that item already does
Spliff in the creative tab listed not listed (a joint needs something to burn)
Paired with a concentrate in one load gets the extra level counts as the concentrate, if it has a helpful effect
Vaporizer bowl finished hands back Scorched Hemp hands back nothing

Packing into a pipe, bong or vaporizer works for every strain: the packing recipe looks the item up in the strain registry. Spliffs, hash spliffs and moon rocks are crafting recipes per strain; the mod ships them for its own strains, and a datapack can add more (below).

model_index

Only the Spliff has per-strain art; every pipe, bong, vaporizer and moon rock is the shared art tinted with color. The spliff's look is chosen by the strain's model_index: the mod's art sits at 1 (Purple Kush), 2 (Lemon Haze) and 7 (Beldía), and every other index wears the shared tinted spliff. So:

  • 0 — use this for any strain you add. The shared tinted spliff.
  • 1–99 are reserved for the mod. A strain from another namespace in that range gets a warning in the log; at 1, 2 or 7 it wears that shipped strain's spliff, anywhere else the tinted one.
  • 100 and up are for a mod or resource pack that ships art. Without an entry of its own in assets/hempdustry/items/spliff.json, a strain at 100 wears the tinted spliff. See Resource Packs. Two strains with the same non-zero index get a warning too.

The shipped strains

Strain id Name File model_index seeds / flower
hempdustry:indica Purple Kush indica.json 1 yes
hempdustry:sativa Lemon Haze sativa.json 2 yes
hempdustry:hashish Hashish hashish.json 3 —
hempdustry:charas Charas charas.json 4 —
hempdustry:filtered_hashish Filtered Hashish filtered_hashish.json 5 —
hempdustry:rosin Rosin rosin.json 6 —
hempdustry:beldia Beldía beldia.json 7 yes (its wild plant is its own crop)
hempdustry:scorched_hemp Scorched Hemp scorched_hemp.json 0 —
hempdustry:schwag Schwag schwag.json 0 —

All are in data/hempdustry/hempdustry/strain/. The effects of each are on Strains and Smoking.

Example — Purple Kush, data/hempdustry/hempdustry/strain/indica.json:

{
  "buds": "hempdustry:indica_buds",
  "color": 11893759,
  "effects": [
    {
      "effect": "minecraft:resistance"
    },
    {
      "effect": "minecraft:hunger"
    },
    {
      "effect": "minecraft:mining_fatigue"
    }
  ],
  "flower": "hempdustry:indica_flower",
  "model_index": 1,
  "seeds": "hempdustry:indica_seeds",
  "translation_key": "hempdustry.strain.indica"
}

Example — Beldía, with a flat effect, an effect on the exhale for a quarter of the time, and a harsher smoke:

{
  "buds": "hempdustry:beldia_buds",
  "color": 14264654,
  "cough_factor": 0.5,
  "effects": [
    {
      "effect": "minecraft:invisibility",
      "scales": false
    },
    {
      "duration_factor": 0.25,
      "effect": "minecraft:blindness",
      "on_exhale": true,
      "scales": false
    },
    {
      "effect": "minecraft:hunger"
    }
  ],
  "flower": "hempdustry:beldia_crop",
  "model_index": 7,
  "seeds": "hempdustry:beldia_seeds",
  "translation_key": "hempdustry.strain.beldia"
}

Rosin's file adds "dose_per_item": 3 and "green_out_factor": 2.0 to the same shape.

Caveats

  • Overriding a shipped strain replaces the whole file. Copy it complete and change what you want; leave out seeds and flower and Purple Kush stops being a plant.
  • Give each strain its own buds item. Two strains may name the same item (the creative tab copes), but packing it always gives the same one of them: the mod's own strain if one is, otherwise the one with the lowest id (namespace first, then path). The other never comes out of a packing grid.
  • seeds puts those seeds into the loot. Every strain's seeds share the hemp-seed roll in grass and chests at equal weight, so a strain naming another strain's seeds doubles that seed's share, and one naming minecraft:wheat_seeds puts wheat seeds into it.
  • Avoid a shipped strain's path in your own namespace (yourpack:indica): recipe viewers build their packing pages from the path.
  • Removing a strain is safe for items. A spliff, pipe or bong loaded with a strain the world no longer has keeps its other contents, or comes back empty (a spliff becomes an inert one), with a warning in the log; nothing is deleted.
  • A datapack cannot add items, blocks, crops, textures or lang lines. What it can do with what exists is on Custom Strains.

Devices

New in 2.1.

How each smokeable smokes: one file per device. Path: data/hempdustry/hempdustry/device/<id>.json, where <id> is wooden_pipe, bong (every bong, all eighteen glasses), vaporizer or spliff. Only these four, only in the hempdustry namespace — override a file by writing your own at the same path.

Field Type Required? Meaning
duration_ticks integer, ≥ 1 yes How long a hit's effects last, before each effect's duration_factor (20 ticks = 1 s).
cooldown_ticks integer, ≥ 0 yes The cooldown after a hit, on every smokeable at once.
cough_one_in integer, ≥ 0 yes The odds of a cough per hit, 1 in N; 0 never. Widened by the strain's cough_factor.
nausea_one_in integer, ≥ 0 yes The odds of a short Nausea (7 s) per hit, 1 in N; 0 never. Not rolled on a hit that greens out.
green_out_factor number yes Widens the green-out odds: 2.0 halves them; 0 or below rules a green-out out.
bowl object no Pipe, bong and vaporizer only. Left out, the device keeps its built-in bowl. The spliff's is never read: how big a spliff rolls is its crafting recipes.
bowl.hits integer, ≥ 1 yes, in a bowl Hits one packing gives.
bowl.max_dose integer, ≥ 1 yes, in a bowl The most dose one load may hold — the highest level the device reaches. Measured on the load's largest entry, which is why rosin (3 a piece) fits only the bong.
bowl.spent_yield integer, ≥ 0 yes, in a bowl Scorched Hemp handed back when a bowl of plant matter is finished.

Wearing the whole hemp outfit doubles the cough and nausea N (half as likely); see Hemp Outfit.

The shipped numbers:

File duration_ticks cooldown_ticks cough_one_in nausea_one_in green_out_factor bowl hits / max_dose / spent_yield
wooden_pipe 700 (35 s) 60 (3 s) 4 50 1.0 2 / 2 / 0
bong 1000 (50 s) 100 (5 s) 3 5 1.0 4 / 3 / 0
vaporizer 800 (40 s) 60 (3 s) 50 200 1.0 2 / 1 / 1
spliff 900 (45 s) 80 (4 s) 6 500 2.0 —

Example — data/hempdustry/hempdustry/device/bong.json:

{
  "bowl": {
    "hits": 4,
    "max_dose": 3,
    "spent_yield": 0
  },
  "cooldown_ticks": 100,
  "cough_one_in": 3,
  "duration_ticks": 1000,
  "green_out_factor": 1.0,
  "nausea_one_in": 5
}

Watch out: every field but bowl is required, so an override must be the whole file. A device's durability (hits before it breaks) and enchantability are not here; they are part of the item.

Edibles

New in 2.1.

What every edible does — one bundle for all six, because the strain's identity ends in the Decarboxylator. Path: data/hempdustry/hempdustry/edible/default.json, and only that file.

Field Type Meaning
qualities object One entry for each cannabutter quality — rough, standard, clean, perfect — all four required.
qualities.<q>.onset_ticks {min, mode, max}, integers ≥ 1 When an edible of that quality kicks in: never before min, never after max, most often at mode (a triangular roll). Must be min ≤ mode ≤ max.
qualities.<q>.duration_ticks integer ≥ 1 How long a tier-IV high of that quality lasts.
tier_share 4 numbers > 0 Each potency tier's share of that length, tier I first.
effects list The effects of the high, below.
effects[].effect effect id The effect.
effects[].amplifier_by_tier 4 integers, 0–255 Its amplifier at tiers I–IV.
effects[].arrives_ticks integer ≥ 0 How long after the onset it lands. It lasts to the end of the high.
effects[].duration_by_tier 4 integers ≥ 1, optional A length of its own per tier, instead of "to the end of the high". Not scaled by the server's duration multiplier.
effects[].amplifier_by_quality object, optional {"<quality>": [4 amplifiers]} — replaces amplifier_by_tier for the qualities it names.

So a high lasts duration_ticks × the tier's tier_share × the config's durationMultiplier, and each effect runs from onset + arrives_ticks to the end of it. The tier is the edible's potency, I–IV, set when it is baked (Cannabutter). The config's onsetMultiplier scales the whole onset window. Lists of four are exactly four: the tiers are fixed.

The shipped numbers:

Quality Onset min / most likely / max Length at tier IV
rough 900 / 2400 / 5200 (0:45 / 2:00 / 4:20) 3600 (3:00)
standard 1100 / 2000 / 3900 (0:55 / 1:40 / 3:15) 5400 (4:30)
clean 1300 / 1800 / 2700 (1:05 / 1:30 / 2:15) 7200 (6:00)
perfect 1740 / 1800 / 1860 (1:27 / 1:30 / 1:33) 9600 (8:00)

tier_share is 0.625, 0.75, 0.875 and 1.0. The effects: Slowness from the onset (I, I, II, II by tier; I at every tier from Perfect butter), Absorption I–IV and Resistance I at +160 ticks (8 s), Hunger I at +400 (20 s), Regeneration I at +600 (30 s) for 100–400 ticks (5–20 s) by tier. Helpful effects are then held to the server's maxBuffLevel, so Absorption stops at II by default.

The whole shipped file
{
  "effects": [
    {
      "amplifier_by_quality": {
        "perfect": [0, 0, 0, 0]
      },
      "amplifier_by_tier": [0, 0, 1, 1],
      "arrives_ticks": 0,
      "effect": "minecraft:slowness"
    },
    {
      "amplifier_by_tier": [0, 1, 2, 3],
      "arrives_ticks": 160,
      "effect": "minecraft:absorption"
    },
    {
      "amplifier_by_tier": [0, 0, 0, 0],
      "arrives_ticks": 160,
      "effect": "minecraft:resistance"
    },
    {
      "amplifier_by_tier": [0, 0, 0, 0],
      "arrives_ticks": 400,
      "effect": "minecraft:hunger"
    },
    {
      "amplifier_by_tier": [0, 0, 0, 0],
      "arrives_ticks": 600,
      "duration_by_tier": [100, 200, 300, 400],
      "effect": "minecraft:regeneration"
    }
  ],
  "qualities": {
    "clean": {
      "duration_ticks": 7200,
      "onset_ticks": { "max": 2700, "min": 1300, "mode": 1800 }
    },
    "perfect": {
      "duration_ticks": 9600,
      "onset_ticks": { "max": 1860, "min": 1740, "mode": 1800 }
    },
    "rough": {
      "duration_ticks": 3600,
      "onset_ticks": { "max": 5200, "min": 900, "mode": 2400 }
    },
    "standard": {
      "duration_ticks": 5400,
      "onset_ticks": { "max": 3900, "min": 1100, "mode": 2000 }
    }
  },
  "tier_share": [0.625, 0.75, 0.875, 1.0]
}

(The shipped file is the same data with every list written one value per line.)

Green-outs

New in 2.1.

What smoking too much costs. Path: data/hempdustry/hempdustry/green_out/default.json, and only that file. Every field is required.

Field Type Meaning
one_in_by_dose list of integers ≥ 0, at least one The odds of a green-out per hit as 1 in N, dose 1 first; 0 is never. The last entry holds for every higher dose.
full_from_dose integer ≥ 1 From this dose a green-out is the full one: it ends every helpful effect of a kind the mod hands out (whatever gave it), empties saturation, and locks smoking out. Below it, it is "the spins".
spins list of effects What the spins give, written as vanilla writes a potion's custom effects: id, amplifier, duration, and optionally ambient, show_particles, show_icon.
full list of effects The same, for the full green-out.
lockout_ticks integer ≥ 0 After a full green-out, the cooldown on every smokeable, in place of the device's own.

A green-out replaces the hit's effects; what it does beyond these lists is the mod's own. The odds are then widened by the device's and the strain's green_out_factor and divided by the config's greenOutChanceMultiplier.

Example — the shipped file, data/hempdustry/hempdustry/green_out/default.json, one effect to a line (dose 1 never, dose 2 1 in 12, dose 3 and up 1 in 4; the spins last 15–20 s, the full one 30–35 s and locks smoking for 60 s):

{
  "full": [
    { "duration": 700, "id": "minecraft:nausea", "show_icon": true },
    { "amplifier": 1, "duration": 600, "id": "minecraft:slowness", "show_icon": true },
    { "amplifier": 1, "duration": 600, "id": "minecraft:weakness", "show_icon": true },
    { "amplifier": 1, "duration": 600, "id": "minecraft:mining_fatigue", "show_icon": true }
  ],
  "full_from_dose": 3,
  "lockout_ticks": 1200,
  "one_in_by_dose": [0, 12, 4],
  "spins": [
    { "duration": 400, "id": "minecraft:nausea", "show_icon": true },
    { "amplifier": 1, "duration": 300, "id": "minecraft:slowness", "show_icon": true },
    { "amplifier": 1, "duration": 300, "id": "minecraft:weakness", "show_icon": true },
    { "amplifier": 1, "duration": 300, "id": "minecraft:mining_fatigue", "show_icon": true }
  ]
}

Recipe types

Every recipe the mod has is an ordinary datapack recipe in data/<namespace>/recipe/, so a datapack, KubeJS or CraftTweaker can add, change or override them; /reload re-reads them. JEI and REI show the machine types (and EMI on 1.21.1). Override a shipped recipe by writing a file at the same path in the hempdustry namespace.

Ingredients are written the way vanilla writes them on each Minecraft version: on 1.21.11 a plain id ("hempdustry:kief"), a tag ("#hempdustry:milk_buckets") or a list; on 1.21.1 an object ({"item": "hempdustry:kief"}, {"tag": "hempdustry:milk_buckets"}). Results are vanilla's item stack: id, optional count and components. The examples below are 1.21.11's.

Type What it is
hempdustry:decarboxylating one Decarboxylator tray: an ingredient in, a stack out
hempdustry:infusing the whole Infuser: what plays each part, and what comes out
hempdustry:pressing one Hemp Press squeeze: an ingredient in, a stack out (new in 2.1)
hempdustry:infused_shaped, hempdustry:infused_shapeless crafting recipes that copy a cannabutter's potency and quality onto the result
hempdustry:container_carried a shapeless crafting recipe that hands back no containers
hempdustry:packing the one special recipe that packs devices; not a format to write

Decarboxylating

Field Meaning
ingredient What goes on a tray.
result What one item of it becomes.

There is no cook time per recipe: the oven runs one clock for its three trays (and the config's machineSpeedMultiplier scales it). The three trays share one output slot, so a recipe that yields something other than what is already there waits until the slot is emptied — keep results to Decarboxylated Hemp unless you mean it.

{
  "type": "hempdustry:decarboxylating",
  "ingredient": "hempdustry:indica_buds",
  "result": {
    "count": 4,
    "id": "hempdustry:decarboxylated_hemp"
  }
}

The shipped ones are in recipe/decarboxylating/: each plant's buds (4), schwag (2) and the Hemp Leaf (1). This is how another mod's buds reach the oven.

Infusing

scorched_hemp new in 2.1.

One recipe describes the whole tub. Strength and quality are measured by the machine and are not part of it (Cannabutter).

Field Required? Meaning
container yes The milk that starts a batch.
hemp yes Hemp that counts as plain.
washed_hemp yes Hemp that counts as washed — what makes the better grades reachable.
scorched_hemp no Hemp worth a quarter, which pulls the grade down. Absent, the tub takes none.
result yes What a finished batch is collected as.
{
  "type": "hempdustry:infusing",
  "container": "#hempdustry:milk_buckets",
  "hemp": "hempdustry:decarboxylated_hemp",
  "result": {
    "count": 1,
    "id": "hempdustry:cannabutter"
  },
  "scorched_hemp": "hempdustry:scorched_hemp",
  "washed_hemp": "hempdustry:washed_decarboxylated_hemp"
}

Watch out: the Infuser reads one infusing recipe — if there are several, the first one found wins. Change the tub by overriding data/hempdustry/recipe/infusing.json, not by adding a second. With no infusing recipe at all, the tub accepts nothing. To add another mod's milk, add it to the #hempdustry:milk_buckets tag instead (Tags).

Pressing

New in 2.1. The same shape as decarboxylating: ingredient and result, one item pressed at a time, no per-recipe time.

{
  "type": "hempdustry:pressing",
  "ingredient": "hempdustry:kief",
  "result": {
    "count": 1,
    "id": "hempdustry:hashish"
  }
}

The five shipped ones are in recipe/pressing/: kief → hashish, filtered kief → filtered hashish, bubble hash → filtered hashish, filtered hashish → rosin, and a retted stem → 8 fibre.

Infused crafting

hempdustry:infused_shaped and hempdustry:infused_shapeless are vanilla's shaped and shapeless crafting recipes (category, group, pattern and key, or ingredients, and result), plus one field:

Field Default Meaning
offset 0 Added to the potency tier the butter gives, then held to I–IV. The cookie and the toast are -1, the dawamesk +1.

The result gets hempdustry:potency (the butter's strength turned into a tier, plus offset) and the butter's hempdustry:quality. Only hempdustry:cannabutter in the grid is read; without it the result is made plain.

{
  "type": "hempdustry:infused_shapeless",
  "category": "misc",
  "ingredients": [
    "minecraft:bread",
    "hempdustry:cannabutter"
  ],
  "offset": -1,
  "result": {
    "count": 3,
    "id": "hempdustry:cannabutter_toast"
  }
}

Container-carried crafting

hempdustry:container_carried is vanilla's shapeless recipe that returns no containers: the milk bucket you poured is the bucket the bhang comes in, and you get it back once, when you drink it. Fields as a shapeless recipe.

{
  "type": "hempdustry:container_carried",
  "category": "misc",
  "ingredients": [
    "hempdustry:decarboxylated_hemp",
    "hempdustry:decarboxylated_hemp",
    "#hempdustry:milk_buckets",
    "minecraft:sugar"
  ],
  "result": {
    "components": {
      "hempdustry:potency": 1,
      "hempdustry:quality": "rough"
    },
    "count": 1,
    "id": "hempdustry:bhang_bucket"
  }
}

Packing

data/hempdustry/recipe/packing.json is {"type": "hempdustry:packing", "category": "misc"}: one special recipe that packs any empty pipe, bong or vaporizer with any strain's buds, up to the device's max_dose, or with one Moon Rock. It reads the strain registry, so a strain you add packs with no recipe of yours. It is not a format to write more of.

Recipes that carry a strain

A spliff, a hash spliff and a moon rock are plain vanilla crafting recipes whose result carries the load in its hempdustry:smoke_contents component. A datapack makes them for any strain the same way:

{
  "type": "minecraft:crafting_shaped",
  "category": "misc",
  "group": "spliff",
  "key": {
    "B": "hempdustry:indica_buds",
    "P": "minecraft:paper"
  },
  "pattern": [
    "B",
    "P"
  ],
  "result": {
    "components": {
      "hempdustry:smoke_contents": {
        "entries": [
          {
            "count": 1,
            "strain": "hempdustry:indica"
          }
        ]
      }
    },
    "count": 1,
    "id": "hempdustry:spliff"
  }
}

The count in an entry is the dose. Two entries make a mixed load, as the hash spliffs do (a bud and a pinch of hash). The shipped ones are recipe/spliff_<strain>_<dose>.json, spliff_<strain>_with_<hash>_<dose>.json and moon_rock_<strain>_<hash>.json.

Loot tables

The mod's blocks drop from ordinary loot tables in data/hempdustry/loot_table/blocks/, which a datapack overrides like any other.

The mod also adds hemp seeds and a few other things to vanilla's grass, chest and archaeology tables (Finding Hemp). It adds them only to tables that come from the game or from mods — never to a table a datapack has replaced: a pack that replaces a chest meant to replace it. The config's loot section switches the additions off or scales them (Configuration).

The spoiling entry

New in 2.1.

hempdustry:spoiling is a loot pool entry that turns some of what another entry drops into a different item. It is how a crop's buds become schwag. A conversion, never an extra drop: what comes out adds up to exactly what the wrapped entry made.

Field Type Required? Meaning
child any loot entry yes The entry it wraps, with its own conditions and functions.
into item id yes What a spoiled item becomes.
enchantment enchantment id no The enchantment whose level on the tool picks the odds below. Absent, or no tool: level 0.
one_item_chances list of numbers, 0–1 no (empty) Rolled once: one item converts.
each_item_chances list of numbers, 0–1 no (empty) Rolled for every item left, each on its own.
conditions loot conditions no As on any entry.

Both lists are indexed by enchantment level, the way vanilla's table_bonus reads its chances: entry 0 for no enchantment, and the last entry holds for every higher level. An empty list never converts. Items are converted after the child's functions, so Fortune's bonus drops can spoil too.

Two behaviours you can rely on:

  • It takes exactly one draw from the loot table's random each time it fires, whatever it decides, so everything rolled after it comes out the same whether or not anything spoiled.
  • Inside an alternatives entry, put the conditions on the spoiling entry, not on its child. Vanilla checks only the conditions of an alternatives' own children; a spoiling entry with none of its own makes every later alternative log "Unreachable entry!" at each load (the drops are right either way).

Example — from data/hempdustry/loot_table/blocks/indica_crop.json: a ripe, untrimmed plant's two buds, with a 1-in-50 chance that one of them comes out as schwag when no Fortune is used:

{
  "type": "hempdustry:spoiling",
  "child": {
    "type": "minecraft:item",
    "functions": [
      {
        "add": false,
        "count": 2.0,
        "function": "minecraft:set_count"
      },
      {
        "enchantment": "minecraft:fortune",
        "formula": "minecraft:binomial_with_bonus_count",
        "function": "minecraft:apply_bonus",
        "parameters": {
          "extra": 2,
          "probability": 0.2
        }
      }
    ],
    "name": "hempdustry:indica_buds"
  },
  "conditions": [
    {
      "block": "hempdustry:indica_crop",
      "condition": "minecraft:block_state_property",
      "properties": {
        "age": "7",
        "half": "lower",
        "trimmed_early": "false",
        "trimmed_late": "false"
      }
    }
  ],
  "enchantment": "minecraft:fortune",
  "into": "hempdustry:schwag",
  "one_item_chances": [
    0.02,
    0.0
  ]
}

The same table's stressed-plant entries use "each_item_chances": [0.25, 0.2, 0.15, 0.1] instead. A datapack that replaces a crop's table keeps its own and simply has no schwag.

World generation

Wild hemp is ordinary worldgen data: configured features and placed features in data/hempdustry/worldgen/ (indica, indica_cave, sativa, sativa_sparse, sativa_rare, beldia, each with a …_placed), added to the biomes in six biome tags (#hempdustry:indica_flower_gen, …_cave, #hempdustry:sativa_flower_gen, …_sparse, …_rare, #hempdustry:beldia_gen). Change where it grows with the tags (Tags) and how often with the placed features; both need a restart and only change new chunks.

Turning a wild plant off on both loaders: replace its biome tag with an empty one ({"replace": true, "values": []}). On Fabric the features are added in code from those tags; on NeoForge through biome modifiers that read the same tags.

The Beldía biome filter

New in 2.1.

hempdustry:in_beldia_biome is a placement modifier with no fields. Used inside a patch's per-plant placement, it keeps each plant only if the exact spot it lands on is in #hempdustry:beldia_gen. Vanilla's minecraft:biome filter tests only a patch's centre, and a patch spreads four blocks — across a desert's edge onto the beach next to it.

{
  "type": "hempdustry:in_beldia_biome"
}

It is used in worldgen/configured_feature/beldia.json, as the last entry of the patch's inner placement list, after the block predicate that asks for #hempdustry:beldia_soil with water beside it.

Advancement triggers

Two criteria triggers for advancements of your own. Every field is optional; with none, the trigger fires on every hit or every harvest.

hempdustry:smoke

strain new in 2.1.

Fires on every hit a player takes, from any smokeable.

Field Type Meaning
player entity predicate As in any vanilla trigger.
item item predicate The stack smoked, still loaded when it is tested — so a predicate can look at its components.
time {min, max}, integers The time of day, inclusive, in ticks of a 24000-tick day where 0 is 6:00 AM and every 1000 ticks is an hour.
strain strain id Only hits whose load holds that strain, in any entry — a hash spliff counts for both the bud and the hash. Works with a strain a datapack adds.

Example — the shipped "Vapor Trail", data/hempdustry/advancement/vapor_trail.json:

"criteria": {
  "smoked_a_vaporizer": {
    "conditions": {
      "item": {
        "items": "hempdustry:vaporizer"
      }
    },
    "trigger": "hempdustry:smoke"
  }
}

Example — a Beldía hit over lunch, 11:00 AM to 1:00 PM:

"criteria": {
  "beldia_at_lunch": {
    "conditions": {
      "strain": "hempdustry:beldia",
      "time": {
        "min": 5000,
        "max": 7000
      }
    },
    "trigger": "hempdustry:smoke"
  }
}

hempdustry:harvest_hemp

condition and bed new in 2.1.

Fires when a player breaks a ripe hemp plant — Purple Kush, Lemon Haze or Beldía, planted or wild.

Field Type Meaning
player entity predicate As in any vanilla trigger.
cuts integer, or {min, max} How many of the plant's two trimming windows it was cut in: 0, 1 or 2.
condition natural, ambient, lamp, grow_lamp or stressed The record the plant kept of how it grew — read off the plant, so it cannot be changed at the last moment (Indoor Growing).
bed block predicate Tested against the block under the plant's lowest block, in the same words as vanilla's minecraft:location: blocks (an id, a list or a #tag), state, nbt.

Example — the shipped "Top Shelf", data/hempdustry/advancement/top_shelf.json: a plant trimmed twice, grown under a Grow Lamp, in a Hydro Tray:

"criteria": {
  "harvested_top_shelf": {
    "conditions": {
      "bed": {
        "blocks": "hempdustry:hydro_tray"
      },
      "condition": "grow_lamp",
      "cuts": 2
    },
    "trigger": "hempdustry:harvest_hemp"
  }
}

A bed can also ask for a state: {"blocks": "hempdustry:hydro_tray", "state": {"fed": "true"}} is a tray with nutrients in it.

The mod's own advancements are in data/hempdustry/advancement/; a few of them are hidden, and their files are best left unread if you want the surprise (Advancements).

Data components

The data the mod keeps on item stacks. All of them can be matched by an item predicate's components (an exact match), set in a recipe result, or given with /give. The ids never change (Stability Promise).

Component Value On Meaning
hempdustry:smoke_contents {"entries": [{"strain": <strain id>, "count": <int>}]} Spliff, every pipe, bong and vaporizer, Moon Rock What is loaded. count is that strain's dose. Absent or empty: unloaded.
hempdustry:charges integer pipe, bong, vaporizer Hits left in the current bowl.
hempdustry:cooldown_until long a smokeable just used The world time its cooldown swipe ends; removed once it does. Nothing to match on.
hempdustry:strength integer, 1–24 Cannabutter How much hemp went into the batch.
hempdustry:quality "rough", "standard", "clean" or "perfect" Cannabutter and the edibles How well the batch was made.
hempdustry:potency integer, 1–4 the six edibles The potency tier.

The mod also uses vanilla's components where they fit: minecraft:damage for a device's wear, minecraft:dyed_color on the dyed shirt and harem pants, minecraft:block_state for a picked-up Grow Pot's fertility.

Example — an item predicate for a Space Cookie of tier IV:

{
  "items": "hempdustry:space_cookie",
  "components": {
    "hempdustry:potency": 4
  }
}

A components match is exact, so for "a bong loaded with Beldía" the smoke trigger's strain field is easier than writing out the whole smoke_contents.

NeoForge-only data

New in 2.1, with the NeoForge builds.

NeoForge only. On Fabric these numbers and features are set in code, and the files below do not exist.

NeoForge keeps compost chances, furnace fuel and features added to biomes as data, so the mod ships them as data there (on Minecraft 26.3 compost and fuel are datapack entries on both loaders instead: below):

What File A datapack can…
Compost chances data/neoforge/data_maps/item/compostables.json ({"values": {"<item>": {"chance": <0–1>}}}) add, change or remove entries, by NeoForge's data-map rules
Furnace fuel data/neoforge/data_maps/item/furnace_fuels.json ({"values": {"<item>": {"burn_time": <ticks>}}}) the same
Wild plants data/hempdustry/neoforge/biome_modifier/<feature>.json, one neoforge:add_features per placed feature override a file at the same path, e.g. with {"type": "neoforge:none"} to turn that patch off

Example — data/hempdustry/neoforge/biome_modifier/beldia_placed.json:

{
  "type": "neoforge:add_features",
  "biomes": "#hempdustry:beldia_gen",
  "features": "hempdustry:beldia_placed",
  "step": "vegetal_decoration"
}

The biome modifiers read the same biome tags Fabric does, so a datapack that edits the tags behaves the same on both loaders.

Differences on Minecraft 26.2 and 26.3

The mod's own formats and numbers are the same as on 1.21.11. What differs:

  • pack.mcmeta: "min_format"/"max_format" 107 on 26.2, 121 on 26.3.
  • Recipes are written as on 1.21.11, ingredients included.
  • Configured features on 26.3: Minecraft 26.3 renamed vanilla's folder, so the wild plants' configured features are data/hempdustry/worldgen/feature/<id>.json there (worldgen/feature/beldia.json holds the Beldía filter); placed features stay in worldgen/placed_feature/.
  • Compost and fuel on 26.3: Minecraft 26.3 made them part of each item, so the NeoForge data maps above are gone there, on both loaders. Hempdustry's numbers are entries of the context_int_provider registry, one per value: data/hempdustry/context_int_provider/cooking/time_<ticks>.json (a burn time) and compostable/chance_<percent>.json (a compost chance). Override one and every Hempdustry item with that value changes; vanilla's items do not.
  • Only on 26.x: the footbag's sulfur cube archetype (data/hempdustry/sulfur_cube_archetype/footbag.json) and the 4:20 time marker (data/hempdustry/timeline/four_twenty.json) (Minecraft 26.x).

Differences on Minecraft 1.21.1

The mod's own formats — strains, devices, edibles, green-out, the recipe types' fields, the spoiling entry, the placement modifier, the triggers, the components — are identical on 1.21.1, 1.21.11 and 26.x, and so are the shipped numbers. What differs is vanilla's:

  • pack.mcmeta: "pack_format": 48 on 1.21.1; "min_format"/"max_format" 94 on 1.21.11 (Custom Strains).
  • Ingredients in every recipe, the mod's types included, are objects on 1.21.1 — {"item": "hempdustry:kief"}, {"tag": "hempdustry:milk_buckets"} — where 1.21.11 writes "hempdustry:kief" and "#hempdustry:milk_buckets".
  • An advancement's background is a full texture path on 1.21.1 ("hempdustry:textures/block/hempcrete_powder_block.png"), a sprite id on 1.21.11 ("hempdustry:block/hempcrete_powder_block").
  • No Hemp Shelf and no Hemp Harness on 1.21.1, so no recipes or loot for them.

Minecraft 1.16.5 and 1.18.2

Forge only. The strain, device, edible and green-out files are the same files, in the same hempdustry/ folders, with the same fields and the same shipped numbers. Around them, much is older:

  • pack.mcmeta: "pack_format": 6 on 1.16.5, 9 on 1.18.2.
  • Strains, devices, edibles and the green-out are re-read by /reload there, and sent to every player again. A broken file does not stop the world: the log says Could not read hempdustry:strain yourpack:whatever: … and that one entry is left out.
  • Vanilla's folders have their old plural names: recipes/, loot_tables/, advancements/, tags/items/, tags/blocks/.
  • Recipes are written the old way: ingredients as objects, a result as item and count. Items carry NBT, not components, so a recipe whose result carries a load is the mod's own hempdustry:crafting_shaped, with the load as an nbt string — the shipped recipes/spliff_indica_1.json:
{
  "type": "hempdustry:crafting_shaped",
  "group": "spliff",
  "key": {
    "B": { "item": "hempdustry:indica_buds" },
    "P": { "item": "minecraft:paper" }
  },
  "pattern": [
    "B",
    "P"
  ],
  "result": {
    "item": "hempdustry:spliff",
    "nbt": "{\"hempdustry:smoke_contents\":{entries:[{count:1,strain:\"hempdustry:indica\"}]}}"
  }
}
  • Wild plants are placed in code, so there are no worldgen files or worldgen biome tags to change there.

Copy anything else from that version's own jar rather than from this page.

See also: Custom Strains · Tags · Configuration · Stability Promise

Clone this wiki locally