Skip to content

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:

TypePurposeResolution time
Expression variableNumeric, boolean, and random-config evaluationWhen ExpressionEngine or a module-specific parser evaluates the value
Internal template variableAction, name, lore, and message replacementWhen the module builds text or an ActionContext
PlaceholderAPI placeholderData exposed to scoreboards, menus, chat, and other pluginsWhen PlaceholderAPI receives a request
Runtime contextDamage, gameplay-event, skill invocation, or other data MapWhen 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

PluginMain expression contextsInternal templates / actionsPlaceholderAPI
CoreLibCaller Map and local random-config variablesPlayer, phase, loop, and caller-provided keysNo expansion; delegates to PAPI at the end
AttributeDamage stages, recovery, DamageContextDamage messagesemakiattribute
StrengthenCurrency cost; limited effect referencesItem presentation and result actionsemakistrengthen
SkillsParameters, custom variables, upgrade costScript text and upgrade messagesemakiskills
ItemItem build, EA attributes, repair costItem actions and set presentationemakiitem
ForgeMaterial stats/EA attributes/capacity random valuesResult item presentation and actionsemakiforge
CookingNutrition action amountRecipe rewards and nutrition messagesemakicooking
GemStats/EA attributes, costs, inlay rateInlay, upgrade, and extraction resultsemakigem
LevelRequirements, source XP, attributes, costsLevel operation and upgrade resultsemakilevel
CodexNo private formula context; uses GameplayEvent conditionsTrigger and advancement-completion textNo 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 to 0.
  • A random config's local variables override 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

VariableMeaning
%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

EventVariables
Block break / placeblock_type
Entity kill / tameentity_type
MythicMobs killmythic_id, mythic_level
Craft / furnace extractresult_type, result_amount
Fishingfish_state
Brewing completepotion_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.

VariableMeaning / unit
input, baseDamage points entering the current stage
flatAggregated flat attribute value
percentPercentage points
chanceTrigger chance, 0..100
multiplierMultiplier attribute in percentage points
rollCurrent random roll, 0..100
critTriggered state, 1 or 0
Any DamageContext keyCaller- 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, range 0..1.
  • Dodge: dodge_chance, dodge_roll, dodged; chance and roll use 0..100.
  • Falling: fall_distance, jump_boost_level, vanilla_fall_damage, fall_damage_formula.

DamageContextVariables normalizes keys to lowercase identifiers.

Recovery recovery.expression

VariableMeaning
input, base, damage, final_damageFinal damage points
flat, healing_flatFlat recovery points
percent, healing_percentRecovery percentage points
percent_amount, healing_percent_amountDamage-derived recovery amount
gross, healing_grossGross recovery before resistance
resistance, healing_resistanceRecovery 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

VariableMeaning
base_costBase currency cost
starTarget 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:

VariableMeaning
level, target_level, max_levelSkill level context
current_levelAdditional current level in resolveAtLevel
skill_id, trigger_idSkill and trigger ids
is_passivePassive state, 1/0
player_levelVanilla experience level
player_health, player_max_healthBukkit health points
sneaking, has_targetBoolean 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

VariableMeaning
max_damageMaximum durability
damage, current_damage, missing_durabilityCurrent missing durability points
missing_ratioMissing ratio, 0..1
restore_amountDurability restored by this operation
restore_ratioRestored ratio, 0..1
base_costBase 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_cost and capacity_bonus.value accept random numeric configs but receive no variable context; results are rounded to integer capacity.
  • effects[type=variables].variables starts with an empty Map per material. Later entries may reference previously resolved stat keys from that material.
  • effects[type=ea_attribute].ea_attributes uses 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

EntryVariables
Gem variables / ea_attributeslevel plus earlier same-category dynamic keys
Resonance EA attributesNo fixed initial key; only earlier resonance attribute keys
inlay_success.rate_formuladefault_chance, level_chance, configured_chance, level
Inlay/extract/upgrade cost_formulalevel, 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

EntryVariables
Upgrade XP requirement formulacurrent_level, target_level, max_level, exp, total_exp
Level attributes attributes.<id>level, exp, total_exp
Upgrade currency/material costtarget_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

  1. Identify whether the field uses an expression, an internal template, PAPI, or a runtime context.
  2. Use only the fixed keys listed for that scope and dynamic keys explicitly produced by that configuration.
  3. Percentage conventions differ between 0..1 and 0..100; follow the module-specific rule.
  4. Where dynamic keys depend on Map order, do not rely on unverified YAML/Map reordering behavior.
  5. Dynamic-id parsing is not consistent across Attribute, Level, and other modules. Avoid underscores in resource and ranking type ids where noted.
  6. Event-based variables are conditional; handle missing keys separately for each event type.