BELOW THE IRON Modding guide

Cookbook#

Pick what you want your mod to do, copy the JSON, and change the numbers. Every recipe shows the goal, the code, the result in game and a few variations.

Before you start#

Hit harder#

Recipe 1: Heal on a critical hit#

Goal: an item that heals you every time you land a critical hit.

{
  "id": "bloodthirst",
  "label": "SYNERGY_BLOODTHIRST",
  "requires": ["damage", "drain"],
  "priority": 5,
  "effect": {
    "text": "SYNERGY_BLOODTHIRST_EFFECT",
    "modifiers": [{ "hook": "hit.drain", "op": "add", "value": 1 }]
  },
  "special": {
    "text": "SYNERGY_BLOODTHIRST_SPECIAL",
    "announce": "SYNERGY_BLOODTHIRST_TRIGGERED",
    "on": "hit.dealt",
    "when": { "critical": true },
    "action": "heal",
    "params": { "amount": "$power" },
    "power": 2
  }
}
In game

Every hit drains 1 more life point, and a critical hit also heals 2 (4 on an exceptional-quality item). Healing never goes above your maximum life.

Variations

Recipe 2: Frost that slows longer#

Goal: make every hit slow the enemy one turn more, and wolves three turns in all.

The game already slows an enemy for as many turns as the value hit.frost. You only raise that value. Here it is a three-piece set bonus:

{
  "pieces": 3,
  "modifiers": [
    { "hook": "hit.frost", "op": "add", "value": 1 },
    { "hook": "hit.frost", "op": "add", "value": 2, "when": { "targetFamily": "wolf" } }
  ]
}
In game

Each hit slows for 1 extra turn. Against a wolf the slow lasts 1 + 2 = 3 extra turns.

Variations

Recipe 3: Thorns#

Goal: enemies that hit you get hurt, and sometimes burn.

Thorns are a plain modifier, valid in any source:

{ "hook": "retaliation.damage", "op": "add", "value": 2 }

For burning thorns, add this listener to a set threshold:

{
  "pieces": 3,
  "listeners": [
    {
      "on": "hit.taken",
      "when": { "attackerBoss": false },
      "action": "burn",
      "params": { "at": "attacker", "turns": 2, "power": 2 },
      "chance": 0.5,
      "cooldown": 2
    }
  ]
}
In game

Each time a creature hits you and you survive, it takes 2 arcane damage. Half of the time, a non-boss attacker also burns for 2 turns, at most once every 2 turns.

Variations

React to what happens#

Recipe 4: Mana from hitting a wolf with a spell#

Goal: get mana back when a spell projectile hits a wolf.

{
  "pieces": 3,
  "listeners": [
    {
      "id": "wolf-mana",
      "on": "spell.hit",
      "when": { "targetFamily": "wolf", "kind": "projectile" },
      "action": "restoreMana",
      "params": { "amount": 2 },
      "chance": 0.25,
      "cooldown": 5
    }
  ]
}
In game

When a projectile spell reaches a wolf, you have a one in four chance to regain 2 mana, at most every 5 turns. Mana never goes above your maximum.

Variations

Recipe 5: A shockwave every third blow#

Goal: every few hits, damage every enemy standing next to you.

{
  "pieces": 4,
  "listeners": [
    {
      "id": "third-blow-wave",
      "on": "hit.dealt",
      "action": "wave",
      "params": { "every": 3, "element": "arcane", "amount": 2 }
    }
  ]
}
In game

Every third hit you land sends out a wave. All enemies next to you (within 1.5 cells) take 2 arcane damage.

Variations

Recipe 6: Once per floor#

Goal: the first creature you kill on each floor heals you.

{
  "pieces": 3,
  "listeners": [
    {
      "id": "first-kill-heal",
      "on": "mob.killed",
      "action": "heal",
      "params": { "amount": 3 },
      "cooldown": "floor"
    }
  ]
}
In game

The first kill on a floor heals 3 life. Other kills do nothing until you enter a floor again. The wait is saved with the game.

Variations

Survive#

Recipe 7: Last breath#

Goal: get up once per floor after a killing blow.

