Configuration
Better Harvest Levels reads its configuration from config/betterharvestlevel/ when the game or server starts and whenever /bhl reload runs. Every file uses a top-level configVersion of 1.
| File | Purpose |
|---|---|
tiers.json | Defines the named harvest tiers and their numeric order. |
blocks.json and blocks*.json | Assign required tiers to blocks. |
tools.json and tools*.json | Assign harvest tiers to items. |
equivalences.json | Makes named tiers satisfy one another regardless of their numeric order. |
The configVersion field is an integer that defaults to 1. Keep it at 1 in every wrapper shown below.
Tier definitions
Section titled “Tier definitions”tiers.json contains the tier IDs used by block overrides, tool overrides, and equivalence groups.
| Field | Type | Meaning |
|---|---|---|
name | string | Tier ID used by overrides and equivalences. hand is reserved. |
level | integer | Numeric order. A tool can satisfy an equal or lower required level. |
displayName | string | Name shown by commands. |
color | string | Hex color used by command output. |
builtIn | boolean | Marks the generated vanilla tier definitions. |
iconItem | item ID | Jade fallback icon for the tier. |
Generated tier ladder
Section titled “Generated tier ladder”A new configuration generates these definitions. The hand tier is not written to tiers.json; Better Harvest Levels injects it internally.
| Name | Level | Display name | Default icon |
|---|---|---|---|
hand | -1 | Hand | none, injected internally |
wood | 0 | Wooden | minecraft:wooden_pickaxe |
gold | 0 | Golden | minecraft:golden_pickaxe |
stone | 1 | Stone | minecraft:stone_pickaxe |
copper | 2 | Copper | minecraft:copper_ingot |
iron | 3 | Iron | minecraft:iron_pickaxe |
diamond | 4 | Diamond | minecraft:diamond_pickaxe |
netherite | 5 | Netherite | minecraft:netherite_pickaxe |
Add a custom tier
Section titled “Add a custom tier”Add the custom object to the generated tiers array. This complete tiers.json keeps every generated tier and adds steel, so the later examples can refer to both steel and the built-in tier IDs.
{ "configVersion": 1, "tiers": [ { "name": "wood", "level": 0, "displayName": "Wooden", "color": "#8B6914", "builtIn": true, "iconItem": "minecraft:wooden_pickaxe" }, { "name": "gold", "level": 0, "displayName": "Golden", "color": "#FFAA00", "builtIn": true, "iconItem": "minecraft:golden_pickaxe" }, { "name": "stone", "level": 1, "displayName": "Stone", "color": "#888888", "builtIn": true, "iconItem": "minecraft:stone_pickaxe" }, { "name": "copper", "level": 2, "displayName": "Copper", "color": "#E77C56", "builtIn": true, "iconItem": "minecraft:copper_ingot" }, { "name": "iron", "level": 3, "displayName": "Iron", "color": "#C8C8C8", "builtIn": true, "iconItem": "minecraft:iron_pickaxe" }, { "name": "diamond", "level": 4, "displayName": "Diamond", "color": "#55FFFF", "builtIn": true, "iconItem": "minecraft:diamond_pickaxe" }, { "name": "netherite", "level": 5, "displayName": "Netherite", "color": "#4D3B3B", "builtIn": true, "iconItem": "minecraft:netherite_pickaxe" }, { "name": "steel", "level": 4, "displayName": "Steel", "color": "#9AA4AD", "builtIn": false, "iconItem": "examplemod:steel_pickaxe" } ]}Block overrides
Section titled “Block overrides”Better Harvest Levels loads blocks.json and every file whose name matches blocks*.json. Files load in alphabetical filename order, and each file contributes its overrides entries in array order.
{ "configVersion": 1, "overrides": [ { "target": "#minecraft:needs_diamond_tool", "type": "tag", "requiredTier": "netherite" } ]}| Field | Type | Meaning |
|---|---|---|
target | string | Block ID, block tag, namespace, or regular expression selected according to type. |
type | string | Selector type: block, tag, mod, or regex. |
requiredTier | tier ID | Registered tier that matching blocks require for drops. |
Tool overrides
Section titled “Tool overrides”tools.json and every file whose name matches tools*.json use the same alphabetical layering. Entries from each file are appended in their array order.
{ "configVersion": 1, "overrides": [ { "target": "examplemod:steel_pickaxe", "type": "item", "tier": "steel" } ]}| Field | Type | Meaning |
|---|---|---|
target | string | Item ID, item tag, namespace, or regular expression selected according to type. |
type | string | Selector type: item, tag, mod, or regex. |
tier | tier ID | Registered tier assigned to matching items. |
Selector syntax
Section titled “Selector syntax”| File family | Type | Target form |
|---|---|---|
| Blocks | block | Exact block ID such as minecraft:obsidian |
| Blocks | tag | Tag with leading #, such as #minecraft:mineable/pickaxe |
| Blocks | mod | Namespace or namespace:* |
| Blocks | regex | Full-string regular expression matched against the block ID |
| Tools | item | Exact item ID such as minecraft:iron_pickaxe |
| Tools | tag | Tag with leading # |
| Tools | mod | Namespace or namespace:* |
| Tools | regex | Full-string regular expression matched against the item ID |
A regex selector must match the complete identifier. For example, examplemod:.*_ore matches IDs in the examplemod namespace that end in _ore.
Layering and precedence
Section titled “Layering and precedence”For each override family, Better Harvest Levels applies this order:
- Files load alphabetically by filename.
- Entries are evaluated in their loaded order, including their order within each
overridesarray. - A later matching entry replaces the tier selected by an earlier matching entry.
This means the last matching block rule wins among all loaded blocks*.json entries, and the last matching tool rule wins among all loaded tools*.json entries.
Invalid entries and files
Section titled “Invalid entries and files”- An exact
blockoritemtarget that is not present in the registry does not resolve to an override. - An unknown selector
typeis logged and skipped. - An invalid regular expression is logged and skipped.
- Invalid JSON causes that entire file to be logged and skipped. Other files still load.
- A duplicate tier name is logged and ignored, leaving the first definition registered.
- A blank tier name or a definition of the reserved
handtier is logged and ignored. - A direct tier comparison involving an unknown tier is denied.
- A block override whose
requiredTieris unknown is logged and dropped during reload. - A tool override whose
tieris unknown is logged and dropped during reload.
Tier equivalences
Section titled “Tier equivalences”equivalences.json groups tier IDs that should satisfy one another.
{ "configVersion": 1, "groups": [ { "name": "diamond-grade", "tiers": ["diamond", "steel"] } ]}| Field | Type | Meaning |
|---|---|---|
name | string | Name used to identify the equivalence group in log messages. |
tiers | string array | Registered tier IDs that are equivalent within this group. |
Membership lets the named tiers satisfy each other even when one has a lower numeric level. In the example, a steel tool satisfies a diamond requirement, and a diamond tool satisfies a steel requirement. Numeric ordering still applies normally outside the group.
References to unknown tiers are logged and ignored. The known tier members of the group remain available for equivalence checks.