Skip to main content

Number Provider Types

Every value that must change with level, realm or event context is a NumberProvider. Evaluation happens on the server; the client only uses the synchronized result.


Shorthand

A JSON number is automatically parsed as a constant:

"amount": 5

A JSON string is automatically parsed as an expression:

"amount": "4 + level * 0.5"

Anything else is a structured provider object with an inlined type:

"amount": {
"type": "mxt:constant",
"value": 5
}

Structured Expressions

{
"type": "mxt:expression",
"expression": "base_damage * multiplier",
"params": {
"base_damage": 8,
"multiplier": "1 + level * 0.1"
}
}

The values inside params are themselves NumberProviders and override the context variables of the same name. An unregistered variable inside an expression is treated as 0. A formula syntax error fails the datapack reload; a runtime NaN or infinity logs a one-line warning and returns 0.

Parameter names must be valid variable names: the first character is a letter or _, and the rest may be letters, digits or _. Every key in params must actually appear in the expression, otherwise the load is rejected.


Built-In Providers

mxt:constant

FieldTypeDefaultDescription
valueDoublerequiredFixed value; must be finite

A JSON number is equivalent to this type.

{"type": "mxt:constant", "value": 12}

mxt:expression

FieldTypeDefaultDescription
expressionStringrequiredexp4j expression
paramsObject of NumberProvider{}Values that override context variables of the same name
{
"type": "mxt:expression",
"expression": "heal + bonus",
"params": {"bonus": "level * 0.5"}
}

mxt:context_variable

FieldTypeDefaultDescription
variableStringrequiredName of the context variable to read
fallbackDouble0Value used when the context does not contain the variable
{"type": "mxt:context_variable", "variable": "absorbed_aura", "fallback": 0}

mxt:sum

FieldTypeDefaultDescription
summandsList of NumberProviderrequiredThe values to add; at least one entry
{"type": "mxt:sum", "summands": [1, "level * 0.25", {"type": "mxt:uniform", "min": 0, "max": 2}]}

mxt:uniform

FieldTypeDefaultDescription
minNumberProviderrequiredLower bound
maxNumberProviderrequiredUpper bound

The value is drawn from the RandomSource carried by the passed context. Equal bounds return that bound directly, and min greater than max logs a warning and returns 0.

{"type": "mxt:uniform", "min": 2, "max": "2 + level"}

mxt:binomial

FieldTypeDefaultDescription
nNumberProviderrequiredNumber of Bernoulli trials; an integer from 0 to 16384
pNumberProviderrequiredSuccess probability from 0 to 1

Returns the number of successes. Out-of-range parameters log a warning and return 0.

{"type": "mxt:binomial", "n": 5, "p": 0.35}

mxt:weighted_list

FieldTypeDefaultDescription
distributionList of entriesrequiredAt least one entry

Each entry has its own fields:

FieldTypeDefaultDescription
dataNumberProviderrequiredThe value produced by this entry
weightIntegerrequiredPositive integer weight; larger weights are picked more often
{
"type": "mxt:weighted_list",
"distribution": [
{"data": 1, "weight": 3},
{"data": "level * 2", "weight": 1}
]
}

mxt:conditional

FieldTypeDefaultDescription
branchesList of branches[]Branches checked in order
fallbackNumber or expression stringnoneValue used when there is no Player or no branch matched; 0 when omitted

Each branch has its own fields:

FieldTypeDefaultDescription
conditionEntityConditionrequiredCondition tested against the player
valueNumberProviderrequiredValue returned when the condition passes

fallback only accepts a number or an expression string, not an arbitrary provider object.

{
"type": "mxt:conditional",
"branches": [
{"condition": {"type": "mxt:sneaking"}, "value": 4},
{"condition": {"type": "mxt:has_realm", "resource": "example:qi"}, "value": "level + 1"}
],
"fallback": 1
}

mxt:js

FieldTypeDefaultDescription
idStringrequiredCallback ID registered with MxtValues.number(...)
paramsObject{}Arbitrary JSON passed to the callback

Calls a KubeJS number provider extension. When no callback is registered for id, the provider logs a warning and returns 0. See the KubeJS API Reference.

{"type": "mxt:js", "id": "example:luck_roll", "params": {"base": 3}}

Aura Concentration Sources

Two numbers describing the aura at a position are provided by the separate resource_value_provider_type family rather than by number_provider_type:

typeDescription
mxt:environment_concentrationThe environmental template concentration at the current position. Only environmental sources such as biome, dimension and zone are counted; chunk storage and aura released by blocks or formations are excluded.
mxt:actual_concentrationThe final resolved concentration at the current position, including the environment, chunk storage and every active source such as blocks and formations.

The full list of resource value providers is in Other Type Families.

