Expressions
Expressions are used to calculate numeric, text, and boolean values in configuration. They are commonly used for costs, chances, scaling, requirements, rewards, and random values.
Variables
Variables are supplied entirely by the calling module and the current field. CoreLib does not inject one global set of business variables into every formula. Cost, success-rate, attribute-value, action, and message fields may use different contexts even within the same plugin.
See the Variable, Expression, and Placeholder Context Matrix for the real variables, units, and scope restrictions derived from the production parsers, services, models, and PlaceholderAPI expansions of all ten plugins.
Variables use the %name% syntax. Numeric expressions require variables to resolve to numbers; text templates convert variables to strings. Do not treat an internal template variable or PlaceholderAPI placeholder as a formula variable unless that formula context explicitly provides it.
Numeric expressions
CoreLib uses exp4j for numeric expressions and registers several helper functions.
| Type | Supported syntax |
|---|---|
| Operators | +, -, *, /, %, ^, parentheses |
| One-argument functions | ceil(x), floor(x), round(x), log10(x) |
| Two-argument functions | min(a,b), max(a,b), pow(a,b) |
economy:
enabled: true
base_cost: 100
cost_formula: '100 + %star% * 50'quality:
chance_formula: 'min(0.95, 0.05 + %material_score% * 0.001)'Numeric expressions are limited for safety:
- Maximum expression length is 256 characters.
- Maximum nested evaluation depth is 10.
- Backticks, dollar signs, and backslashes are not allowed.
- After variables are resolved, a numeric expression may only contain numbers, whitespace, operators, parentheses, commas, and supported function names.
- Results must not be
NaNor infinite.
Boolean expressions
Boolean expressions are used by conditions and pipeline if branches.
Truthy literals: true, yes, y, on, 1.
Falsy literals: false, no, n, off, 0.
| Operation | Example |
|---|---|
| Numeric comparison | %level% >= 10, %score% < 100 |
| String equality | "forge" == "forge", %phase% != "fail" |
| AND | %level% >= 10 && %money% >= 100 |
| OR | `%rarity% == "rare" |
| NOT | !%locked%, !(%level% < 10) |
| Parentheses | `(%a% > 0 && %b% > 0) |
String comparisons should be quoted to avoid numeric-expression ambiguity.
condition:
entries:
- type: expression
expression: '%player_level% >= 20 && %money% >= 1000'Text templates
Text evaluation replaces %name% variables with string values.
message: 'Current level: %level%, next cost: %next_cost%'Missing text variables are replaced with an empty string and reported in detailed evaluation results. Numbers are formatted compactly: integer values are shown as integers, and decimals are shortened.
Object syntax is also supported:
name:
type: string
value: 'Lv.%level% Stone'type accepts only these two literals, with no aliases:
| Type | Accepted value |
|---|---|
| String | string |
| Boolean | boolean |
str, text, bool, and flag are not recognised; such a config falls into the parse-failure branch.
Random numeric configs
Numeric fields can also be written as random config objects.
Range shorthand
A string in the form min~max means uniform random:
reward_amount: '10 ~ 20'Both sides can be expressions:
reward_amount: '%level% * 5 ~ %level% * 8'Local variables
Random config objects may define local variables:
amount:
type: expression
variables:
base: 100
bonus: '%level% * 5'
value: '%base% + %bonus%'variables extend or override outer variables for the current config and its children.
Supported numeric config types
| Type | Aliases | Fields | Description |
|---|---|---|---|
constant | - | value | Fixed value. |
range | - | value or min + max | Uses value if present; otherwise behaves like uniform. |
uniform | - | min, max | Uniform random in [min,max]. |
gaussian | - | optional mean, std_dev, min, max, max_attempts | Normal distribution. Defaults derive from min/max when possible. |
skew_normal | - | same as gaussian, plus skewness | Skew-normal distribution. skewness defaults to 0. |
triangle | - | optional mode, deviation | Triangle distribution. Defaults: mode=0, deviation=1. |
expression | - | value | Numeric expression. |
bonus:
type: uniform
min: 5
max: '10 + %level%'quality_score:
type: gaussian
min: 0
max: 100
mean: '50 + %material_quality% * 5'
std_dev: 12
max_attempts: 128If type is missing, CoreLib tries to infer the config:
valueexists: evaluatevalue.minandmaxexist: treat asuniform.expressionexists: evaluate as an expression.- Otherwise the config is unsupported.
Random text configs
Text configs can randomly select one or more text candidates. Supported types:
random_textrandom_text_linesrandom_linesrandom_linetext_lines
Candidate field: lines.
| Field | Aliases | Default | Description |
|---|---|---|---|
count | - | 1 | Number of selected lines. Can be a numeric expression or random numeric config. |
allow_duplicates | - | false | Whether the same candidate can be selected multiple times. |
separator | - | newline | Separator used when joining multiple results. |
message:
type: random_text
count: 1
lines:
- '<green>Forge success!</green>'
- '<gold>Sparks fly as the item takes shape.</gold>'
- '<aqua>%player_name% created a masterpiece.</aqua>'Quantity configs
Fields that need "a number worked out per situation" — costs, chances, capacities, experience — can also be written as a quantity config object, in addition to plain formulas and random configs. Three types are supported.
Fixed
quantity: 100The equivalent long form:
quantity:
type: fixed
value: 100Formula
quantity:
type: formula
expression: "player_level * 10 + 50"Lookup table
Looks up the integer value of a variable, falling back to default on a miss:
quantity:
type: lookup_table
key: player_level
default: 0
table:
1: 10
2: 20
5: 50| Field | Default | Description |
|---|---|---|
type | fixed | One of fixed, formula, lookup_table (alias table). |
value | 0 | The value used by fixed. |
expression | "0" | The formula used by formula. |
key | player_level | Variable name the lookup table reads. |
default | 0 | Value used when the lookup table misses. |
table | empty | Integer-key to number mapping. Entries whose key is not an integer are skipped. |
An invalid form does not raise an error; it degrades in this order:
- A plain number or numeric string is treated as
fixed. - A config section is parsed by
type; an unknowntypedegrades tofixedand readsvalue. - Blank or absent becomes
fixed(0).
Cron expressions
A cron field uses the 6-field Quartz format and fires on real system time, not game ticks:
second minute hour day-of-month month day-of-week*, ? (equivalent to *), literal values, , enumerations, - ranges, and / steps are supported.
"0 0 19 * * ?" every day at 19:00:00
"0 30 8 ? * MON-FRI" weekdays at 08:30:00
"0 0/15 * * * *" every 15 minutesIf no next fire time exists within 4 years, the task is not scheduled. An invalid expression skips only that task and leaves a console warning; the rest of the plugin is unaffected.
cron is used by EmakiMobs spawn rules (type: autonomous with trigger: cron) and by scheduled EmakiSkills passive skills.
Random char configs
Text configs also support three families of random char types. They share the count, allow_duplicates, and separator control fields with the same meaning as random text configs.
| Type | Aliases | Candidate field |
|---|---|---|
random_char | random_chars, char_random, chars_random | chars |
weighted_random_char | weighted_random_chars, weighted_char, weighted_chars, weighted_char_random | chars |
conditional_char | condition_char, case_char, if_char | cases |
When chars is omitted, abcdefghijklmnopqrstuvwxyz is used.
suffix:
type: random_char
count: 3
chars: 'ABCDEF'conditional_char evaluates the condition of each entry in cases in order and returns the value of the first one that is true. If none match, it returns fallback, or an empty string when fallback is absent.
grade_mark:
type: conditional_char
cases:
- condition: '%level% >= 50'
value: 'S'
- condition: '%level% >= 20'
value: 'A'
fallback: 'B'YAML tips
- Quote expressions containing
>,<,:,{},%,#,&, or*. - Verify whether a module expects chance values as
0~1or0~100; the pipelinechancegate supports both decimals and percent notation. - Clamp money, amount, and level formulas with
max(0, value)when negative values are invalid. - Random configs can nest, but nested evaluation depth is limited to 10.
Troubleshooting
Expression cannot be parsed
Common causes:
- Mismatched parentheses.
- Missing or misspelled variables.
- Unsupported functions.
- Disallowed characters such as backticks, dollar signs, or backslashes.
- Unquoted YAML strings containing special characters.
Result is unexpected
Check the actual variables injected by the current module, integer vs decimal behavior, percentage conventions, clamping or rounding logic, and whether string comparisons are quoted.
Random config always returns 0
Common causes include a misspelled type, missing min / max for uniform, missing value for expression configs, or nested variables that cannot resolve to numbers.