Variable, Expression, and Placeholder Context Matrix
This page is derived from the 4.5.6 production parsers, services, models, and PlaceholderAPI expansions. It covers CoreLib, Attribute, Strengthen, Skills, Item, Forge, Cooking, Gem, Level, and Codex.
Four different systems share similar syntax
Many values use %key%, but they are not one global variable system:
| Type | Purpose | Resolution time |
|---|---|---|
| Expression variable | Numeric, boolean, and random-config evaluation | When ExpressionEngine or a module-specific parser evaluates the value |
| Internal template variable | Action, name, lore, and message replacement | When the module builds text or an ActionContext |
| PlaceholderAPI placeholder | Data exposed to scoreboards, menus, chat, and other plugins | When PlaceholderAPI receives a request |
| Runtime context | Damage, gameplay-event, skill invocation, or other data Map | When an expression, condition, or template consumes that context |
A key is valid only in its documented scope. The existence of a PAPI placeholder does not create a same-named short variable in module formulas.
Overview
| Plugin | Main expression contexts | Internal templates / actions | PlaceholderAPI |
|---|---|---|---|
| CoreLib | Caller Map and local random-config variables | Player, phase, loop, and caller-provided keys | No expansion; delegates to PAPI at the end |
| Attribute | Damage stages, recovery, DamageContext | Damage messages | emakiattribute |
| Strengthen | Currency cost; limited effect references | Item presentation and result actions | emakistrengthen |
| Skills | Parameters, custom variables, upgrade cost | Script text and upgrade messages | emakiskills |
| Item | Item build, EA attributes, repair cost | Item actions and set presentation | emakiitem |
| Forge | Material stats/EA attributes/capacity random values | Result item presentation and actions | emakiforge |
| Cooking | Nutrition action amount | Recipe rewards and nutrition messages | emakicooking |
| Gem | Stats/EA attributes, costs, inlay rate | Inlay, upgrade, and extraction results | emakigem |
| Level | Requirements, source XP, attributes, costs | Level operation and upgrade results | emakilevel |
| Codex | No private formula context; uses GameplayEvent conditions | Trigger and advancement-completion text | No expansion |
CoreLib
General ExpressionEngine
Variables are supplied by the caller Map and referenced as %name%. CoreLib does not inject one global set of business variables into every formula.
- Operators:
+,-,*,/,%,^, and parentheses. - Functions:
ceil,floor,round,log10,min,max,pow, plus runtime-registered JavaScript functions. - Maximum expression length: 256 characters. Maximum recursive depth: 10.
- Backticks,
$, and backslashes are forbidden. - Missing, self-referencing, non-numeric,
NaN, or infinite results fail detailed evaluation; the simple API normally falls back to0. - A random config's local
variablesoverride same-named outer variables. Dynamic variables are evaluated in actual Map iteration order, so a later entry may reference an already-resolved earlier entry.
Implementation: ExpressionEngine, ExpressionRules, RandomExpressionEvaluator, BooleanExpressionEvaluator.
ActionContext internal variables
| Variable | Meaning |
|---|---|
%player%, %player_name% | Player name |
%player_uuid% | Player UUID |
%player_world% | World name |
%player_x%, %player_y%, %player_z% | Player coordinates |
%phase% | Current action phase |
%template_<key>% | Action-template with.<key> argument |
%loop_id%, %loop_key%, %loop_index% | Loop id, key, and 1-based index |
%loop_times%, %loop_remaining%, %loop_interval% | Total iterations, remaining iterations, and tick interval text |
<show_item> | Separate inline token, replaced only when show_item exists |
Calling modules may add any lowercase key through ActionContext.placeholders(). attributes() are not automatically converted to template placeholders.
Implementation: PlaceholderRenderer, ActionTemplateProcessor, LoopActionService, ActionInlineTokenResolver.
GameplayEvent variables
| Event | Variables |
|---|---|
| Block break / place | block_type |
| Entity kill / tame | entity_type |
| MythicMobs kill | mythic_id, mythic_level |
| Craft / furnace extract | result_type, result_amount |
| Fishing | fish_state |
| Brewing complete | potion_type |
These values come from real Bukkit event objects and are consumed by modules such as Level and Codex.
PlaceholderAPI boundary
CoreLib registers no private PlaceholderAPI expansion. It resolves internal variables and inline tokens first, then delegates to external PAPI parsing when PlaceholderAPI and a player context are available.
Attribute
Custom damage stage stages[].expression
Only CUSTOM stages evaluate this expression.
| Variable | Meaning / unit |
|---|---|
input, base | Damage points entering the current stage |
flat | Aggregated flat attribute value |
percent | Percentage points |
chance | Trigger chance, 0..100 |
multiplier | Multiplier attribute in percentage points |
roll | Current random roll, 0..100 |
crit | Triggered state, 1 or 0 |
| Any DamageContext key | Caller- or service-provided runtime context |
Important boundary: the implementation writes the fixed keys first and then merges DamageContext. A same-named context key therefore overrides a fixed stage key. ATTACKER and TARGET sources read the snapshot first and may fall back to a same-named numeric context value; CONTEXT reads context only.
Implementation: StageCalculator, DamageContextVariables.
Standard DamageContext keys
- Entities:
attacker,attacker_name,attacker_type,attacker_uuid,source,source_name,target,target_name,target_type,target_uuid. - Damage type:
damage_type,damage_type_name,damage_type_id. - Damage values:
source_damage,input_damage,base_damage,damage,final_damage. - Cause:
cause,cause_name,cause_id,damage_cause,damage_cause_name,damage_cause_id. - Projectile:
projectile_type,projectile_uuid. - Controls:
allow_critical,allow_target_dodge,calculate_target_defense. - Random values:
damage_roll,damage_roll_flat,damage_roll_percent,damage_roll_chance,damage_roll_multiplier, range0..1. - Dodge:
dodge_chance,dodge_roll,dodged; chance and roll use0..100. - Falling:
fall_distance,jump_boost_level,vanilla_fall_damage,fall_damage_formula.
DamageContextVariables normalizes keys to lowercase identifiers.
Recovery recovery.expression
| Variable | Meaning |
|---|---|
input, base, damage, final_damage | Final damage points |
flat, healing_flat | Flat recovery points |
percent, healing_percent | Recovery percentage points |
percent_amount, healing_percent_amount | Damage-derived recovery amount |
gross, healing_gross | Gross recovery before resistance |
resistance, healing_resistance | Recovery resistance in percentage points |
Recovery inherits DamageContext and then writes its fixed keys, so the fixed recovery values override same-named context entries. The default result is gross * (1 - resistance / 100), followed by min/max constraints and a non-negative clamp.
Implementation: DamageRecoveryCalculator.
Damage message templates
message, attacker_message, and target_message use plain %key% text replacement. In addition to the entity, damage-type, damage-value, and cause keys above, they expose:
source_type, source_uuid, critical, critical_text, critical_suffix, roll, attacker_health, attacker_max_health, target_health, target_max_health, distance.
Health and distance are read only from DamageContext and render as 0 when not supplied.
Implementation: DamageMessageDispatcher.
PlaceholderAPI: emakiattribute
%emakiattribute_<attribute_id>%%emakiattribute_power%%emakiattribute_resource_<id>_current%%emakiattribute_resource_<id>_max%%emakiattribute_resource_<id>_default%%emakiattribute_resource_<id>_bonus%%emakiattribute_resource_<id>_percent%%emakiattribute_resource_<id>_regen%
The resource parser treats the text before the first underscore as the resource id. Resource ids should therefore avoid underscores.
Strengthen
Success rate
Success chance is not an ExpressionEngine formula. The implementation adds the target star's base chance to effective temper level times the per-level bonus, then clamps the result to 0..success_chance_cap.
Implementation: ChanceCalculator.
Currency cost_formula
| Variable | Meaning |
|---|---|
base_cost | Base currency cost |
star | Target star, equal to current star + 1 |
The result must be finite and greater than 0, then it is rounded to an integer cost. Otherwise the cost entry is skipped.
Effect-value boundary
stars.<n>.variables, effects[type=variables].variables, and ea_attributes accept only:
- a Number;
- a numeric string;
- a whole value that is exactly
%name%.
Arithmetic text such as %star% * 2 is not evaluated by CoreLib ExpressionEngine and falls back to 0. The only initial fixed variable is star; references to earlier dynamic keys depend on actual Map iteration order.
Implementation: StrengthenRecipe.resolveExpressions, StrengthenApiValues.evaluateNumber/evaluateMixed.
Presentation and action variables
Presentation exposes dynamic stat keys plus star, temper, max_temper, and temper_color. Attribute-line templates also receive id, sign, and value.
Success/failure actions expose:
operation_id, strengthen_operation_id, strengthen_recipe_id, strengthen_recipe, strengthen_star, strengthen_temper, strengthen_show_item, strengthen_result_slot, strengthen_max_star, strengthen_success_rate, show_item, star, temper, dropped, protected, was_star.
Implementation: StrengthenSnapshotBuilder, StrengthenActionCoordinator.
PlaceholderAPI: emakistrengthen
mainhand_star, mainhand_temper, mainhand_recipe, mainhand_eligible, mainhand_success_count, mainhand_failure_count, mainhand_max_star, mainhand_success_rate, mainhand_crack_level.
Skills
Skill parameters and custom variables
skill_parameters.* and upgrade-level parameters.* receive:
| Variable | Meaning |
|---|---|
level, target_level, max_level | Skill level context |
current_level | Additional current level in resolveAtLevel |
skill_id, trigger_id | Skill and trigger ids |
is_passive | Passive state, 1/0 |
player_level | Vanilla experience level |
player_health, player_max_health | Bukkit health points |
sneaking, has_target | Boolean state, 1/0 |
Custom skill variables may additionally reference resolved parameters and earlier custom variables. Parameters do not automatically receive results from other parameters, and TriggerInvocation.extraVariables() is currently not merged into this evaluation context.
Implementation: SkillParameterResolver, SkillVariableResolver.
Upgrade cost and text
Upgrade currency cost_formula receives the fixed context above plus base_cost, with trigger_id=upgrade. Upgrade success rates come from static tables, not formulas.
Skill script text can use level, skill_id, trigger_id, has_target, and all resolved parameter/custom dynamic keys. Upgrade messages expose player, skill_id, skill, level, current_level, target_level, max_level, success_rate, success_rate_raw, roman_level, and dynamic cost/result entries.
PlaceholderAPI: emakiskills
- Global:
cast_mode,global_cooldown,unlocked_count,slot_count,level_total. - Skill:
level_<skill_id>,cooldown_<skill_id>. - Slot:
slot_<index>_skill|name|trigger|empty. - Resource:
resource_<id>_current|max|percent.
Cooldown values use seconds. Slot indexes are zero-based.
Item
Item-build variables
Top-level variables and effects[type=variables].variables start with no fixed built-ins and are resolved in Map order. Display name, lore, structured presentation, and vanilla attribute modifiers may consume these dynamic keys.
ea_attributes and effects[type=ea_attribute].ea_attributes use a separate empty evaluation context and do not inherit top-level build variables. Do not reference build variables from EA attribute expressions.
Implementation: EmakiItemDefinitionParser, EmakiItemFactory, EmakiItemPdcWriter.
Repair cost
| Variable | Meaning |
|---|---|
max_damage | Maximum durability |
damage, current_damage, missing_durability | Current missing durability points |
missing_ratio | Missing ratio, 0..1 |
restore_amount | Durability restored by this operation |
restore_ratio | Restored ratio, 0..1 |
base_cost | Base currency cost |
Implementation: ItemRepairService.
Actions, sets, and PlaceholderAPI
Item actions: player, item_id, item_trigger, item_name.
Item-set context: item_id, set_id, piece_id, set_name, active, active_count, total, total_pieces, active_thresholds.
emakiitem PAPI: held_id, held_name, held_components, held_components_raw, loaded_count, plus held_component_has_<id>, held_component_value_<id>, and held_component_json_<id>.
Forge
Material numeric contexts
capacity_costandcapacity_bonus.valueaccept random numeric configs but receive no variable context; results are rounded to integer capacity.effects[type=variables].variablesstarts with an empty Map per material. Later entries may reference previously resolved stat keys from that material.effects[type=ea_attribute].ea_attributesuses another independent empty Map and does not inherit stat variables.
No separate Forge success-rate, quality-probability, or currency-cost ExpressionEngine formula was found.
Presentation and actions
Final name/lore receives all final stat keys plus quality, quality_name, quality_multiplier, and multiplier.
Result actions receive forge_recipe_id, forge_recipe_name, forge_source_item_name, forge_result_item_name, forge_quality, forge_multiplier, forge_multiplier_raw, forge_error_key, forge_failure_reason, forge_show_item, and show_item.
Implementation: ForgeMaterial, ForgeStatContributionBuilder, ForgeResultPostProcessor, ForgeActionCoordinator.
PlaceholderAPI: emakiforge
recipe_count, craft_count_<recipe_id>, has_crafted_<recipe_id>, total_crafts, last_crafted, guarantee_<key>.
Cooking
Expressions and internal variables
No general ExpressionEngine formula was found in the recipe production path. A nutrition operation action's amount may be an expression. Its variables are all current ActionContext placeholder and attribute values that can be converted to numbers; no additional fixed variables are injected. The unit is nutrition points, and evaluation failures fall back to 0.
Recipe reward actions: recipe_id, recipe_name, station_type, cooking_recipe_id, cooking_recipe_name, cooking_station_type, cooking_outcome.
Nutrition messages: dynamic nutrition_<type>, nutrition_<type>_max, nutrition_<type>_min, plus nutrition_type, nutrition_value, nutrition_threshold, nutrition_combo_count, nutrition_combo_required.
Implementation: NutritionOperationAction, RunRecipeRewardAction, NutritionService.
PlaceholderAPI: emakicooking
- Recipe count:
recipe_count,recipe_count_<station_type>. - Nutrition:
nutrition_<type>,nutrition_<type>_max|min,nutrition_combo_count_<rule_id>. - Station:
station_[<type>_]type|type_name|world|x|y|z|location|block|heat_block|burning|burning_seconds|heat|moisture|steam|input|input_source|input_amount|ingredient_count|recipe|recipe_id|progress|progress_target|progress_percent|completed|fluid|fluid_amount|player.
fluid_amount is measured in ml. burning_seconds is measured in seconds.
Gem
Gem values and costs
| Entry | Variables |
|---|---|
Gem variables / ea_attributes | level plus earlier same-category dynamic keys |
| Resonance EA attributes | No fixed initial key; only earlier resonance attribute keys |
inlay_success.rate_formula | default_chance, level_chance, configured_chance, level |
Inlay/extract/upgrade cost_formula | level, current_level, target_level, base_cost |
Inlay chance uses percentage points and is clamped to 0..100. Upgrade chance comes from a static per-level table, not a formula. A fixed amount >= 0 takes precedence over a currency formula; formula results are clamped non-negative.
Implementation: GemDefinition, GemResonanceLoader, GemInlayService, GemExtractService, GemUpgradeService.
Operation variables and PlaceholderAPI
Upgrade, inlay, and extraction paths provide scenario-dependent keys such as player, gem_id, gem, level, current_level, target_level, success_rate, and slot. Gem presentation context additionally exposes display_name, old_display_name, gem_type, and the per-level stat keys. Currency messages expose provider, currency, currency_id, name, display_name, required, and available; material messages expose item, material, display_name, required, and available.
emakigem PAPI: mainhand_opened_slots, mainhand_total_slots, mainhand_filled_slots, mainhand_item_definition_id, mainhand_resonance_count, plus mainhand_slot_<index>_gem|level|opened|type.
Level
Requirements and costs
| Entry | Variables |
|---|---|
Upgrade XP requirement formula | current_level, target_level, max_level, exp, total_exp |
Level attributes attributes.<id> | level, exp, total_exp |
| Upgrade currency/material cost | target_level, type, base_cost, base_amount |
A fixed values.<target_level> entry takes precedence over a requirement formula. Requirement and currency results are clamped non-negative; material amounts are rounded to non-negative integers.
Source experience
exp_formula receives only the variables carried by the current GameplayEvent; no uniform player or level variables are added:
- Entity:
entity_type. - MythicMobs:
mythic_id,mythic_level. - Block:
block_type. - Craft/furnace:
result_type,result_amount. - Fishing:
fish_state. - Brewing:
potion_type.
Mythic drop formulas additionally receive amount, drop_amount, metadata_amount, generations, and tick, with text context player, type, and drop.
A Level operation action's amount behaves like the Cooking nutrition action: it reads numeric-convertible dynamic values from ActionContext and receives no additional fixed variables.
Implementation: RequirementService, SourceExperienceService, LevelGameplaySubscriber, LevelAttributeBridge, PlayerLevelService, MythicLevelDropBridge, LevelOperationAction.
PlaceholderAPI: emakilevel
- Player:
level_<type>,exp_<type>,total_exp_<type>,totalexp_<type>,total_<type>,required_exp_<type>,requiredexp_<type>,required_<type>,progress_<type>,progress_percent_<type>. - Ranking:
top_<type>_<rank>_name|level|total_exp|totalexp|total.
The ranking parser splits on underscores. Type ids should avoid underscores.
Codex
Codex does not call a private ExpressionEngine context and registers no PlaceholderAPI expansion.
Advancement trigger conditions
Conditions use CoreLib ConditionEvaluator. Variables come from GameplayEvent and Codex additionally supplies player and world:
block_type, entity_type, mythic_id, mythic_level, result_type, result_amount, fish_state, potion_type, player, world.
The available keys depend on the event type and are not all present at once.
Trigger and completion text
Trigger/action lines can read current event keys. Advancement-completion context additionally exposes advancement_id, advancement_node, advancement_title, and advancement_page.
Codex performs local %key% replacement first, then consumes external placeholders from other PAPI expansions when a player and PlaceholderAPI are available.
Implementation: CodexGameplaySubscriber, CodexTriggerService, AdvancementListener.
Configuration checklist
- Identify whether the field uses an expression, an internal template, PAPI, or a runtime context.
- Use only the fixed keys listed for that scope and dynamic keys explicitly produced by that configuration.
- Percentage conventions differ between
0..1and0..100; follow the module-specific rule. - Where dynamic keys depend on Map order, do not rely on unverified YAML/Map reordering behavior.
- Dynamic-id parsing is not consistent across Attribute, Level, and other modules. Avoid underscores in resource and ranking type ids where noted.
- Event-based variables are conditional; handle missing keys separately for each event type.