Files
SoundGame/docs/design/23-hunt-voice-ids.md
T
xsl 005851d01a feat(hunt): 《围猎》2-4人实时联机纯音频协作守卫——纯音频MMORPG第一阶段切片
- 设计:docs/design/23-hunt.md + voice-ids(84 id,166条)+ 13号断言登记,§15记录10+1条设计裁决
- 服务器:零依赖WebSocket(ws.js)+ 房间管理/服务端权威战斗/bot AI(hunt-room.js),断线30s宽限resume回槽、超时转bot;修复package.json模块类型误判的既有破坏
- 客户端:web/hunt/ 全套(教学T0-T4/听觉视野裁剪R1-R8/结算排行榜/guide接入),playtest 211断言
- 引擎:audio.js 后向兼容 opts.pan(StereoPannerNode),web-engine-api.md 同步
- 资产:166条TTS语音(QC无离群)+ 13件合成sfx(真峰值≤-3dBFS)+ 2首Mureka BGM,终检全绿
- 平衡:bot调参至挂机局71%失守/C、3bot局71% A/B(hunt-balance-scan.mjs 24种子扫描)
- 接线:大厅卡片、profiles.js hunt桶、README/roadmap MMO路线条目

验证:hunt-sim 16/16 + api-smoke 12/12 + hunt playtest 211/211 + 既有10游戏与引擎回归零回退 + 真服务器WS端到端冒烟通过
2026-09-13 11:08:01 +08:00