{
  "pieces": 4,
  "listeners": [
    {
      "on": "player.dying",
      "action": "heal",
      "params": { "amount": 8 },
      "cooldown": "floor"
    }
  ]
}
In game

The first deadly blow on a floor leaves you with 8 life instead of killing you. The next one on the same floor kills you. On the next floor it works again.

Variations

Recipe 8: Emergency ration#

Goal: get food back when you become very hungry.

{
  "pieces": 4,
  "listeners": [
    {
      "on": "hunger.stageChanged",
      "when": { "hungerStage": "veryHungry" },
      "action": "restoreSatiety",
      "params": { "amount": 15 },
      "cooldown": "floor"
    }
  ]
}
In game

The moment your hunger drops to the "very hungry" stage (20 or less), you regain 15 satiety, once per floor.

Variations

Build sets and synergies#

Recipe 9: A new set bonus#

Goal: add a three-piece bonus to a set that only has bonuses at two and four pieces.

{
  "pieces": 3,
  "modifiers": [
    { "hook": "hunger.cost", "op": "mul", "value": 0.9 },
    { "hook": "attack.accuracy", "op": "add", "value": 1, "when": { "target": "lit" } }
  ],
  "listeners": [
    {
      "on": "floor.entered",
      "action": "revealTraps",
      "params": { "radius": 6 }
    }
  ]
}

Add it to the thresholds list of the lanterniers set.

In game

With three pieces worn you eat 10% less, hit lit targets more easily, and see traps within 6 cells when you enter a floor. The two-piece bonus still applies as well.

Variations

Recipe 10: A synergy with a lucky effect#

Goal: a quarter of your arrows cost no ammunition.

A synergy's special can be a modifier with "op": "chance": it applies a change only some of the time.

{
  "id": "thrifty-quiver",
  "label": "SYNERGY_THRIFTY_QUIVER",
  "requires": ["precision", "damage"],
  "priority": 3,
  "effect": {
    "text": "SYNERGY_THRIFTY_QUIVER_EFFECT",
    "modifiers": [{ "hook": "attack.critRange", "op": "add", "value": -1 }]
  },
  "special": {
    "text": "SYNERGY_THRIFTY_QUIVER_SPECIAL",
    "hook": "ammo.consumed",
    "op": "chance",
    "value": 0.25,
    "then": { "op": "mul", "value": 0 }
  }
}
In game

25% of shots use no ammunition. The ordinary effect also lowers the number needed for a critical hit by one step.

Variations

Create new content#

Recipe 11: A new affix effect, in JSON only#

Goal: invent a "Siphon" affix that returns mana when your projectile spells hit. It takes three linked pieces of JSON and no code. An affix effect is the behaviour behind a family of affixes; the affixes themselves are the names you see on items.

Step 1. Declare the effect in affixEffects in equipment.json. Its name uses lowercase letters and dashes.

{
  "siphon": {
    "text": "AFFIX_EFFECT_SIPHON",
    "listeners": [
      {
        "id": "siphon-mana",
        "on": "spell.hit",
        "when": { "kind": "projectile" },
        "action": "restoreMana",
        "params": { "amount": "$value" },
        "cooldown": 2
      }
    ]
  }
}

Step 2. Write an affix of that family in affixes in the same file.

{
  "id": "of-the-siphon",
  "label": "AFFIX_NAME_OF_THE_SIPHON",
  "position": "suffix",
  "family": "siphon",
  "kinds": ["amulet", "ring"],
  "tiers": [[1, 1], [1, 2], [2, 2], [2, 3]],
  "weight": 4,
  "minLevel": 2,
  "group": "siphon"
}

Step 3. Give the effect an engraving reagent in engrave.reagentByFamily in crafting.json. Each effect needs exactly one reagent, and it must exist in the world.

{ "siphon": "pearl" }

Step 4. Write AFFIX_EFFECT_SIPHON (it receives {value}) and AFFIX_NAME_OF_THE_SIPHON in the nine locale files.

In game

Amulets and rings can now drop "of the Siphon". When a projectile spell hits a creature, you regain as much mana as the affix value, at most every 2 turns. The affix can be engraved with pearl, like every affix of its family.

Variations

Combining recipes#