Conditions & variables
A condition is a small boolean expression you add to a level with the condition: key. When the condition is false, the ability is gated out — it simply doesn't run. When it's true, the ability proceeds (then its chance: roll happens as usual).
levels:
1:
chance: 100
condition: "%actor.healthpercent% < 30" # only when you're below 30% HP
effects:
- { POTION: { effect: REGENERATION, level: 2, duration: 100 } }
Conditions are built from three pieces:
- Variables —
%scope.name%placeholders that read live game state (your health, the victim's type, the weather…). - Operators — compare those variables (
<,==,contains, …). - Glue — combine clauses with
&&(and),||(or),!(not), and( )for grouping.
Variables: %scope.name%
Every fact you can read is written between percent signs. Most are scoped by a prefix (actor., victim., world., block.); a handful of bare combat/state facts have no prefix at all.
:::note Scope means "whose fact?"
%actor.health% is your health; %victim.health% is the health of the entity you hit. The victim. and bare combat facts (%combo%, %damage%, %distance%…) only carry meaning on combat triggers (ATTACK, DEFENSE, KILL). On a non-combat trigger there's no victim to read.
:::
Variables come in three flavours: numbers (compare with <, >, ==, …), text (compare with ==, contains, matchesregex), and true/false flags (use them on their own, e.g. %sneaking%, or negate with !%sneaking%).
actor. — the player who triggered it
Facts about the player wearing/using the enchant.
| Variable | Type |
|---|---|
%actor.behindvictim% | true / false |
%actor.belowvictim% | number |
%actor.food% | number |
%actor.gamemode% | text |
%actor.groundblock% | text |
%actor.health% | number |
%actor.healthpercent% | number |
%actor.helditem% | text |
%actor.heroicpieces% | number |
%actor.level% | number |
%actor.maxhealth% | number |
%actor.ownedground% | true / false |
%actor.setweapon% | true / false |
%actor.souls% | number |
%actor.totalexp% | number |
%actor.type% | text |
%actor.world% | text |
%actor.y% | number |
victim. — the entity they hit
Facts about the combat victim. Only meaningful on combat triggers (ATTACK, DEFENSE, KILL, …).
| Variable | Type |
|---|---|
%victim.blocking% | true / false |
%victim.flying% | true / false |
%victim.food% | number |
%victim.fromspawner% | true / false |
%victim.gliding% | true / false |
%victim.health% | number |
%victim.healthpercent% | number |
%victim.helditem% | text |
%victim.heroicpieces% | number |
%victim.inzone% | true / false |
%victim.maxhealth% | number |
%victim.mobtype% | text |
%victim.relation% | text |
%victim.sneaking% | true / false |
%victim.souls% | number |
%victim.sprinting% | true / false |
%victim.swimming% | true / false |
%victim.type% | text |
block. — the block in play
Facts about the block (e.g. on a MINE/BREAK trigger).
| Variable | Type |
|---|---|
%block.type% | text |
world. — the world & weather
Facts about the world the activation happened in.
| Variable | Type |
|---|---|
%world.raining% | true / false |
%world.thundering% | true / false |
%world.time% | number |
Combat & state facts (no scope prefix)
Bare facts about the current activation and the player's state.
| Variable | Type |
|---|---|
%attackerindex% | number |
%blocking% | true / false |
%combo% | number |
%damage% | number |
%damagecause% | text |
%distance% | number |
%equipchange% | text |
%flying% | true / false |
%gliding% | true / false |
%heldticks% | number |
%impactheight% | number |
%isblock% | true / false |
%nearbyallies% | number |
%nearbyenemies% | number |
%onfire% | true / false |
%onground% | true / false |
%projectilekind% | text |
%proximityevent% | text |
%ragestacks% | number |
%recentattackers% | number |
%selected% | number |
%sneaking% | true / false |
%soulcost% | number |
%sprinting% | true / false |
%swimming% | true / false |
:::tip Variables work in messages and SET_VAR too
The same %name% placeholders expand inside a MESSAGE effect and as the value of a SET_VAR. So you can write { MESSAGE: { text: "&7You hit %victim.type% for %damage%" } } or stash a fact for a later condition.
:::
Operators
Comparing numbers and values
| Operator | Means |
|---|---|
== | equal to |
!= | not equal to |
< | less than |
<= | less than or equal to |
> | greater than |
>= | greater than or equal to |
Comparing text
| Operator | Means |
|---|---|
contains | text contains the substring |
matchesregex | text matches the regular expression |
Text comparisons are handy for things like the held item or mob type:
condition: "%actor.helditem% contains DIAMOND"
condition: "%victim.type% == ZOMBIE"
Combining clauses
Glue clauses together with the usual boolean operators, and group with parentheses:
| Glue | Meaning |
|---|---|
&& | and — both sides must be true |
|| | or — either side may be true |
! | not — flip a clause |
( ) | group, to control precedence |
# Below half health AND either sneaking or it's night
condition: "%actor.healthpercent% < 50 && (%sneaking% || %world.time% > 13000)"
Flow & chance clauses
Sometimes you don't want a plain gate — you want the condition to change the outcome instead of just blocking it. For that, end the condition with a clause shaped <test> : <outcome>: the outcome is applied only when the test is true.
| Clause | What it does when the test is true |
|---|---|
%continue% | proceed to the chance roll as normal |
%stop% | block this activation |
%force% | force activation, skipping the chance roll |
%allow% | allow activation regardless of the chance roll |
±N %chance% | add N percentage points to the chance roll |
A bare condition with no clause is just a gate (false = stop). Adding a clause lets you nudge the chance roll or override it:
# Base 20% chance, but when you're below 25% HP, force it through.
chance: 20
condition: "%actor.healthpercent% < 25 : %force%"
# Base 10% chance, +40 points while sneaking (so 50% when sneaking).
chance: 10
condition: "%sneaking% : +40 %chance%"
# Never fire on players in creative.
condition: "%actor.gamemode% == CREATIVE : %stop%"
:::tip %force% vs %allow%
%force% makes the ability fire and skips the chance roll entirely. %allow% lets it through regardless of the chance roll but still respects everything else. Use %force% for "this absolutely must happen now," %allow% for "don't let the dice block this one."
:::
Cookbook
A few complete, copy-pasteable conditions:
# Execute: only against low-health victims.
condition: "%victim.healthpercent% < 20"
# Combo finisher: reward sustained melee.
condition: "%combo% >= 5"
# Crowd control: only when outnumbered.
condition: "%nearbyenemies% >= 3"
# Stormcaller: only fires during a thunderstorm.
condition: "%world.thundering%"
# Sniper bonus: long-range hits only.
condition: "%distance% > 25"
# Anti-cheese: skip if the victim is blocking, otherwise normal roll.
condition: "%victim.blocking% : %stop%"
# Aerial: airborne and gliding with elytra.
condition: "!%onground% && %gliding%"
# Tank stance: heavy bonus while sneaking and full HP.
chance: 5
condition: "%sneaking% && %actor.health% == %actor.maxhealth% : +60 %chance%"