脚本概览
IM 的脚本语法与 YAML 是两回事。所有写在 variables、init、conditions、execute、onchange、scripts 等字段里的内容都是脚本,而字段本身是 YAML 多行字符串(必须用 |)。
yaml
variables: | # 这里 ↓ 开始就是脚本,不是 YAML
最大等级 = 10
当前等级 = @input.counter('强化等级')
成功率 = max(10, 100 - 当前等级 * 5)
// 支持单行注释,支持 if/else、for、switch、chance
if @input.filled {
slot.set("展示", item("ni:材料"))
}脚本语法 vs YAML 的区别
| 特征 | YAML | IM 脚本 |
|---|---|---|
| 赋值 | 键: 值 | 变量 = 值 |
| 引号 | 字符串必须加引号(大多数场合) | 标识符不加引号,字符串加 " 或 ' |
| 注释 | # | //、#、/* */ 都支持 |
| 分支 | 无 | if / else、switch / case、chance / fail |
| 循环 | 无 | for i in 1..N |
不要把脚本写成 YAML 键值对:
yaml
# ❌ 错误
variables:
最大等级: 10
当前等级: "@input.counter('强化等级')"
# ✓ 正确
variables: |
最大等级 = 10
当前等级 = @input.counter('强化等级')数据类型
| 类型 | 示例 | 说明 |
|---|---|---|
| Number | 10, 3.14, -5 | 整数或浮点数 |
| String | "文本", '文本' | 字符串 |
| Boolean | true, false | 布尔 |
| List | [1, 2, 3], ["a", "b"] | 列表 |
| ItemStack | @input, item("mm:Sword") | 物品 |
| null | null | 未定义/未匹配 |
字符串和数字相加会自动拼接;布尔在条件位置自动解包。
运算符
算术
| 运算符 | 说明 | 示例 |
|---|---|---|
+ | 加 / 字符串拼接 | "等级 " + 5 → "等级 5" |
- / * / / / % | 减 / 乘 / 除 / 取模 | 10 / 3 = 3.33... |
比较
==、!=、>、>=、<、<=。可以比较数字和字符串(后者按字典序)。
逻辑
&&、||、!。短路求值。
三元
结果 = 条件 ? 真值 : 假值可以嵌套,多分支时建议加括号:
yaml
variables: |
阶段名称 = 阶段1 ? "初级" : (阶段2 ? "中级" : (阶段3 ? "高级" : "传说"))
强化材料 = 阶段1 ? item("ni:低级材料") : (阶段2 ? item("ni:中级材料") : item("ni:高级材料"))赋值
=、+=、-=、*=、/=、%=。
yaml
execute: |
总伤害 = 0
总伤害 += 物理攻击
总伤害 += 法术攻击 * 0.5variables / init / execute 的区别
| 字段 | 触发时机 | 允许操作 | 不建议 |
|---|---|---|---|
init | GUI 打开,仅一次 | 预加载、初始化槽位(slot.set / slot.lock) | — |
variables | 每次刷新都跑 | 变量计算、动态 slot.set | 禁用 effect.message(刷屏) |
execute | 按钮点击 / 默认脚本 | 全部动作 | — |
conditions | 按钮点击前校验 | require 风格检查 | 不应做长耗时 / 有副作用操作 |
onchange | 玩家手动放入/取出槽位 | 提示音、消息 | 不放业务逻辑 |
variables 中禁止发消息
yaml
variables: |
effect.message("...") # ❌ 每次 refresh 都会执行,会刷屏消息提示请放进 onchange 或 execute。
变量作用域
variables中定义的变量,可在execute/conditions/onchange/scripts中直接使用。execute中定义的变量,不能被预览脚本访问(预览运行在独立沙箱中)。- 循环内定义的变量在循环外仍可见(无块级作用域)。
- 函数调用不会创建新作用域。
yaml
execute: |
for i in 1..10 {
最后值 = i // 循环外也能访问
}
log(最后值) // 10插值与拼接
字符串里用 {变量} 做插值。插值只在字符串参数里生效(effect.message、name.set、lore.append、display 的 name / lore 等):
yaml
execute: |
effect.message("&a{player.name} 强化 {名称} 到了 {当前等级}/{最大等级} 级")
装备.name.set("&6{原名} +{新等级}")也可以用 + 拼接:
yaml
variables: |
颜色 = 成功率 >= 50 ? "&a" : "&c"
状态文本 = 颜色 + 成功率 + "%" # 运行时类型自动转字符串什么时候选哪种?
| 场景 | 推荐 |
|---|---|
| 静态模板 + 几个变量 | 插值 {变量} |
| 需要动态拼接前缀 / 颜色码 | 拼接 + |
| 在匹配表达式里 | 都不要用 {} — 直接写变量名 |
详见 引用与插值。
一个完整的脚本生命周期示例
yaml
variables: |
// 每次刷新都跑
当前等级 = @input.filled ? @input.counter('强化等级') : 0
成功率 = max(5, 95 - 当前等级 * 5)
init: |
// 打开 GUI 时执行一次
slot.set("展示", item("ni:装饰"))
slot.lock("展示")
onchange:
input: |
// 玩家手动放入 / 取出时
if @input.filled {
effect.sound("ITEM_ARMOR_EQUIP_GENERIC", 1.0, 1.0)
}
conditions: |
// 按钮点击前的前置检查
require @input.filled : "&c请先放入装备"
require money >= 消耗金币 : "&c金币不足"
execute: |
// 主逻辑
money.take(消耗金币)
chance 成功率 {
装备 = @input
装备.lore.attr("攻击力", "+10")
slot.set("input", 装备)
effect.message("&a强化成功!")
} fail {
effect.message("&c强化失败")
}下一步:引用与插值 了解所有 @ 引用和 {} 插值规则;或 流程控制 系统学习 if / switch / for / chance / with / require。