跳到主要内容

脚本写法

副本里所有会「做事」的地方都用同一种脚本:一个清单,每一行一个动作,从上往下执行。

文件哪里写脚本
before.ymlscript
start.ymlscript
monster.yml每组的 start、end、timeout,每一波的 start、end
script.yml每个脚本组本身
task.ymltimeline 里每个时间点、every 的 script
trigger.yml每个触发的 script
end.ymlclear、fail
before.yml
script:
- "title &b&l霜烬古殿||&7寒气从四面八方涌来"
- "sound ENTITY_ELDER_GUARDIAN_CURSE 0.6 1"
- "delay 2"
- "message &7长老:「先打倒前厅的卫兵,大门才会打开。」"

每个动作能写哪些参数,见 动作:消息与音效、动作:流程、动作:怪物 等页面; 条件见 条件,变量见 变量。

三种写法​

同一个动作可以用下面三种方式写,可以在同一个清单里混用。

写法格式例子
简写动作 参数1 参数2 …monstergroup 怪物组1
等号动作=参数monstergroup=怪物组1、delay=2
完整写法(与 DungeonPlus 相同)$动作{名称=值;名称=值} @对象 ~区域$monstergroup{group=怪物组1} @dungeon

简写​

动作名称后面接参数,用空格分开。参数照顺序填,每个动作的参数顺序见各动作页面。 消息类的最后一个参数是「整段文字」,中间可以有空格:

- "message &a欢迎来到 &b霜烬古殿"
- "sound ENTITY_WITHER_SPAWN 1 0.8"
- "mob minecraft:zombie 补怪点 3"

简写里也可以夹带 名称=值,不必记顺序,也能补上简写没有位置的参数:

- "mob SkeletonKing 王座 amount=2 level=10 spread=3"

最后一个参数是一整段文字的动作(message、title、hologram 的文字、npc 的名字……)也可以在文字后面接参数, 例如 title &c第二波||&7更多骷髅来了 stay=3、hologram create 传送石 传送石 &e点我传送 click=true, 能接哪些参数见 动作:消息与音效。

等号写法​

只有一个参数时可以写成 动作=参数,和简写完全相同:

- "monstergroup=怪物组1"
- "delay=1.5"

完整写法(DungeonPlus)​

以 $ 开头,参数写在 {} 里,用 ; 分开,每个参数是 名称=值。DungeonPlus 的脚本行可以直接贴进来:

- "$message{type=title;text=&c第二波,&7更多骷髅来了} @dungeon"
- "$monstergroup{group=怪物组2;delay=3} @dungeon"
- "$command{text=eco give <self:player-name> 100;console=true} @self"
  • 值里面要放 ; 时写成 \;。
  • 值里面可以有 {v:变量} 这种大括号,不会被当成结尾。
  • } 后面的 @对象 与 ~区域 顺序不限。
用哪种?

新写的副本用简写最好读;从 DungeonPlus 搬过来的直接贴,不用改。两种混着写也没问题。

@对象:作用在谁身上​

行尾的 @对象 决定这一行作用在哪些玩家身上。没写时用每个动作自己的默认值(大部分是 @dungeon,tell 是 @self)。

对象作用在
@dungeon副本里所有还在场的人(大部分动作的默认值)
@all同 @dungeon
@player每个人各执行一次(消息类与 @dungeon 效果相同;script 名称 @player 见下方)
@self触发的玩家(@init 也算这个)。触发组、@player 执行的脚本组里才有触发者
@leader队长
@random随机一人
@alive还活着的人
@dead倒下(等待复活、旁观)或已出局的人
@others触发者以外的人
@system条件用:全队每个人都要符合(DungeonPlus 的 @system)
- "message &e你踩到了机关 @self"
- "message &7{self} 踩到了机关 @others"
- "effect SPEED 10 2 @alive"
- "teleport 王座 @random"

谁是触发者(@self、{self})

脚本在哪里触发者
trigger.yml引发这次触发的玩家,各种类见 触发组;mob-health、wipe、variable 这类没有触发者
script.yml呼叫它的那一串的触发者;用 script 名称 @player 时每个人各当一次触发者
before.yml、start.yml、monster.yml、task.yml、end.yml没有触发者,@self 不会作用在任何人身上
简写的 @ 要放在最后

简写时 @对象 必须是整行最后一个词,前面要有空格。消息内容里刚好出现「空格 + @ + 对象名」(例如 @leader)也会被当成对象, 这种文字请改用完整写法 $message{text=…}。

~区域:只对区域里的人执行​

在 @对象 后面加 ~区域A,区域B,只对站在这些区域里的玩家执行(区域在 编辑模式 用金斧框出来):

