【Code With SOLO】我是如何用Tare solo开发阿瓦隆桌游的

用 TRAE SOLO 打造「阿瓦隆・智能主持人」——从 0 到 1 的 AI 驱动桌游革命


1. 摘要

我用 TRAE SOLO 独立开发了一套完整的「阿瓦隆・智能主持人」系统,完全替代真人主持人,支持 5-10 人通过手机网页参与游戏。项目包含实时游戏服务器(Node.js + Socket.IO)、语音控制面板(14 阶段智能播报决策表)、离线语音助手(Orange Pi + Sherpa-ONNX + MeloTTS),以及完整的自动化测试框架(86 项测试,97.7% 通过率)。原本需要 5 分钟准备、45-60 分钟游玩的桌游局,现在 2 分钟开玩、20-40 分钟完成,全程零主持人


2. 背景

我是一名10年没写过代码的PM,平时喜欢和朋友聚会玩桌游。阿瓦隆是我们最喜欢的推理对抗游戏之一,但一直有个痛点:

  • :tired_face: 需要一位熟悉规则的主持人,新手往往无法胜任,且每次需要朋友带卡牌。

  • :tired_face: 真人主持人容易出错、疲劳(主持人带卡牌的哥们 提前离场)(忘记轮次、叫错角色、统计错票数)

  • :tired_face: 现有电子主持人工具不好用(要下载 APP、有广告,需要注册且功能简陋 )

我尝试过用传统方式解决:

  1. 自己写一个主持人脚本 → 写了 1 周,放弃了

  2. 找开源项目二次开发 → 没有合适的开源,或者根本看不懂

于是,我决定用 TRAE SOLO 从零打造一套软硬件结合的智能主持人系统——全部纯SOLO 无一条手动代码
结果,我用 SOLO 花了4周时间,完成了一个基本可上线的系统(由于还有其它事情期间开发断断续续,大概全力在做的时间跨度基本是4周)
其实吧,最基础的web版本从开发到测试总共只花了1周左右,后来自己硬折腾到了4~5周,下面是我的项目记录。


3. 实践过程

3.1 我是怎么拆解任务的

我一开始原计划把整个项目拆为 4 个阶段,每个阶段用 SOLO 独立完成,阶段之间有明确的输入输出:

第 1 周:房间 / 身份模块开发 → 测试任务(Day7 完成验收)

测试阶段目标

验证「玩家能加入房间、身份分配符合规则、信息私密不泄露」

第 2 周:游戏流程模块开发 → 测试任务(Day14 完成验收)

测试阶段目标

验证「全自动流程能跑通、投票 / 任务逻辑符合规则」

第 3 周:UI / 防作弊 / 体验优化 → 测试任务(Day20 完成验收)
测试阶段目标

验证「界面操作无歧义、防作弊逻辑生效、体验流畅

第 4 周:稳定化 / 演示版 / 内测 → 测试任务(Day28 完成验收)

测试阶段目标

验证「全场景稳定、演示无 bug、内测反馈可落地

Phase 1: 游戏核心服务器(Node.js + Socket.IO) 输入:AVALON_RULES.md(完整游戏规则文档——要AI帮我找的) 输出:server.js(1500 行,包含房间管理、角色分配、游戏状态机) 交付物:主控端(index.html)+ 玩家端(player.html)

:date: 第一阶段(3月14-19日):规则理解与核心逻辑

目标: 让 SOLO 理解阿瓦隆规则,搭建游戏核心

3月14日 09:26 - 阿瓦隆规则测试

我的 Prompt:

帮我设计一个阿瓦隆游戏的状态机,包含以下阶段:
- waiting(等待玩家)
- role-assign(角色分配)
- night(夜间行动:闭眼→坏人睁眼→坏人闭眼→梅林睁眼→梅林闭眼→派西睁眼→派西闭眼→天亮了)
- team-building(队长组队)
- voting(投票)
- mission(任务执行)
- assassination(刺杀梅林)
- ended(游戏结束)

要求:
1. 每个阶段有明确的进入条件和退出条件
2. 支持 5-10 人的任务人数配置
3. 连续 5 次投票否决则坏人直接胜利
4. 第 4 轮任务需要 2 张失败卡才失败
5. 每个角色有特定的视野(梅林知道坏人、派西维尔知道梅林和莫甘娜...)

