Expressions
The compiled math engine behind number fields that read the world.
Many numeric fields — amount, chance, velocity components, duration — accept not just a constant but an expression: a bit of math that can reference the entity’s state. "amount": "health * 0.5" heals for half the entity’s current health. This page is for addon authors who want their own fields to accept expressions.
Accepting an expression
Use Expression.FLOAT_OR_EXPR instead of Codec.FLOAT for a field that should accept either a number or an expression string:
public record Cfg(Expression amount) {}
Expression.FLOAT_OR_EXPR.fieldOf("amount").forGetter(Cfg::amount) A data pack can now write either form:
{ "amount": 4 }
{ "amount": "2 + armor" } Evaluating it
Expressions are compiled once at load, then evaluated cheaply per use. Evaluate against the entity, its container, and the level:
float value = cfg.amount().eval(entity, container, level, /* fallback */ 0f); The engine resolves variables (like health, armor, resource values) from that entity without allocating maps. Keep a compiled Expression; never re-parse a string at runtime.
Contextual variables
Some triggers expose extra variables. In a damage context, damage is bound to the incoming amount, so a modifier can be "damage * 0.5". These are set on a thread-local before evaluation and cleared after — read them, don’t hold them.
Performance
- Compile once, eval many. Parsing is done at load;
evalis the hot path and must stay allocation-free. - The built-in engine is the fast path; a general parser exists only as a fallback for expressions it can’t compile. Prefer syntax the fast engine understands.
- Don’t call
evalmore often than you need — cache the result within a tick if it’s reused.