Run Timing¶
Quick Start: Spice it up with twists.
Triggers plus the options that shape them: start timing, chance, execution, intervals, and delays.
The commands run on these triggers:
| Value | Trigger |
|---|---|
ON_START |
Once when the match starts (runs for all participants) |
INTERVAL |
On a fixed interval that starts counting when the game begins |
ON_MOB_KILLED |
When a participating player kills a mob or other non-player entity (never players) |
ON_PLAYER_KILLS, ON_HUNTER_KILLS, ON_SPEEDRUNNER_KILLS |
When a participating player kills another player (variants fire for hunter/speedrunner killers only) |
ON_BLOCK_BROKEN, ON_BLOCK_PLACED |
When a participating player breaks or places a block (runs for the acting player only) |
ON_RIGHT_CLICK, ON_LEFT_CLICK |
When a participating player presses right or left click, main hand only (runs for the clicker only) |
ON_CRAFT_PREPARE, ON_CRAFT |
When a participating player previews a recipe result or lands a craft (runs for the crafter only) |
ON_NETHER_ENTER |
When a participating player enters the Nether (once per player per match) |
ON_END_ENTER |
When a participating player enters the End (once per player per match) |
ON_FIRST_NETHER_ENTER |
When the first participating player enters the Nether (once per match) |
ON_FIRST_END_ENTER |
When the first participating player enters the End (once per match) |
ON_EVERY_ADVANCEMENT |
When a participating player earns an advancement the engine announces (recipe book unlocks and hidden advancements excluded) |
ON_RESPAWN, ON_SPEEDRUNNER_RESPAWN, ON_HUNTER_RESPAWN |
When a player is back in play after respawning (only the executing player; fires once per life, after headstart and respawn holds release; variants fire for their role only) |
ON_DAMAGE_TAKEN |
When a player takes damage from any source (runs for the damaged player only) |
ON_DEATH |
When a participant dies (runs for the dead player only; <args:0> is the exact dead-player name, <args:1> is the exact killer name or null; elimination kills from <loseplayer> and lethal max health skip it, observe those with ON_ELIM) |
ON_DISCONNECT |
When a match member disconnects, eliminated by it or not (runs for the quitter only; <args:0> is the exact quitter name, <args:1> is the quitter role; there are no hunter/speedrunner variants) |
ON_ELIM, ON_SPEEDRUNNER_ELIM, ON_HUNTER_ELIM |
When a participant is eliminated, by death, removal, or disconnect (runs for the eliminated player only; <args:0> is the exact eliminated-player name, <args:1> is the former role; variants fire for their side only) |
ON_CLEANUP |
When modifier state must be undone: at match end (console lists once, then every participant), on mid-match toggle-off (same shape), and for one player mid-match on elimination, role switch, or leave (player and role lists only, console skipped) |
ON_PLAYER_INPUT paid |
Every tick the movement vector is nonzero, plus one zero-vector release when it settles (runs for the acting player only; skipped on free) |
ON_MOVE |
Every tick the player's x/y/z spot changed since last tick (runs for the moving player only; rotation never fires) |
ON_CROUCH |
Every tick the player is crouching (runs for the crouching player only) |
ON_JUMP |
Every tick the player holds the jump key (runs for the acting player only) |
ON_PGHOST_EXIT |
When a ghost session ends for any reason except match end (runs for the ghosted player only; quits pass no player, so per-player lists skip) |
ON_SHAPESHIFT_EXIT |
When a shapeshift session ends for any reason except match end (runs for the shifted player only; quits pass no player, so per-player lists skip) |
Who runs¶
- Nothing runs automatically: if
runs-onis omitted or empty, the behavior stays silent. Blocks that only<runblock>calls omit it on purpose. ON_STARTandINTERVALrun for all participants. Every other event trigger runs theplayer,hunter, andspeedrunnerlists only for the player involved.ON_CLEANUPat match end runs console once, then every participant; mid-match it runs the one involved player with console skipped.- Eliminations that land while the player is offline run console only:
there is no
<p>executor, so read the name from<args:0>. - Kill triggers see the attributed killer: the vanilla killer when clear,
else the last player the victim fought within 8 seconds (lava and fire
deaths after combat count). Natural deaths fire no kill trigger and
report
nullas theON_DEATHkiller. To count every kill, enable bothON_MOB_KILLEDandON_PLAYER_KILLS. ON_BLOCK_BROKENlistens at HIGH priority so it observes protection cancels from lower priorities; a cancel from a later priority is a documented residual risk.ON_CRAFT_PREPAREfires on every recipe preview update while the crafter arranges the grid;ON_CRAFTfires once per landed craft, with shift-clicks reporting the per-unit result.
Intercepting Drops¶
<intercept:item> replaces event drops on the events that allow it:
ON_MOB_KILLED, ON_BLOCK_BROKEN, and ON_CRAFT_PREPARE (where it
replaces the prepared result slot instead). On ON_BLOCK_PLACED the
same payload swaps the placed block instead.
- The payload is one item or a nested list of
[material, qty]items. OnON_CRAFT_PREPAREandON_BLOCK_PLACEDit must be exactly one item: a nested payload warns and keeps the original. - On
ON_BLOCK_PLACED,aircancels the placement without consuming anything, while qty and item data stay ignored. - Replacements keep nothing of the originals, except on
ON_BLOCK_BROKEN, where only the primary drop is replaced and every other drop (including container contents) still drops. XP still drops as vanilla computed it everywhere. - Using
<intercept>in any other block is a blocking validator error; at runtime the tag warns and yields empty outside an interceptable dispatch. - Intercepting behaviors run synchronously during the event (their
options.delayis ignored with a once-per-match warning), the last evaluated intercept wins across every behavior, and a payload that builds zero valid stacks keeps the original drops.
Lucky blocks, for example:
behavior:
lucky:
runs-on:
- ON_BLOCK_BROKEN
commands:
player:
- <intercept:[[diamond, 3], [tnt, 1]]>
Lucky crafting, for example (prepare takes exactly one item):
behavior:
lucky_craft:
runs-on:
- ON_CRAFT_PREPARE
commands:
player:
- <intercept:[diamond_sword, 1]>
Start Timing¶
An ON_START modifier can wait out the pre-start window before
running:
mods/modifiers/hunter-post-start-speed.yml:
behavior:
0:
on-start:
# BEFORE runs at /manhunt start; AFTER waits until the speedrunner
# first hits a hunter (or the match force-starts), plus each
# side's own headstart after that. Defaults to BEFORE.
pre-start-order: AFTER
- Only applies when
runs-oncontainsON_START. - When
start-on-speedrunner-damageis disabled there is no pre-start window, so both settings run at match start. - With headstarts configured, AFTER runs per player: console lists fire
once at begin, each side's player lists fire once its own hold lifts
(sides with no headstart get theirs at begin, held sides at release).
PER_INVOKEchance and picks roll once per side delivery instead of once per match when headstarts split the run. INTERVALbehaviors can fire while anON_STARTbehavior withAFTERis still waiting. Guard intervals that depend on deferred initialization with a match flag, set after initialization finishes:
behavior:
init:
runs-on: [ON_START]
on-start:
pre-start-order: AFTER
commands:
console:
- '<runblock:generate-card>'
- '<gflag:card-ready,true>'
poll:
runs-on: [INTERVAL]
commands:
console:
- '<if:"<gflag:card-ready> != true","exit">'
- '<runblock:check-card>'
Success Chance¶
Make the modifier run only sometimes:
mods/modifiers/gear-dice.yml:
behavior:
0:
options:
success-chance:
# Chance to run, from 0.0 (never) to 1.0 (always). This is a fraction,
# not a percent: use 0.5 for 50%. Defaults to 1.0.
chance: 0.5
# PER_INVOKE rolls once for everyone; PER_EXECUTOR rolls the console
# and each player separately. Defaults to PER_INVOKE.
behavior: PER_EXECUTOR
Without this section the modifier always runs. The roll happens on every
trigger, including each interval firing and ON_CLEANUP.
Command Execution¶
Run a random line from a command list instead of every line:
mods/modifiers/gear-dice.yml:
behavior:
0:
options:
execution:
# IN_ORDER runs every line. PICK_RANDOM runs a random few instead.
# Defaults to IN_ORDER.
selection: PICK_RANDOM
pick-random:
# How many lines to pick. Minimum 1. Defaults to 1.
count: 1
# PER_INVOKE picks once for everyone; PER_EXECUTOR picks separately
# for the console and each player. Defaults to PER_INVOKE.
behavior: PER_EXECUTOR
- Applies to each command list on its own. Asking for more lines than the list has runs the whole list.
ON_CLEANUPbehaviors honor the selection like any trigger, so keep cleanup selection atIN_ORDERunless a random undo is really what you want.
Interval Settings¶
How often an INTERVAL modifier repeats (only applies with
INTERVAL in runs-on):
mods/modifiers/random-mob-spawner.yml:
enabled: false
behavior:
0:
runs-on:
- INTERVAL
options:
interval-settings:
# Interval duration in seconds.
interval: 60
# Random spread in seconds. 60 and 15 means every 45 to 75 seconds.
# Cannot go above interval. Defaults to 0.
deviation: 15
# PER_INVOKE shares one timer; PER_EXECUTOR gives every player and the
# console their own timer. Defaults to PER_INVOKE.
behavior: PER_INVOKE
- Counting starts when the game actually begins (first damage or force
start), not at
/manhunt start. - With
PER_EXECUTORdeviation, each player has their own timer, so players who join mid-match get timed in as well. intervalsupports decimals, rounded to the nearest tick (1 tick is 0.05 seconds). Values between0and0.05execute every tick; set0or0.05for every-tick execution. Negative values disable the modifier.- Each firing skips players who cannot play right now: match watchers, dead players waiting on a respawn, and players held in spectator mode. The console list still fires.
Command Delay¶
Delay the modifier's commands by a number of ticks after they trigger:
mods/modifiers/everyone-gets-beef.yml:
- Applies to start, interval, and event triggers, but never to
ON_CLEANUP: cleanup always runs inline, so teardown observes settled state. - Positions and roles resolve when the delayed commands fire, not when they trigger. If the match ends before the delay elapses, the commands are dropped.
Line Delays¶
<delay:seconds,id?> pauses the command list mid-run: the lines
after it fire after the pause (seconds as a decimal, at most 600,
converted to ticks), while the lines before it run inline:
behavior:
storm:
runs-on:
- ON_START
commands:
console:
- 'say The storm gathers.'
- '<delay:1.5,storm>'
- 'summon lightning_bolt 0 64 0'
- 'say The storm breaks.'
- The id is optional and names the pending delay:
<delaycancel:storm>cancels it instantly, and the lines after it never run. - A delay evaluated during any line splits the list after that line
(inside
<if>branches too); the first delay per line wins. - Like behavior delays, positions and roles resolve when the rest fires, and match end drops everything pending. A continuation whose executor left skips silently, while console continuations always fire.
- Delays and intercepts do not mix:
<intercept>lines after a delay never apply, so keep replacements before the pause.