SOLO 的输出:

  • 完整的 AvalonGame 类(约 400 行)

  • 包含 getRoleConfig()(角色配置)、getMissionConfig()(任务人数)、getPlayerView()(角色视野)

  • 状态转换方法:startNight()startTeamBuilding()processVote()executeMission()

3月14日 14:56 - 优化游戏代码

  • 优化角色分配逻辑

  • 完善玩家视野隔离机制

  • 实现任务人数配置表(5人[2,3,2,3,3]、6人[2,3,4,3,4]…)

3月19日 08:17 - 测试阿瓦隆规则

测试结果: 核心游戏规则全部验证通过 :white_check_mark:

  • 好人/坏人数量正确

  • 角色视野隔离正确

  • 投票机制正确(超过半数通过)

  • 任务成功/失败判定正确

关键决策:

  • 选择 Node.js + Socket.IO 作为服务器技术栈

  • 5-10人可配置,角色根据人数动态分配

  • 梅林、派西维尔、莫甘娜、刺客、忠臣角色体系

    最开始的主控界面大概长这个样子

实际上印象中是一周时间就用solo 基本完成了以上全部过程,web版本主控客户端基本能跑。
想起了角落里闲置的orangepi5 ultra + 和车载蓝牙喇叭… 于是乎需求开始自我膨胀——决定增加第二阶段语音控制面板的功能

:date: 第二~三阶段(3月20-4月9日):硬件与语音控制

目标: 让语音助手控制游戏流程

Phase 2: 语音控制面板(HTML + WebSocket)

输入:Phase 1 的 WebSocket 事件列表

输出:voice-panel.html(650 行,包含 14 阶段智能播报决策表)

交付物:一键推进游戏流程的 UI

Phase 3: 离线语音助手(Python + Orange Pi)

输入:Phase 2 的语音指令列表

输出:device/(Python 模块,包含唤醒词检测、ASR、TTS)

交付物:Orange Pi 5 Ultra 上的离线语音控制系统

又折腾了1~2周,Phase2~3终于收敛了。

3月20日 16:10 - 修复自动测试

问题发现: 玩家断线重连时,旧 socket 映射未清理 修复: 优化测试脚本中的断线重连问题,完善错误上下文捕获

3月31日 21:44 - 智能音箱设备开发(这个期间清明假期,开发中间断了几天)

技术选型对比:

我的 Prompt:

帮我实现一个离线语音助手,支持:
1. 唤醒词检测("主持,主持")
2. 语音指令解析("下一环节"、"当前状态"、"重新开始")
3. 通过 WebSocket 控制游戏服务器
4. 使用 Sherpa-ONNX 进行离线 ASR
5. 使用 MeloTTS 进行离线 TTS

主要工作:

  • Orange Pi 5 Ultra 环境搭建(RK3588 8核,8GB RAM)

  • 集成 Sherpa-ONNX 离线 ASR(语音识别)

  • 集成 MeloTTS 离线 TTS(语音合成)

  • 实现唤醒词检测(基于能量阈值 + 音频匹配)

  • 实现语音指令解析和游戏联动

技术成果:

  • 唤醒词检测:延迟 < 200ms,误触发率 < 1%

  • ASR 识别:延迟 < 500ms,准确率 95%+

  • 无需联网,完全离线运行

4月8日 12:53 - 语音面板测试

我的 Prompt:

帮我设计一个语音播报的决策表,实现"一键智能推进"功能。
当前游戏状态包括:phase, round, playerCount, goodWins, badWins, currentLeaderIndex

要求:
1. 根据当前状态自动决定下一步播报什么
2. 支持音频队列拼接(例如:"任命队长" + "3号" + "人" + "选择队员" + "2人")
3. 夜间行动按固定顺序推进(8 个步骤)
4. 每个步骤有对应的提示信息

输出格式:
SMART_ANNOUNCEMENTS = {
  [PHASE]: {
    check: () => boolean,
    announce: () => void,
    hint: string
  }
}

SOLO 的输出:

  • 14 阶段完整决策表:

    WAITING → OPENING → ROLE_ASSIGN → NIGHT(8步) → DAY → 
    TEAM_BUILDING → DISCUSSION → VOTING → 
    VOTE_PASSED/VOTE_REJECTED → MISSION → 
    MISSION_SUCCESS/MISSION_FAIL → ASSASSINATION → ENDED
    
  • 音频队列拼接函数 playAudioQueue()

