变量、表达式与占位符上下文矩阵
本页依据 4.5.6 生产实现中的 parser、service、model 与 PlaceholderAPI expansion 整理,覆盖 CoreLib、Attribute、Strengthen、Skills、Item、Forge、Cooking、Gem、Level、Codex。
先区分四种同形语法
很多位置都写成 %key%,但它们不是同一套系统:
| 类型 | 用途 | 解析时机 |
|---|---|---|
| 表达式变量 | 数值、布尔、随机配置计算 | ExpressionEngine 或模块自身解析器求值时 |
| 内部模板变量 | Action、名称、Lore、消息等文本替换 | 对应模块构造文本或 ActionContext 时 |
| PlaceholderAPI 占位符 | 给计分板、菜单、聊天等外部插件读取 | PlaceholderAPI 请求时 |
| 运行时上下文 | 伤害、玩法事件、技能调用等携带的数据 Map | 由消费该上下文的表达式、条件或模板读取 |
同名变量只在其明确作用域内有效。不能因为某个 PAPI 占位符存在,就假定同名短变量可用于模块公式。
总览
| 插件 | 主要表达式上下文 | 内部模板 / Action 上下文 | PlaceholderAPI |
|---|---|---|---|
| CoreLib | 调用方 Map、随机配置局部 variables | 玩家、阶段、循环与调用方动态键 | 无自有扩展,仅负责最后转交 PAPI |
| Attribute | 伤害阶段、恢复、DamageContext | 伤害消息 | emakiattribute |
| Strengthen | 货币成本;效果值仅有限引用 | 强化展示、成功/失败动作 | emakistrengthen |
| Skills | 技能参数、自定义变量、升级成本 | 技能脚本文本、升级消息 | emakiskills |
| Item | 物品构建、EA 属性、修复成本 | 物品动作、套装显示 | emakiitem |
| Forge | 材料 stat/EA 属性/容量随机值 | 最终物品展示、结果动作 | emakiforge |
| Cooking | 营养 Action 数量表达式 | 食谱奖励与营养消息 | emakicooking |
| Gem | 宝石 stat/EA 属性、成本、镶嵌率 | 镶嵌/升级/提取结果 | emakigem |
| Level | 升级需求、来源经验、属性、成本 | 等级操作与升级结果 | emakilevel |
| Codex | 无自有公式环境;使用 GameplayEvent 条件变量 | 触发器与成就完成文本 | 无自有扩展 |
CoreLib
通用 ExpressionEngine
变量由调用方 Map 注入,写法为 %name%。CoreLib 没有为所有公式自动注入一组全局业务变量。
- 运算符:
+、-、*、/、%、^、括号。 - 函数:
ceil、floor、round、log10、min、max、pow,以及运行时注册的 JavaScript 函数。 - 最大表达式长度 256 字符,最大递归深度 10。
- 禁止反引号、
$、反斜杠。 - 缺失变量、自引用、非数值变量、
NaN或无限结果会使详细求值失败;简化接口通常回退为0。 - 随机配置自身的
variables会覆盖外部同名变量;动态变量按实际 Map 迭代顺序求值,后项可引用已经解析的前项。
实现依据:ExpressionEngine、ExpressionRules、RandomExpressionEvaluator、BooleanExpressionEvaluator。
ActionContext 内部变量
| 变量 | 说明 |
|---|---|
%player%、%player_name% | 玩家名称 |
%player_uuid% | 玩家 UUID |
%player_world% | 世界名 |
%player_x%、%player_y%、%player_z% | 玩家坐标 |
%phase% | 当前动作阶段 |
%template_<key>% | Action 模板 with.<key> 参数 |
%loop_id%、%loop_key%、%loop_index% | 循环标识、键与从 1 开始的索引 |
%loop_times%、%loop_remaining%、%loop_interval% | 循环总次数、剩余次数与 tick 间隔文本 |
<show_item> | 独立内联 token;仅在上下文存在 show_item 时替换 |
调用模块还可通过 ActionContext.placeholders() 注入任意小写键。attributes() 不会自动转成模板变量。
实现依据:PlaceholderRenderer、ActionTemplateProcessor、LoopActionService、ActionInlineTokenResolver。
GameplayEvent 变量
| 事件 | 变量 |
|---|---|
| 方块破坏 / 放置 | block_type |
| 实体击杀 / 驯服 | entity_type |
| MythicMobs 击杀 | mythic_id、mythic_level |
| 合成 / 熔炉取出 | result_type、result_amount |
| 钓鱼 | fish_state |
| 酿造完成 | potion_type |
这些键来自真实 Bukkit 事件,并由 Level、Codex 等模块按事件类型消费。
PlaceholderAPI 边界
CoreLib 不注册自己的 PlaceholderAPI expansion。解析链先处理内部变量与内联 token,再在安装 PlaceholderAPI 且存在玩家上下文时转交外部解析。
Attribute
自定义伤害阶段 stages[].expression
仅 CUSTOM 阶段使用表达式。
| 变量 | 语义 / 单位 |
|---|---|
input、base | 进入当前阶段的伤害点 |
flat | 固定属性聚合值 |
percent | 百分比点 |
chance | 触发概率,0..100 |
multiplier | 倍率属性的百分比点 |
roll | 当前判定随机值,0..100 |
crit | 是否触发,1 或 0 |
| DamageContext 任意键 | 调用方或伤害服务写入的运行时上下文 |
重要边界:实现先写入上述固定键,再合并 DamageContext。因此 DamageContext 中的同名键会覆盖固定键。ATTACKER / TARGET 来源先读属性快照,缺失时可回退到上下文同名数值;CONTEXT 来源只读取上下文。
实现依据:StageCalculator、DamageContextVariables。
DamageContext 标准键
- 实体:
attacker、attacker_name、attacker_type、attacker_uuid、source、source_name、target、target_name、target_type、target_uuid。 - 伤害类型:
damage_type、damage_type_name、damage_type_id。 - 伤害数值:
source_damage、input_damage、base_damage、damage、final_damage。 - 原因:
cause、cause_name、cause_id、damage_cause、damage_cause_name、damage_cause_id。 - 投射物:
projectile_type、projectile_uuid。 - 控制:
allow_critical、allow_target_dodge、calculate_target_defense。 - 随机:
damage_roll、damage_roll_flat、damage_roll_percent、damage_roll_chance、damage_roll_multiplier,范围0..1。 - 闪避:
dodge_chance、dodge_roll、dodged,概率/随机值范围0..100。 - 摔落:
fall_distance、jump_boost_level、vanilla_fall_damage、fall_damage_formula。
键在 DamageContextVariables 中会规范化为小写 identifier。
恢复公式 recovery.expression
| 变量 | 说明 |
|---|---|
input、base、damage、final_damage | 最终伤害点 |
flat、healing_flat | 固定恢复点数 |
percent、healing_percent | 恢复百分比点 |
percent_amount、healing_percent_amount | 按伤害折算的恢复量 |
gross、healing_gross | 抗性前总恢复量 |
resistance、healing_resistance | 恢复抗性百分比点 |
恢复固定键在继承 DamageContext 后写入,因此会覆盖上下文同名键。默认结果为 gross * (1 - resistance / 100),随后应用最小/最大值并钳制为非负。
实现依据:DamageRecoveryCalculator。
伤害消息模板
message、attacker_message、target_message 使用普通 %key% 文本替换。除上述实体、伤害类型、伤害数值与原因键外,还提供:
source_type、source_uuid、critical、critical_text、critical_suffix、roll、attacker_health、attacker_max_health、target_health、target_max_health、distance。
健康值与距离只从 DamageContext 读取;未注入时显示为 0。
实现依据: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%
资源解析会把第一个下划线前的文本视为资源 ID,因此资源 ID 建议不要包含下划线。
Strengthen
成功率
成功率不是 ExpressionEngine 公式。实际计算为目标星基础成功率,加上有效锻印等级乘每级加成,最后限制到 0..success_chance_cap。
实现依据:ChanceCalculator。
货币成本 cost_formula
| 变量 | 说明 |
|---|---|
base_cost | 货币基础成本 |
star | 目标星级,即当前星级 + 1 |
公式结果必须有限且大于 0,然后四舍五入为整数成本;否则该成本项会被跳过。
效果值解析边界
stars.<n>.variables、effects[type=variables].variables、ea_attributes 的生产实现只支持:
- Number;
- 数值字符串;
- 整个值恰好为
%name%的引用。
%star% * 2 这类算术文本不会进入 CoreLib ExpressionEngine,会回退为 0。初始固定变量只有 star,后续动态键能否引用前项取决于实际 Map 迭代顺序。
实现依据:StrengthenRecipe.resolveExpressions、StrengthenApiValues.evaluateNumber/evaluateMixed。
展示与动作变量
展示提供动态 stat 键,以及 star、temper、max_temper、temper_color;属性行另有 id、sign、value。
成功/失败 Action 提供:
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。
实现依据: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.*、升级等级 parameters.* 使用:
| 变量 | 说明 |
|---|---|
level、target_level、max_level | 技能等级上下文 |
current_level | resolveAtLevel 额外提供的当前等级 |
skill_id、trigger_id | 技能与触发器 ID |
is_passive | 是否被动技能,1/0 |
player_level | 原版经验等级 |
player_health、player_max_health | Bukkit 生命点 |
sneaking、has_target | 布尔量,1/0 |
技能自定义 variables 还可引用已经解析的参数和此前自定义变量。参数本身不会自动获得其他参数的求值结果,TriggerInvocation.extraVariables() 当前也未合并进这套解析环境。
实现依据:SkillParameterResolver、SkillVariableResolver。
升级成本与文本
升级货币 cost_formula 使用上述固定上下文,并额外提供 base_cost;调用时 trigger_id=upgrade。升级成功率来自静态成功率表,不是公式。
技能脚本文本可使用 level、skill_id、trigger_id、has_target,以及已解析参数和自定义动态键。升级消息提供 player、skill_id、skill、level、current_level、target_level、max_level、success_rate、success_rate_raw、roman_level 和成本/结果动态键。
PlaceholderAPI:emakiskills
- 全局:
cast_mode、global_cooldown、unlocked_count、slot_count、level_total。 - 技能:
level_<skill_id>、cooldown_<skill_id>。 - 槽位:
slot_<index>_skill|name|trigger|empty。 - 资源:
resource_<id>_current|max|percent。
冷却单位为秒,槽位使用从 0 开始的索引。
Item
物品构建变量
顶层 variables 与 effects[type=variables].variables 没有固定内置变量,从空 Map 按顺序解析。名称、Lore、结构化展示与原版 attribute modifier 可读取这些动态键。
ea_attributes 和 effects[type=ea_attribute].ea_attributes 使用独立的空上下文顺序解析,不继承顶层 variables。不要在 EA 属性表达式中引用顶层构建变量。
实现依据:EmakiItemDefinitionParser、EmakiItemFactory、EmakiItemPdcWriter。
修复成本
| 变量 | 说明 |
|---|---|
max_damage | 最大耐久 |
damage、current_damage、missing_durability | 当前缺失耐久点 |
missing_ratio | 缺失比例,0..1 |
restore_amount | 本次恢复耐久点 |
restore_ratio | 恢复比例,0..1 |
base_cost | 货币基础成本 |
实现依据:ItemRepairService。
动作、套装与 PlaceholderAPI
物品 Action:player、item_id、item_trigger、item_name。
套装上下文: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,以及 held_component_has_<id>、held_component_value_<id>、held_component_json_<id>。
Forge
材料数值上下文
capacity_cost与capacity_bonus.value可使用随机数值配置,但没有变量上下文;结果四舍五入为容量整数。effects[type=variables].variables每种材料从空 Map 开始,后项可引用当前材料此前 stat 动态键。effects[type=ea_attribute].ea_attributes使用另一套独立空 Map,不继承 stat 变量。
未发现独立的锻造成功率、品质概率或货币成本 ExpressionEngine 公式。
展示与动作
最终名称/Lore 提供所有最终 stat 动态键,以及 quality、quality_name、quality_multiplier、multiplier。
结果 Action 提供: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、show_item。
实现依据:ForgeMaterial、ForgeStatContributionBuilder、ForgeResultPostProcessor、ForgeActionCoordinator。
PlaceholderAPI:emakiforge
recipe_count、craft_count_<recipe_id>、has_crafted_<recipe_id>、total_crafts、last_crafted、guarantee_<key>。
Cooking
表达式与内部变量
食谱生产链未发现通用 ExpressionEngine 公式。营养操作 Action 的 amount 可写表达式,变量来自当前 ActionContext 中能够转换为数字的 placeholder 与 attribute 动态键;没有额外固定变量。单位为营养点,异常回退为 0。
食谱奖励 Action:recipe_id、recipe_name、station_type、cooking_recipe_id、cooking_recipe_name、cooking_station_type、cooking_outcome。
营养消息:动态 nutrition_<type>、nutrition_<type>_max、nutrition_<type>_min,以及 nutrition_type、nutrition_value、nutrition_threshold、nutrition_combo_count、nutrition_combo_required。
实现依据:NutritionOperationAction、RunRecipeRewardAction、NutritionService。
PlaceholderAPI:emakicooking
- 配方数:
recipe_count、recipe_count_<station_type>。 - 营养:
nutrition_<type>、nutrition_<type>_max|min、nutrition_combo_count_<rule_id>。 - 工位:
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 单位为 ml,burning_seconds 单位为秒。
Gem
宝石数值与成本
| 入口 | 变量 |
|---|---|
宝石 variables / ea_attributes | level,以及此前解析的同类动态键 |
| 共鸣 EA 属性 | 无固定初始键,仅此前共鸣属性键 |
inlay_success.rate_formula | default_chance、level_chance、configured_chance、level |
镶嵌/提取/升级 cost_formula | level、current_level、target_level、base_cost |
镶嵌率单位是百分比点,结果限制到 0..100。升级成功率来自静态等级成功率表,不是公式。成本固定 amount >= 0 时优先固定值,否则公式结果钳制非负。
实现依据:GemDefinition、GemResonanceLoader、GemInlayService、GemExtractService、GemUpgradeService。
操作变量与 PlaceholderAPI
升级、镶嵌、提取链按场景提供 player、gem_id、gem、level、current_level、target_level、success_rate、slot 等;宝石展示上下文另有 display_name、old_display_name、gem_type 与各等级 stat 动态键。货币消息提供 provider、currency、currency_id、name、display_name、required、available;材料消息提供 item、material、display_name、required、available。
emakigem PAPI:mainhand_opened_slots、mainhand_total_slots、mainhand_filled_slots、mainhand_item_definition_id、mainhand_resonance_count,以及 mainhand_slot_<index>_gem|level|opened|type。
Level
升级需求与成本
| 入口 | 变量 |
|---|---|
升级经验需求 formula | current_level、target_level、max_level、exp、total_exp |
等级属性 attributes.<id> | level、exp、total_exp |
| 升级货币/材料成本 | target_level、type、base_cost、base_amount |
固定 values.<target_level> 优先于需求公式。需求和货币结果钳制非负,材料数量四舍五入为非负整数。
来源经验
exp_formula 只获得当前 GameplayEvent 实际携带的键,不会自动追加统一玩家/等级变量:
- 实体:
entity_type。 - MythicMobs:
mythic_id、mythic_level。 - 方块:
block_type。 - 合成/熔炉:
result_type、result_amount。 - 钓鱼:
fish_state。 - 酿造:
potion_type。
Mythic drop 公式另有 amount、drop_amount、metadata_amount、generations、tick,并携带文本上下文 player、type、drop。
Level operation Action 的 amount 与 Cooking 营养动作相同:只读取 ActionContext 中能转为数字的动态键,没有额外固定变量。
实现依据:RequirementService、SourceExperienceService、LevelGameplaySubscriber、LevelAttributeBridge、PlayerLevelService、MythicLevelDropBridge、LevelOperationAction。
PlaceholderAPI:emakilevel
- 玩家:
level_<type>、exp_<type>、total_exp_<type>、totalexp_<type>、total_<type>、required_exp_<type>、requiredexp_<type>、required_<type>、progress_<type>、progress_percent_<type>。 - 排行:
top_<type>_<rank>_name|level|total_exp|totalexp|total。
排行榜 parser 按下划线分段,类型 ID 建议不要包含下划线。
Codex
Codex 不调用自己的 ExpressionEngine,也不注册 PlaceholderAPI expansion。
成就触发条件
触发条件使用 CoreLib ConditionEvaluator,变量来自 GameplayEvent,并额外提供 player、world:
block_type、entity_type、mythic_id、mythic_level、result_type、result_amount、fish_state、potion_type、player、world。
实际可用键取决于事件类型,不会同时全部存在。
触发器与完成文本
触发/action 行可读取当前事件键。成就完成上下文另有 advancement_id、advancement_node、advancement_title、advancement_page。
Codex 先执行本地 %key% 替换;有玩家且安装 PlaceholderAPI 时,再消费其他插件注册的外部占位符。
实现依据:CodexGameplaySubscriber、CodexTriggerService、AdvancementListener。
配置时的通用检查清单
- 先确认当前位置属于公式、内部模板、PAPI 还是运行时上下文。
- 只使用本页对应作用域列出的固定键与该配置明确产生的动态键。
- 百分比可能使用
0..1或0..100;以对应模块说明为准。 - 动态键按 Map 顺序求值的模块,不要依赖未经验证的 YAML/Map 重排行为。
- Attribute、Level 等动态 ID parser 对下划线支持不一致,资源/排行 ID 优先使用不含下划线的形式。
- 若变量来自事件,必须为不同事件配置分别处理缺失键。