Skip to content

阶段.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_清怪

如果不写,源码会默认拿文件里第一个阶段当入口。

正式副本建议手动写清楚,后期改顺序时不容易埋坑。

触发方式

按源码当前实现,阶段触发方式实际认这两种:

  • 副本开始
  • 不写时默认按“上一阶段完成”处理

也就是说:

  • 第一阶段通常写 触发方式: 副本开始
  • 后续阶段大多数可以直接不写

旧字段 类型 目前也还能读,但文档建议统一写 触发方式,后面维护更清楚。

通关条件 也认旧字段

阶段通关条件当前优先读 通关条件,如果没写,还会继续读旧字段 完成条件

对应的脚本字段也一样:

  • 通关脚本 兼容旧字段 完成脚本
  • 通关玩家脚本 兼容旧字段 完成玩家脚本

现在新文档统一用 通关... 这一套名称,旧项目迁移过来时不用急着一次改完。

阶段脚本的执行顺序

源码当前顺序是这样:

  1. 执行阶段自己的 开始脚本
  2. 执行阶段自己的 开始玩家脚本
  3. 再触发 事件绑定 -> 阶段开始

阶段完成时也是同样思路:

  1. 先执行阶段自己的 通关脚本
  2. 再执行阶段自己的 通关玩家脚本
  3. 再触发 事件绑定 -> 阶段完成

所以阶段自己的脚本,优先级比全局事件更高。

如果一段逻辑明显只属于这个阶段,最好直接写在阶段里,不要绕去 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

后续阶段没自动开始

如果这个阶段不是最后阶段,就必须保证 下一阶段 能解析出结果。

写了条件分支时,还要确认至少有一条分支能命中,或者留一个无条件兜底分支。

阶段里写了玩家脚本,但效果不对

阶段里的 开始玩家脚本通关玩家脚本 都是对当前副本内在线玩家逐个执行。

如果你只想处理某个玩家,通常要靠变量判断,或者把逻辑移到更具体的触发点上。

下一步阅读

TQ Minecraft Server Plugin Docs