Config Presets (Inheritance)
Share repeated field clusters across near-identical block and item entries with a named presets map and a per-entry preset key.
Content catalogs repeat the same field clusters across near-identical entries — the four short swords carry a byte-identical wielded-item-data block, ore and stone blocks share the same breaking triplet, and so on. A preset lets you write that shared shape once and point entries at it: the preset supplies defaults, and each entry overrides only what makes it different.
Presets are currently supported by Block Configuration (block-config.yaml), Item Configuration (item-config.yaml), Mob Configuration (mob-config.yaml), and Tree Configuration (tree-config.yaml).
File Location
Presets are not a separate file. Add a top-level presets: map to the same catalog file that holds the entry list, alongside the blocks: or items: list:
presets:
SHORT_SWORD:
type: weapon
weapon-info:
type: melee
class-name: Short Sword
wielded-item-data:
x-offset: 2.0
y-offset: 1.0
primary-use-animation:
- towards-cursor: true
position-offset: 3.0
time-ms: 400
items:
- name: wooden_short_sword
preset: SHORT_SWORD
weapon-info:
damage: 0.5
scripts:
server-on-primary-use: /items/sword_use.lua
- name: stone_short_sword
preset: SHORT_SWORD
weapon-info:
damage: 5.0
- name: diamond_short_sword
preset: SHORT_SWORD
weapon-info:
damage: 100.0
Each preset: names an entry of that file’s own presets: map. Presets are file-local — you cannot reference a preset declared in another mod’s config.
Fields
presets: (top-level map)
A map of PRESET_NAME: { …partial entry fields… }. A preset body holds the same keys a real entry does, but only the ones it wants to share. The name is yours to choose (uppercase-with-underscores is the convention used here, but any string works).
preset: (per-entry, optional)
The name of a preset whose fields become this entry’s defaults. Omit it and the entry loads exactly as it would without presets — adding a presets: map to a file changes nothing until an entry opts in with preset:.
The preset: key (and the whole presets: map) is resolved away before the entry is validated, so it never trips the strict unknown-key check that catalog entries are subject to.
Merge semantics
An entry’s own fields win over the preset’s. The merge is applied field by field:
- Nested mappings deep-merge. In the short-sword example every entry sets
weapon-info.damagewhile inheritingweapon-info.typeandweapon-info.class-namefrom the preset — the twoweapon-infoblocks are merged, not replaced. This is what lets an entry override a single sub-field. - Scalars and sequences replace wholesale. A scalar (
type: weapon) or a list in the entry replaces the preset’s value outright. Sequences are never element-merged: if an entry declaresprimary-use-animation, it replaces the preset’s animation entirely rather than appending to it.
Chaining
A preset may itself carry a preset: key to extend another preset in the same file, so common shapes can layer:
presets:
MINEABLE:
tool-break-types: pickaxe
time-to-break-ms: 500
STONE_LIKE:
preset: MINEABLE # inherits tool-break-types + time-to-break-ms
power-required: 1
blocks:
- name: cobblestone
preset: STONE_LIKE # gets all three fields
Chains resolve parent-first, then apply the child on top. A cycle (A extends B extends A) is detected and reported.
Errors
Preset resolution runs per entry, and a broken reference skips only that entry (the rest of the catalog still loads), with a logged error:
- Unknown preset — the
preset:name has no matching key in thepresets:map. - No
presets:map — an entry names a preset but the file declares none. - Preset cycle — a chain of
preset:references loops back on itself. - Non-string
preset:— thepreset:value must be a preset name written as a string.
Example
A block catalog using a preset for the repeated breaking triplet:
presets:
SHOVELABLE:
tool-break-types: shovel
time-to-break-ms: 500
power-required: 1
blocks:
- name: dirt
preset: SHOVELABLE
- name: sand
preset: SHOVELABLE
- name: gravel
preset: SHOVELABLE
Each block loads exactly as if the three breaking fields had been written out on it directly.
Last updated