阶段.yml
阶段.yml 负责副本流程本身。
一场副本的推进顺序、前后阶段衔接、Boss 切入时机和收尾流程,主要都在这里安排。
如果把 DM 的文件拆开看:
main.yml管总控阶段.yml管流程节点区域.yml管空间和区域专属脚本
阶段里最常放什么
- 阶段显示名
- 阶段触发方式
- 通关条件
- 开始脚本
- 开始玩家脚本
- 通关脚本
- 通关玩家脚本
- 下一阶段
一份够用的入门示例
yaml
入口: 阶段1_清怪
阶段1_清怪:
显示名称: '清理战斗区'
触发方式: 副本开始
通关条件: '怪物组.全灭("第一波")'
开始脚本: |
消息.全体("&e阶段一开始")
区域.解锁("战斗区")
怪物组.生成("第一波")
通关脚本: |
消息.全体("&a第一波已清空")
障碍物.关闭("Boss房大门")
下一阶段: 阶段2_Boss
阶段2_Boss:
显示名称: '击败 Boss'
通关条件: '怪物组.全灭("Boss组")'
开始脚本: |
消息.全体("&cBoss 战开始")
怪物组.生成("Boss组")
通关脚本: |
消息.全体("&6Boss 已被击败")先看懂这几个关键字段
入口
入口 是整套阶段流程的起点。
yaml
入口: 阶段1_清怪如果不写,源码会默认拿文件里第一个阶段当入口。
正式副本建议手动写清楚,后期改顺序时不容易埋坑。
触发方式
按源码当前实现,阶段触发方式实际认这两种:
副本开始- 不写时默认按“上一阶段完成”处理
也就是说:
- 第一阶段通常写
触发方式: 副本开始 - 后续阶段大多数可以直接不写
旧字段 类型 目前也还能读,但文档建议统一写 触发方式,后面维护更清楚。
通关条件 也认旧字段
阶段通关条件当前优先读 通关条件,如果没写,还会继续读旧字段 完成条件。
对应的脚本字段也一样:
通关脚本兼容旧字段完成脚本通关玩家脚本兼容旧字段完成玩家脚本
现在新文档统一用 通关... 这一套名称,旧项目迁移过来时不用急着一次改完。
阶段脚本的执行顺序
源码当前顺序是这样:
- 执行阶段自己的
开始脚本 - 执行阶段自己的
开始玩家脚本 - 再触发
事件绑定 -> 阶段开始
阶段完成时也是同样思路:
- 先执行阶段自己的
通关脚本 - 再执行阶段自己的
通关玩家脚本 - 再触发
事件绑定 -> 阶段完成
所以阶段自己的脚本,优先级比全局事件更高。
如果一段逻辑明显只属于这个阶段,最好直接写在阶段里,不要绕去 main.yml 的全局事件。
开始脚本 与 开始玩家脚本
建议这样分:
开始脚本:开门、刷怪、切区域状态、改副本变量、全队播报开始玩家脚本:给每个人挂 Buff、发个人提示、处理个人变量
例如:
yaml
开始脚本: |
副本.设置变量("暴雪开启", 1)
消息.全体("&b暴雪来袭")
开始玩家脚本: |
效果.药水("slowness", 99999, 5)
效果.药水("blindness", 99999, 100)这里的 开始玩家脚本 会对当前副本内在线玩家逐个执行。
通关脚本 与 通关玩家脚本
建议这样分:
通关脚本:播报、开门、切下一阶段前的公共处理通关玩家脚本:清 Buff、发个人提示、做个人结算前清理
例如:
yaml
通关脚本: |
消息.全体("&a第一阶段完成")
通关玩家脚本: |
效果.药水("slowness", 0, 0)
效果.药水("blindness", 0, 0)下一阶段 的两种写法
最常用的单线写法
yaml
下一阶段: 阶段2_Boss这适合普通线性副本。
分支写法
如果你要根据条件切不同阶段,可以写成列表:
yaml
下一阶段:
- 目标: 困难Boss
条件: '副本.读取变量("困难模式") == true'
- 目标: 普通Boss源码当前会按顺序判断:
- 先看有条件的分支
- 第一个条件成立的分支直接进入
- 如果都没命中,再走没有条件的兜底分支
如果这个阶段本身就是最后一段流程,也可以直接不写 下一阶段。
当前阶段通关后,阶段控制器会把它当成最终阶段,整场副本进入总通关流程。
适合写在阶段里的逻辑
- 某一波怪什么时候刷
- 某道门什么时候开
- 某个区域什么时候切成激活或清除
- 某一阶段开始时给全队挂什么效果
- 某一阶段完成后清什么状态
- 某个玩法变量什么时候打开或关闭
不建议硬塞在阶段里的内容
- 整场副本都会反复共用的全局播报
- 明显只属于某个区域的进入/离开逻辑
- 明显只属于某个按钮、拉杆、机关的逻辑
- 明显只属于某个全息点的逻辑
这些内容拆回对应配置更清楚。
玩法拆法示例
比如你要做“暴雪阶段”,推荐这样拆:
开始脚本里打开副本变量开始玩家脚本里给全员挂 Debuff 并进入循环- 外部道具通过
/dm script改副本变量 通关玩家脚本里做最终清理
yaml
暴雪阶段:
显示名称: '&b暴雪区'
触发方式: 副本开始
通关条件: '怪物组.全灭("暴雪守卫")'
开始脚本: |
副本.设置变量("暴雪开启", 1)
开始玩家脚本: |
for i in 1..10000 {
状态 = 副本.读取变量("暴雪开启") * 1
if (状态 == 0) {
效果.药水("slowness", 0, 0)
效果.药水("blindness", 0, 0)
break
}
if (状态 == 1) {
效果.药水("slowness", 99999, 5)
效果.药水("blindness", 99999, 100)
}
流程.等待(100)
}
通关玩家脚本: |
效果.药水("slowness", 0, 0)
效果.药水("blindness", 0, 0)配置建议
- 第一版副本先做单线流程,不要一开始就写分支。
- 阶段名尽量表达用途,比如
阶段1_清怪、阶段2_Boss,后面排错快很多。 - 一个阶段只解决一个明确目标,后期最稳。
- 开始脚本负责开场,通关脚本负责收尾,这样结构最好认。
- 阶段过长、逻辑过多时,优先拆成多个小阶段,不要把所有内容塞进一个阶段。
常见问题
阶段不推进
优先检查:
通关条件是否真的会成立- 怪物组、区域、变量名是否写对
- 当前阶段是不是你以为的那个阶段
下一阶段是否指向了存在的阶段 ID
后续阶段没自动开始
如果这个阶段不是最后阶段,就必须保证 下一阶段 能解析出结果。
写了条件分支时,还要确认至少有一条分支能命中,或者留一个无条件兜底分支。
阶段里写了玩家脚本,但效果不对
阶段里的 开始玩家脚本 和 通关玩家脚本 都是对当前副本内在线玩家逐个执行。
如果你只想处理某个玩家,通常要靠变量判断,或者把逻辑移到更具体的触发点上。