Skip to content

Modifier Behaviors

For: intermediate authors wiring triggers, plus advanced authors tuning timing.

Enabling a Modifier

In its file, the enabled flag decides whether the bundle runs at all. Toggle a bundle in-game with:

/manhunt modifiers setmod everyone-gets-beef true

You can also flip enabled in the file directly, then run /manhunt reload. Create new ones with /manhunt modifiers create, the admin GUI editor, or a copy.

Mid-match toggles apply live, but each modifier fires its start commands at most once and runs its cleanup commands at most once per match, so repeated toggling never duplicates rewards. Repeat toggles are skipped with a console warning.

Exclusive Groups

Modifiers that must never run together share one exclusive-group key under config.advanced:

config:
  advanced:
    exclusive-group: bingo

Only one member per group stays active per match. The engine picks deterministically: ascending modifier id, first wins (bingo beats bingo-teams), and the console names the winner once per match. Toggling a loser on mid-match is refused with a warning; toggling the winner off hands the group to the next winner, which fires its start commands. Reload recomputes from the current toggles. Leave the key out (or blank) for normal modifiers.

Groups that must all run but announce once use exclusive-as: BROADCAST (the default is FULL): every member stays active, only the winner broadcasts, and mixed groups resolve as FULL with a one-time console warning naming the group.

At match start the engine broadcasts one line per active modifier from meta.visibility, using the broadcast-format template in messages.yml (default {prefix}{color}<bold>{name}</bold> (by {author})). Modifiers with broadcast: false stay silent, and a preset whose members exactly match the active set replaces every member line with one preset line. Keep announcements out of behavior blocks.

Behaviors

Under the file's behavior: map, a modifier holds one behavior per id. Ids are strings in file order: plain numbers (0, 1, ...) work, and so do names (poll, broadcast). Each behavior has its own triggers, options, and command lists, and every behavior of an enabled modifier fires on its own triggers. Numeric ids need not be contiguous; a modifier with no behaviors does nothing:

mods/modifiers/everyone-gets-beef.yml:

enabled: false
behavior:
  0:
    runs-on:
      - ON_START
    commands:
      player:
        - "give <p> minecraft:cooked_beef 8"
  1:
    runs-on:
      - INTERVAL
    options:
      interval-settings:
        interval: 60
    commands:
      player:
        - "give <p> minecraft:cooked_beef 1"

All trigger, option, and command paths below live under behavior.<id>.

Run Timing

Triggers plus the options that shape them moved to Run Timing.

Command Lists

commands picks which commands run and for whom. The bundled everyone-gets-beef gives every participant eight steaks on match start:

mods/modifiers/everyone-gets-beef.yml:

enabled: false
behavior:
  0:
    commands:
      player:
        # Runs for every participating player (only hunters and speedrunners, not including NONE)
        - "give <p> minecraft:cooked_beef 8"

The available lists are:

  • commands.player: runs for every participating player.
  • commands.hunter: runs only for hunters.
  • commands.speedrunner: runs only for speedrunners.
  • commands.console: runs once from the console on every trigger firing, no matter which player or role caused the event.
  • commands.console-cleanup: runs from the console when the match ends.
  • commands.player-cleanup: runs for every participating player when the match ends.

<p> is replaced with the participating player's name. Commands may start with /.

The role lists only run when the executing player actually has that role: if a hunter enters the Nether and only a speedrunner block is configured, that block does not run. The console list has no such filter: it runs once per trigger firing for every matched event, regardless of role. Only a chance below 1.0 can skip it (see Success Chance).

Reusable Blocks

Shared blocks and <runblock> fan-out moved to Calling Behaviors.

Blacklisted Commands

Some commands are too dangerous for modifiers to dispatch. The advanced.misc.interop.blacklisted-modifier-commands list in config.yml names command roots that never run, no matter which list holds them.

Matching uses the first token of the resolved line with slashes and any namespace: prefix stripped, case-insensitively, so stop, /Stop, and minecraft:stop all match a stop entry. A hit logs an error naming the command and its source line, then skips the rest of that list. The match itself keeps running.

Defaults: op, deop, stop, restart, reload, luckperms, lp, permissions, ban, kick, whitelist (empty the list to disable it).

Targeting Sides with Selectors

Manhunt roles mirror to vanilla scoreboard teams (HUNTER, SPEEDRUNNER, and SPECTATOR), so console commands can aim at a whole side with the team selector argument:

mods/modifiers/hunter-fear.yml:

enabled: false
behavior:
  0:
    runs-on:
      - INTERVAL
    options:
      interval-settings:
        interval: 30
    commands:
      console:
        - "effect give @a[team=HUNTER] minecraft:darkness 5 0"

@a[team=HUNTER] only covers hunters in the running match, so it stays safe when several matches run at once. Membership follows roles exactly, carries no colors or friendly-fire rules, and none/afk players sit in no team. Pair with player/hunter/speedrunner lists when you need per-player tags like <p> or ~ coordinates instead.

Match-End Cleanup

The console-cleanup and player-cleanup lists run when the match ends, which makes them the right place to undo whatever the modifier changed. The bundled perma-night, for example, re-enables daylight when the match is over:

mods/modifiers/perma-night.yml:

enabled: false
behavior:
  0:
    commands:
      console:
        # Ran by the console when the match starts.
        - "gamerule advance_time false"
        - "time set midnight"
      console-cleanup:
        # Ran by the console when the match ends.
        - "gamerule advance_time true"

Similarly, speedrunner-health-advantage resets every participant's max health in player-cleanup, so temporary changes never leak into the next match.

player-cleanup also runs for one player mid-match when they are eliminated, switch roles, or leave the match, so role-specific state never sticks to the wrong role. A switch into the game then runs that role's ON_START lists like a fresh entrant (the <pswitch> order is in Match Control); ON_RESPAWN still fires once per life.

Relative Coordinates

In player and role commands (player, hunter, speedrunner), tildes (~) resolve to the participating player's position: summon zombie ~ ~ ~ becomes summon zombie 10.5 64 -20.2 if the player is at (10.5, 64.0, -20.2). Offsets like ~5 and ~-3 work. All commands dispatch as the console sender, so there are no permission issues.