Skip to content

Script Engine

Noogear edited this page Mar 9, 2026 · 4 revisions

脚本引擎

GloomLib Script — 高性能声明式 YAML 脚本引擎。

目录

节点参考

节点 说明
[[条件判断 check Check-Node]]
[[动作调用 action Action-Node]]
[[返回值 return Return-Node]]
[[多分支 switch Switch-Node]]
[[数学运算 math Math-Node]]
[[复合条件 any / all Composite-Conditions]]
[[集合操作 collect Collect-Node]]
[[操作符参考 Operators]]
[[数学表达式 Math-Expressions]]

顶层结构

id: "my-script"                              # 脚本标识符(可选,默认 AnonymousScript)
event: "com.example.MyEvent"                 # 必填,事件/载荷类的全限定名
priority: 0                                  # 可选,事件优先级(默认 0)
ignore-cancelled: true                       # 可选,已取消事件是否跳过(默认 true)

variables:
  # ...

flow:
  # ...
字段 类型 必填 默认值 说明
id String AnonymousScript 脚本唯一标识,用于日志和错误追踪
event String 载荷类全限定名
priority Integer 0 事件监听优先级
ignore-cancelled boolean true true 时已被取消的事件不触发脚本
variables Map {} 变量声明映射
flow List [] 流程节点列表

variables 变量声明

将载荷对象的属性映射为脚本变量。

variables:
  # 简单属性:调用 event.getDamage()
  damage: "damage"

  # 链式属性:event.getEntity().getName()
  entityName: "entity.name"

  # 集合索引:event.getPlayer().getInventory().get(0)
  firstItem: "player.inventory[0]"

  # Map 索引:event.getMetadata().get("key")
  metaValue: "metadata[key]"
  quotedKey: "metadata['damage_all']"

  # payload 别名:直接引用载荷对象本身
  event: "$self"

属性解析规则

语法 示例 解析方式
简单属性 damage 调用 getDamage()damage()
链式属性 entity.name 依次调用 getEntity()getName()
List 索引 inventory[0] 调用 getInventory()List.get(0)
Map 索引 metadata[key] 调用 getMetadata()Map.get("key")
payload 别名 $self 直接引用载荷对象

getter 查找优先级

  1. getXxx() — 标准 Java Bean getter
  2. isXxx() — boolean getter
  3. xxx() — Record 风格 accessor

flow 流程节点

flow 是一个有序列表,引擎按顺序执行每个节点。共支持 8 种节点类型

类型 YAML 触发键 说明 详细参考
CHECK check 条件判断 [[详情
ACTION action 或动态推断 调用已注册动作 [[详情
RETURN return 返回值并终止 [[详情
SWITCH switch 多分支选择 [[详情
MATH math 数学表达式求值 [[详情
ANY any OR 复合条件 [[详情
ALL all AND 复合条件 [[详情
COLLECT collect 集合遍历与筛选 [[详情

节点类型通过触发键自动推断,无需显式声明 type 字段。


模板字符串

使用 {变量名} 语法在字符串中插入变量值。

# 单变量引用
args: ["{damage}"]

# 多变量模板
args: ["玩家 {playerName} 受到 {damage} 点伤害"]

# 链式属性引用
args: ["{entity.name}"]

# return 中使用模板
- return: "HP:{hp} DMG:{damage}"

属性链解析

属性路径支持多级嵌套:

player.inventory[0].amount
  │       │      │     └── getAmount() → int
  │       │      └──────── List.get(0) → ItemStack
  │       └─────────────── getInventory() → List<ItemStack>
  └─────────────────────── getPlayer() → Player
类型 语法 说明
属性访问 property 标准 getter 调用
List 索引 list[index] List.get(int)
Map 索引 map[key] Map.get(String),支持引号包裹 key

完整示例

示例 1:伤害指示器

id: "damage-indicator"
event: "org.bukkit.event.entity.EntityDamageByEntityEvent"
priority: 3

variables:
  target: "entity"
  source: "damager"
  value: "finalDamage"
  cause: "cause"
  critical: "critical"

flow:
  - check: target
    op: "instanceof"
    value: "org.bukkit.entity.LivingEntity"

  - check: value
    op: ">"
    value: 0

  - check: critical
    op: "!="
    value: true
    on_fail:
      - showIndicator: ["{target}", "{source}", "{value}", "CRITICAL"]
      - return

  - showIndicator: ["{target}", "{source}", "{value}", "{cause.name}"]

示例 2:复合条件与失败回退

id: "pvp-guard"
event: "org.bukkit.event.entity.EntityDamageByEntityEvent"

variables:
  damage: "damage"
  entity: "entity"
  weapon: "damager.itemInMainHand.type.name"

flow:
  - all:
      - check: damage
        op: ">"
        value: 5
      - check: weapon
        op: "in"
        value: ["DIAMOND_SWORD", "IRON_SWORD", "NETHERITE_SWORD"]
      - check: entity
        op: "!null"
    on_fail:
      - return

  - any:
      - check: damage
        op: "between"
        value: [100, 999]
      - check: weapon
        op: "starts_with"
        value: "NETHERITE"

  - showIndicator: ["{entity}", "{entity}", "{damage}", "SPECIAL"]

示例 3:数学计算与分支

id: "rpg-damage"
event: "com.example.CombatEvent"

variables:
  attack: "attacker.attack"
  defense: "target.defense"
  level: "attacker.level"
  weaponType: "weapon.type"

flow:
  - math: "clamp({attack} * (1 + {level} * 0.05) - {defense} * 0.3, 1, 99999)"
    store: "finalDmg"

  - switch: weaponType
    cases:
      SWORD:
        - math: "{finalDmg} * 1.2"
          store: "finalDmg"
      BOW:
        - math: "{finalDmg} * 0.9"
          store: "finalDmg"

  - action: "applyDamage"
    args: ["{finalDmg}"]

示例 4:集合筛选

id: "inventory-check"
event: "com.example.TradeEvent"

variables:
  items: "player.inventory"

flow:
  # 必须存在稀有物品
  - collect: items
    op: exists
    match:
      - check: "$it"
        op: "contains"
        value: "rare"
    on_fail:
      - action: "sendMessage"
        args: ["背包中没有稀有物品"]
      - return

  # 统计匹配数量
  - collect: items
    op: count
    store: "rareCount"
    match:
      - check: "$it"
        op: "contains"
        value: "rare"

  - action: "log"
    args: ["找到 {rareCount} 个稀有物品"]

Clone this wiki locally