配对码与认领(B): - POST /api/pair/start|join:6 位码 10 分钟单次有效、仅存内存零泄露面、5 连错 per-IP 封锁 10 分钟;join=新设备档案按桶 LWW 并入老档案+token 改绑(复用 claim-merge);日志脱敏 - 大厅:生成配对码(speechSynthesis 逐位朗读+aria-live+重听)/从其他设备转入(one-time-code 输入框)/从本机移除/401 过期自愈引导/aria 补全/玩家名可听化 - api-smoke 12/12(配对全流程/频控/封锁/过期自愈/移除/digitsToCn)+ CDP 真浏览器 E2E 22/22 键盘语音双套资产(A,路线 a): - 164 变体句(8 游戏 grep 实测,超出调研预估 153:含轻触/点两下/按住变体)×2 性别=328 生成 656 文件 36.9 分钟;触屏主资产零字节改动(PCM 逐样本比对后还原) - 引擎 _candidates 三跳路由 key→gender→平铺(inputMode 跟随);缓存键 mode|gender|id;engine-input 新增 K9 路由断言(72 条) - check_all_assets 增 key 列(两性别一致且 ⊆ 主集)8 游戏全绿;voice_text.json 增 __key__ 表;live control.mjs key 会话对照键盘措辞验收(集成) - voice-ids 文档:8 游戏键盘变体小节由 KEY_LINES 程序化生成(与台词表逐字断言一致);补齐 storyline/escape/simon 三个历史缺失文档;design README 增 new8 索引 - mock 适配:playtest persona 加 maxTouchPoints=1 保持触屏链断言语义零改动 回归:12 套件全绿(8 playtest + guide 122 + engine-voice 19 + engine-input 72 + api-smoke 12/12) 同批入库:批次 2/3 已完稿设计文档(17-abyss/18-detective/19-cipher 全套,20-22 在途)
音序回响(Simon)
音频版西蒙记忆游戏。屏幕只有封面,全靠耳朵:系统用六种特征音播放一段 手势序列,玩家按同样顺序复现手势。序列从 2 个音开始,每轮 +1,播放速度 逐轮略微加快;复现错误即游戏结束,播报「坚持了 X 轮」与本局内历史最高 (数字用 TTS 片段拼接),单击屏幕重开(重开跳过教学)。
手势 → 音色映射
| 手势 | 音色 |
|---|---|
| 上滑 | 上行琶音(C5-E5-G5-C6 明亮弹拨) |
| 下滑 | 下行低音(A2→A1 浑厚贝斯) |
| 左滑 | E4 弹拨,声像极左 |
| 右滑 | G4 弹拨,声像极右 |
| 单击 | 短促底鼓 |
| 双击 | 两声连响(木琴质感) |
流程
- 启动遮罩「轻触开始」解锁音频(游玩全程无 BGM;仅结算/菜单挂
bgm/menu轻垫乐,volume 0.3)。 - 开场教学(t0 附近插播一次 skip_hint):语音依次教 6 个手势音,教一个练一个; 教学期下滑=跳过整个教学(正练下滑手势时除外)。
- 正式对局:报「第 N 轮」→ 播放序列(此阶段手势忽略)→ 「轮到你了」 (仅第 1 轮)→ 玩家复现;每个手势即时回声放对应音色。
- 全部复现正确:答对反馈,进入下一轮(序列尾部 +1,速度加快,第 12 轮起 420ms 下限)。
- 复现错误:有机会则自动消耗重听(输入阶段上滑=主动重听——免费重听每局 2 次 先用,不耗真机会;免费用尽后重听才扣机会)→ 无机会则 播报成绩与新纪录 → 单击重开(重开跳过教学)。
- 旁白播放中单击=跳过当前句(skipVoice,链播继续);无语音时单击=各阶段原语义。
测试
test/playtest.mjs — Node 无头试玩仿真(mock 浏览器环境 + 虚拟时钟 + 种子随机),
覆盖 docs/design/13-playtest-criteria.md §3 全部关键路径与边界断言:
tools/node/bin/node web/simon/test/playtest.mjs
目录
game.js— 游戏逻辑(继承引擎Game,语音链用 onComplete 串行)test/playtest.mjs— 无头试玩测试(见上)cover.png— 1080x1920 封面audio/{bgm,voice,sfx}/— 全部双格式(.ogg + .m4a,iOS 回退)gen/— 资产生成脚本(SFX 合成、TTS、封面、资产校验),非运行依赖