Expression (Data Type)

A String representing a mathematical expression.

A String representing a mathematical expression. Any field documented as accepting an Expression also accepts a plain number.

Where Expressions work

ConsumerFields
Attribute Modifiervalue
Status Effect Instanceduration, amplifier (evaluated against the entity receiving the effect)
apoli:chancechance
apoli:resource / apoli:cooldownmin, max, start_value / cooldown
Resourcecompare_to
apoli:change_resourcechange
Entity actionsadd_velocity (x/y/z), damage (amount), heal, exhaust, feed (food/saturation), gain_air, add_xp (points/levels), set_on_fire (duration)

Operators

OperationOperator(s)SyntaxDescription
Addition+a + bAdds a and b.
Subtraction-a - bSubtracts b from a.
Multiplication*, ×a * bMultiplies a by b.
Division/, ÷a / bDivides a by b.
Fraction_a_bRepresents a fraction of a / b.
Mixed number_c_a_bc + (a / b).
Exponentiation^a^bRaises a by the power of b (right-associative).
Factorial!a!Factorial of a.
Modulo#a # ba mod b.
Percentage%a%Decimal form of a as a percentage: (a / 100).
Negation--aNegative of a.
Tetration (hyper-4)^^a^^ba raised to itself b times.
Integer division\a\bInteger part of a / b.
Implied multiplication()a(b), 2xa * b.
Comparison==/=, !=/<>, <, <=, >, >=a < b1 if true, 0 if false, multiply or feed into if() to branch.
Boolean AND&&, &a && b1 if both are non-zero, else 0. Binds tighter than OR.
Boolean OR\|\|, \|a \|\| b1 if either is non-zero, else 0. Lowest precedence.

Functions

NameFunctionSyntaxDescription
Square rootsqrt()sqrt(a)√a.
Absolute valueabs()abs(a)|a|.
Minimum / Maximummin(), max()min(a, b, ...)Smallest / largest argument (any count).
Clampclamp()clamp(v, lo, hi)v limited to [lo, hi].
Floor / Ceilingfloor(), ceil()floor(a)Round down / up.
Roundround()round(a)Round to nearest integer.
Signsign(), sgn()sign(a)-1, 0 or 1.
Linear interpolationlerp()lerp(a, b, t)a + (b - a) * t.
Branchif()if(cond, then, else)then if cond is non-zero, else else. Only the taken branch is evaluated.
Logicand(), or(), not()and(a, b, ...)Boolean logic over non-zero values, returns 1/0.
Modulo / Powermod(), pow()mod(a, b)Function forms of # and ^.
Sine / Cosine / Tangentsin(), cos(), tan(), tg()sin(a)Trigonometry (radians).
Secant / Cosecant / Cotangentsec(), csc(), cosec(), cot(), ctg(), ctan()sec(a)Reciprocal trigonometry.
Inverse trigasin(), acos(), atan() (+ ar…/arc… aliases)asin(a)Inverse trigonometry.
Two-argument arctangentatan2()atan2(y, x)Angle of the point (x, y) in radians.
Hyperbolicsinh(), cosh(), tanh() (tgh, th), coth() (ctgh, cth), sech(), csch() (cosech)sinh(a)Hyperbolic functions.
Inverse hyperbolicasinh(), acosh(), atanh() (+ ar…/arc… aliases)asinh(a)Inverse hyperbolic functions.
Logarithmsln(), log2(), lg(), log10()ln(a)Natural, binary and common log.
Arbitrary-base logarithmlog()log(base, a)Log of a in base base.
Exponentialexp()exp(a)e^a.
Cube root / n-th rootcbrt(), root()root(n, a)∛a / n-th root of a (odd integer roots of negatives work).
Hypotenusehypot()hypot(a, b)√(a² + b²) without overflow.
Degrees / Radiansdeg(), rad()deg(a)Radians → degrees / degrees → radians.
Averageavg(), mean()avg(a, b, ...)Arithmetic mean of the arguments (any count).

