Skip to content

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.

- '<pmessage:<p>,\<yellow\>This is yellow text!>'
- '<pmessage:<p>,a\,b>'

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.