顶级字段
一个完整的 GUI 配置文件(recipes/*.yml)由若干顶级字段组成。本页列出所有字段、依赖关系,以及脚本的执行顺序。
必填字段
| 字段 | 类型 | 说明 |
|---|---|---|
title | String | GUI 标题(支持 & 颜色码) |
rows | Integer | GUI 行数(1–6) |
layout | String | 9 列 × N 行的字符矩阵 |
slots | Map | 布局字符到槽位定义的映射 |
常用可选字段
| 字段 | 作用 | 执行时机 |
|---|---|---|
match | 配方级匹配(决定此 GUI 能处理哪些物品) | 打开 GUI 前 |
target | 默认操作的槽位(只影响 targetItem 内部字段,不自动建"装备"变量) | 渲染前 |
variables | 变量定义块(支持 if、slot.set) | 每次刷新都执行 |
init | 初始化脚本 | 只在打开 GUI 时执行一次 |
conditions | 前置条件检查 | 按钮点击时 |
execute | 主脚本(点击按钮执行) | 条件通过后 |
onchange | 槽位变化事件(键必须是槽位 ID) | 玩家手动放入/取出时 |
scripts | 命名脚本块(供 execute=name / script=name 引用) | 按需 |
closeable | 是否允许玩家按 ESC 关闭(默认 true) | — |
session_timeout | 会话超时秒数(0 立即销毁、-1 永不超时) | — |
use | 引用的模块列表 | 启动加载时合并 |
modules | 内联模块定义 | 启动加载时合并 |
recipes | 锻造配方定义(供 match_recipe 使用) | 按需 |
字段依赖
title (必须)
└── rows (必须)
└── layout (必须)
└── slots (必须)
├── init (可选,只执行一次)
├── variables (可选,每次刷新求值)
├── conditions (可选,execute 之前检查)
├── execute (可选,按钮点击执行)
├── onchange (可选,手动放入/取出触发)
├── scripts (可选,命名脚本块)
├── closeable (可选,默认 true)
└── session_timeout (可选,默认 0)脚本执行顺序
┌────────────────────────────────┐
│ GUI 打开 │
├────────────────────────────────┤
│ 1. 创建 GUISession │
│ 2. 执行 variables │
│ 3. 执行 init(仅一次) │
│ 4. 渲染槽位(预览槽位跑 preview)│
│ 5. 打开 Inventory 给玩家 │
└────────────────────────────────┘
│
▼
┌────────────────────────────────┐
│ 玩家手动放入 / 取出物品 │
├────────────────────────────────┤
│ 1. 更新槽位 │
│ 2. 触发 onchange(如配置) │
│ 3. 重新执行 variables │
│ 4. 重新渲染所有槽位 │
└────────────────────────────────┘
│
▼
┌────────────────────────────────┐
│ 玩家点击按钮 │
├────────────────────────────────┤
│ 1. 执行 variables │
│ 2. 执行 conditions │
│ └─ 失败:中止并提示 │
│ 3. 执行 execute(或按钮绑定脚本)│
│ 4. 同步修改后的物品回槽位 │
│ 5. 刷新 GUI │
└────────────────────────────────┘
│
▼
┌────────────────────────────────┐
│ GUI 关闭 │
├────────────────────────────────┤
│ session_timeout == 0:立即销毁 │
│ session_timeout > 0:后台保留 │
│ session_timeout == -1:永不超时 │
└────────────────────────────────┘init 与 variables 的区别
| 特性 | init | variables |
|---|---|---|
| 执行时机 | 仅打开时执行一次 | 每次刷新都执行 |
| 执行顺序 | variables 之后 | init 之前 |
| 主要用途 | 初始化槽位内容、预加载数据 | 动态计算、动态更新槽位显示 |
| 可用变量 | 可使用 variables 中的变量 | 可使用槽位变量 |
| 典型操作 | slot.set() 初始化 | 计算变量、根据状态 slot.set() |
| 副作用限制 | 无 | 禁止 effect.message()(会重复) |
yaml
# init:只执行一次,适合初始化转盘奖品或锁定展示槽位
init: |
slot.set("s1", item("mm:红宝石"))
slot.lock("s1,s2,s3,s4,s5,s6,s7,s8,s9")
# variables:每次刷新都会执行,可以 if + slot.set 动态更新展示
variables: |
当前等级 = @input.filled ? @input.counter('强化等级') : 0
强化材料 = 当前等级 <= 5 ? item("ni:低级材料") : item("ni:高级材料")
if @input.filled {
slot.set("材料展示", 强化材料)
}variables 中不能发消息
yaml
variables: |
effect.message("xxx") # ❌ 每次 refresh 都会触发,消息会刷屏消息提示请放进 onchange(玩家手动放入时)或 execute(点击按钮时)。
onchange 的触发时机
onchange 只在玩家手动把物品放入/取出对应槽位时触发,键名必须是槽位 ID(不是槽位类型名,也不是布局字符)。
yaml
slots:
I: input(id=input, ...)
装: input(id=主装备, ...)
onchange:
input: | # ← 对应 id=input 的槽位
if @input.filled {
effect.message("&a检测到装备")
}
主装备: | # ← 对应 id=主装备 的槽位
effect.sound("ITEM_ARMOR_EQUIP_GENERIC", 0.5, 1.0)关键特性:
slot.set()+effect.refresh()不会触发onchange,因为不是玩家手动操作。- 想在按钮点击后自动更新其他槽位显示,把逻辑放在
variables末尾,配合effect.refresh()刷新即可。 onchange适合做一次性的提示消息和音效反馈,不适合放业务逻辑。
closeable 与 session_timeout
closeable: false:玩家按 ESC 会被自动重开 GUI,需要脚本里调用gui.unlock()才能真的关闭。session_timeout(秒):0:关闭 GUI 立即销毁会话,未锁定的槽位物品全部归还玩家。> 0:关闭后进入后台模式,N 秒后自动销毁。玩家可重新打开查看进度。-1:永不超时(直到玩家退出服务器)。
这两项配合使用可以实现转盘动画、制造台倒计时等跨生命周期的流程。详见 会话与物品安全。
一个最小完整示例
yaml
title: "&6示例 GUI"
rows: 3
match: "lore.contains('可操作')"
layout: |
.........
....I....
.........
slots:
I: input(id=input, match="lore.contains('可操作')")
variables: |
可操作 = @input.filled
onchange:
input: |
if @input.filled {
effect.message("&a已放入物品")
}
execute: |
require @input.filled : "&c请先放入物品"
effect.message("&a操作成功")