数字自动转音频 numberToAudioQueue(3)NUM-3.mp3

4月9日 08:16 - 生成项目语音文件

主要工作:

  • 开发 voice-generator 自定义 Skill

  • 批量生成 30+ 个音频文件:

    • opening/ (3个): CMD-003.mp3 欢迎词、CMD-009.mp3 分发身份…

    • night/ (7个): CMD-022.mp3 天亮了、CMD-044.mp3 坏人睁眼…

    • day/ (4个): CMD-042.mp3 任命队长、CMD-044.mp3 选择队员…

    • voting/ (3个): CMD-071.mp3 投票开始、CMD-074.mp3 投票通过…

    • mission/ (3个): CMD-091.mp3 任务开始、CMD-094.mp3 任务成功…

    • numbers/ (11个): NUM-1.mp3 到 NUM-10.mp3

输出目录:

device/assets/audio/commands/
├── opening/ (3个)  ├── night/ (7个)  ├── day/ (4个)
├── voting/ (3个)   ├── mission/ (3个) ├── ending/ (2个)
├── numbers/ (11个) └── segments/ (4个)

语音控制面板大概长这样

:date: 第四阶段(4月10日):**重构与完善**

目标: 代码重构、文档整理、准备上线
—— 这个阶段是最让人崩溃的阶段,重构了好几个版本,每个版本相同或者类似的bug都会不断复现,回归测试过无数次,bug依然。

Phase 4: 自动化测试与代码重构

输入:Phase 1-3 的所有代码

输出:86 项测试用例(5 个测试脚本)+ 33 个 Bug 追踪记录

交付物:97.7% 测试通过率 + 重构指南

4月10日 08:27 - 分析整理文件夹

主要工作:

  • 整理代码文件(server.js、voice-panel.html、device/…)

  • 整理文档文件(REFACTORING_GUIDE.md、VOICE_PANEL_LOGIC.md…)

  • 整理测试文件(5个测试脚本 + 80+ 张截图)

  • 整理音频文件(30+ 个 mp3)

  • 整理 Bug 追踪文件(.trae/bug-memory/)

4月10日 20:30 - 代码重构(player-join 事件处理器)

问题发现:

  • 540 行代码堆砌在一个函数里,违反单一职责原则

  • 混合了 8 种不同的业务逻辑

  • 存在大量重复代码(player-reconnect-success 4次、you-are-leader 3次)

  • 圈复杂度高达 25,几乎无法单元测试

我的 Prompt:

  • 这个 player-join 事件处理器(server.js 第 292-831 行)约 540 行,违反了单一职责原则,混合了:

  • - 房间验证(298-313 行)

  • - 玩家编号验证(315-328 行)

  • - 通过 playerId 的断线重连恢复(346-412 行)

  • - 通过 clientId 的离线玩家检查(414-459 行)

  • - 重复加入检查(461-465 行)

  • - 离线同名玩家继承(467-539 行)

  • - 在线同名玩家继承(541-661 行)

  • - 新玩家加入和角色分配(675-825 行)

  • 请帮我重构,要求:

  • 1. 提取验证逻辑(validateRoomExists, validatePlayerNumber, checkDuplicateJoin, checkRoomFull)

  • 2. 提取恢复逻辑(restoreByPlayerId, checkOfflinePlayersByClientId, restoreOfflineSameNamePlayer, restoreOnlineSameNamePlayer)

  • 3. 提取公共事件发送函数(消除 player-reconnect-success 的 4 处重复、you-are-leader 的 3 处重复)

  • 4. 提取新玩家加入函数(addNewPlayer, assignRolesIfFull)

  • 5. 主函数保持清晰,展示 12 步处理流程

SOLO 的重构输出:

将 540 行拆分为 18 个辅助函数 + 70 行主函数:

拿着重构文档,继续执行优化任务,项目大小由423M优化到8.34M,代码由10w行,优化到3.2w行。

3.2 我用了 SOLO 哪些能力

能力 1: 复杂系统设计(架构师)

我的 Prompt:

帮我设计一个阿瓦隆游戏的状态机,包含以下阶段:
- waiting(等待玩家)
- role-assign(角色分配)
- night(夜间行动:闭眼→坏人睁眼→坏人闭眼→梅林睁眼→梅林闭眼→派西睁眼→派西闭眼→天亮了)
- team-building(队长组队)
- voting(投票)
- mission(任务执行)
- assassination(刺杀梅林)
- ended(游戏结束)

要求:
1. 每个阶段有明确的进入条件和退出条件
2. 支持 5-10 人的任务人数配置(5人[2,3,2,3,3]、6人[2,3,4,3,4]...)
3. 连续 5 次投票否决则坏人直接胜利
4. 第 4 轮任务需要 2 张失败卡才失败
5. 每个角色有特定的视野(梅林知道坏人、派西维尔知道梅林和莫甘娜...)

SOLO 的输出:

  • 完整的 AvalonGame 类(约 400 行)

  • 包含 getRoleConfig()(角色配置)、getMissionConfig()(任务人数)、getPlayerView()(角色视野)

  • 状态转换方法:startNight()startTeamBuilding()processVote()executeMission()

能力 2: 状态机实现(智能播报决策表)

我的 Prompt:

帮我设计一个语音播报的决策表,实现"一键智能推进"功能。
当前游戏状态包括:phase, round, playerCount, goodWins, badWins, currentLeaderIndex

要求:
1. 根据当前状态自动决定下一步播报什么
2. 支持音频队列拼接(例如:"任命队长" + "3号" + "人" + "选择队员" + "2人")
3. 夜间行动按固定顺序推进(8 个步骤)
4. 每个步骤有对应的提示信息

输出格式:
SMART_ANNOUNCEMENTS = {
  [PHASE]: {
    check: () => boolean,      // 进入条件
    announce: () => void,      // 播报动作
    hint: string               // 提示信息
  }
}

SOLO 的输出:

  • 14 个阶段的完整决策表(WAITING → OPENING → ROLE_ASSIGN → NIGHT → DAY → TEAM_BUILDING → DISCUSSION → VOTING → VOTE_PASSED → VOTE_REJECTED → MISSION → MISSION_SUCCESS → MISSION_FAIL → ASSASSINATION → ENDED)

  • 每个阶段有 check() 条件、announce() 播报动作、hint() 提示信息

  • 夜间行动 8 步骤固定序列(NIGHT_STEPS 数组)

  • 音频队列拼接函数 playAudioQueue()numberToAudioQueue()

能力 3: 代码重构(重构专家)

我的 Prompt:

这个 player-join 事件处理器(server.js 第 292-831 行)约 540 行,违反了单一职责原则,混合了:
- 房间验证(298-313 行)
- 玩家编号验证(315-328 行)
- 通过 playerId 的断线重连恢复(346-412 行)
- 通过 clientId 的离线玩家检查(414-459 行)
- 重复加入检查(461-465 行)
- 离线同名玩家继承(467-539 行)
- 在线同名玩家继承(541-661 行)
- 新玩家加入和角色分配(675-825 行)

请帮我重构,要求:
1. 提取验证逻辑(validateRoomExists, validatePlayerNumber, checkDuplicateJoin, checkRoomFull)
2. 提取恢复逻辑(restoreByPlayerId, checkOfflinePlayersByClientId, restoreOfflineSameNamePlayer, restoreOnlineSameNamePlayer)
3. 提取公共事件发送函数(消除 player-reconnect-success 的 4 处重复、you-are-leader 的 3 处重复)
4. 提取新玩家加入函数(addNewPlayer, assignRolesIfFull)
5. 主函数保持清晰,展示 12 步处理流程

SOLO 的输出:

  • 将 540 行拆分为 18 个辅助函数(17 个 + 主函数 70 行)

  • 圈复杂度从 25 降至 5-8

  • 消除了 4 处重复的 player-reconnect-success 事件发送

  • 消除了 3 处重复的 you-are-leader 事件发送

  • 主函数清晰展示 12 步处理流程:

    1. 验证房间 → 2. 验证编号 → 3. 检查重复 → 4. 恢复 playerId → 5. 检查 clientId → 6. 恢复离线同名 → 7. 恢复在线同名 → 8. 检查满员 → 9. 添加新玩家 → 10. 游戏已开始重连 → 11. 分配角色 → 12. 广播事件

能力 4: 自定义Bug skill

我的 Prompt:

