技能定义全字段
这一页是技能定义文件(skills/<分类>/xxx.yml)的逐字段参考手册。所有字段按功能分组,每组一张表 + 一个小示例。配技能时哪不会就翻到对应小节。
💡 不用一次看完。 第一次配技能,只要写
id/display/meta/trigger/type/cooldown就能跑起来(见文末"最小可用模板")。其余字段按需添加。本页字段以
SkillDefinitionLoader实际加载的为准,对应 QS 1.0.22。
🖼️ [图片占位] 一张技能 yml 字段分组示意图(基础 / 触发 / 门控 / 目标 / 消耗 / 进阶) · 建议
assets/field-groups.png
🔑 一条贯穿全页的规则:别名与优先级
很多字段有两种写法:嵌套段(如 cooldown.base)和顶层别名(如 cooldown_ms)。两种都能用,但同时写时谁生效有固定优先级:
| 嵌套写法(优先) | 顶层别名 | 谁赢 |
|---|---|---|
cooldown.base / cooldown.group / cooldown.charges | cooldown_ms / cooldown_group / charges | 嵌套段优先 |
cost.health / cost.hunger | health_cost / hunger_cost | 嵌套段优先 |
gcd.triggers_ms / gcd.ignore | gcd_ms / ignore_gcd | 嵌套段优先 |
execution.mythic_skill | mythic_skill(顶层) | execution.mythic_skill 优先 |
⚠️ 不要两种都写然后纳闷为什么改了没用。 记住一句话:嵌套段 /
execution.mythic_skill永远赢。 本页示例统一用嵌套写法。
1️⃣ 基础身份
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
id | String | 文件名 | 技能唯一 id,全小写;别处(物品 / 连招 / 命令)都用它引用 |
display | String | = id | 显示名,支持 & 颜色码 |
type | active / passive | active | 顶层这一行真正决定主动 / 被动,loader 读它定 SkillType |
max_level | Int | 1 | 最高等级,配合 levels 做成长曲线 |
tags | List | [] | 纯展示 / 检索用标签 |
id: fire_wave
display: "&c火焰波"
type: active # ← 决定主动/被动的是这一行(被动技能写 passive)
max_level: 5
tags: [fire, aoe, combat]2️⃣ 生态信息(meta / trigger / state / graph / execution)
这套字段供 /qs reload 做一致性校验,并给连招编排参照。缺 meta 会报 schema 警告。
| 字段 | 取值 | 说明 |
|---|---|---|
meta.category | combat/movement/utility/boss/combo | 分类,要和文件所在文件夹一致 |
meta.type | active/passive/reactive | 仅标签(真正生效的是顶层 type) |
meta.rank | basic/advanced/elite/boss | 仅展示用品阶 |
trigger.primary | TriggerType | 主触发键,须在 graph 入口节点的 triggers 内 |
state.required | SkillState | 施放所需状态,默认 IDLE;要和入口节点 require_state 一致 |
graph.entry | String | 用哪张 graph(按 graph_id 找) |
execution.mythic_skill | String | 实际执行的 MM 技能名,优先级最高(> 顶层 mythic_skill) |
meta:
category: combat
type: active # 标签,仅归类
rank: basic # 仅展示
trigger:
primary: RIGHT_CLICK # 须出现在 graph 入口节点 triggers 里
state:
required: IDLE # 须和入口节点 require_state 一致
graph:
entry: fire_wave # 按 graph_id 找图
execution:
mythic_skill: fire_wave # 真正执行的 MM 技能(优先于顶层 mythic_skill)全部 TriggerType 与 graph 节点细节见 graph 与连招。
3️⃣ 冷却 / 充能 / 冷却组(cooldown)
| 字段(嵌套 / 别名) | 类型 | 默认 | 说明 |
|---|---|---|---|
cooldown.base / cooldown_ms | Long(ms) | 0 | 冷却时长,毫秒。3000 = 3 秒 |
cooldown.group / cooldown_group | String? | 无 | 冷却组:同组技能共享冷却 |
cooldown.charges / charges | Int | 1 | 充能层数;>1 时替代二元冷却,逐层按 base 恢复 |
cooldown:
base: 3000 # 3 秒冷却
group: fire # 同组(如所有火系技能)共享冷却
charges: 3 # 充能 3 层:放完一层进恢复,3 秒补满一层💡 二元冷却 vs 充能:
charges不写或 = 1 就是普通"能放 / 在冷却"二元状态;charges > 1切换成"有几层就能放几次"的充能制,每层按base时间恢复。详见 冷却充能GCD与冲突。
⚠️
cooldown.base有前置条件——必须有meta.category。 整个meta.*/trigger.*/graph.*/execution.*生态信息(含cooldown.base嵌套段)只有在技能文件含meta.category时才会被解析——SkillSchemaParser 见到没有meta.category就直接返回 null。没写meta.category,cooldown.base不生效,必须改用顶层cooldown_ms。另外:
levels.N缺省冷却时,只回退到顶层cooldown_ms,不回退到cooldown.base。所以若你用cooldown.base定义冷却,但某个level没写cooldown_ms,该级会得到 0(无冷却)。建议:要么同时写
meta.category+cooldown.base,要么统一用顶层cooldown_ms并在每个level显式写cooldown_ms。(注:所有自带示例都带
meta.category,所以示例里的cooldown.base都正常工作。)
4️⃣ 资源消耗(resource)
| 字段 | 类型 | 说明 |
|---|---|---|
resource.<键> | Map | 资源消耗,如 mana: 15 |
resource:
mana: 15 # 施放消耗 15 法力⚠️ 关于 mana:
mana等资源池将来归 QinhClass(QC)管,现在是临时占位。先这么用,QC 接管后技能 yml 不用改。详见 核心概念 的职责边界。
5️⃣ 施法模式(cast_mode)
| 取值 | 含义 |
|---|---|
instant(默认) | 瞬发 |
toggle | 开关(再按一次关) |
channel | 吟唱读条(蓄力条) |
cast_mode: instant # instant / toggle / channel吟唱
channel的完整字段见下方 §10,开关toggle细节见 施法模式与吟唱。
6️⃣ 目标与索敌(target)
target 可写成标量(只写模式)或段(带范围 / 过滤等)。
标量写法:
target: NEAREST # 直接写模式可选模式:SELF(自己) / LOOK(准星射线) / NEAREST(最近) / FARTHEST(最远) / LOWEST_HP(最残,收割) / HIGHEST_HP(最肉) / RANDOM(随机)。
段写法(更精细):
| 字段 | 默认 | 说明 |
|---|---|---|
target.mode | SELF | 上面那些模式之一 |
target.range | 30 | 索敌半径(格),范围 1–100 |
target.filter | LIVING | ANY / LIVING / MONSTERS(仅怪) / PLAYERS(仅玩家) / NOT_PLAYERS(生物非玩家) |
target.required | false | true = 没锁到目标直接放不出(提示"没有可用目标") |
target.require_los | false | true = 只锁有视线(不隔墙)的目标 |
target:
mode: NEAREST # 选最近的
range: 6 # 6 格内
filter: MONSTERS # 只锁怪
required: true # 没目标就放不出
require_los: true # 只锁看得见的(不隔墙)💡 QS 选好的目标会作为 MM 技能的
@Target传入。require_los主要影响NEAREST(默认可穿墙锁);LOOK本就是射线。完整说明见 目标与索敌。
7️⃣ 全局冷却 GCD(gcd)
| 字段(嵌套 / 别名) | 类型 | 默认 | 说明 |
|---|---|---|---|
gcd.triggers_ms / gcd_ms | Long(ms) | 0 | 施放后全角色技能短暂封禁的时长;0 = 不触发 GCD |
gcd.ignore / ignore_gcd | Boolean | false | true = 本技能不受 GCD 限制 |
gcd:
triggers_ms: 800 # 放完后 0.8 秒内所有技能被拦
ignore: false # 本技能自己受不受 GCD 限制💡 输出技常配
triggers_ms防一帧连放多个技能;瞬发位移 / 打断技常配ignore: true让它不被别的技能的 GCD 锁住。
8️⃣ 血祭 / 饥饿消耗(cost)
用原版生命 / 饥饿当代价(非 QC 法力池),适合"血祭流"技能。
| 字段(嵌套 / 别名) | 类型 | 说明 |
|---|---|---|
cost.health / health_cost | Double | 扣血量,半颗心 = 1;血量 ≤ 此值时放不出,扣后保底 0.5 |
cost.hunger / hunger_cost | Int | 扣饥饿值 |
cost:
health: 4.0 # 扣 2 颗心;血量不足则放不出,扣完至少留 0.5
hunger: 2 # 扣 2 点饥饿9️⃣ 冷却就绪提示(ready_notify)
冷却结束那一刻发 actionbar + 音效。
| 字段(嵌套 / 别名) | 默认 | 说明 |
|---|---|---|
ready_notify.enabled / ready_notify: true | false | 开关 |
ready_notify.sound | block.note_block.pling | 音效 id(点号 / 下划线皆可) |
ready_notify.message | &a{skill} &7已就绪 | actionbar 文本,{skill} = 显示名 |
ready_notify:
enabled: true
sound: block.note_block.pling
message: "&7{skill} &f已就绪" # {skill} 替换成显示名⚠️ 仅二元冷却技能适用,充能技能(
charges > 1)不适用。
🔟 吟唱读条(channel)
仅 cast_mode: channel 生效;time_ticks > 0 才真正进吟唱,否则退化为瞬发。
| 字段 | 默认 | 说明 |
|---|---|---|
channel.time_ticks(别名 channel.ticks) | 0 | 读条时长(tick,20 = 1 秒),>0 才进吟唱;顶层别名 channel.ticks 等效 |
channel.bar_type | bossbar | 读条 UI:bossbar(顶部) / actionbar(下方文字) / none |
channel.interrupt_on_move | true(取 config) | 位移打断 |
channel.move_threshold | 0.5 | 位移阈值(格),超过即打断 |
channel.interrupt_on_damage | true | 受伤打断 |
channel.cost_on_start | false | true = 起手即扣资源(防刷);false = 完成时扣 |
channel.cooldown_on_start | false | true = 起手即进 CD;false = 完成时进 CD |
cast_mode: channel
channel:
time_ticks: 40 # 读条 2 秒
bar_type: bossbar # 顶部 boss 血条样式进度
interrupt_on_move: true # 走动打断
move_threshold: 0.5
interrupt_on_damage: true # 受伤打断
cost_on_start: false # 完成时才扣费(被打断不亏)
cooldown_on_start: false # 完成时才进冷却完整吟唱机制见 施法模式与吟唱。
1️⃣1️⃣ 释放条件(conditions)
声明式前置条件列表,全部满足才放;空 = 无限制。
conditions:
- "player_level:>=5" # 玩家等级 ≥ 5
- "player_in_world:world" # 在主世界
- "player_health_pct:>=50" # 血量 ≥ 50%
- "has_target:true" # 有目标
- "target_type:ZOMBIE" # 目标是僵尸
- "target_distance:<=10" # 目标 10 格内语法是 键:值,值可带比较符 >= <= == != > < =(默认 =)。未知键恒为真(写错不会把技能锁死)。可用键概览:
| 键 | 说明 |
|---|---|
player_level | 玩家等级 |
player_health / player_health_pct | 血量绝对值 / 百分比(0–100) |
player_food | 饥饿值 |
player_in_world | 世界名 |
player_has_permission | 权限节点 |
player_gamemode | SURVIVAL / CREATIVE… |
player_sneaking / player_sprinting / player_on_fire / player_on_ground | 布尔 |
player_y | Y 坐标 |
has_target | 是否有目标 |
target_type | 目标实体类型(如 ZOMBIE) |
target_distance | 与目标距离 |
完整条件用法见 消耗条件与变量。复杂逻辑用下方 §15 的
script.pre_js。
1️⃣2️⃣ 互斥组与连段标记
| 字段 | 类型 | 说明 |
|---|---|---|
conflict_groups | Set<String> | 互斥组:施放后同组短期不可放,窗口 gate.conflict_window_ms(默认 1000ms) |
combo_group | String? | 连段分组标记 |
conflict_groups:
- melee_burst # 放完后约 1 秒内同组其它技能放不出
combo_group: fire_combo # 连段分组标记1️⃣3️⃣ 变量透传(variables)
把自定义键值透传给 MM 技能变量 <skill.var.键>。
variables:
element: fire # MM 里用 <skill.var.element> 读到 "fire"QS 还会自动注入
mode/source/slot/player/origin等内置变量,详见 消耗条件与变量。
1️⃣4️⃣ 分等级覆盖(levels)
按等级覆盖冷却 / 消耗 / 参数。params 透传给 MM(MM 里 <skill.var.power> 读)。
levels:
1:
cooldown_ms: 3000
resource: { mana: 15 }
params: { power: "1.0" } # 一级威力
2:
cooldown_ms: 2800
resource: { mana: 18 }
params: { power: "1.2" } # 升级:冷却更短、威力更高| 子字段 | 说明 |
|---|---|
levels.N.cooldown_ms | 该等级冷却 |
levels.N.resource | 该等级资源消耗 |
levels.N.params | 透传 MM 的数值参数(MM 自己决定怎么用) |
1️⃣5️⃣ 脚本出口(script)
| 字段 | 说明 |
|---|---|
script.pre_js | 施放前跑,返回 false 拦截施放 |
script.post_js | 施放成功后跑(副作用) |
script:
pre_js: "qinhskills:demo.js:canCast" # 返回 false 则放不出
post_js: "qinhskills:demo.js:onCast" # 施放成功后跑效果脚本写法见 脚本。
1️⃣6️⃣ 触发源(active_triggers / passive_triggers)
主动触发源 active_triggers,缺省 [QI_ACTION](QinhItems 物品触发):
active_triggers:
- type: KEY_SLOT # KEY_SLOT / QI_ACTION / COMMAND / API
slot: 1 # 可选;仅 KEY_SLOT 有意义(绑定到哪个技能槽)
- type: QI_ACTION # 默认;QinhItems 物品触发| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
type | 枚举 | QI_ACTION | 触发来源:KEY_SLOT / QI_ACTION / COMMAND / API |
slot | Int | 无 | 可选,仅 type: KEY_SLOT 有意义——绑定到哪个技能槽 |
| type | 触发来源 |
|---|---|
KEY_SLOT | 按键技能槽(配合 slot 指定槽位) |
QI_ACTION | QinhItems 物品按键(默认) |
COMMAND | 命令桥 /qs cast |
API | 外部插件 API |
被动触发 passive_triggers(仅 type: passive 技能用)。每条支持以下字段:
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
type | 枚举 | 必需 | 被动触发类型(受伤 / 攻击 / 击杀 / 低血…) |
id | String | = type 的小写 | 该被动的标识 |
cooldown_ms | Long(ms) | 0 | 此被动的限流冷却,高频被动务必配 |
threshold_pct | Double | 30.0 | 血量百分比阈值;仅 ON_LOW_HEALTH 等阈值型触发使用 |
type: passive # 顶层也要写 passive
passive_triggers:
- type: ON_DAMAGED # 受伤时触发
id: thorns
cooldown_ms: 1500 # 高频被动务必限流
- type: ON_LOW_HEALTH # 低血触发(阈值型)
id: last_stand
threshold_pct: 30.0 # 血量 ≤ 30% 才触发11 种被动触发的完整说明(受伤 / 攻击 / 击杀 / 低血 / 潜行 / 跳跃 / 疾跑 / 挖掘 / 重生 / 坠落 / 周期)见 被动技能。
📊 优先级速查
同时写嵌套与别名时,谁生效:
cooldown.base / .group / .charges > cooldown_ms / cooldown_group / charges
cost.health / .hunger > health_cost / hunger_cost
gcd.triggers_ms / .ignore > gcd_ms / ignore_gcd
execution.mythic_skill > mythic_skill(顶层)记忆口诀:嵌套段永远赢;execution.mythic_skill 永远赢。
📄 实战范例(逐字段注解)
范例 A:fire_wave —— 最基础的主动技能
id: fire_wave # 技能唯一 id,全小写;省略则取文件名
display: "&c火焰波" # 显示名,支持 & 颜色码
#--- 生态信息:分类归档 + reload 一致性校验 ---
meta:
category: combat # 固定五类之一
type: active # 归类标签:active / passive / reactive
rank: basic # 品阶标签(仅展示)
trigger:
primary: RIGHT_CLICK # 主触发键,须在 graph 入口节点 triggers 里
state:
required: IDLE # 施放所需状态。要和入口节点 require_state 一致
graph:
entry: fire_wave # 用哪张 graph(按 graph_id 找)
execution:
mythic_skill: fire_wave # 真正执行的 MM 技能;要和入口节点 mythic_skill 一致
#--- 运行期字段 ---
type: active # 真正决定主动/被动的是这一行
max_level: 5 # 最高等级,配合 levels 做成长曲线
cooldown:
base: 3000 # 冷却 3 秒
resource:
mana: 15 # 施放消耗(⚠ mana 将来归 QinhClass,临时占位)
cast_mode: instant # instant 瞬发 / channel 吟唱 / toggle 开关
# 分等级数值:不同等级吃不同冷却/消耗,并把 params 透传给 MythicMobs
levels:
1:
cooldown_ms: 3000
resource: { mana: 15 }
params: { power: "1.0" } # 一级威力(MM 里 <skill.var.power> 读)
2:
cooldown_ms: 2800
resource: { mana: 18 }
params: { power: "1.2" } # 升级:冷却更短、威力更高
# 透传给 MythicMobs 的自定义变量(MM 里 <skill.var.element> 读取)
variables:
element: fire
tags: [fire, aoe, combat] # 自定义标签,纯展示/检索范例 B:blade_slash —— 索敌 + 血祭 + GCD + 条件 + 就绪提示 + 互斥
id: blade_slash
display: "&7刃斩"
meta:
category: combat
type: active
rank: advanced
trigger:
primary: LEFT_CLICK # 左键触发(要和 graph 入口节点 triggers 一致)
state:
required: IDLE
graph:
entry: blade_slash
execution:
mythic_skill: blade_slash
type: active
max_level: 3
cooldown:
base: 2500
# 自动索敌:施放时由 QS 选好目标,作为 MM 的 @Target 传入
target:
mode: NEAREST # NEAREST 最近 / FARTHEST / LOWEST_HP 收割 / HIGHEST_HP / RANDOM
range: 6 # 索敌半径(格)
filter: MONSTERS # ANY / LIVING / MONSTERS 仅怪 / PLAYERS / NOT_PLAYERS
required: true # true=没锁到目标直接放不出
require_los: true # true=只锁有视线(不隔墙)的目标
# 代价:用血和饱食度,不消耗 mana(没写 resource: 段,纯血祭)
cost:
health: 2.0 # 扣 2 点血(1 点 = 半颗心);不足时放不出,扣后保底 0.5
hunger: 1 # 扣 1 点饱食度
# 全局冷却(GCD):放完此技后 0.8 秒内放任何技能都被拦
gcd:
triggers_ms: 800
# 冷却就绪提示:冷却结束那一刻发 actionbar + 音效(仅二元冷却技能有效)
ready_notify:
enabled: true
sound: block.note_block.pling
message: "&7{skill} &f已就绪" # {skill} 会替换成显示名
# 互斥组:放完后短时间内(默认 1 秒)同组其它技能不可放
conflict_groups:
- melee_burst
# 释放前置条件:全部满足才放得出(写错的键当作恒为真,不会锁死技能)
conditions:
- "player_level:>=3" # 玩家等级 ≥ 3
- "has_target:true" # 必须有目标(和 target.required 双保险)
levels:
1: { cooldown_ms: 2500 }
2: { cooldown_ms: 2200 }
3: { cooldown_ms: 2000 }🧱 拿来即用的模板
最小可用技能(复制改名即可跑)
id: my_skill
display: "&a我的技能"
meta:
category: combat
type: active
trigger:
primary: RIGHT_CLICK
state:
required: IDLE
graph:
entry: my_skill
execution:
mythic_skill: my_skill
type: active
cooldown:
base: 2000配套还要一张最简 graph,见 graph 与连招 的入口节点示例。
全字段模板(按需删减)
id: full_demo
display: "&6完整示例"
meta: { category: combat, type: active, rank: advanced }
trigger: { primary: RIGHT_CLICK }
state: { required: IDLE }
graph: { entry: full_demo }
execution: { mythic_skill: full_demo }
type: active
max_level: 3
cooldown: { base: 3000, group: fire, charges: 1 }
resource: { mana: 15 }
cast_mode: instant
target: { mode: NEAREST, range: 20, filter: MONSTERS, required: false, require_los: false }
gcd: { triggers_ms: 800, ignore: false }
cost: { health: 0.0, hunger: 0 }
ready_notify: { enabled: true, sound: block.note_block.pling, message: "&a{skill} &7已就绪" }
conditions:
- "player_level:>=3"
conflict_groups: [melee_burst]
combo_group: fire_combo
variables: { element: fire }
script: { pre_js: "", post_js: "" }
levels:
1: { cooldown_ms: 3000, resource: { mana: 15 }, params: { power: "1.0" } }
2: { cooldown_ms: 2800, resource: { mana: 18 }, params: { power: "1.2" } }
3: { cooldown_ms: 2600, resource: { mana: 20 }, params: { power: "1.4" } }
active_triggers:
- type: QI_ACTION
tags: [fire, aoe, combat]