commands.yml
commands.yml 负责注册 AchieveMaster 的动态脚本命令。
它的价值不只是“多几个命令”,更重要的是:
- 让玩家主动触发某类成就逻辑
- 让你把签到、兑换、查询、补偿入口统一接到成就系统里
- 改完直接
/ach reload,不用重启服
基本结构
yaml
commands:
签到:
permission: ""
aliases: ["qd", "checkin", "signin"]
description: "每日签到领取奖励"
cooldown: 0
player-only: true
兑换:
permission: "achieve.command.exchange"
aliases: ["dh", "exchange"]
description: "兑换物品"
args: ["物品ID", "数量"]
player-only: true每个节点就是一个命令定义,键名本身就是主命令名。
可用字段
| 字段 | 作用 |
|---|---|
permission | 执行命令所需权限,留空表示不额外拦截 |
aliases | 命令别名列表 |
description | 命令描述 |
args | 参数说明,仅用于 usage 展示和你自己理解 |
cooldown | 命令冷却,单位秒 |
player-only | 是否只允许玩家执行 |
target-player-arg | 哪个参数位用作目标玩家 |
target-player-arg 的实际作用
这是当前实现里很实用,但默认示例没完全展开的一项。
例如:
yaml
commands:
发任务:
permission: "achieve.command.quest"
player-only: false
target-player-arg: 1
args: ["玩家名", "任务ID"]你可以这样理解:
- 第 1 个参数是目标玩家
- 真实触发器上下文会以这个玩家为执行目标
- 剩下的参数才会继续传给脚本
如果是玩家自己想指定别人,还需要权限:
text
achieve.command.target控制台默认有这个能力。
命令执行后,脚本里能拿到什么
动态命令最终会走成就系统的 COMMAND 触发器,并注入这些变量:
commandargs参数1、参数2、参数3...arg1、arg2、arg3...
所以你完全可以在成就脚本里按参数做分支:
yaml
trigger:
type: COMMAND
script: |
if (command == "兑换" && 参数1 == "钻石礼包") {
增加进度(1)
}典型接法
签到命令
yaml
commands:
签到:
permission: ""
aliases: ["qd"]
description: "每日签到"
cooldown: 0
player-only: true配合 COMMAND 触发器和脚本标记,就能把签到逻辑做进成就系统里。
兑换命令
yaml
commands:
兑换:
permission: "achieve.command.exchange"
aliases: ["dh"]
description: "兑换物品"
args: ["物品ID", "数量"]
player-only: true适合让脚本统一处理:
- 扣积分
- 扣金币
- 发物品
- 写标记
目标玩家命令
yaml
commands:
发任务:
permission: "achieve.command.givequest"
player-only: false
target-player-arg: 1
args: ["玩家名", "任务ID"]适合 GM、NPC 对话桥、菜单服转发。
热重载行为
按当前实现,执行 /ach reload 时:
- 旧动态命令会先从
CommandMap注销 - 命令配置重新从
commands.yml读取 - 新命令重新注册
这意味着:
- 新增命令可以即时生效
- 删除命令也会即时失效
- 别名修改同样会生效
使用建议
args更像文档说明,不负责强制校验参数个数,真正校验还是脚本自己做。- 复杂业务别全写在命令配置层,命令只负责入口,逻辑还是回到成就脚本或自定义函数。
- 需要对别人执行时再开
target-player-arg,别把所有命令都做成可指定别人。 - 给玩家开放的动态命令,一定配好权限和冷却。
常见问题
改了 commands.yml 但命令没更新
先确认:
- 改完后有没有执行
/ach reload - 命令名和别名有没有和别的插件冲突
- 当前控制台有没有报动态注册失败
玩家执行命令提示“只能由玩家执行”
这是 player-only: true 的正常结果。
如果你又想让控制台执行,又想让命令针对某个玩家生效,就把它改成:
yaml
player-only: false
target-player-arg: 1想靠 args 自动拦截缺参
当前实现不会按 args 自动拦截参数个数。
它更像 usage 说明。真正的参数校验,还是建议在脚本里自己写清楚。