Constants: pi, e.

Random functions

NameFunctionSyntaxDescription
Random uniform continuousrUni()rUni(a, b)Random real in [a, b].
Random uniform discreterUnid()rUnid(a, b)Random integer in [a, b].
Normal (Gaussian)rNor()rNor(μ, σ)Drawn from N(μ, σ).
Random from listrList()rList(a, b, ..., z)Random element (only the chosen one is evaluated).

Random generators

NameFunctionDescription
Random integer[Int]Random integer in [-2^31, 2^31 - 1].
Random bounded integer[IntX]Random integer in [-(10^X), 10^X], X = 1–9.
Random natural (incl. 0)[nat]Random integer in [0, 2^31 - 1].
Random natural (incl. 0, bounded)[natX]Random integer in [0, 10^X].
Random natural (excl. 0)[Nat]Random integer in [1, 2^31 - 1].
Random natural (excl. 0, bounded)[NatX]Random integer in [1, 10^X].
Random uniform [0, 1][Uni]Random uniform real in [0, 1].
Standard normal[Nor]Drawn from N(0, 1).

Bound variables

Variables are resolved when the expression is compiled and read live from the entity each evaluation. If the evaluating context has no entity (e.g. chance in a block action), entity variables read 0.

VariableMeaning
valueContext-dependent: the current resource/cooldown value in resource operations; the unmodified base value inside an Attribute Modifier. 0 elsewhere.
damageThe damage amount of the hit, inside actions fired by action_on_hit / action_when_hit (including their self/target/attacker/bi-entity actions and anything nested in them, e.g. a modify_resource with "value": "damage * 2"). 0 outside a hit context.
<namespace>:<path>Value of any Resource/Cooldown power the entity has (the full power id is the variable name). Missing → 0.
<namespace>:<path>_maxThe maximum of that Resource/Cooldown power, evaluated live — so it follows an expression-valued max. If no such resource exists, the whole name is read as a plain resource id instead. Missing → 0.
<namespace>:<path>_minThe minimum of that Resource power, same rules as _max.
health / max_healthCurrent / maximum health.
absorptionAbsorption hearts.
armorArmor value.
air / max_airAir supply ticks / maximum.
fall_distanceCurrent fall distance in blocks.
x, y, zEntity position.
yaw, pitchHead rotation in degrees.
velocity_x, velocity_y, velocity_zCurrent motion vector.
foodFood level (0–20). Players only, else 0.
saturationSaturation level. Players only, else 0.
xp_levelExperience level. Players only, else 0.
xp_progressProgress in the current XP level (0.0–1.0). Players only, else 0.
world_timeThe level’s game time (ticks).
day_timeThe level’s time-of-day (# 24000 for the clock time).
moon_phaseMoon phase, 0–7.

Unknown variable names, unknown functions and any other syntax error are a load-time error: the power (or other JSON file) containing the expression fails to parse and the error message names the offending expression and position. There is no fallback engine — the compiled engine is the only evaluator (the bundled mXparser fallback was removed in July 2026; everything it was kept around for is now supported natively).

Reading a resource’s bounds

Suffixing a resource id with _max or _min reads that resource’s limit rather than its current value:

{ "type": "apoli:change_resource", "resource": "example:mana", "change": "example:mana_max / 10", "operation": "add" }

The bound is evaluated at the same moment as the expression around it, so a resource whose max is itself an Expression ("max": "20 + 5 * xp_level") reports its current ceiling, not a stale one.

If there is no resource power at the stripped id, the name is treated as an ordinary resource id — so a resource genuinely called example:mana_max still resolves to its own value. Bound lookups nest up to 8 deep; beyond that they read 0, which stops a cycle (a max referring to its own _max) from hanging the server.

NaN policy

If an Expression evaluates to NaN or ±Infinity (e.g. division by zero, sqrt(-1)), Apoli substitutes 0. Use if() for explicit fallbacks: if(max_health > 0, health / max_health, 1).