变量参考
DM 的变量层分得很细。
副本公共状态、玩家个人状态、上下文对象、外部占位符、外部插件变量,都可以一起接进脚本。
读取顺序
普通脚本里直接写变量名时,源码的读取顺序是:
- 当前脚本上下文里刚写进去的变量
- 当前玩家的副本会话变量
- 当前副本实例变量
同名变量如果在多层都存在,离当前脚本最近的那层会先被读到。
变量来源总表
| 类型 | 读取写法 | 写入方式 | 返回值 | 可写 | 说明 |
|---|---|---|---|---|---|
| 脚本局部变量 | 变量名 | 变量名 = 值、变量.设置()、设置变量() | 任意类型 | 可以 | 当前脚本最先读取到的一层。 |
| 玩家会话变量 | 变量名、玩家.读取变量("变量名") | 玩家.设置变量()、玩家.增加变量()、玩家.扣除变量() | 任意类型 | 可以 | 只对当前玩家生效,不和队友共用。 |
| 副本实例变量 | 变量名、副本.读取变量("变量名") | 副本.设置变量()、变量名 = 值、设置变量() | 任意类型 | 可以 | 这次副本全队共用,副本结束后清空。 |
| 玩家内建统计 | damage_dealt 等 | 无 | 数字 | 不可以 | 副本运行时自动统计,不能手动改。 |
| 玩家上下文属性 | @player.xxx | 无 | 文本、数字或布尔 | 不可以 | 直接从当前玩家对象读取。 |
| 玩家对象本体 | @player | 无 | Player 对象 | 不可以 | 主要给内部对象调用和条件环境用。 |
| 副本对象本体 | @dungeon | 无 | 副本实例对象 | 不可以 | 主要给内部对象调用和条件环境用。 |
| PAPI 占位符 | 变量.PAPI("%placeholder%") | 无 | 文本或数字 | 不可以 | 读取 PlaceholderAPI。 |
| 外部变量 | CX读取()、AM读取()、AM服务器读取() | 对应动作页里的写入动作 | 依插件而定 | 取决于接入插件 | CraftX 和 AchieveMaster 的变量层。 |
| 仓库数量 | 仓库数量("物品ID", [目标]) | 对应动作页里的仓库动作 | int | 不适用 | 用来把仓库物品数量接进脚本条件。 |
普通变量
副本公共变量
| 项目 | 读取写法 | 写入方式 | 返回值 | 可写 | 说明 |
|---|---|---|---|---|---|
| 自定义副本变量 | Boss已开启、副本.读取变量("Boss已开启") | Boss已开启 = true、副本.设置变量("Boss已开启", true) | 任意类型 | 可以 | 全队共用,适合写开门、剧情、机关、阶段状态。 |
| 赋值落库行为 | 当前阶段 = "第二阶段" | 同左 | 任意类型 | 可以 | 在副本脚本上下文里直接赋值,会同步写到当前副本实例。 |
示例:
text
Boss已开启 = true
当前阶段 = "第二阶段"
if 副本.读取变量("Boss已开启") {
消息.广播("&cBoss 已经激活")
}玩家个人变量
| 项目 | 读取写法 | 写入方式 | 返回值 | 可写 | 说明 |
|---|---|---|---|---|---|
| 自定义玩家变量 | 个人积分、玩家.读取变量("个人积分") | 玩家.设置变量("个人积分", 100)、玩家.增加变量("个人积分", 20) | 任意类型 | 可以 | 只对当前玩家生效,常拿来写个人积分、个人进度、个人 Buff 层数。 |
| 直接读取覆盖关系 | 个人积分 | 同上 | 任意类型 | 可以 | 当前玩家有同名变量时,直接写变量名会优先读到玩家层。 |
示例:
text
玩家.设置变量("个人积分", 100)
玩家.增加变量("个人积分", 20)
if 玩家.读取变量("个人积分") >= 120 {
消息.发送("&a个人奖励已解锁")
}玩家内建统计
这些变量由 PlayerSession 自动维护,只能读,不能写。
| 变量名 | 读取写法 | 返回值 | 可写 | 说明 |
|---|---|---|---|---|
damage_dealt | damage_dealt、玩家.读取变量("damage_dealt") | double | 不可以 | 当前玩家本次副本累计造成伤害。 |
damage_taken | damage_taken、玩家.读取变量("damage_taken") | double | 不可以 | 当前玩家本次副本累计承受伤害。 |
kill_count | kill_count、玩家.读取变量("kill_count") | int | 不可以 | 当前玩家本次副本累计击杀数。 |
death_count | death_count、玩家.读取变量("death_count") | int | 不可以 | 当前玩家本次副本累计死亡数。 |
elapsed_seconds | elapsed_seconds、玩家.读取变量("elapsed_seconds") | long | 不可以 | 当前玩家从进本到现在已经过了多少秒。 |
@player.*
这组变量不走副本变量表,直接从当前玩家对象读取。
没有玩家上下文时,这些值会是 null 或默认值。
| 写法 | 返回值 | 可写 | 说明 |
|---|---|---|---|
@player.online | boolean | 不可以 | 当前玩家是否在线。 |
@player.name | String | 不可以 | 当前玩家名字。 |
@player.uuid | String | 不可以 | 当前玩家 UUID。 |
@player.health | double | 不可以 | 当前血量。 |
@player.maxhealth | double | 不可以 | 当前最大生命值。 |
@player.food | int | 不可以 | 当前饥饿值。 |
@player.level | int | 不可以 | 当前经验等级。 |
@player.exp | double | 不可以 | 当前经验条进度。 |
@player.gamemode | String | 不可以 | 当前游戏模式枚举名。 |
@player.world | String | 不可以 | 当前所在世界名。 |
@player.x | double | 不可以 | 当前 X 坐标。 |
@player.y | double | 不可以 | 当前 Y 坐标。 |
@player.z | double | 不可以 | 当前 Z 坐标。 |
@player.yaw | double | 不可以 | 当前水平朝向。 |
@player.pitch | double | 不可以 | 当前俯仰角。 |
示例:
text
require @player.level >= 30: "&c等级不足"
if @player.health <= 10 {
消息.发送("&c你的血量已经很低")
}@player 和 @dungeon
| 写法 | 返回值 | 可写 | 说明 |
|---|---|---|---|
@player | Player 对象 | 不可以 | 当前玩家对象本体。 |
@dungeon | 副本实例对象 | 不可以 | 当前副本对象本体。 |
这两个对象本体更适合内部对象调用和条件环境。
日常配副本时,绝大多数场景直接写 副本.*()、阶段.*()、区域.*() 会更稳。
@dungeon.xxx 命名空间
源码里还有一层 DungeonVariableProvider,支持 @dungeon.xxx 这种写法。
这层只在有 VariableManager 注入的上下文里才能用,普通脚本不要把它当默认入口。
能确认支持的字段如下:
| 写法 | 返回值 | 可写 | 说明 |
|---|---|---|---|
@dungeon.id | String | 不可以 | 模板 ID。 |
@dungeon.name / @dungeon.displayname | String | 不可以 | 副本显示名。 |
@dungeon.instanceid | String | 不可以 | 实例 ID。 |
@dungeon.state | String | 不可以 | 当前副本状态枚举名。 |
@dungeon.playercount | int | 不可以 | 当前副本人数。 |
@dungeon.alivecount | int | 不可以 | 当前存活人数。 |
@dungeon.maxplayers | int | 不可以 | 模板最大人数。 |
@dungeon.timelimit | int | 不可以 | 模板限时秒数。 |
@dungeon.elapsed | long | 不可以 | 实例创建后的总秒数。 |
@dungeon.running | boolean | 不可以 | 当前状态是不是运行中。 |
@dungeon.dailylimit | int | 不可以 | 当前副本的每日进入上限。 |
@dungeon.dailycount | int | 不可以 | 当前玩家今天已进入当前副本多少次。 |
@dungeon.dailyremaining | int | 不可以 | 当前玩家今天还剩多少次可进。 |
@dungeon.var.变量名 | 任意类型 | 不可以 | 读取指定副本变量。 |
日常副本脚本更推荐下面这些等价写法:
@dungeon.id用副本.模板ID()@dungeon.playercount用副本.人数()@dungeon.var.floor_current用副本.读取变量("floor_current")
每日进入相关这三项要注意:
@dungeon.dailylimit读的是模板配置值,小于等于0时会按0返回@dungeon.dailycount没有玩家上下文时返回0@dungeon.dailyremaining没有玩家上下文时返回0- 当前副本没有每日限制时,
@dungeon.dailyremaining返回-1
示例:
text
if @dungeon.dailylimit > 0 {
已进 = @dungeon.dailycount
剩余 = @dungeon.dailyremaining
消息.发送("&7今日已进入: " + 已进 + " 次")
消息.发送("&7今日剩余: " + 剩余 + " 次")
}PAPI 与外部输入
PlaceholderAPI
| 写法 | 返回值 | 可写 | 说明 |
|---|---|---|---|
变量.PAPI("%player_name%") | 文本或数字 | 不可以 | 有玩家上下文且装了 PAPI 时会正常解析;结果像数字时会自动转成数字。 |
变量.PAPI("%server_online%") | 文本或数字 | 不可以 | 没有玩家上下文或没装 PAPI 时,会原样返回占位符文本。 |
CraftX / AchieveMaster / 仓库
| 写法 | 返回值 | 可写 | 说明 |
|---|---|---|---|
CX读取("变量名") | String | null | 通过 CX.* 动作可写 | 读取当前玩家 CraftX 永久变量。 |
CX临时读取("变量名") | String | null | 通过 CX.临时* 动作可写 | 读取当前玩家 CraftX 临时变量。 |
AM读取("变量名") | 任意类型 | 通过 AM.* 动作可写 | 读取当前玩家 AM 变量。 |
AM服务器读取("变量名") | 任意类型 | 通过 AM.服务器* 动作可写 | 读取服务器级 AM 变量。 |
AM临时读取("变量名") | 任意类型 | 通过 AM.临时设置 可写 | 读取当前玩家 AM 临时变量。 |
AM服务器临时读取("变量名") | 任意类型 | 通过 AM.服务器临时设置 可写 | 读取服务器级 AM 临时变量。 |
仓库数量("物品ID", [目标]) | int | 通过 仓库.* 动作可改 | 统计仓库物品数量。目标默认 all,支持 srx、lw、all 和中文别名。 |
变量命名建议
| 类型 | 建议写法 | 说明 |
|---|---|---|
| 副本公共变量 | Boss已开启、剧情已播放、机关轮次 | 一眼能看懂全队状态。 |
| 玩家个人变量 | 个人积分、个人层数、个人印记 | 一眼能看懂这是个人数据。 |
| 模块变量 | floor_current、bonus_multiplier、speedrun_elapsed | 模块自带变量尽量保持原名,后期排查最省事。 |
实战建议
- 团队共用状态统一放副本变量,个人状态统一放玩家变量。
- 玩家内建统计不要当普通变量去写,源码里就是只读的。
@player.*适合拿来写即时条件,副本核心流程还是优先用副本.*()和阶段.*()。- 外部变量、PAPI、仓库数量适合拿来做限制条件、倍率条件、显示文本,不适合替代副本内部状态。