配置详解
EmakiLevel 的配置分为主配置、升级需求、等级类型、经验来源、GUI 和语言文件。服主日常最常改的是:
config.yml:全局开关。requirements.yml:升级经验曲线。types/*.yml:等级类型、升级行为、奖励、消耗、属性贡献。sources/*.yml:哪些事件给哪些类型经验。
修改后执行 /elv reload 即可重载大部分配置并同步在线玩家。
config.yml
默认主配置:
version: "1.4.0"
language: "zh_CN"
release_default_data: true
primary_type: "main"
level:
default_start_level: 1
default_max_level: 100
max_auto_upgrade_steps: 10
keep_total_exp_at_max_level: true
multipliers:
enabled: true
global: 1.0
types:
main: 1.0
combat: 1.0
cooking: 1.0
forging: 1.0
reasons:
action: 1.0
mythic_drop: 1.0
event_bonus: 1.0
daily_caps:
enabled: true
default_limit: -1
types:
main: -1
combat: -1
cooking: -1
forging: -1
storage:
type: "yaml"
save_on_quit: true
save_on_shutdown: true
pdc:
enabled: true
namespace: "emakilevel"
sync_on_join: true
sync_on_exp_change: true
sync_on_level_change: true
sync_on_reload: true
attribute:
enabled: true
provider_id: "emakilevel"
mythicmobs:
enabled: true
kill_sources: true
drops:
enabled: true
names:
- "emakilevel_exp"
- "elv_exp"
anti_abuse:
placed_block_tracking: true
placed_block_exp: false
placed_block_record_ttl_ticks: 864000
last_damager_tracking:
enabled: true
expire_ticks: 200
gui:
enabled: true
default_template: "level_gui"字段说明:
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
version | string | 1.4.0 | 默认资源版本标记。 |
language | string | zh_CN | 使用 lang/<language>.yml 语言文件。 |
release_default_data | boolean | true | 缺失默认数据文件时是否释放内置 requirements.yml、types/、sources/、gui/。 |
primary_type | string | main | 默认主等级类型;/elv levelup 不填类型、部分 Action 不填类型时使用。 |
level.default_start_level | int | 1 | 类型未写 start_level 时的默认起始等级。 |
level.default_max_level | int | 100 | 类型未写 max_level 时的默认最高等级。 |
level.max_auto_upgrade_steps | int | 10 | 单次经验变更最多自动连升多少级。防止一次超大经验触发无限循环。 |
level.keep_total_exp_at_max_level | boolean | true | 达到最高等级后继续获得经验时,是否继续累计 total_exp。当前等级内 exp 不再增加。 |
multipliers.enabled | boolean | true | 是否启用经验倍率计算入口。 |
multipliers.global | double | 1.0 | 全局经验倍率。 |
multipliers.types.<type> | double | 1.0 | 按等级类型的经验倍率。键会被规范化为小写。 |
multipliers.reasons.<reason> | double | 1.0 | 按经验来源 reason 的经验倍率。键会被规范化为小写。 |
daily_caps.enabled | boolean | true | 是否启用每日经验上限入口。 |
daily_caps.default_limit | double | -1 | 未单独配置类型时的每日上限。-1 表示不限制。 |
daily_caps.types.<type> | double | -1 | 按等级类型的每日上限。-1 表示不限制。 |
storage.type | string | yaml | 默认配置中保留的键。当前实现固定使用 YAML 文件存储,不读取此键。 |
storage.save_on_quit | boolean | true | 默认配置中保留的键。当前实现不读取此键:玩家退出/被踢时总会异步保存并卸载缓存。 |
storage.save_on_shutdown | boolean | true | 默认配置中保留的键。当前实现不读取此键:插件关闭时总会尝试落盘并封存数据存储。 |
pdc.enabled | boolean | true | 是否把在线玩家等级数据写入 PDC。 |
pdc.namespace | string | emakilevel | PDC 命名空间。 |
pdc.sync_on_join / sync_on_exp_change / sync_on_level_change / sync_on_reload | boolean | true | 默认配置中保留的键。当前实现不读取这些键:只要 pdc.enabled 为 true,加入、经验变化、等级变化和重载都会同步。 |
attribute.enabled | boolean | true | 是否尝试接入 EmakiAttribute 属性贡献。需要安装 EmakiAttribute。 |
attribute.provider_id | string | emakilevel | 注册到 EmakiAttribute 的属性来源 ID。 |
mythicmobs.enabled | boolean | true | 总开关。关闭后不处理 MythicMobs 击杀和 Drop。 |
mythicmobs.kill_sources | boolean | true | 是否启用 mythic_mob_kill 来源规则。 |
mythicmobs.drops.enabled | boolean | true | 是否注册 MythicMobs 非实物经验 Drop。 |
mythicmobs.drops.names | list | emakilevel_exp、elv_exp | 可识别的 Drop 名称。为空时回退默认名称。 |
anti_abuse.placed_block_tracking | boolean | true | 是否记录玩家放置过的方块位置。 |
anti_abuse.placed_block_exp | boolean | false | 玩家放置再破坏的方块是否允许给经验。默认不允许。 |
anti_abuse.placed_block_record_ttl_ticks | int | 864000 | 放置方块记录的存活时间,单位 tick。超时记录会在下一次读写时清理。 |
anti_abuse.last_damager_tracking.enabled | boolean | true | 是否接受非直接击杀(由最近伤害玩家归属)的击杀事件。false 时只处理 Bukkit killer 直接击杀。 |
anti_abuse.last_damager_tracking.expire_ticks | int | 200 | 默认配置中保留的键。当前实现不读取此键:最近伤害归属窗口由 CoreLib config.yml > gameplay_events.last_damager_expire_ticks 控制(默认同为 200)。 |
gui.enabled | boolean | true | 是否启用等级 GUI 模板入口。 |
gui.default_template | string | level_gui | 默认 GUI 模板 ID。 |
经验倍率与每日上限
multipliers 和 daily_caps 在经验写入玩家之前生效,处理顺序是:倍率 → JavaScript 经验规则 → 每日上限。
倍率计算方式:
倍率 = multipliers.global × multipliers.types.<type> × multipliers.reasons.<reason>types与reasons中未列出的键按1.0处理,不参与相乘。multipliers.enabled: false时倍率固定为1.0。- 倍率结果不会小于 0。
<reason>就是经验来源传入的 reason,例如来源规则的 trigger ID、Action 的reason参数、MythicMobs Drop 的reason。
每日上限:
daily_caps.enabled: false时不限制。- 类型有
daily_caps.types.<type>时使用该值,否则使用daily_caps.default_limit。 -1表示不限制。- 当日剩余额度不足时,本次经验会被裁剪到剩余额度;额度为 0 时本次操作返回失败原因
daily_cap_reached。 - 计数按系统默认时区的日期分桶,只保存在内存中,服务器重启后清零。
requirements.yml
requirements.yml 控制升级所需经验。默认结构:
global:
formula: "floor(100 + 25 * %target_level% + 8 * pow(%target_level%, 2))"
values: {}
groups:
main:
formula: "floor(150 + 40 * %target_level% + 14 * pow(%target_level%, 2))"
values:
2: 150
3: 350
4: 750
5: 1200
combat:
formula: "floor(60 + 18 * %target_level% + 5 * pow(%target_level%, 2))"
values:
2: 80
3: 160
4: 300
# mining / logging / farming / fishing / gathering / taming 使用与 combat 相同的默认曲线
crafting:
formula: "floor(80 + 22 * %target_level% + 6 * pow(%target_level%, 2))"
values: {}
# brewing / cooking / forging / smelting 使用与 crafting 相同的默认曲线默认 requirements.yml 为每个内置等级类型各写了一个同名分组:main、combat、mining、logging、farming、fishing、gathering、taming、crafting、brewing、cooking、forging、smelting。types/<type>.yml > requirement.group 默认指向同名分组。
解析优先级
当玩家从当前等级升到 target_level 时,需求经验按以下顺序查找:
types/<type>.yml > requirement.values.<target_level>types/<type>.yml > requirement.formularequirements.yml > groups.<group>.values.<target_level>requirements.yml > groups.<group>.formularequirements.yml > global.values.<target_level>requirements.yml > global.formula
只要精确值存在且大于 0,就优先使用精确值;否则继续寻找公式。
需求公式变量
需求公式由 CoreLib 表达式引擎计算,使用 %key% 变量语法。
| 变量 | 说明 |
|---|---|
%current_level% | 玩家当前等级。没有玩家上下文时使用类型起始等级。 |
%target_level% | 本次要升到的目标等级。 |
%max_level% | 该类型最高等级。 |
%exp% | 玩家当前等级内经验。 |
%total_exp% | 玩家该类型总经验。 |
示例:
groups:
hard_profession:
formula: "floor(120 + 35 * %target_level% + 10 * pow(%target_level%, 2))"
values:
2: 100
3: 250可以用 /elv debug requirement <type> <level> 检查某个目标等级最终命中的来源和值。
types/*.yml
每个 types/*.yml 文件定义一个等级类型。文件名只是 fallback ID,最终以文件内 id 为准。
基础结构:
id: "combat"
enabled: true
display_name: "<red>战斗等级</red>"
description:
- "<gray>通过击杀实体或 MythicMobs 生物获得经验。</gray>"
primary: false
start_level: 1
max_level: 80
requirement:
group: "combat"
formula: ""
values: {}
upgrade:
enabled: true
auto_upgrade: true
manual_upgrade: true
cost:
enabled: false
economy:
enabled: false
currencies: []
materials: []
rewards:
items: []
actions:
gain: []
success: []
failure: []
pdc:
enabled: true
attributes:
enabled: true
values:
physical_attack: "%level% * 0.25"字段说明:
| 字段 | 说明 |
|---|---|
id | 等级类型唯一 ID。命令、Placeholder、来源规则、Action 都引用它。 |
enabled | 是否启用。禁用后不能获得经验或升级。 |
display_name | MiniMessage 显示名。 |
description | 描述文本列表,供配置维护和 GUI 展示使用。 |
primary | 是否标记为主等级。主等级选择仍以 config.yml > primary_type 为准。 |
start_level | 玩家初始等级,也是 reset 后等级。 |
max_level | 最高等级。直接设置等级也会被限制在此范围内。 |
requirement.group | 使用 requirements.yml > groups.<group>。 |
requirement.formula | 类型专属需求公式,非空时覆盖分组/全局公式。 |
requirement.values | 类型专属目标等级精确值,优先级最高。 |
upgrade.enabled | 是否允许升级。关闭后自动/手动都无法升级。 |
upgrade.auto_upgrade | 获得经验后是否自动升级。 |
upgrade.manual_upgrade | 是否允许玩家执行 /elv levelup。 |
upgrade.cost | 升级消耗,支持经济和物品。 |
upgrade.rewards.items | 升级成功奖励物品。 |
upgrade.actions.gain | 获得经验后执行的 CoreLib Action。 |
upgrade.actions.success | 升级成功后执行的 CoreLib Action。 |
upgrade.actions.failure | 升级失败后执行的 CoreLib Action。 |
pdc.enabled | 该类型是否同步 PDC。默认 true,还需要全局 pdc.enabled: true。 |
attributes.enabled | 该类型是否向 EmakiAttribute 贡献属性。未写该键时默认 false。 |
attributes.values | 属性 ID 到公式表达式的映射。 |
升级消耗
升级消耗只有在 upgrade.cost.enabled: true 时生效。
经济消耗
upgrade:
cost:
enabled: true
economy:
enabled: true
currencies:
- provider: "auto"
currency_id: ""
base_cost: 100
cost_formula: "%base_cost% * %target_level%"
display_name: "<gold>金币</gold>"| 字段 | 说明 |
|---|---|
provider | CoreLib 经济提供器,常用 auto、vault、excellenteconomy。 |
currency_id | 经济插件的货币 ID。Vault 通常留空。 |
base_cost | 基础费用,会作为 %base_cost% 进入公式。 |
cost_formula | 最终费用公式。 |
display_name | 展示名称,当前主要用于配置可读性和后续 UI 展示。 |
经济公式变量:
| 变量 | 说明 |
|---|---|
%target_level% | 本次目标等级。 |
%type% | 等级类型 ID。 |
%base_cost% | 当前货币条目的基础费用。 |
材料消耗
upgrade:
cost:
enabled: true
materials:
- item_sources:
- "minecraft-diamond"
base_amount: 1
amount_formula: "%base_amount% + floor(%target_level% / 10)"| 字段 | 说明 |
|---|---|
item_sources | 可消耗的 CoreLib ItemSource 列表。插件会按列表顺序扣除。 |
base_amount | 基础数量。也兼容 amount 作为输入,但新配置建议写 base_amount。 |
amount_formula | 最终扣除数量公式,结果四舍五入为整数。 |
材料公式变量:
| 变量 | 说明 |
|---|---|
%target_level% | 本次目标等级。 |
%type% | 等级类型 ID。 |
%base_amount% | 当前材料条目的基础数量。 |
升级奖励
upgrade:
rewards:
items:
- levels: "*"
item_sources:
- "minecraft-experience_bottle"
amount: 1
- levels: "10,20,30"
item_sources:
- "minecraft-diamond"
amount: 2
- levels: "50-60"
item_sources:
- "minecraft-nether_star"
amount: 1| 字段 | 说明 |
|---|---|
levels | 匹配等级。支持 *、单个等级、逗号列表和 min-max 范围。 |
item_sources | 奖励物品来源列表。插件会使用第一个能成功创建的来源。 |
amount | 奖励数量,最小为 1。 |
奖励通过 CoreLib ItemSource 创建物品,并使用 give-or-drop 逻辑发放;玩家背包满时会掉落。
升级动作变量
upgrade.actions.gain、success、failure 都是 CoreLib Action 字符串列表。动作上下文提供以下变量:
| 变量 | 说明 |
|---|---|
%type% | 等级类型 ID。 |
%type_display_name% | 等级类型显示名。 |
%level% | 当前等级。 |
%old_level% | 操作前等级。 |
%new_level% | 操作后等级。 |
%exp% | 当前等级内经验,已格式化。 |
%old_exp% | 操作前经验,已格式化。 |
%new_exp% | 操作后经验,已格式化。 |
%total_exp% | 总经验,已格式化。 |
%required_exp% | 升到下一级所需经验,已格式化。 |
%progress% | 0 到 1 的数值进度。 |
%progress_percent% | 0 到 100 的百分比数值,已格式化。 |
%amount% | 本次经验或等级操作数量,已格式化。 |
%reason% | 操作原因。 |
%failure_reason% | 失败原因;失败动作中通常使用它。 |
示例:
upgrade:
actions:
gain:
- '@chance=10 sendactionbar text="<gray>%type_display_name% 经验 +%amount%</gray>"'
success:
- 'sendmessage text="<green>%type_display_name% 提升到了 <yellow>%new_level%</yellow> 级!</green>"'
- 'broadcast text="<gold>%player%</gold> 的 %type_display_name% 达到了 <yellow>%new_level%</yellow> 级"'
failure:
- 'sendmessage text="<red>升级失败: %failure_reason%</red>"'属性贡献
安装并启用 EmakiAttribute 后,EmakiLevel 会把启用的等级类型注册为属性贡献来源。默认来源 ID 是 config.yml > attribute.provider_id,即 emakilevel。
attributes:
enabled: true
values:
physical_attack: "%level% * 0.25"
physical_crit_rate: "%level% * 0.02"属性公式变量:
| 变量 | 说明 |
|---|---|
%level% | 玩家该类型当前等级。 |
%exp% | 当前等级内经验。 |
%total_exp% | 总经验。 |
当经验、等级或配置重载导致等级变化时,插件会尝试刷新在线玩家的 Attribute 属性贡献。没有安装 EmakiAttribute 时,该桥接会自动跳过,不影响等级系统本体运行。
PDC 同步
全局 pdc.enabled: true 且类型 pdc.enabled: true 时,在线玩家实体会写入以下逻辑字段:
| 字段 | 类型 | 说明 |
|---|---|---|
player/<type>_level | int | 当前等级。 |
player/<type>_exp | double | 当前等级内经验。 |
player/<type>_total_exp | double | 总经验。 |
player/<type>_required_exp | double | 升到下一级所需经验。 |
player/<type>_progress | double | 0 到 1 的进度。 |
这些字段位于 config.yml > pdc.namespace 命名空间下,默认 emakilevel,逻辑分区为 player。PDC 同步发生在玩家加入、经验变化、等级变化、重载和显式 /elv debug pdc 同步时。
玩家数据文件
玩家数据位于 data/<uuid>.yml:
schema_version: 1
uuid: "00000000-0000-0000-0000-000000000000"
name: "PlayerName"
levels:
main:
level: 1
exp: 0.0
total_exp: 0.0
updated_at: 1730000000000说明:
level是当前等级。exp是当前等级内经验,升级时会扣除需求经验。total_exp是累计经验,用于排行榜排序和长期统计。updated_at是最近更新时间戳。- 新增等级类型后,玩家下次加载数据时会自动补齐该类型起始数据。
不建议在服务器运行时手改 data/*.yml。如果确实需要修正数据,优先使用 /elv setexp、/elv setlevel 或 /elv reset。