The RandomSource of an entity or a Level is passed to the random providers first. Do not re-roll a random value on the client to decide a game result; the client only displays the synchronized server result.


Formula Functions

Formulas are evaluated with exp4j. The mod registers these additional functions into the built-in mxt:formula_function registry:

FunctionArgumentsDescription
round(x)1Rounds to the nearest whole number
clamp(x, min, max)3Limits x to the inclusive range min..max
min(a, b)2Smaller of the two values
max(a, b)2Larger of the two values

The standard exp4j functions are also available: abs, acos, asin, atan, cbrt, ceil, cos, cosh, exp, floor, log, log10, sin, sinh, sqrt, tan and tanh. The constants pi and e are recognized as well.


Formula Variables

Formulas read named variables. An explicit value in the context always wins over the variable registry, an unknown name resolves to 0, and params overrides any name.

Which names exist depends on where the formula is evaluated: every resource, cultivation and ability formula runs with an entity context, bi-entity formulas add the target_ set, and each trigger adds a few names of its own. Only rely on the names that the context in question provides.

Registry Variables

The built-in mxt:formula_variable registry provides two names that work in every context:

VariableDescription
zeroAlways 0
randomA new random double between 0 and 1, drawn from the authoritative RandomSource of the context

Entity Variables

Whenever a context is built from a living entity (resource regeneration, cultivation, abilities, contracts, forging, alchemy), these names are added:

VariableDescription
caster_healthCurrent health of the entity
caster_max_healthMaximum health of the entity
caster_levelExperience level of the entity when it is a player, otherwise 0
caster_<resource>Current value of every resource the entity holds
caster_<attribute>Current value of every synchronized attribute of the entity

Bi-entity contexts (target_condition, bi_entity_action, and the aura ability's target action) add the same set a second time with the target_ prefix: target_health, target_max_health, target_level, target_<resource> and target_<attribute>.

<resource> and <attribute> are the registry ID with the namespace and path joined by _; /, . and - inside the path also become _:

IDVariable
mxt:spirit_powercaster_mxt_spirit_power
example:fire/qicaster_example_fire_qi
minecraft:max_healthcaster_minecraft_max_health
minecraft:attack_damagecaster_minecraft_attack_damage

Only synchronized attributes are exposed, so an attribute that the client does not need is not available in a formula.

caster_level is not the realm

caster_level is the vanilla experience level. The realm rank is the separate level / realm_rank variable described below, and it only exists in a resource context.

Resource and Cultivation Variables

Formulas evaluated for one resource — resource.max, resource.regen, the resource conversions, resource costs, realm stages, breakthrough conditions and resource bars — add the cultivation state of that resource on top of the entity context:

VariableDescription
realmRank of the current realm in this resource's chain; 0 when the chain does not match
realm_rankSame value as realm
levelSame value as realm, kept as a shorthand for realm formulas
absorbed_auraAccumulated cultivation progress of this resource; 0 when the chain does not match
cultivation_progressSame value as absorbed_aura

A resource definition can therefore write:

{
"max": "100 + realm_rank * 50 + absorbed_aura * 0.5",
"regen": "0.25 + realm_rank * 0.1"
}

Ability Variables

VariableAvailable whenDescription
element_modifierThe ability declares a non-empty element_affinityThe element affinity multiplier computed for the caster, usable to scale damage or costs by element match

Abilities of the aura type also evaluate the target action once per affected entity with two extra names:

VariableDescription
aura_radiusThe radius resolved for this aura pulse
distanceDistance in blocks between the caster and the current target

Trigger Variables

Abilities with a triggered type are evaluated when the trigger fires, and the trigger adds these names to the entity context:

TriggerVariables addedDescription
tickEntity context only
attacktarget_is_living, target_healthtarget_is_living is 1 when the attacked entity is a living entity
hurtdamageDamage that was actually inflicted on the caster
killtarget_healthHealth of the killed entity at the moment of death
deathvictim_healthHealth of the dying entity, floored at 0
block_break, block_useblock_x, block_y, block_zCoordinates of the block involved
item_useuse_durationTicks the used item took to finish
equipequipment_slotOrdinal of the changed equipment slot
breakthroughbreakthroughAlways 1, so it can be used as a flag

Variables From Other Systems

VariableProvided byDescription
damageContract combat actionsDamage the contracted spirit beast just dealt
aura_tribulation_modifierTribulation phasesLocal aura influence, taken from the tribulation_modify rule of the aura zone

Custom Variables

mxt:expression accepts params, whose values are themselves NumberProviders and replace the context variable of the same name:

{
"type": "mxt:expression",
"expression": "realm_rank * scale + bonus",
"params": {
"scale": 1.5,
"bonus": "caster_minecraft_attack_damage * 0.5"
}
}

Use params when one formula must depend on a value that the current context does not provide, or when the same expression is reused in several tables with different constants.