- "message &c岩浆在你脚下翻滚! @dungeon ~岩浆区"
- "effect SLOWNESS 3 2 @alive ~岩浆区,火焰走廊"
- "$message{type=actionbar;text=&c好热} @dungeon ~岩浆区"
  • 简写时一定要连同 @对象 一起写(@对象 ~区域),而且 ~ 后面的区域清单不能有空格;单独写 ~区域 会被当成消息文字的一部分。
  • 区域限制只过滤「作用在哪些玩家身上」,对不针对玩家的动作(例如 monstergroup、obstacle)没有效果。
  • ~@ALL 等于不限区域(DungeonPlus 的写法)。

delay:等一下再继续​

delay 秒数 让这一串停下来,时间到了再接着执行下一行(wait 也可以):

写法意思
delay 22 秒
delay 1.51.5 秒
delay 10t10 tick
delay 500ms0.5 秒
delay 1m30s1 分 30 秒
delay 5分钟5 分钟(中文单位也可以,例如 1小时)
delay {v:等待秒数}用变量
- "title &c它醒了"
- "delay 2"
- "monstergroup 霜烬守卫"
  • delay 只会卡住这一串,同时进行中的其他脚本(任务组、触发组、其他怪物组)照常运行。
  • 副本结束(通关、失败、强制结束)时所有还在等的 delay 都会被取消,不会跑到副本外面。
  • script 名称 会等脚本组跑完(包含里面的 delay)才执行下一行;怪物组 start 里的 delay 跑完才会出怪。
  • monstergroup 组名 3 这种「最后一个数字 = 几秒后」的写法不会卡住后面的行,见 怪物组。

条件​

一行条件:if … -> 动作​

- "if {v:钥匙} >= 3 -> obstacle open 大门"
- "if !task 倒数 -> task start 倒数"
- "chance 30 -> message &e幸运!你捡到了额外的碎片"
  • if 条件 -> 动作:条件成立才执行箭头后面的一个动作。
  • chance 概率 -> 动作:概率(%)成立才执行。
  • 条件前面加 ! 代表反过来。

条件区块:if / then / else​

要执行好几行、或不成立时也要做事,用区块:

script.yml
检查钥匙:
- if: "{v:钥匙} >= 3"
then:
- "obstacle open 大门"
- "title &a大门开启了"
else:
- "message &c还差 {v:钥匙}/3 把钥匙 @self"
- "message &7(检查完毕)"
键别名说明
ifcondition、conditions一个条件,或条件清单(默认全部成立才算成立)
thentrue、do成立时执行
elsefalse不成立时执行(可省略)
anytrue = 条件清单里任一成立就算成立
- if:
- "region 祭坛区 all"
- "{v:钥匙} >= 3"
any: true
then:
- "monstergroup 守卫"

区块里也可以放 delay、script 或另一个区块,分支跑完才会接着跑区块后面的行。

DungeonPlus 的 condition / true / false​

DungeonPlus 脚本组的写法原样可用:

- condition:
- "$data-condition{key=钥匙;type=value;value=>=3} @system"
true:
- "$message{type=text;text=门开了} @dungeon"
false:
- "$message{type=text;text=还差钥匙} @self"

条件能写什么(kill、left、var、group、region、players、任何 PlaceholderAPI 运算式……)见 条件。

单键写法​

清单里写成 动作: 参数 的单键对照,等同于 动作 参数:

script:
- message: "&a欢迎"
- delay: 2
- monstergroup: 怪物组1

变量​

任何一行都可以用变量,执行时才代入:

写法例子
本插件变量 {…}{self}、{v:钥匙}、{elapsed}、{group:守卫:state}、{killed}/{total}
PlaceholderAPI %…%%player_level%(对作用的那位玩家代入)
DungeonPlus 占位符 <头:参数><self:player-name>、<data:value *钥匙>

全部变量见 变量。

stop:提前结束这一串​

stop(或 return)让目前这一串到此为止,后面的行不执行。它只停目前这一串:用 script 名称 呼叫的脚本组里碰到 stop 时, 脚本组就此结束、回到呼叫它的那一串,呼叫的那一串会接着执行下一行。要整场副本结束请用 fail / end。

- if: "{v:已开启} == 1"
then:
- "message &7机关已经启动过了 @self"
- "stop"
- "var set 已开启 1"
- "obstacle open 暗门"

出错时​

  • 某一行出错只会跳过那一行,后面照常执行;控制台会写出是哪个文件、哪一行、什么原因 (例如 monster.yml 怪物组1.end 动作执行失败「teleport 王坐」:找不到点位 王坐)。
  • 读设置时发现的问题(动作名称打错、怪物组没有怪、触发种类写错……)在 /cd admin reload 时列出来; /cd admin validate <副本> 可以单独检查一个副本。设置错误只会略过那一项,不会让整个副本失效。
  • 不认得的动作名称会被当成错误略过;DungeonPlus 的 Kether 语句不支持,请改用一般动作。

YAML 小提醒​

  • 每一行用双引号包起来最保险:- "message &a你好"。& 开头、或文字里有 : 、# 的行一定要加引号。
  • 文字里要放双引号时,外面改用单引号:- 'message &7长老说:"快走"'。
  • 缩进用空格,不要用 Tab。