帮我建立一个 Bug 追踪系统,记录项目中遇到的所有问题。
要求:
1. 每个 Bug 有 ID、标题、状态、严重级别、相关文件
2. 为每个 Bug 生成测试用例(TC-XXX.md + TC-XXX.js)
3. Bug 修复后自动更新状态
4. 定期生成验证报告

SOLO 的输出:

Bug 追踪系统(.trae/bug-memory/)

33 个 Bug 记录(BUG-001 到 BUG-033),涵盖:

  • 角色分配后游戏无法推进(遗漏 controller-game-started 事件)

  • 语音面板音频路径错误(Windows/Linux 路径不一致)

  • 玩家断线重连失败

  • 房间号显示问题

  • 33 个测试用例(TC-001 到 TC-033),包含自动化测试脚本

  • 验证报告生成(verification-reports/)

能力 5: 自动化测试生成(QA 工程师)

我的 Prompt:

帮我生成阿瓦隆游戏的自动化测试,要求:
1. 基于 AVALON_RULES.md 的完整规则
2. 覆盖房间管理、角色分配、游戏流程、断线重连、并发操作
3. 使用 Playwright 进行 UI 测试
4. 使用 Python 脚本进行 E2E 测试

SOLO 的输出:

  • 5 个测试脚本

    • avalon_test.py(HTTP API 测试,6 项)

    • avalon_browser_test.py(浏览器模拟,4 项)

    • avalon_full_test.py(HTTP 完整测试,6 项)

    • avalon_playwright_test.py(UI 自动化,8 项)

    • avalon_e2e_test.pyE2E 完整测试,55 项

    • avalon_reliability_test.py(可靠性测试,13 项)

  • 86 项测试97.7% 通过率(84/86)

3.3 中间踩过什么坑

总结下来,前两个基于项目,后来个基于工具

坑一:Bug反复复现

典型案例:语音面板夜晚状态未同步(BUG-023)

问题描述

推进游戏到夜晚阶段时,客户端状态没有立即切换到"night",需要等到白天阶段才显示夜晚状态。

复现历程

第一次修复(2026-04-03)

  • 认为是状态更新延迟问题

  • 添加了 setTimeout 延迟播放音频

  • 结果:无效,问题依然存在

第二次修复(2026-04-04 上午)

  • 发现服务器端roomId类型不匹配

  • 修复了CMD-044/CMD-045指令ID冲突

  • 结果:部分修复,但核心问题仍在

第三次修复(2026-04-04 下午)- 最终解决

  • 发现语音面板的阶段流程与服务器端不一致

  • 语音面板有 role-assign 阶段,但服务器端没有

  • 修复了阶段同步逻辑

根因分析

// 修复前:语音面板有自己的 role-assign 阶段
case 'opening':
    playCommandAudio('CMD-009');
    gameState.phase = 'role-assign';  // ❌ 服务器没有这个阶段
    break;

case 'role-assign':
    playCommandAudio('CMD-011');
    gameState.phase = 'night';  // ❌ 没有通知服务器
    break;

// 修复后:与服务器阶段流程保持一致
case 'opening':
    playCommandAudio('CMD-009');
    gameState.phase = 'role-confirm';  // ✅ 与服务器一致
    break;

case 'role-confirm':
    gameState.phase = 'night';
    // ✅ 通知服务器
    socket.emit('next-phase', { roomId: gameState.roomId });
    break;

经验教训

  1. 多端状态必须保持一致

    • 客户端、服务器端、语音面板的阶段流程必须完全一致

    • 不能在任何一端私自添加中间阶段

  2. 修复后必须完整测试整个流程

    • 不能只测试单个步骤

    • 要从开始到结束完整走一遍流程

  3. 类型转换要谨慎

    • JavaScript中 Map 的 key 类型必须一致

    • 使用 String() 进行类型转换

  4. 配置ID命名要唯一

    • 不同阶段使用不同ID(如 CMD-044D 表示白天)

    • 避免后面的定义覆盖前面的

坑二:更换平台环境后自适应能力不强

