Tags: Basics¶
For: intermediate authors. Straightforward tags up front; the full cheatsheet lives in Tag Cheatsheet.
Straight to the most useful ones: <random-num:4,12> rolls a whole
number, <random-pick:a,b> picks one item, and interval triggers (see
Behaviors) run lines on a timer. Everything below builds
from there.
Placeholders in Commands¶
Modifier commands run through JMHScript (JMHS), the tag engine: tags evaluate to text, then the full line runs as one command.
Every tag looks like <name> or <name:arg1,arg2>, with lowercase
names and comma-separated args; quote an arg when it holds commas,
and nest tags freely (they evaluate inside out).
Commands can use these tags:
| Tag | Replaced with |
|---|---|
<p> |
The participating player's name. Use this in player and role commands. |
<random-mob> |
A random spawnable living entity type in lowercase (e.g. zombie, creeper). Under pick-random PER_INVOKE one mob is rolled per activation for everyone; under PER_EXECUTOR every executor rolls their own. |
<random-item> |
A random item material in lowercase (e.g. diamond_sword, bread). Same scope rule as <random-mob>. |
<all-players> |
Every participating player in this match, as a name list like [Alice, Bob]. [] when nobody matches. |
<all-players:HUNTER> |
Same, but only hunters. SPEEDRUNNER works too. |
<random-player> |
One random participating player in this match. |
<random-num:4,12> |
A random whole number between 4 and 12. Order does not matter: <random-num:12,4> works the same. |
<random-pick:coal, "dirt", 'sand'> |
One random item from the list. Items can be bare, "double-quoted", or 'single-quoted', and may hold spaces. A bracketed list works too (<random-pick:[coal, dirt]>), but it splits every comma, so quoted commas need the a,b form. |
<setting:base-y> |
One config setting of the running modifier (<s:base-y> works too). Dotted paths reach folder children (<setting:palette.accent>); missing paths read null. |
<modcolor> |
The running modifier's broadcast color as \<#ffffff\>, defaulting to the brand color outside modifiers. |
<gerror:text> |
Broadcasts an error line as {prefix} plus the configured error-color plus the text. <perror:player,text> tells one player and <rerror:role,text> tells a role; every form also takes [enabled,text] to gate on a toggle. Longer aliases: <gerrormessage>, <perrormessage>, <rerrormessage> (see Messages). |
Tags evaluate from the inside out, so they nest. The bundled
random-start-resources modifier uses this to hand out a random ore stash:
- "give <p> <random-pick:coal <random-num:4,12>, iron_ingot <random-num:3,9>, gold_ingot <random-num:3,9>, diamond <random-num:1,3>>"
Each <random-num> rolls first, then <random-pick> chooses one
item amount pair, giving coal (4-12), iron (3-9), gold (3-9), or
diamonds (1-3).
If a <random-pick> item is malformed (mixed quotes, two quoted strings in
one item), it is skipped with a console warning and another item is tried.
Raw @a, @r, @p, and @s selectors work like vanilla and are
the recommended default for plain commands: they convert automatically
and stay scoped to the match, so commands never leak into other
matches. @a runs the command once per participant; a team=
argument on @a[...] survives as a role filter, while other vanilla
selector arguments are dropped. @r draws one random participant,
and @p/@s resolve to the executing player. Inside tag arguments
only JMHS tags (<p>, <random-player>) resolve; bare @
selectors there stay verbatim.
Escaping Special Characters¶
A backslash before any char makes it literal text: \<yellow\>
survives tag parsing and renders MiniMessage yellow, say a\,b
keeps one arg with a comma, and \\ collapses to \. Escaped
text never evaluates as tags, math, conditions, lists, selectors,
or tildes.
Write escaped lines in single-quoted YAML: double-quoted YAML eats backslashes before the engine sees them. Escapes hide chars from JMHScript parsing only: PlaceholderAPI expansion still sees the restored literal text afterwards.
Extended Tags¶
Besides the placeholders above, JMHS understands computing tags for branching, messages, sounds, stats, math, lists, loops, and flags. They nest inside each other and inside the basic tags, and the creator editor validates them as you type. A taste:
| Tag | Meaning |
|---|---|
<if:"7 le 5","yes","no"> |
no: yes when the condition holds, else no (the else branch may be omitted). |
<min:8,3> |
The smaller number: 3. |
<max:8,3> |
The larger number: 8. |
<clamp:8,1,5> |
8 clamped into 1..5: 5. |
<id> |
The name of the modifier (or trigger) running the commands. |
<gmessage:"hi"> |
Sends hi to every participant; the tag itself leaves nothing behind. |
<pmessage:Alex,yo> |
Sends yo to Alex only. Message tags take literal preset text (MiniMessage), never messages.yml keys. |
<gsound:block.stone.break> |
Plays the sound for every participant. |
<psound:Alex,block.stone.break,0.5,2> |
Plays the sound for Alex, with pitch 0.5 and volume 2 (both default to 1). |
<args:0> |
The trigger's first event arg (see Event Args); bare <args> reads index 0. |
<len:[a,b]> |
List tools (list.get, list.set, list.append, and more; see Lists). |
<range:1,5> |
The list [1, 2, 3, 4], Python style (see Lists). |
<active-players:HUNTER> |
Eligible hunters as a list, like [Alex, Bo] (ALL lists both sides). |
<phasitem:Alex,golden_apple,2> |
true when Alex holds at least 2 golden apples, else false (the count is 1 when omitted). |
<plocation:Alex> |
Alex's spot as [x, y, z, world, pitch, yaw]. |
<for:[a,b],...> |
Repeats the body per item with the item behind <i> (see Loops). |
<run:say hi> |
Runs say hi from the console like a command list entry; the tag leaves nothing behind. |
<format:"{0} found {1}",[Alex,gold]> |
Alex found gold. Plain {n} substitution; missing indexes, {x}, and stray braces stay verbatim silently. No conversion specifiers. |
<rmessage:hunter,push!> |
Tells the named role only (ALL tells both). |
Everything else, one line per tag, lives in the Tag Cheatsheet, with full rules in Conditions, Flags, Lists, Strings, Math, Messages and Sounds, Players, Vectors, Cooldowns, Effects, Loops and Functions, Match Control, Shared Max Health, and Teleport and Fill.
Stats¶
<pstat:player,key> reads one player's numbers; <gstat:key> reads
match- or world-wide ones. Keys match case-blindly:
| Tag | Meaning |
|---|---|
<pstat:<p>,health> |
The player's health, normally 0-20. |
<pstat:Steve,hunger> |
The player's hunger, 0-20. |
<pstat:<p>,max-health> |
The player's effective max health, normally 20. |
<pstat:Steve,mobs-killed> |
Mobs the player killed this match. |
<pstat:Steve,achievements-gained> |
Non-recipe advancements earned this match. |
<pstat:Steve,exp-level> |
Vanilla experience level. |
<pstat:Steve,damage-dealt> |
Damage dealt this match in health points (20 is 10 hearts). |
<pstat:Steve,crafts> |
Craft actions this match (one per craft, regardless of result size). |
<pstat:Steve,blocks-broken> |
Blocks broken this match (one per break, placed blocks count). |
<gstat:duration> |
Whole seconds since the match began. |
<gstat:daytime> |
The main world clock in ticks. |
Unknown keys warn and yield nothing, listing the valid keys. Reading a
stat of an offline player warns and yields nothing. duration outside
a live match warns and yields 0. Every <pstat> key yields -1 for an
eliminated player, so -1 reliably means out of the game.
Roster and locations¶
<active-players:HUNTER> (or SPEEDRUNNER, case does not matter)
lists the players currently eligible for interval commands: online,
active, and neither respawning nor held. ALL lists both sides as
one list. <prole:Alex> reads one player's side, and
<plocation:Alex> reads their spot as
[x, y, z, world, pitch, yaw], the same shape as the respawn
event arg. Unknown or offline players yield null silently, as do
spectators for <prole>. <peliminated:Alex> reads false only
while Alex is active in a live match; eliminated, left, and
never-joined names all read true, with no live match needed.
<overlap-players:origin,role,radius,max> and
<nearby-players:player,role,radius,max> list names within
radius blocks, nearest first with name order breaking ties, capped
at max names. The role filters like <active-players> and
accepts ALL. A bare [x, y, z] origin searches every world; a
full [x, y, z, world, pitch, yaw] origin searches that world only.
<nearby-players> centers on the named player (whose own world
scopes the search) and drops the executing player from the list, so
console lists still see everyone. Bad shapes warn and yield null;
an unknown center player yields null silently, and an empty search
yields [].
<pworld:Alex> reports the world alias: nether for the nether,
end for the end, else the raw world name. <world:Alex> is the
same tag. <px:Alex>, <py:Alex>, <pz:Alex>,
<pyaw:Alex>, and <ppitch:Alex> read single numbers from the
live spot. Unknown or offline players yield null silently.
<distance> measures between two spots with only the x, y, z
entries, ignoring pitch and yaw. Two full primitives in different
dimensions yield null silently, while short lists carry no
dimension and always compare by coordinates:
<distance:<plocation:Alex>,[0, 64, 0]> is the blocks from Alex to
spawn. Null, blank, and unparseable sides (an offline player's spot,
for example) also yield null silently. Genuinely malformed non-null
sides warn and stop the line.
Bare math¶
Any no-space token that fully parses as math evaluates: give <p> egg
1+1 hands out 2 eggs. Parentheses, **, //, and % work;
division by zero warns and yields 0. Quote a token to protect it:
say "2026-09-26" stays a date, while a bare 2026-09-26 computes
to 1991. For fallback values use <default:value,fallback> (see
Flags).
Placeholders¶
After tags and math resolve, raw %...% spans expand through
PlaceholderAPI when it is installed (any expansion works, including
%jmanhunt_game_kills_this_session%), or in-house for %jmanhunt_*%
spans when it is not. <placeholder:key> is the same lookup as a
tag, which matters inside math: <clamp:<placeholder:x>-1, 0, 9>
computes on the number, while a raw span would only expand after
math ran.
Placeholders need an executor player, so console lists skip the raw pass silently; the tag form warns without an executor instead. Unknown keys stay verbatim.
Stopping a list¶
A lone exit line stops the command list: later lines never run. It is
checked after tags expand, so <if:"1 == 2","exit","say hi"> skips
the rest only when the branch hits. exit with anything else on its
line is skipped with a warning.
Null lines¶
A line that resolves to exactly null (lowercase, nothing else on
it) is never dispatched: the console logs a warning naming the
modifier, behavior, list, and line instead. Anything else holding
null runs as usual.