204 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 23b · 《围猎》语音台词表(voice ids,录音依据)
> **给音频总监的录制说明**
> - **旁白/系统音双性别组(60 句,预算打满)**:落 `web/hunt/audio/voice/female|male/<id>.{ogg,m4a}`,两性别 id 集合完全一致。
> - female = `Serena`,instruct 常量:`清亮沉稳的女声,像守夜猎人的领队,冷静中带着鼓舞`
> - male = `Uncle_Fu`,instruct 常量:`低沉醇厚的男声,像守夜猎人的领队,沉稳有力`
> - 两常量全表统一(含教学/警报/结算),禁止句级变体、禁语速词(引擎 SoundTouch 变速)。
> - **bot 喊话组(N 组,24 句 = 3 角色 × 8 句)**:固定单音色平铺、**不做双性别**。因喊话经 **sfx 层 + opts.pan 空间化播放**(引擎按 id 前缀分发,主设计 §8 R2 / §15 裁决 7),资产**落盘 `web/hunt/audio/sfx/npc_<char>_<line>.{ogg,m4a}`**——这是 NPC 平铺惯例的异例:生成仍走 voice 管线(TTS、峰值归一 0.89 沿用 voice 策略),仅落盘目录不同。角色 speaker+instruct 恒定:
>
> | 角色 | char | speaker | instruct 常量 | 区分度风险 |
> |---|---|---|---|---|
> | 阿岩 | yan | `Uncle_Fu` | `憨厚壮实的中年男声,猎户,话少踏实` | **中**:与 male 旁白同 speaker——缓解:sfx 层 pan 空间分离 + 1-2s 短喊话语境 + instruct 差异(abyss 先例口径) |
> | 小筝 | zheng | `Serena` | `轻快爽利的年轻女声,猎手,干脆利落` | **中**:与 female 旁白同 speaker——缓解同上 |
> | 老周 | zhou | `Eric` | `沙哑沉稳的老年男声,老猎手,带点调侃` | 低:与两侧旁白零重叠 |
>
> - **数字规避**:耐久 4 档 / 波次 3 档(st_wave_*)+ 5 整句(wave_band1-5)/ 在场猎人 2 句 / 击杀 3 档 / 威胁 3 档 / 评级 4 整句——全部分档整句,无运行时拼接。「八秒冷却」「五波」等数字写死在整句内(一次生成,非拼接)。
> - **称呼中性**:旁白称「你/你们」,无性别化称呼;bot 句不含绝对方位(方位由 pan 承载,主设计 §15 裁决 3/7——任务书示例句"东侧交给我!"据此落地为"这边交给我")。
> - **多音字自查**:全表无「血」「爪」「挨」「壳」「弹」「重(chóng/zhòng 歧义句)」;「重听」一律写「重新听」(tut_skill_cd)。已标注风险 3 处:「还」(hái:营地还在/守得还行/还没开张——asset-manifest 既有风险项,三处均 hái 语境,试听确认);「啧」(zé,npc_zhou_breach 叹词,试听异常则整句改「哼,溜进去一只。」);评级字母 S/A/B/C(rhythm「评级,S!」先例,试听确认字母读音)。
> - **触发纪律**(开发轮次对照主设计):警报类(breach/breach_heavy/danger_low)可顶掉状态/播报类,教学/结算链不可顶;skill_ready 与状态链一律 `queue:true`;gd_* idle-only + onceKey;bot 喊话调度上限见主设计 §7.4/§8 R2。
> - **键盘变体(V 组,11 对)**:操作提示句在 `gesture.inputMode()==='key'` 时改播 `voice/<gender>/key/<id>.*` 变体,变体缺失回退主资产;与 `tools/gen_voice_dual.py` 的 `KEY_LINES` 逐字一致(两表一致铁律:改一处必改另一处)。
> - 管线:`tools/gen_voice_dual.py` 照录(SPEAKERS 新增 hunt 行 + HUNT_NPC 平铺表);生成后 `--convert` 落盘 + `tools/check_all_assets.py` 终检(双格式配对、双性别集合一致、key 变体 ⊆ 主集)。
## A 组 · 开场/房间(旁白 ×4)
| id | 台词全文 | 触发/语境 |
|---|---|---|
| `intro_1` | 夜幕降临,野兽在山林里游荡。 | 开场 1(TITLE 单击后/教学房 T0) |
| `intro_2` | 你们是守夜的猎人,营地就在身后。 | 开场 2 |
| `room_wait` | 房间已开好,等同伴到齐。单击,立即开局。 | LOBBY 进入(12s 倒计时自动开局) |
| `room_start` | 狩猎开始,先听声音的方向。 | 开局(ev wave 1 前) |
## B 组 · 教学 TEACH(旁白 ×11;教学波突入不扣耐久,学期零惩罚)
| id | 台词全文 | 触发/语境 |
|---|---|---|
| `tut_rule` | 野兽会从八个方向围上来。声音在哪边,就往哪边滑。 | T0(规则总述,含后半平面发闷约定由音效演示承担) |
| `tut_attack` | 听,有狼在靠近。朝声音的方向,滑一下。 | T1(教学狼 1 放出后) |
| `tut_kill_ok` | 好,杀掉了。就是这样。 | T1 首杀(成功只给新短句) |
| `tut_callout` | 单击一下,呼喊支援,队友会来帮你。 | T2 |
| `tut_callout_ok` | 听到没,同伴回应你了。 | T2(bot help_ack 播完后,呼喊-响应闭环点明) |
| `tut_skill` | 双击,旋风斩,清掉身边一圈。 | T3(教学狼 2、3 贴近后) |
| `tut_skill_cd` | 旋风斩有八秒冷却。冷却中双击,重新听威胁。 | T3 放出后(讲冷却与宪法双击语义) |
| `tut_status` | 上滑,听营地状态。下滑,打开菜单。 | T4 |
| `tut_breach` | 野兽冲进营地,营地就会受损。撑过五波就赢。 | T4 状态链播完后 |
| `tut_done` | 教学完了。真正的围猎,现在开始。 | TEACH 完成 → 进 WAVE 1 |
| `tut_skip` | 已跳过教学,开打。 | TEACH 中下滑跳过 |
## C 组 · 波次(旁白 ×6)
| id | 台词全文 | 触发/语境 |
|---|---|---|
| `wave_band1` | 第一波来了,别慌。 | ev wave 1 |
| `wave_band2` | 第二波,比刚才多。 | ev wave 2 |
| `wave_band3` | 第三波,有大家伙混在里面。 | ev wave 3(首只暴熊) |
| `wave_band4` | 第四波,更快,更多。 | ev wave 4 |
| `wave_band5` | 最后一波,全来了! | ev wave 5 |
| `wave_clear` | 这一波,守住了。 | ev waveclear(波间休整 8s 开场) |
## D 组 · 状态链(旁白 ×12;上滑 4 段链播:耐久档 → 波次档 → 猎人数 → 击杀档)
| id | 台词全文 | 触发/语境 |
|---|---|---|
| `hp_band1` | 营地固若金汤。 | 耐久 >75%(10 制:≥8) |
| `hp_band2` | 营地受了些损伤。 | 50~75%(5-7) |
| `hp_band3` | 营地损毁过半。 | 25~50%(3-4) |
| `hp_band4` | 营地快守不住了。 | ≤25%(≤2) |
| `st_wave_a` | 还在头几波。 | 波次档:第 1-2 波 |
| `st_wave_b` | 打到中段了。 | 第 3-4 波 |
| `st_wave_c` | 最后一波了。 | 第 5 波 |
| `team_3` | 三名猎人在守。 | 在场 3 猎人(含 bot) |
| `team_4` | 四名猎人全在。 | 在场 4 猎人 |
| `kill_band0` | 你还没开张。 | 个人击杀 0 |
| `kill_band1` | 你小有斩获。 | 1-9 |
| `kill_band2` | 你战果累累。 | ≥10 |
## E 组 · 威胁重听(旁白 ×3;冷却中双击 = 重听;只报数量档,方位由声像承载)
| id | 台词全文 | 触发/语境 |
|---|---|---|
| `threat_none` | 近处暂时没有野兽。 | 内圈(eta≤4s)0 只 |
| `threat_few` | 有野兽贴近了,听方向出手。 | 内圈 1-2 只 |
| `threat_many` | 四周全是动静,快出手! | 内圈 ≥3 只 |
## F 组 · 警报(旁白 ×3;警报类,可顶状态/播报类)
| id | 台词全文 | 触发/语境 |
|---|---|---|
| `breach` | 有野兽冲进营地了! | ev breach(狼,-1);节流 ≥3.5s |
| `breach_heavy` | 巨兽撞进营地,损伤很重! | ev breach(熊,-2);节流同上 |
| `danger_low` | 营地危险了,一只都不能再漏! | 耐久首次 ≤2(每局 1 次,配 danger 震) |
## G 组 · 技能(旁白 ×1)
| id | 台词全文 | 触发/语境 |
|---|---|---|
| `skill_ready` | 旋风斩准备好了。 | 旋风斩冷却完成(queue:true,每轮冷却 1 次) |
## H 组 · 结算(旁白 ×9;进 END 盖 800ms 手势死窗)
| id | 台词全文 | 触发/语境 |
|---|---|---|
| `end_win` | 天亮了,营地还在。 | 胜利结算链首句 |
| `end_lose` | 营地守不住了,撤退! | 失守结算首句(耐久归零) |
| `grade_s` | 评级,S!完美的围猎。 | 胜利评级 S(耐久 ≥9) |
| `grade_a` | 评级,A。漂亮。 | 评级 A(7-8) |
| `grade_b` | 评级,B。守得还行。 | 评级 B(4-6) |
| `grade_c` | 评级,C。险胜。 | 评级 C(1-3) |
| `end_rank` | 成绩已记入猎手榜。 | 胜利局排行榜写入后(失守局不播) |
| `end_again` | 单击,再猎一局。 | 结算链尾句(重开入口) |
结算链:胜利 = `end_win → grade_* → kill_band_*(自己击杀档)→ end_rank → end_again`;失守 = `end_lose → kill_band_* → end_again`。
## I 组 · 断线/重连(旁白 ×4)
| id | 台词全文 | 触发/语境 |
|---|---|---|
| `net_lost` | 与营地断了联系,正在重连。 | WS 断开(本地静默重连开始,≤30s) |
| `net_back` | 联系恢复了,接着打。 | resume 回槽成功(joined + snap 到达) |
| `net_to_bot` | 有猎人离队,老猎手顶上。 | roster 变更:他人槽位转 bot(非自己) |
| `net_gone` | 回不去那场围猎了,回大厅。 | 重连失败/房已灭(err room_gone 或 30s 超时)→ LOST |
## J 组 · 菜单/帮助(旁白 ×6;菜单不暂停,E3 豁免)
| id | 台词全文 | 触发/语境 |
|---|---|---|
| `sys_menu` | 菜单。单击切换,双击确认。 | 下滑呼出模态菜单 |
| `sys_menu_resume` | 回到猎场。 | 菜单项 1 |
| `sys_menu_help` | 重新听帮助。 | 菜单项 2 |
| `sys_menu_home` | 退出房间,回大厅。 | 菜单项 3(= 发 leave) |
| `help_main` | 朝声音的方向滑,就是出击。单击呼喊支援,双击旋风斩。上滑状态,下滑菜单。 | 菜单内上滑 / 帮助项 |
| `settings_hint` | 音色、语速、背景音乐,请回大厅修改。 | 菜单内设置提示 |
## K 组 · 向导/纠错(旁白 ×2;idle-only,queue:true)
| id | 台词全文 | 触发/语境 |
|---|---|---|
| `gd_invalid` | 这个操作现在用不上。 | 无效手势纠错(onceKey 同局 1 次,之后仅 error 震) |
| `gd_idle` | 听声音的方向,滑过去。 | WAVE/LOBBY 看门狗第 1 级(10s);TEACH 错向重教复用 |
---
**旁白合计:60 句 ×2 性别 = 120 条音频**(×2 格式 = 240 文件;预算 ≤60 打满,无冗余位)。
## N 组 · bot 喊话(24 句 = 3 角色 × 8;固定单音色,落盘 `audio/sfx/`,见头注)
> 触发映射(服务端纪律见主设计 §7.4:全局 10s ≤2 条,每 bot 20s 节流,help_call/help_ack 优先):
> `greet`=开局补位完成逐只间隔 ≥1.5s;`help_call`=bot 防区压力呼救 / **真人单击呼喊(用其座位角色声)**;
> `help_ack`=响应呼喊(空闲 bot 一只);`cover`=补位落定 / 转 bot 接管;`kill`=杀熊或三连杀(15s 节流);
> `breach`=本防区漏怪(20s 节流);`skill`=bot 放旋风斩;`wave`=第 2 波起轮转一只鼓劲。
| id | 台词全文 | 触发/语境 |
|---|---|---|
| `npc_yan_greet` | 我来了,这边有我。 | 阿岩 · 开局/补位 |
| `npc_yan_help_call` | 我这侧吃紧,来个人搭把手! | 阿岩 · 呼救(或座 0 真人呼喊) |
| `npc_yan_help_ack` | 撑住,我来了。 | 阿岩 · 响应呼喊 |
| `npc_yan_cover` | 这边交给我。 | 阿岩 · 补位/接管 |
| `npc_yan_kill` | 拿下! | 阿岩 · 杀熊/三连杀 |
| `npc_yan_breach` | 漏了一个,都小心。 | 阿岩 · 本防区突入 |
| `npc_yan_skill` | 都闪开,看我的! | 阿岩 · 旋风斩 |
| `npc_yan_wave` | 新一波,稳住。 | 阿岩 · 波次鼓劲 |
| `npc_zheng_greet` | 小筝到位,开工啦。 | 小筝 · 开局/补位 |
| `npc_zheng_help_call` | 这边太多了,谁来帮一下! | 小筝 · 呼救(或座 1 真人呼喊) |
| `npc_zheng_help_ack` | 别慌,我来了! | 小筝 · 响应呼喊 |
| `npc_zheng_cover` | 这边我罩着。 | 小筝 · 补位/接管 |
| `npc_zheng_kill` | 搞定! | 小筝 · 杀熊/三连杀 |
| `npc_zheng_breach` | 哎呀,漏了一个! | 小筝 · 本防区突入 |
| `npc_zheng_skill` | 看我清场! | 小筝 · 旋风斩 |
| `npc_zheng_wave` | 又来一波,打起精神。 | 小筝 · 波次鼓劲 |
| `npc_zhou_greet` | 老周我守着,放心。 | 老周 · 开局/补位 |
| `npc_zhou_help_call` | 我这边压不住了,来人。 | 老周 · 呼救(或座 2 真人呼喊) |
| `npc_zhou_help_ack` | 听见了,这就到。 | 老周 · 响应呼喊 |
| `npc_zhou_cover` | 这边交给我吧。 | 老周 · 补位/接管 |
| `npc_zhou_kill` | 嗯,解决了。 | 老周 · 杀熊/三连杀 |
| `npc_zhou_breach` | 啧,溜进去一只。 | 老周 · 本防区突入(「啧」风险见头注) |
| `npc_zhou_skill` | 让让,老骨头活动活动。 | 老周 · 旋风斩 |
| `npc_zhou_wave` | 听,又来了。 | 老周 · 波次鼓劲 |
**bot 喊话合计:24 条单音色音频**(×2 格式 = 48 文件;座 3 真人呼喊无角色声,用 `sfx/call_whistle` 哨音,主设计 §15 裁决 6)。
---
## V 组 · 键盘变体(key,11 对;`gesture.inputMode()==='key'` 时选播,措辞规范同 dungeon/bridge)
| id | 键盘台词全文(触屏原句见上方对应 id) |
|---|---|
| `room_wait` | 房间已开好,等同伴到齐。按空格,立即开局。 |
| `tut_rule` | 野兽会从八个方向围上来。声音在哪边,就按哪边方向键。 |
| `tut_attack` | 听,有狼在靠近。朝声音的方向,按方向键。 |
| `tut_callout` | 按空格,呼喊支援,队友会来帮你。 |
| `tut_skill` | 按回车,旋风斩,清掉身边一圈。 |
| `tut_skill_cd` | 旋风斩有八秒冷却。冷却中按回车,重新听威胁。 |
| `tut_status` | 按上方向键,听营地状态。按下方向键,打开菜单。 |
| `sys_menu` | 菜单。按空格切换,按回车确认。 |
| `help_main` | 朝声音的方向按方向键,就是出击。按空格呼喊支援,按回车旋风斩。上方向键状态,下方向键菜单。 |
| `end_again` | 按空格,再猎一局。 |
| `gd_idle` | 听声音的方向,按方向键。 |
**变体合计:11 对 ×2 性别 = 22 条**(×2 格式 = 44 文件;落 `voice/<gender>/key/`)。
---
**全集账目**:旁白 60×2 + bot 24 + key 变体 11×2 = **166 条音频**(×2 格式 = 332 文件)。
主设计触发逻辑对照 [23-hunt.md](23-hunt.md) §2/§5/§7/§8/§11/§12;协议事件(ev 种类 → 播报映射)对照其 §6.3。