阿瓦隆游戏插件
由机器人担任主持人的阿瓦隆游戏插件,支持角色分配、任务投票、刺杀与湖中仙女等完整规则。
作者: 蜥蜴
背景
阿瓦隆(Avalon)是一款经典的推理与欺骗类桌游,规则上接近狼人杀,但对信息管理与逻辑推演的要求更高。线下进行时需要一位主持人完成以下工作:
- 分配身份,向每位玩家单独告知其角色与可见信息
- 逐轮指定发车人、记录任务成员
- 收集投票并公布结果
- 处理刺杀、湖中仙女等特殊机制
若由玩家兼任主持人,则主持人需提前知晓全部身份,可能影响游戏公平。koishi-plugin-avalon-lizard 将上述流程交由机器人执行,玩家可以完整地参与游戏本身。
工具定位
koishi-plugin-avalon-lizard 是一款由机器人驱动的阿瓦隆游戏插件,主要能力如下:
| 能力 | 说明 |
|---|---|
| 自动化角色分配 | 按玩家人数从固定角色池中分配正义/邪恶角色 |
| 私密身份通知 | 通过私聊向每位玩家发送角色、阵营与可见信息 |
| 任务与投票管理 | 记录任务成员、统计投票并公布结果 |
| 特殊机制支持 | 刺杀、湖中仙女查验 |
| 角色与规则查询 | 提供角色信息与完整规则的查询指令 |
当前版本为 2.1.0,依赖 Koishi ^4.18.11。
游戏基础
阵营与目标
| 阵营 | 包含角色 | 胜利条件 |
|---|---|---|
| 正义阵营 | 梅林、派西维尔、忠臣、好兰斯洛特 | 成功完成 3 次任务 |
| 邪恶阵营 | 莫甘娜、刺客、爪牙、莫德雷德、奥伯伦、坏兰斯洛特 | 使 3 次任务失败,或刺杀梅林成功 |
角色一览
| 角色 | 阵营 | 任务 | 投票权限 | 可见信息 |
|---|---|---|---|---|
| 梅林 | 正义 | 隐藏身份取得胜利 | 仅可投成功 | 除莫德雷德外的全部邪恶阵营 |
| 派西维尔 | 正义 | 保护梅林 | 仅可投成功 | 梅林与莫甘娜(不区分) |
| 忠臣 | 正义 | 保护梅林 | 仅可投成功 | 无 |
| 好兰斯洛特 | 正义 | 保护梅林 | 仅可投成功 | 坏兰斯洛特 |
| 莫甘娜 | 邪恶 | 破坏任务 | 可投成功或失败 | 除奥伯伦外的邪恶阵营 |
| 刺客 | 邪恶 | 破坏任务或刺杀梅林 | 可投成功或失败 | 除奥伯伦外的邪恶阵营 |
| 爪牙 | 邪恶 | 破坏任务 | 可投成功或失败 | 除奥伯伦外的邪恶阵营 |
| 莫德雷德 | 邪恶 | 破坏任务 | 可投成功或失败 | 除奥伯伦外的邪恶阵营 |
| 奥伯伦 | 邪恶 | 破坏任务 | 可投成功或失败 | 无(独立) |
| 坏兰斯洛特 | 邪恶 | 破坏任务 | 可投成功或失败 | 好兰斯洛特 |
安装
前置条件
- 已搭建并可正常运行的 Koishi 项目(
koishi-app) - 已启用 Koishi 的数据库服务(插件声明
inject: ['database']) - 机器人具备向玩家发送私聊消息的权限
方式一:通过插件市场安装(推荐)
- 启动 Koishi 项目,打开控制台(默认地址
http://localhost:5140)。 - 进入左侧「插件市场」。
- 在搜索框中输入
avalon-lizard。 - 找到插件后点击「添加」,Koishi 会自动完成依赖安装与配置写入。
方式二:通过 npm 安装
在 Koishi 项目根目录执行:
1 | npm install koishi-plugin-avalon-lizard |
随后在 koishi.yml 中手动添加配置:
1 | plugins: |
方式三:通过 yarn / pnpm 安装
若项目使用 yarn 或 pnpm,可执行:
1 | # yarn |
启用数据库
插件声明了 inject: ['database'],需确保 Koishi 中已启用数据库服务。若尚未配置,可在控制台「插件配置」中启用 database-sqlite:
1 | plugins: |
保存配置后重启 Koishi 项目。
资源文件
插件包含角色头像图片(位于 assets/ 目录),会随 npm 包一同安装。若图片缺失,角色信息仍会以文字形式正常显示。
验证安装
在任意已接入机器人的群聊中输入:
1 | 阿瓦隆 规则 |
若能返回完整规则文本,则说明安装成功。
配置
当前版本无需额外配置,安装并启用即可使用:
1 | plugins: |
使用流程
父指令为 阿瓦隆,别名 avalon。
完整指令列表
| 指令 | 说明 | 使用位置 |
|---|---|---|
阿瓦隆 开始 |
开始新一局游戏 | 群聊 |
阿瓦隆 加入 |
加入当前游戏 | 群聊 |
阿瓦隆 分配 |
分配角色(5-11 人) | 群聊 |
阿瓦隆 发车 <玩家名> |
选择任务成员 | 群聊(发车人) |
阿瓦隆 投票 <成功/失败> |
任务投票 | 私聊(任务成员) |
阿瓦隆 刺杀 <玩家名> |
刺客刺杀梅林 | 群聊(刺客) |
阿瓦隆 查验 <玩家名> |
湖中仙女查验 | 私聊(车长) |
阿瓦隆 角色 <角色名> |
查看单个角色信息 | 群聊 / 私聊 |
阿瓦隆 规则 |
查看完整规则 | 群聊 / 私聊 |
阿瓦隆 结束 |
结束当前游戏 | 群聊 |
流程一:开局与角色分配
步骤 1:创建游戏
由任意玩家在群聊中发起:
1 | 阿瓦隆 开始 |
机器人返回「阿瓦隆游戏开始,输入”阿瓦隆 加入”加入游戏。」,并将该群聊锁定为本局游戏频道。同一时间仅支持一个游戏频道。
步骤 2:玩家加入
每位玩家在群聊中输入:
1 | 阿瓦隆 加入 |
每成功加入一次,机器人返回「<玩家名> 已加入!当前 N 人」。重复加入会被提示「你已经加入了游戏。」。
支持人数为 5 至 11 人。
步骤 3:分配角色
人数满足要求后,由任意玩家在群聊中输入:
1 | 阿瓦隆 分配 |
机器人随机打乱玩家顺序,按人数对应的角色配置进行分配,并通过私聊向每位玩家发送:
- 角色头像
- 角色名称与阵营
- 该角色的任务说明
- 投票权限说明
- 该角色可见的其他玩家(视角色而定)
随后在群聊中公布第 1 轮任务的发车人与所需人数。
流程二:任务阶段(逐轮重复)
步骤 1:发车
被随机指定的发车人在群聊中选择本轮任务成员:
1 | 阿瓦隆 发车 玩家A,玩家B |
注意事项:
- 玩家名之间使用英文逗号或中文逗号分隔,均支持
- 玩家名需与游戏内显示名称完全一致(含大小写)
- 成员数量必须与当前轮次要求的人数一致,否则机器人会提示所需人数
- 仅当前发车人可执行该指令
步骤 2:私聊投票
被选中的玩家通过私聊进行投票:
1 | 阿瓦隆 投票 成功 |
规则约束:
- 每位任务成员仅可投票一次
- 正义阵营角色仅可投「成功」,邪恶阵营角色可投「成功」或「失败」
- 机器人不会对「正义阵营投失败」做出拦截,需要玩家自觉遵守角色规则
投票完成后,机器人会在群聊中广播「<玩家名> 已投票。」,待全部成员投票完毕后公布结果。
步骤 3:公布任务结果
机器人公布投票统计与任务结果:
1 | 票数:成功 X / 失败 Y。任务成功!/ 任务失败! |
判定规则:
- 默认情况下,只要出现 1 票失败即判定任务失败
- 第 4 轮任务且玩家人数为 7 至 11 人 时,需出现 2 票及以上失败才判定任务失败
步骤 4:进入下一轮
若未达到胜负条件,机器人自动推进至下一轮,并指定新的发车人、公布所需人数。
流程三:胜负判定与刺杀
步骤 1:胜负条件
- 正义阵营任务成功次数达到 3 次 → 进入刺杀环节
- 邪恶阵营任务失败次数达到 3 次 → 邪恶阵营直接胜利,游戏结束
步骤 2:刺客发动刺杀
当正义阵营即将达到 3 次成功时,机器人会在群聊中提示:
1 | 正义阵营即将胜利! |
刺客在群聊中执行:
1 | 阿瓦隆 刺杀 玩家A |
结果:
- 目标为梅林:刺杀成功,邪恶阵营胜利
- 目标非梅林:刺杀失败,正义阵营胜利
刺杀成功或失败后,游戏立即结束。
流程四:湖中仙女(8-11 人局)
在 8-11 人局中,第 2、3、4 轮任务发车前,车长可以通过私聊查验一名玩家的阵营:
1 | 阿瓦隆 查验 玩家A |
执行条件:
- 玩家人数在 8 至 11 之间
- 当前轮次为第 2、3 或 4 轮
- 执行者须为当前轮次的车长
- 当前轮次尚未使用过查验
查验后,机器人私聊告知执行者目标玩家的阵营,并在群聊中广播「车长查验了 <玩家名> 的身份。」。每轮仅可使用一次查验。
流程五:查询角色与规则
查看完整规则:
1 | 阿瓦隆 规则 |
查看某个角色的详细信息(仅支持代码中已定义的角色名):
1 | 阿瓦隆 角色 梅林 |
若输入未定义的角色名,机器人将返回全部支持的角色列表。
流程六:结束游戏
任何时候均可提前结束当前游戏:
1 | 阿瓦隆 结束 |
机器人返回「游戏已结束。」,并解除对当前频道的占用。
角色配置与任务人数
各人数角色分配
| 人数 | 正义阵营 | 邪恶阵营 |
|---|---|---|
| 5 | 梅林、派西维尔、忠臣 | 莫甘娜、刺客 |
| 6 | 梅林、派西维尔、忠臣 ×2 | 莫甘娜、刺客 |
| 7 | 梅林、派西维尔、忠臣 ×2 | 莫甘娜、刺客、爪牙 |
| 8 | 梅林、派西维尔、忠臣 ×3 | 莫甘娜、刺客、爪牙 |
| 9 | 梅林、派西维尔、忠臣 ×3 | 莫甘娜、刺客、奥伯伦、莫德雷德 |
| 10 | 梅林、派西维尔、忠臣 ×4 | 莫甘娜、刺客、奥伯伦、莫德雷德 |
| 11 | 梅林、派西维尔、忠臣 ×3、好兰斯洛特 | 莫甘娜、刺客、奥伯伦、莫德雷德、坏兰斯洛特 |
各人数任务人数
| 人数 | 第 1 轮 | 第 2 轮 | 第 3 轮 | 第 4 轮 | 第 5 轮 |
|---|---|---|---|---|---|
| 5 | 2 | 3 | 2 | 3 | 3 |
| 6 | 2 | 3 | 4 | 3 | 4 |
| 7 | 2 | 3 | 3 | 4 | 4 |
| 8 | 3 | 4 | 4 | 5 | 5 |
| 9 | 3 | 4 | 4 | 5 | 5 |
| 10 | 3 | 4 | 4 | 5 | 5 |
| 11 | 3 | 4 | 5 | 6 | 6 |
完整对局示例
1 | [群聊] 玩家A:阿瓦隆 开始 |
技术实现
技术栈
| 技术 | 用途 |
|---|---|
| Koishi | 机器人框架 |
| TypeScript | 开发语言 |
| 私聊 API | 向玩家秘密发送角色信息 |
核心设计
全局游戏状态
游戏状态保存在 apply 函数内的局部变量中:
1 | let game: Game = { players: [], missionResults: [], round: 0, started: false, ... }; |
fixedChannelId 记录本局游戏锁定的群聊,用于统一广播。游戏未开始时该值为 undefined,因此同一时间仅支持一个游戏频道。
角色分配
按玩家人数从 roleDistribution 中取出正义与邪恶角色列表,将玩家随机打乱后依次填充:
1 | const dist = roleDistribution[num]; |
私密通知
角色信息通过 Koishi 的私聊接口发送:
1 | const whisper = async (s: any, uid: string, msg: string) => |
每位玩家收到的信息包含角色头像与角色/阵营/可见信息等文本内容,由角色名称通过 switch 分支分别构造。
任务判定
投票完成后统计成功与失败票数,并根据轮次与人数决定判定规则:
1 | const need2Fail = game.round === 4 && [7, 8, 9, 10, 11].includes(game.players.length); |
发车人与轮次推进
发车人在玩家数组中按顺序轮转:
1 | game.currentLeaderIndex = (game.currentLeaderIndex + 1) % game.players.length; |
查验次数控制
湖中仙女查验通过复用玩家的 voted 标记限制每轮仅一次:
1 | game.players[game.currentLeaderIndex]!.voted = true; |
注意事项
1. 昵称设置
发车指令按玩家名精确匹配,建议玩家在开局前使用简洁昵称(如「小明」「小红」),避免使用特殊符号或表情,便于其他玩家输入。
2. 私聊权限
机器人的角色分配、投票与查验均依赖私聊。请确保:
- 机器人未被玩家屏蔽
- 玩家未开启「禁止陌生人私聊」
- 机器人所在平台支持私聊消息
3. 单频道限制
插件同时仅支持一个频道进行游戏。若在多个群聊同时使用,可能出现频道广播混乱。
4. 游戏状态不持久化
游戏状态保存在内存中,机器人重启后数据会丢失。已进行中的对局需要重新开始。
5. 投票需全员参与
任务投票需要全部任务成员完成,任一玩家长时间不投票会导致游戏停滞。开局前建议确认所有玩家均可及时响应。
6. 第 4 轮特殊规则
在 7-11 人局中,第 4 轮任务需出现 2 票及以上失败才判定失败。这一规则与常规轮次不同,玩家需注意。
常见问题
Q1:为什么收到的角色信息没有头像图片?
角色头像通过 assets/ 目录下的本地图片以文件 URL 形式发送。若图片缺失,机器人会自动降级为纯文字发送角色信息,不影响游戏进行。
Q2:发车时提示「未找到部分玩家」?
说明所填玩家名与游戏内显示名不完全一致。请核对大小写与前后空格,建议开局前统一使用简洁昵称。
Q3:私聊没有收到角色信息?
可能原因包括:
- 机器人被玩家屏蔽
- 玩家开启了「禁止陌生人私聊」
- 机器人所在平台不支持私聊消息
建议确认上述条件后重新开始游戏。
Q4:游戏进行中卡住怎么办?
任务投票需要全部任务成员完成。可在群聊中提醒未投票的玩家;若长时间无法继续,可由任意玩家执行 阿瓦隆 结束 强制结束本局。
Q5:为什么我的投票被判为无效?
可能原因包括:
- 你不在本轮任务成员列表中
- 你已投过票
- 投票参数不是「成功」或「失败」
Q6:刺杀指令由谁执行?
刺杀由持有刺客角色的玩家执行,在正义阵营完成 3 次任务后由机器人在群聊中提示。
Q7:8 人以上局如何触发湖中仙女?
湖中仙女在 8-11 人局自动生效,无需额外开启。第 2、3、4 轮任务发车前,由当轮车长私聊执行 阿瓦隆 查验 玩家名,每轮限一次。
Q8:安装后指令无响应?
依次检查以下项:
- 插件是否已在控制台启用
- 数据库服务是否已启用
- 机器人是否已连接目标平台
- 指令是否完整输入(父指令与子指令之间以空格分隔)
开发计划
- 支持多频道同时进行游戏
- 增加游戏状态持久化
- 支持自定义角色配置
- 增加游戏日志记录
- 优化湖中仙女交互方式
获取工具
- npm 包:
koishi-plugin-avalon-lizard - GitHub 仓库:lizard0126/avalon-lizard
- 反馈建议:GitHub Issues
- 支持作者:请我喝可乐