问题场景

  1. Windows → Linux 部署

    • 音频文件路径分隔符问题(\ vs /

    • 端口占用检测方式不同

    • 进程管理方式不同

  2. 桌面端 → 移动端

    • 视觉单位不一致(px vs vw/vh)

    • 触摸事件与鼠标事件差异

    • 音频自动播放限制不同

  3. 开发环境 → Orange Pi

    • 语音识别模型不兼容

    • 麦克风设备路径不同

    • 性能差异导致超时问题

典型案例:音频路径问题

问题描述:在Windows下正常的音频文件,在Linux下无法播放。

经验教训

  1. 路径处理要使用标准库

  2. 环境检测要提前

  3. 配置文件要支持环境变量

经验教训

  1. 不同平台的限制要提前了解

    • 查阅官方文档

    • 进行跨平台测试

  2. 提供降级方案

    • 音频无法播放时显示提示

    • 允许用户手动触发播放

坑三:自定义Skill不工作

问题表现

  1. Skill不被触发

    • 定义好的 bug-tracker skill 在某些情况下不自动触发

    • 需要手动调用才能执行

  2. Skill记忆丢失

    • 跨会话后,部分Skill的配置或记忆丢失

    • 导致重复记录相同的Bug

  3. Skill执行不完整

    • bug-tracker 的6步闭环经常中断在第4步

    • 没有完成测试验证和报告生成

根因分析

  1. 触发条件设置不当

    • SKILL.md 中的 description 字段不够清晰

    • 导致AI无法准确识别何时应该触发Skill

  2. 数据存储路径问题

    • 跨会话时,部分临时文件被清理

    • 导致Skill无法读取历史数据

  3. 执行步骤过于复杂

  • 6步闭环流程太长,容易中断

  • 缺少断点续传机制

经验教训

  1. Skill的触发条件要具体明确

    • 包含具体的用户行为关键词

    • 列出所有应该触发的场景

  2. 数据持久化要可靠

    • 使用项目目录存储,而非临时目录

    • 定期检查数据完整性

  3. 流程设计要简洁

    • 步骤越多,失败概率越高

    • 关键步骤必须有验证机制

坑四:AI不停增加功能而非优化功能,导致冗余和重复代码

问题描述

在项目开发过程中,AI倾向于不断添加新功能而非优化现有功能,导致:

  • 代码量急剧膨胀(原始版本104,973行 → 优化版本32,043行,减少了69.5%

  • 大量重复代码(player-reconnect-success 事件发送了4次,you-are-leader 事件发送了3次)

  • 函数过长(player-join 事件处理器达到540行)

  • 功能冗余(多个功能实现相同或相似的业务逻辑)

数据对比

根因分析
  1. AI的"功能导向"倾向

    • AI 倾向于通过添加新功能来解决问题

    • 而非优化现有代码结构

    • 导致功能膨胀和代码冗余

  2. 缺乏重构意识

    • AI 不会主动识别和消除重复代码

    • 除非明确要求,否则不会进行代码重构

    • 导致重复代码不断累积

  3. 上下文限制

    • AI 的上下文窗口有限

    • 无法全局把握代码库的整体结构

    • 容易在局部添加新功能,而忽略全局影响

经验教训

  1. 指定需要明确要AI在原有基础上优化

    • 需要明确要求进行代码优化

    • 否则AI会倾向于添加新功能

    • 开发者必须主动发起重构

  2. 定期清理冗余代码

    • 每次功能迭代后进行代码审查

    • 删除不再使用的函数和文件

    • 合并相似的功能实现

  3. 建立代码质量标准

    • 设定函数行数上限(50行)

    • 设定文件行数上限(500行)

    • 使用工具检测重复代码

  4. 功能添加前先问"能否复用"

    • 添加新功能前检查是否有类似实现

    • 优先扩展现有功能而非创建新函数

    • 使用设计模式提高代码复用率


4. 成果展示

4.1 系统架构

┌─────────────────────────────────────────────────────────────┐
│                    阿瓦隆・智能主持人系统                      │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌──────────────┐      ┌──────────────┐      ┌──────────┐  │
│  │   主控端      │      │   玩家端      │      │ 语音面板  │  │
│  │  (index.html) │◄────►│ (player.html) │◄────►│(voice-  │  │
│  └──────┬───────┘      └──────┬───────┘      │ panel)   │  │
│         │                     │               └────┬─────  │
│         │    WebSocket        │                    │        │
│         ──────────┬──────────┘                    │        │
│                    │                               │        │
│         ┌──────────▼──────────┐                   │        │
│         │   Node.js 服务器     │◄──────────────────┘        │
│         │   (server.js)       │  Socket.IO                 │
│         │   - 房间管理        │                            │
│         │   - 角色分配        │                            │
│         │   - 游戏状态机      │                            │
│         │   - 断线重连        │                            │
│         └────────────────────┘                            │
│                    │                                        │
│         ┌──────────▼──────────┐                            │
│         │  Orange Pi 语音助手  │                            │
│         │  (Python + Sherpa)   │                            │
│         │  - 唤醒词检测        │                            │
│         │  - 离线 ASR (500ms)  │                            │
│         │  - 离线 TTS          │                            │
│         └─────────────────────┘                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

4.2 核心功能演示

主控界面

游戏大厅

玩家加入

分发身份-夜间阶段

任务历史

队长组队

游戏结算画面

功能 1: 一键创建房间

主持人打开主控页面(http://localhost:3000),选择玩家人数(5-10 人),点击"创建房间",系统自动生成 4 位房间号(如:2682)。玩家通过手机打开链接(http://IP/player.html?roomId=2682),输入名字即可加入。

技术亮点:

  • 房间号自动生成(4 位数字,不重复)

  • WebSocket 实时通信,毫秒级延迟

  • 支持 5-10 人任意人数配置

功能 2: 自动角色分配

当人数达到配置值(如 5 人),系统自动分配角色:

  • 3 个好人(梅林、派西维尔、忠臣)

  • 2 个坏人(莫甘娜、刺客)

  • 每个玩家私密收到自己的角色和视野信息

技术亮点:

  • 角色配置根据人数自动适配(5-10 人各有不同)

  • 视野隔离:梅林知道坏人、派西维尔知道梅林和莫甘娜、坏人互相知道

  • 私密发送,防止作弊

功能 3: 语音智能播报(14 阶段决策表)

点击"智能下一环节",系统自动播报当前阶段:

技术亮点:

  • SMART_ANNOUNCEMENTS 决策表,每个阶段有 check/announce/hint

  • 音频队列拼接:playAudioQueue() 支持多个音频连续播放

  • 数字自动转音频:numberToAudioQueue(3)NUM-3.mp3

  • 夜间行动 8 步骤自动推进

功能 4: 离线语音控制(硬件)

对 Orange Pi 说"主持,主持",唤醒语音助手:

  • “下一环节” → 自动推进游戏

  • “当前状态” → 播报当前轮次和队长

  • “重新开始” → 重置游戏

技术亮点:

  • 唤醒词检测:基于能量阈值和音频匹配

  • 离线 ASR:Sherpa-ONNX Zipformer CTC,延迟 500ms

  • 离线 TTS:MeloTTS 中文语音合成

  • 无需联网,完全离线运行

功能 5: 断线重连机制

玩家刷新页面或网络断开后,可以恢复之前的游戏状态:

  • 通过 playerId 恢复(保留角色信息)

  • 通过 clientId 恢复(关联客户端)

  • 同名玩家继承(自动踢出旧连接)

技术亮点:

  • 3 种恢复方式,覆盖所有断线场景

  • 状态完整保留(角色、阵营、游戏阶段)

  • 自动清理旧 socket 映射

4.3 代码质量

4.4 测试报告

可以安全上线

E2E 测试覆盖:

  • :white_check_mark: 房间管理:创建房间、玩家加入、房间号生成

  • :white_check_mark: 角色分配:5-10 人配置验证、好人/坏人数量、特殊角色存在性

  • :white_check_mark: 游戏流程:身份确认、夜间阶段(各角色视野)、组队阶段(任务人数、队长轮换)、投票阶段(超过半数通过)、任务阶段(第 4 轮 2 张失败规则)、刺杀阶段、游戏结束判定

  • :white_check_mark: 可靠性:断线重连、页面刷新、非法操作、边界条件、并发操作

测试截图: 80+ 张截图(E2E 测试、可靠性测试、UI 测试、响应式设计)


5. 效果与总结

5.1 提效数据

核心提升:

  • :video_game: 主持人解放:原本需要 1 人全程主持,现在零主持人,所有人都能参与游戏

  • :high_voltage: 流程加速:自动推进消除了人工操作的等待时间

  • 氛围增强:语音播报让游戏体验更沉浸

  • :bullseye: 零出错率:系统不会忘记轮次、叫错角色、统计错票数

5.2 SOLO 在我的流程中做了什么

SOLO 不仅是代码生成器,更是我的:

  1. 架构师 :triangular_ruler::帮我设计游戏状态机、语音决策表、测试框架

    • 输入:AVALON_RULES.md(游戏规则)

    • 输出:AvalonGame 类(状态机)、SMART_ANNOUNCEMENTS(决策表)

  2. 重构专家 :wrench::将 540 行烂代码重构为 18 个清晰函数

    • 输入:server.js 第 292-831 行(540 行混乱代码)

    • 输出:18 个辅助函数 + 70 行主函数

  3. 测试工程师 :test_tube::生成 86 个测试用例,覆盖所有边界条件

    • 输入:所有代码 + AVALON_RULES.md

    • 输出:5 个测试脚本、33 个测试用例、80+ 张截图

  4. Bug 追踪器 :bug::自动记录 33 个 Bug,生成验证报告

    • 输入:问题描述

    • 输出:BUG-XXX.md + TC-XXX.md + TC-XXX.js + 验证报告

  5. 文档写手 :memo::生成重构指南、语音面板逻辑文档、API 文档

    • 输入:代码 + 注释

    • 输出:REFACTORING_GUIDE.md、VOICE_PANEL_LOGIC.md

5.3 可复用的方法

方法 1: 分层 Prompt 策略(5 层递进)

第一层:需求描述
"我要一个阿瓦隆游戏主持人,支持 5-10 人手机网页参与,完全替代真人主持人"

第二层:架构设计
"帮我设计状态机、通信协议、角色分配逻辑、语音决策表"

第三层:代码实现
"实现 AvalonGame 类,包含 getRoleConfig、getMissionConfig、getPlayerView"

第四层:测试验证
"生成测试用例,基于 AVALON_RULES.md 验证所有规则"

第五层:重构优化
"这段 540 行代码太长了,帮我拆分为 18 个职责单一的函数"

关键技巧:

  • 每层输出作为下一层输入,形成完整的开发流水线

  • 不要一次性给太多信息,分层递进效果更好

  • 每层完成后验证输出,再进入下一层

方法 2: Bug 追踪闭环

发现 Bug
  ↓
记录到 .trae/bug-memory/bugs/BUG-XXX.md
  ↓
生成测试用例 TC-XXX.md + TC-XXX.js
  ↓
修复代码
  ↓
运行测试 TC-XXX.js
  ↓
生成验证报告
  ↓
更新知识库 knowledge-base.md

关键文件:

  • BUG-XXX.md:Bug 描述、复现步骤、根本原因、解决方案

  • TC-XXX.md:测试用例文档

  • TC-XXX.js:自动化测试脚本

  • knowledge-base.md:常见问题和解决方案

方法 3: 语音面板状态机模式

SMART_ANNOUNCEMENTS = {
  [PHASE]: {
    check: () => boolean,      // 进入条件
    announce: () => void,      // 播报动作
    hint: string               // 提示信息
  }
}

// 使用方式
function smartNextStep() {
  for (const [key, config] of Object.entries(SMART_ANNOUNCEMENTS)) {
    if (config.check()) {
      config.announce();
      updateHint(config.hint);
      return;
    }
  }
}

适用场景: 任何需要按顺序推进的流程(游戏、教程、工作流)

5.4 项目成果


6. 后续计划

  1. AI 语音主持人:用 LLM 生成自然语言播报,替代固定音频(“第 1 轮,队长是 3 号玩家,请选择 2 名队员”)

  2. 增加玩家端智能墨水屏

  3. 更多桌游:狼人杀等


7. 总结

用 TRAE SOLO,一个人就是一支团队。

在这个项目中,SOLO 扮演了架构师、重构专家、测试工程师、Bug 追踪器、文档写手等多个角色。我从零开始,用几天时间完成了一个完整可上线的系统,这是传统方式无法想象的。

核心经验:

  1. 分层 Prompt:不要一次性给太多信息,分层递进效果更好

  2. 及时验证:每层输出后验证,再进入下一层

  3. 建立追踪:Bug 追踪系统让我不会忘记任何问题

  4. 完整测试:86 项测试让我有信心上线

SOLO 不是替代开发者,而是放大开发者的能力。


项目链接: