Skip to content

Tutorial Abilities and Battle Hooks

johnjohto edited this page Jul 25, 2026 · 1 revision

Tutorial: Abilities and Battle Hooks

Give your monsters abilities -- sandboxed scripts that react to battle moments. Turn the layer on with one ruleset knob, then author records.

1. Enable in data/ruleset.json: {"battle_hooks": true}

2. An ability record -- data/abilities/thick_hide.json:

{
 "id": "ability:thick_hide", "name": "THICK HIDE",
 "hooks": {"on_modify_damage": "script:thick_hide"}
}

3. Its handler -- an ordinary HatchScript record:

if is_attacker { return damage }
return max(0, damage - 2)

4. Attach it on a species: "abilities": ["ability:thick_hide"] (slot 1 is active).

The contract

Six hook points (on_switch_in/out, on_modify_damage, on_status_apply, on_field_clear, on_turn_end) -- a closed roster; unknown names refuse at validation and boot. Handlers never write state directly: value hooks return (the modified damage, the status to apply, "" to block), effect hooks queue intents -- message, damage, heal, set_status, clear_status, stat_stage, field_set, field_clear -- executed as ordinary battle events. Read the battle through state("<path>") (self.hp, other.status, self.stage.atk, turn, ...) and draw randomness only through rand_int/rand_range/rand_float -- so every hooked battle replays byte-identically, and link play stays honest. A script error is loud and atomic: the value falls back, none of its intents run.

Held items can carry the same battle: {hooks: ...} block. The full contract (every path, every ordering rule) is docs/v2/battle-hooks.md in the repo.

Clone this wiki locally