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.damage while inheriting weapon-info.type and weapon-info.class-name from the preset — the two weapon-info blocks 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 declares primary-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 the presets: 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: — the preset: 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