跳转到内容

阶段配置 stages.yml

stages.yml 给副本一条流程主线:清怪 → 开门 → Boss → 结算。以前这类推进逻辑只能在 scripts.yml 里用 setVar + if 手搓状态机,现在有了正经的落点。

这个文件是可选的——不建它,副本行为与以前完全一致。

五行能跑:清完一波怪自动进 Boss 阶段,打完 Boss 通关。

清怪:
通关条件: "dungeon.isGroupCleared('wave_1')"
下一阶段: Boss
Boss:
通关条件: "dungeon.isGroupCleared('boss')"

不写 入口 就取文件里第一个阶段;最后一个阶段不写 下一阶段,通关后走 scripts.yml 的 complete 流程。

阶段少的时候也可以直接内联在 scripts.yml 的 阶段:(或 stages:)段下,不必单开文件。

入口: 清怪 # 可省略,默认取第一个阶段
清怪:
名称: "&e清理前厅" # 可省略,默认用阶段 key
通关条件: "dungeon.isGroupCleared('wave_1')"
超时: 300 # 秒,可省略;0 或不写 = 不限时
开始脚本: |-
action.title('@all', '&e第一阶段', '&7清理所有敌人')
action.spawn_group('wave_1')
通关脚本: |-
action.remove_obstacle('Boss房大门')
超时脚本: |-
action.fail('超时')
下一阶段: Boss
Boss:
名称: "&c击败守卫者"
通关条件: "dungeon.isGroupCleared('boss')"
开始脚本: |-
action.spawn_group('boss')
下一阶段: # 分支写法
- 目标: 隐藏房
条件: "getVar('找到密道') == 1"
- 目标: 结算 # 无条件兜底,放最后

顶层

键(中/英)类型默认说明
入口 / entryString第一个阶段起始阶段 key

单个阶段

键(中/英)类型必填默认说明
名称 / nameString否阶段 key显示名,支持 & 颜色
通关条件 / complete_whenString是—JS 表达式,返回真值即完成
超时 / timeoutInt否0秒,0 = 不限时
开始脚本 / on_start列表/多行否空进入该阶段时执行一次
通关脚本 / on_complete列表/多行否空该阶段完成时执行一次
超时脚本 / on_timeout列表/多行否空超时时执行;不写则什么都不做
下一阶段 / nextString 或 List否无不写 = 最终阶段

分支项(下一阶段 写成列表时)

键(中/英)类型必填说明
目标 / targetString是目标阶段 key
条件 / conditionString否不写 = 无条件兜底

分支按列表顺序判定,第一个成立的命中;都不成立就走无条件兜底;没有兜底则视为最终阶段,副本直接通关。

阶段 ID 不能含点号,也不能叫 入口 / entry。

阶段完全由事件驱动,没有任何定时器在轮询通关条件。以下事件发生后会重新判定一次当前阶段:

  • 怪物组全灭(或被 skip_group 跳过)
  • 交互点被触发
  • 玩家进入或离开区域
  • 脚本调用 action.complete_stage()
  • 阶段超时

进入一个阶段时也会立即判定一次,所以条件在进入瞬间就成立的话会直接连跳到下一阶段。

动作说明
action.complete_stage()跳过通关条件,直接完成当前阶段
action.goto_stage('阶段ID')跳转到指定阶段,不执行当前阶段的通关脚本
action.restart_stage()重新进入当前阶段,会再跑一次开始脚本

中文别名分别是 完成阶段 / 跳转阶段 / 重启阶段。

action.complete() 仍然可以随时直接通关,不受阶段限制——这是保留的紧急出口。

方法返回说明
dungeon.stageString当前阶段 key,未启用返回空
dungeon.stageNameString当前阶段显示名
dungeon.stageIndexInt当前是第几个阶段,1 起;未启用返回 0
dungeon.stageCountInt阶段总数
dungeon.isFinalStage()Boolean当前是否最终阶段
dungeon.stageElapsedLong当前阶段已进行秒数

写通关条件常用的几个查询:

方法返回说明
dungeon.isGroupCleared('组ID')Boolean该组是否已启动过并且全灭
dungeon.isGroupActive('组ID')Boolean该组是否正在进行中
dungeon.getAliveMonsterCount('组ID')Int该组存活怪物数
dungeon.getMobKillCount('怪物ID')Int按怪物类型统计的击杀数
dungeon.getZonePlayerCount('区域')Int区域内玩家数
getVar('变量名')Any脚本变量
变量说明
%quedp_stage%当前阶段 key
%quedp_stage_name%当前阶段显示名
%quedp_stage_index%当前是第几个阶段
%quedp_stage_count%阶段总数

主编辑器界面的「阶段」入口进管理界面:

  • 阶段列表:显示顺序、显示名、通关条件、超时、流向、哪个是入口。左键编辑,右键设为入口,Shift+左键上移,Shift+右键删除(点击确认)
  • 单阶段编辑:改显示名 / 通关条件 / 超时 / 三个脚本 / 下一阶段
  • 通关条件模板:常用条件(清空怪物组、击杀数达标、变量达标、区域内有人)可以直接挑一个套上再改,不用背 JS

删除阶段时,其他阶段指向它的分支会一并断开,避免留下加载时报错的配置。

条件分支在阶段编辑里 Shift+左键「下一阶段」 进入分支管理:新增(选目标再输条件)、改条件、换目标、上移、删除;输入 none 表示无条件兜底。

  • 和怪物组 TRIGGERED 并存:两套推进机制可以同时用,但建议二选一。用了阶段就别再配 TRIGGERED 链,否则两条线互相推进很难排查
  • 不替换生命周期脚本:scripts.yml 的 init / start / complete / fail 语义完全不变。阶段是叠加在上面的一层,最终阶段完成后仍然走 complete
  • 入口阶段在 start 脚本之后进入:所以 start 脚本里可以先铺好前置状态
  • 只有单条主线 + 条件分支,没有并行阶段和阶段树,一次只有一个当前阶段
  • 一条推进链最多连跳 8 个阶段。超过会打 warn 并停在原地——通常意味着某个通关条件恒为真
  • 条件表达式在运行期求值,语法错误只会 warn 一次并当作 false,不会在加载时报出来。分支目标写错、入口写错、通关条件漏填这三类会在加载期报错
  • 条件表达式请保持简短,只做查询不要有副作用。它是同步求值的,action.* 在条件里不可用