PmmoJS.registerPerk(...) 在 startup_scripts/ 中注册新的 PMMO Perk 类型。这是用来定义全新 Perk 的 —— 如果你只想编辑已有的 Perk 条目,请使用 server_scripts/ 中的 PmmoJS.perksConfig(...)。
基本语法
注册一个 Perk 至少需要一个 ID、一个 Side、一个技能和至少一个回调。构建器为其他所有内容提供默认值。
PmmoJS.registerPerk(event => {event.create('kubejs:steady_mind', PMMOPerkSide.SERVER).withSkill('combat').description('一个从 KubeJS 注册的自定义 Perk。').conditions(ctx => true).start(ctx => {}).tick(ctx => {}).stop(ctx => {}).status(ctx => {}).register()})
调用 register() 之后,你的 Perk 就进入了 PMMO 的注册表。你必须把 register() 作为最后一步调用 —— 没有它,构建器会丢弃所有内容。
设置默认值
这些构建器方法定义 Perk 的启动默认值。它们会成为 PMMO 传入回调的 tag 的一部分。
标准 PMMO 字段:
| 方法 | 写入的键 | 作用 |
|---|---|---|
withSkill(skill) | skill | 此 Perk 关联的技能 |
withCooldown(ticks) | cooldown | 两次激活之间的最小 tick 数 |
withDuration(ticks) | duration | Perk 保持活跃的时长(0 = 不 tick) |
withChance(value) | chance | 激活概率 —— 0.0 到 1.0 |
withMinLevel(level) | min_level | 技能最低要求等级 |
withMaxLevel(level) | max_level | 技能最高允许等级 |
withPerXLevel(step) | per_x_level | 仅在技能等级能被此值整除时激活 |
withMilestones(values) | milestones | 仅在达到这些特定等级时激活 |
自定义字段:
withString(key, value)、withBool(key, value)、withInt(key, value)withLong(key, value)、withFloat(key, value)、withDouble(key, value)withStringList(key, values)、withNumberList(key, values)withCompound(key, value)—— 嵌套 compound tagdefaults(tag => {})—— 通过PerkTagJS自由编辑默认 tag
生命周期回调
每个回调在 Perk 生命周期的特定时刻运行,并接收一个方法集不同的上下文对象。
conditions(ctx) —— 此 Perk 是否应该激活?
在 PMMO 内置的有效性检查之后运行。返回 true 允许激活,false 阻止激活。
start(ctx) —— Perk 刚刚激活
这是初始化状态的地方。start() 是唯一同时获得 ctx.getSettings()(用于持久状态)和 ctx.getResult()(用于一次性输出回当前 PMMO 执行趟次)的回调。
tick(ctx) —— Perk 处于活跃状态
在 Perk 保持活跃期间持续触发。使用 ctx.getElapsedTicks() 进行计时。PMMO 会忽略返回值。
stop(ctx) —— Perk 正在停用
清理你在 ctx.getSettings() 中存储的所有持久状态。
status(ctx) —— UI 正在请求显示文本
使用 ctx.addLine(...) 和 ctx.addLines(...) 构建显示在 PMMO 的 UI 中的状态行。PMMO 会忽略返回值。
上下文对象速览
| 回调 | 上下文类型 | 额外方法 |
|---|---|---|
conditions(ctx) | PerkConditionContextJS | — |
start(ctx) | PerkStartContextJS | getResult() |
tick(ctx) | PerkTickContextJS | getElapsedTicks() |
stop(ctx) | PerkStopContextJS | — |
status(ctx) | PerkStatusContextJS | addLine(v)、addLines(vs)、clearLines()、getLines() |
所有上下文共享:getPerkId()、getPlayer()、getServerPlayer()、getSettings()。
设置如何合并
在调用你的回调之前,PMMO 会按顺序叠加以下数据源,构建一个合并后的 tag:
- 你在构建器方法中设置的启动默认值
perks.toml中匹配的条目(如果有的话)- 当前 PMMO 事件传入的数据
- 同一执行趟次中更早 Perk 的输出
如果合并后的 tag 有 skill 字段,PMMO 会注入该技能下玩家当前的 level。
ctx.getSettings() 给你最终的合并结果。
PerkTagJS 快速参考
你的回调使用 ctx.getSettings() 和(在 start() 中)ctx.getResult(),两者都是 PerkTagJS 实例。
读取: keys()、has(key)、getString(key)、getInt(key)、getLong(key)、getFloat(key)、getDouble(key)、getBoolean(key)、getOrCreateCompound(key)。每个都有 *Or(key, fallback) 变体。
写入: remove(key)、clear()、putString(key, value)、putBoolean(key, value)、putInt(key, value)、putLong(key, value)、putFloat(key, value)、putDouble(key, value)、putCompound(key, value)、putStringList(key, values)、putNumberList(key, values)、merge(value)。
PMMO 辅助方法: getSkill()、getResolvedLevel()、getCooldown()、getDuration()、getChance()。
完整示例
下面是一个完整的 Perk,在活跃时治疗玩家,且只在玩家生命值未满时生效:
PmmoJS.registerPerk(event => {event.create('kubejs:steady_mind', PMMOPerkSide.SERVER).withSkill('combat').withCooldown(200).withDuration(100).withMinLevel(10).withInt('heal_interval', 20).withDouble('heal_amount', 1.0).defaults(tag => {tag.putBoolean('active', false)tag.putLong('started_at', 0)}).description('在 Perk 活跃期间持续治疗玩家。').conditions(ctx => {return ctx.getPlayer().getHealth() < ctx.getPlayer().getMaxHealth()}).start(ctx => {ctx.getSettings().putBoolean('active', true)ctx.getSettings().putLong('started_at', ctx.getPlayer().level().getGameTime())ctx.getResult().putString('steady_mind_started', ctx.getPerkId())}).tick(ctx => {const settings = ctx.getSettings()const interval = settings.getIntOr('heal_interval', 20)const amount = settings.getDoubleOr('heal_amount', 1.0)if (settings.getBooleanOr('active', false) && ctx.getElapsedTicks() % interval === 0) {ctx.getPlayer().heal(amount)}}).stop(ctx => {ctx.getSettings().putBoolean('active', false)}).status(ctx => {const settings = ctx.getSettings()ctx.clearLines()ctx.addLine(`perk: ${ctx.getPerkId()}`)ctx.addLine(`skill: ${settings.getSkill()}`)ctx.addLine(`level: ${settings.getResolvedLevel()}`)ctx.addLine(`active: ${settings.getBooleanOr('active', false)}`)}).register()})
要点说明:
withInt('heal_interval', 20)和withDouble('heal_amount', 1.0)设置了可配置的调节项。玩家可以在perks.toml中覆盖它们。defaults(tag => {})设置只有你的 Perk 使用的私有字段。PMMO 忽略未知键。conditions(ctx)只决定是否激活 —— 不存储状态。start(ctx)把active和started_at存入ctx.getSettings(),以便tick()和stop()后续读取。start(ctx)把steady_mind_started写入ctx.getResult()—— 这是当前执行趟次的一次性输出。tick(ctx)使用ctx.getElapsedTicks()配合取模检查,按可配置间隔执行治疗。stop(ctx)清理active标记。status(ctx)只构建 UI 行 —— 不创建额外状态。