Creating and Sharing Modifiers¶
Quick Start: Spice it up with twists.
Modifiers are named command bundles: one .yml file each under
mods/modifiers/, presets beside them under mods/presets/. The id
is the filename minus .yml, so gear-dice.yml is the gear-dice
modifier. Subdirectories are allowed and load recursively. A modifier
can run commands when a match starts, on an interval, on game events,
and when the match ends, from the console or per player. New entries
start disabled.
Bundled defaults ship with the plugin and copy in the first time each
folder is created. Deleting a file removes it for good: defaults are
never restored. All examples below match the bundled files in the
mods/ folder.
Writing commands by hand is tedious. Use mcstacker.net to generate up-to-date commands, then paste them into your modifier. Then check the file with the Mod Validator: it catches tag, syntax, trigger, key-typo, and settings mistakes locally before you load or share the mod.
Creating Modifiers and Presets¶
Build entries in the GUI or inline from chat; both write the same
per-file entries manual editing produces. Everything lands as a
root-level file: mods/modifiers/<id>.yml or mods/presets/<id>.yml.
Ids use letters, numbers, - and _, up to 64 chars; a taken name
gets {n} numbering.
In the GUI, the create button sits top-right of the lists. It prompts
for a display name (you become the author) and opens the new entry in
its editor; right-clicking any existing entry opens the same editor.
The create command behaves the same (the console records CONSOLE
as author). The modifier editor covers every field: meta, triggers,
timing and chance options, and every command list. Blank answers clear
optional fields back to defaults. See
Your First Modifier for a worked kit example.
- Commands validate on save: unbalanced brackets, empty commands,
malformed random args, unknown root commands, and unknown
giveitems are refused with an error, while unknown tags only warn. Setadvanced.misc.modifier-editor.validate-commandsto false to skip the root and item checks. See Modifiers for the create flags. Lines edited outside the GUI skip that check, so at runtime an unterminated<run>warns in the console naming the line instead of running silently. - Some command roots can never dispatch from a modifier; see Blacklisted Commands.
- Toggling a modifier mid-match runs its start and
ON_CLEANUPbehaviors on every toggle, which suits rapid testing. Setadvanced.misc.modifier-editor.prevent-duplicate-toggleto true so each runs at most once per match and rewards never duplicate.
Presets keep display data under meta: with the member list beside it:
mods/presets/chaos-mode.yml:
meta:
name: "Chaos Mode"
description: "Random mobs, random items, gear dice"
visibility:
icon: TNT
color: ffaa00
broadcast: true
modifiers:
- random-mob-spawner
- random-item-giver
- Presets carry the same visibility block as modifiers (icon, broadcast
toggle, hex color), edited from the Meta panel's Visibility page. The
icon lives only in
visibility.icon; a file that still carries the retired top-levelmeta.iconwarns as an unknown key and the stale value is ignored. Every icon field accepts JMH Icon Data. The match-start line for a preset uses the preset's own color; a preset with broadcast off stays silent. - A modifier's message color lives only in
visibility.color: behavior reads it with<modcolor>instead of defining a second color setting (bingo is the exception with its extranormalcolor for card text). - Member ids with no loaded modifier show as
'id' missingin red and are skipped by toggles; a preset with nothing but missing members refuses to toggle. - Presets written in the old flat shape (display keys next to
modifiers:) no longer load: re-indent the four display keys undermeta:, and re-export old share strings. Upgrading from the singlemodifiers.ymllayout: copy entries into per-file form by hand, nothing migrates automatically.
Presets can nest other presets with a presets: list beside
modifiers:, as deep as you like:
- Toggling a stacking preset flips every transitive member, and the preset reads on only when all of them are on. A preset holding more present members than the match allows refuses the whole enable with an error instead of partially enabling.
- The lore lists direct modifiers first, then direct nested presets
with a
(preset)suffix; nested contents are never inlined, so open the nested preset to see them. - At match start, a preset whose transitive members exactly equal the active set replaces the member lines with one line; when several presets match, the outermost wins and the nested ones stay silent.
- The
(by ...)slot lists every credited author: the preset creator first, then each deeper nesting level, then the transitive modifier authors, with repeats keeping their highest spot. - A cycle (
anestingbnestinga) warns at load naming the full path and ignores the closing link in memory; the file is left alone, and the GUI refuses nests that would close a cycle. Unknown nested ids warn and skip like missing members, renames follow intopresets:lists, and share strings carry nesting (strings exported before nesting import as direct-only).
Sharing Modifiers and Presets¶
Export any entry to a share string: a click-to-copy chat line for friends or the community. Import takes one back in, always disabled no matter the export state; colliding names get numbered automatically. Strings that fail their checksum or schema check are refused without touching anything.
/manhunt modifiers export modifier gear-dice
/manhunt modifiers export preset chaos-mode
/manhunt modifiers import modifier JMH1D:...
The lists carry an import button that prompts for the string, and every editor has an export button for its own share string.
Mod Files and Load Order¶
- Modifiers load fully before presets. Inside each tree, every
directory loads its subdirectories first (sorted naturally by name,
each processed with this same rule), then its own
.ymlfiles sorted naturally by filename. Root-level files therefore load after everything nested. Sorting is Explorer style: case-insensitive, with digit runs compared numerically (mod2beforemod10). - Two files of the same kind with the same id in different folders are a duplicate: the first in load order wins and the rest are skipped, with a console warning naming both paths. A modifier and a preset may share an id; they are separate namespaces.
- Loads warn about mistakes that used to pass silently: unknown YAML
keys are ignored with a warning naming the key and level; unknown
runs-ontriggers never fire and warn;<setting:>references to undefined settings read null and warn; duplicate setting names drop the wholeconfig.settingsblock with a warning; setting defaults outside their allowed range clamp with a warning. The validator reports the same findings offline. - Non-
.ymlfiles are reported as unknown files on reload (temp files and dotfiles are ignored silently). A.ymlfile that fails to parse or validate is logged as<path>: <error>, skipped, and reported; fixing it later reloads quietly. - A preset that names an unknown modifier id warns and skips that member in memory only: the file keeps the id, so a later reload picks it up once the modifier exists.
- Enable flags stored in the lobby config for ids that no longer exist are pruned on load and reload (with one console warning); per-setting values are kept, so re-adding the file restores its customization. The Added/Removed counts only reflect files: mods created or deleted in-game never re-report on the next reload.
Example¶
A minimal starter kit for every participant:
mods/modifiers/starter-kit.yml:
The bundled files ship more examples to copy from: full-leather-kit,
speedrunner-health-advantage, random-mob-spawner,
random-item-giver, random-start-resources, gear-dice,
regen-on-kill, diamond-on-advancement, fireres-on-nether-enter,
hunter-start-debuffs, get-stronger-on-kill,
speedrunner-gapple-on-low-hp, vip-escort, and infection.
Get Stronger On Kill¶
Runs on every player kill (executor: the killer) and every respawn
(executor: the respawner). Each run works in half-hearts from two
tunables (cap 40, step 4): cache the baseline max health, set base
to baseline plus step times session kills capped at cap, heal 2
hearts on the spot, and refill only missing hunger. Respawn re-applies
the target from the still-current counter, so a killer who dies keeps
their hearts. ON_CLEANUP clears this modifier's ledger entry per
participant.
Gapple On Low HP¶
Runs every 2 seconds for speedrunners. Lines exit cheapest-first:
cooldown read, health check, inventory scan, then the gate itself.
<pcooldown> yields true and stamps at most every 300 seconds, so
the apple lands only when all four pass.
VIP Escort¶
Flags one random speedrunner as the VIP after the pre-start window;
runners lose outright when the VIP dies. Run it with speedrunner lives
at -1 so everyone else respawns forever while the VIP stays mortal.
Four blocks: an ON_START pick, an ON_DEATH guard that ends the
match for the hunters, a 1-second INTERVAL armor toggle, and an
ON_START plus ON_RESPAWN effects toggle (effects and no_armor
in config.settings).
Infection¶
Speedrunners who die their final death come back as hunters via
<pswitch>. Guards read the victim's former role plus live role, so
hunter deaths, non-final runner deaths, and disconnect removals (which
never fire ON_DEATH) exit quietly. When no runners remain, the engine
ends the match with a hunter win on its own. A second block runs every
12 seconds per hunter: converted hunters get sporadic blindness plus
occasional drops (80% give-fail chance by default), while root hunters
exit untouched. Durations and counts live in config.settings.