Files
SoundGame/docs/design/18-detective-voice-ids.md
T
xsl 566241e05d feat(platform/P1): 配对码跨设备 + 认领打磨 + 键盘语音双套资产(两 agent 并行 + 集成收口)
配对码与认领(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 在途)
2026-09-10 00:43:23 +08:00

20 KiB
Raw Blame History

18b · 《雨夜专案》语音台词表(voice ids,录音依据)

给音频总监的录制说明

  • 旁白双性别组(106 句):旁白只做系统/指引/教学/状态/现场勘验(探长自勘)/裁决宣读,不念证词。落 web/detective/audio/voice/female|male/<id>.{ogg,m4a},两性别 id 集合完全一致。
    • female = Serena,instruct 常量:沉稳清晰的女声,专案组探长,冷静克制,像在雨夜读卷宗
    • male = Uncle_Fu,instruct 常量:低沉沉稳的男声,专案组探长,冷静克制,像在雨夜读卷宗
    • 两常量全表统一(含教学/指证/结案/结算),禁止句级变体、禁语速词(引擎 SoundTouch 变速)。
  • NPC 平铺组(52 句):证词=证人 NPC 平铺单音色、不做双性别,落 web/detective/audio/voice/<id>.{ogg,m4a}(引擎平铺回退命中)。NPC ≤5;同一角色 speaker+instruct 恒定;不加电话滤波(区别于 radio——本作区分度靠 speaker+instruct+游戏侧签名 earcon sig_* 前缀,见主设计 §8.2/§3.7)。区分度风险逐个标注:
    角色 speaker instruct 常量 区分度风险
    老葛(62 岁门卫) Eric 苍老沙哑的男声,守夜人,慢悠悠,带倦意 低
    小顺(19 岁学徒) Dylan 年轻清亮的男声,学徒,怯生生的,慌张诚实 低
    周先生(45 岁账房,pack A 真凶) Uncle_Fu 平板谨慎的男声,账房,字斟句酌,被追问时渐慌 中:与 male 旁白同 speaker——sig_zhou 前缀+账房腔+证词链内零旁白插话,试听确认
    温太太(50 岁房东) Vivian 快嘴泼辣的中年女声,房东太太,嗓门亮,热心肠 低
    秦法医 Serena 冷静干练的女声,验尸官,临床腔,短句平直 中:与 female 旁白同 speaker——sig_fore 前缀+报告固定语境,试听确认
  • 声音演技核心:周先生 z_react_1..4(记岔→支吾→拒答→想走)与 z_break_1..3(认罪三段)、pack B 的 b_shun_react/b_shun_break——情绪全部写在句内文本(省略号/破折号引导),instruct 恒定不变。
  • 数字规避:进度/疑点/冗余指证全部分档整句(st_asked 7 档 / st_doubt 5 档 / st_miss 3 档);句序号一律不播(指证选句用重播该句代替报「第几句」,交互侧落实拼接禁令);句内时刻数字写死在整句里(十点二十、九点四十)。
  • 称呼中性:旁白称玩家「你」,不出现性别化称呼(旁白性别随设置变化不影响证词内容)。
  • 多音字自查:全表无「血」「爪」「挨」「壳」;「重新听」统一写法(不用「重听」);已排雷:「当废铜卖了」→「卖给收废品的了」(当 dāng/dàng 歧义)。低风险 3 处标注:「记得真真的」「账算得比谁都精」的「得」(de,助词)、「微驼背」的「背」(bèi)、「疑点,一处」的「处」(chù)——试听异常再改写。
  • 键盘变体(V 组):操作提示句在 gesture.inputMode()==='key' 时改播 _k 变体(touch 回基础句);变体与基础句 id 一一对应、集中登记见文末 V 组。
  • 管线:tools/gen_voice_dual.py 照录(SPEAKERS 需新增 detective 行 + DETECTIVE_NPC 平铺表);生成后 --convert 落盘 + tools/check_all_assets.py 终检(双格式配对、双性别集合一致)。

G0 组 · 系统/菜单/帮助(旁白 ×11)

id 台词全文 触发/语境
sys_menu 菜单。单击切换,双击确认。 下滑呼出模态菜单
sys_menu_resume 回到证词板。 菜单项
sys_menu_cf 去指证。 菜单项(长按捷径的冗余入口,P4)
sys_menu_save 保存并回大厅。 菜单项
sys_menu_help 重新听帮助。 菜单项
sys_menu_restart 重新查这桩案子。 菜单项
sys_saved 进度已保存。 存档写入后
settings_hint 音色、语速、背景音乐,请回大厅修改。 菜单内设置提示
sys_help 左右滑换卷宗,单击听取,双击重新听。长按指证,上滑状态,下滑菜单。 菜单内上滑 / 帮助项
sys_continue_ask 检测到未结的案子。单击继续,右滑换一桩新案。 有存档进游戏(TITLE)
sys_new_case 新案开卷。 新案开始 / 菜单重开

G1 组 · 开场/教学(旁白 ×12)

id 台词全文 触发/语境
intro_1 雨下了一整夜。清晨,聚宝斋后院,古董商沈万川死了。 开场链 1(TITLE 上滑重听)
intro_2 你是专案组探长。这桩案子,归你。 开场链 2
intro_3 卷宗六份:四位证人的证词,现场勘验,法医报告。 开场链 3
tut_d0 先熟悉证词板。左右滑,换卷宗。 D0 前
tut_listen 单击,听取当前卷宗。 D1 前
tut_replay 双击,重新听这一句。 D2 前
tut_status 上滑,随时听进度:问了几份,疑点几处。 D3 前
tut_confront 按住屏幕,进入指证。去找两句对不上的证词。 D4 前(豁免 E2 教学)
tut_cf_try 练习一次。选一份证词,单击确认;再选一份,任意一句。 D5(判定被教学截获)
tut_cf_ok 指证就是这样。练习不算数,真矛盾要靠耳朵找。 D5 完成(success 震)
tut_done 教学完了。开始查案。 D6(进 BOARD)
tut_skip 已跳过教学。左右滑换卷宗,单击听取。 下滑跳过教学

G2 组 · 状态/条目(旁白 ×20)

id 台词全文 触发/语境
st_asked_0 六份卷宗,一份都没听。 上滑状态链(已听条目数 0)
st_asked_1 已听一份,还有五份。 已听 1
st_asked_2 已听两份,还有四份。 已听 2
st_asked_3 已听三份,还有三份。 已听 3
st_asked_4 已听四份,还有两份。 已听 4
st_asked_5 已听五份,还有一份。 已听 5
st_asked_6 六份都听完了。 已听 6
st_doubt_0 疑点,还没有。 状态链第 2 段(疑点 0)
st_doubt_1 疑点,一处。 疑点 1
st_doubt_2 疑点,两处。 疑点 2
st_doubt_3 疑点,三处。 疑点 3
st_doubt_4 疑点,四处,齐了。 疑点 4(齐时追加 hint_fin 一次)
item_w1 门卫老葛的证词。 条目切换(前缀 sig_ge)
item_w2 学徒小顺的证词。 条目切换(sig_shun)
item_w3 账房周先生的证词。 条目切换(sig_zhou)
item_w4 房东温太太的证词。 条目切换(sig_wen)
item_scene 现场勘验。 条目切换(sig_scene)
item_fore 法医报告。 条目切换(sig_fore)
item_case 结案陈词。 条目切换(无签名,turn earcon);单击进 FINISH
intro_w3 周先生,管了十年的账,见人三分笑。 周证词链首(旁白报名,防与 male 旁白混淆的强化锚点)

G3 组 · 现场勘验(旁白 ×6,探长自勘,sig_scene 前缀链播)

id 台词全文 触发/语境
sc_0 你打伞进了后院。雨水顺着瓦檐,淌成一道帘子。 现场链 1(无轴)
sc_1 柴房门口,沈万川面朝下倒着。后脑一处伤,现场没有凶器。 struggle=none
sc_2 后门门闩完好,是死者自己开的门。生人叫不开这扇门。 door=victim_opened
sc_3 泥地上只有进来的脚印,没有出去的。墙根的花盆,翻了一个。 wall=climbed
sc_4 库房铜秤立在架上,秤砣不见了。 scale=present(M4 对立端)
sc_5 柴房墙上,挂钥匙的铜钩,空着。 无轴(叙事佐证,不参与判定)

G4 组 · 指证(旁白 ×8)

id 台词全文 触发/语境
cf_start 指证矛盾。先选第一份证词。左右滑换,单击确认。 进 CONFROST(turn earcon 同点)
cf_pick_line 左右滑,一句一句听。 选句相位入口(首次)
cf_confirm 就这句?单击,定下来。 选句两段确认(重播该句后接播)
cf_second 再选与它矛盾的那份证词。 第一份定下(自动重播所选句一次)
cf_self 同一句证词,和自己比不出矛盾。 判定:同一句(真话)
cf_same 这两句说得一致,不矛盾。 判定:同轴同值(真话)
cf_diff 这两句,说的不是一件事。 判定:无共享轴(真话)
cf_hit 对不上!矛盾成立,记入疑点。 判定:命中(contra_hit 音先响)

G5 组 · 结案三问(旁白 ×18)

id 台词全文 触发/语境
fin_start 结案陈词。先指认真凶:四位证人,选一个。 进 FINISH(choice earcon)
fin_who_confirm 就指认他?单击,定下来。 真凶问两段确认(重播选项名后接播)
fin_clear 不在场证明成立。证据放人,回到证词板。 指认错(acc_NPC 句后接播;无限再机会)
fin_right 证据链闭合。周先生,你还有什么话说? pack A 指认对 → 认罪链起(rain_swell 同点)
fin_right_b 证据链闭合。小顺,你还有什么话说? pack B 指认对
fin_ask_weapon 第二问:凶器是什么? 凶器问入口
wp_1 松木劈柴。 凶器选项(顺序由 seed 洗牌)
wp_2 铜秤砣。 凶器选项(正确答案,两包共用)
wp_3 铁门闩。 凶器选项
wp_4 青瓷花盆。 凶器选项
fin_wp_right 对。创口的铜屑,不见了的秤砣,都指向它。 凶器答对
fin_wp_wrong 不对。铜屑不答应。记下了。 凶器答错(真话归因,不重答)
fin_ask_motive 第三问:动机是什么? 动机问入口
mv_1 监守自盗。 动机选项(正确答案,两包共用)
mv_2 寻仇泄愤。 动机选项
mv_3 劫财入户。 动机选项
fin_mv_right 对。库里短的东西,就是引线。 动机答对
fin_mv_wrong 不对。账上短的东西,才是引线。记下了。 动机答错(真话归因)

G6 组 · 结算(旁白 ×9)

id 台词全文 触发/语境
settle_open 案件归档。雨,停了。 结算链首句(gavel 后)
rate_s 教科书结案。四处疑点,一击即中。 S 档(条件见主设计 §7.2,措辞=账目)
rate_a 干净利落的结案。 A 档
rate_b 案子结了,卷宗上有疏漏。 B 档
rate_c 案子是结了,卷宗上补丁不少。 C 档(保底/多错)
st_miss_0 指证,一次没错。 冗余指证 0 次
st_miss_1 指证,错过一两回。 1-2 次
st_miss_2 指证,错了不少。 ≥3 次
settle_hook 同一场雨里,还有别的案子。单击,接新案。 结算尾(链锁解除后单击生效;键盘态播 settle_hook_k)

G7 组 · 看门狗/卡关/纠错(旁白 ×12)

id 台词全文 触发/语境
gd_board 还在证词板。左右滑,换卷宗。 BOARD 无操作轨第 1 级(10s,full,idle-only)
gd_cf 还在选证词。左右滑,单击确认。 CONFRONT 无操作轨第 1 级(15s)
gd_fin 在想?左右滑选,单击定。 FINISH 三问无操作轨第 1 级(20s)
gd_invalid 这个操作,这里用不上。 无效手势纠错(onceKey 同局 1 次)
hint_a 探长,还没听的卷宗,先过一遍耳朵。 无进展轨 L2(90s,有未听条目时)
hint_b 探长,证词里有对不上的地方,逐句比对。 无进展轨 L2(90s,条目听齐但疑点未齐)
hint_c1 试试指证:周先生说熄了灯,温太太说灯还亮着。 无进展轨 L3(150s,M1 保底,每句全局限 2 次)
hint_c2 试试指证:周先生说铜秤卖了,现场铜秤还在。 L3(M4 保底)
b_hint_c1 试试指证:小顺说熄了灯,温太太说灯还亮着。 pack B L3(M1b 保底)
b_hint_c2 试试指证:小顺说铜秤卖了,现场铜秤还在。 pack B L3(M4b 保底)
hint_fin 疑点齐了。去结案陈词。 4 疑点齐(一次)/ 无进展轨 L3(疑点齐时)
recap_go 接着查。 中断复述链尾

V 组 · 键盘变体(旁白 ×10;gesture.inputMode()==='key' 时替代同名基础句)

id 替代基础句 台词全文
sys_help_k sys_help 方向键换卷宗,空格听取,回车重新听。按住空格指证,上键状态,下键菜单。
tut_d0_k tut_d0 先熟悉证词板。左右方向键,换卷宗。
tut_listen_k tut_listen 空格,听取当前卷宗。
tut_replay_k tut_replay 回车,重新听这一句。
tut_confront_k tut_confront 按住空格,进入指证。
gd_board_k gd_board 还在证词板。左右方向键,换卷宗。
gd_cf_k gd_cf 还在选证词。左右方向键,空格确认。
cf_pick_line_k cf_pick_line 左右方向键,一句一句听。
cf_confirm_k cf_confirm 就这句?空格,定下来。
settle_hook_k settle_hook 同一场雨里,还有别的案子。按空格,接新案。

N1 组 · 老葛证词(NPC Eric 平铺 ×6,sig_ge 前缀,链播句间 0.8s)

id 台词全文 线索标签
w1_1 昨儿夜里雨大,我守着街门,一步没敢挪窝。 无
w1_2 九点四十,雨点子刚砸下来,小顺打着伞出的街门。 rain=2140, dep_s=2140
w1_3 十点一刻,一位先生收着黑伞进了后巷。个儿高,微驼背。 visitor=male_tall_hunched
w1_4 九点五十,周账房出的街门,跟我说了声,回家。 dep_z=2150
w1_5 后半夜,温太太还来门房借过一回热水。 无
w1_6 听说店里账上短了银子,沈老板撂了话,月底清账。 motive=short

N2 组 · 小顺证词(NPC Dylan 平铺 ×6,sig_shun 前缀)

id 台词全文 线索标签
w2_1 夜里,师父打发我去城南,给刘掌柜送匣子。 away_s=south
w2_2 雨太大,刘掌柜留我住的,今早才回店。 away_s=south
w2_3 库房钥匙?师父嫌沉,平日就挂在柴房墙上的铜钩。 key=hook
w2_4 师父的账,向来只信周先生一个人。 无
w2_5 后门那闩,生人叫不开。熟人来了,师父才亲自去开。 door=victim_opened
w2_6 周先生常念叨,账房的活,越到夜里越清静。 无

N3 组 · 周先生证词(NPC Uncle_Fu 平铺 ×6,sig_zhou 前缀;pack A 真凶,4 句谎)

id 台词全文 线索标签
z_1 我七点进店上夜账。九点五十对完,锁了前门回家。 dep_z=2150
z_2 临走,我顺手熄了店堂的灯。那会儿,店里就剩老板。 lamp=off(谎①,M1)
z_3 库房钥匙?沈老板贴身带着,从不离身。 key=body(谎②,M2)
z_4 那伤,是松木劈柴砸的。铜秤?上个月卖给收废品的了。 weapon=wood, scale=sold(谎③④,M3/M4)
z_5 我到家倒头就睡,夜里的事,一概不知。 无
z_6 你们要是不信,去问我家婆娘。 无

N4 组 · 温太太证词(NPC Vivian 平铺 ×6,sig_wen 前缀)

id 台词全文 线索标签
wen_1 雨是九点四十下的。我正收晾的衣裳,记得真真的。 rain=2140
wen_2 十点二十,我出门倒垃圾。聚宝斋店堂的灯,亮着呢。 lamp=on_2220(M1 对立端)
wen_3 刚回屋,柴房后墙咯噔一响,有人爬墙!花盆翻了一个。 wall=climbed
wen_4 吓得我蒙头半宿没睡着,天亮才敢吱声。 无
wen_5 店里短银子的事,街坊都有耳闻。上礼拜他还摔了账本。 motive=short
wen_6 周账房那人,见人三分笑,账算得比谁都精。 无

N5 组 · 法医报告(NPC Serena 平铺 ×5,sig_fore 前缀)

id 台词全文 线索标签
fo_1 验尸报告,念给你听。 无
fo_2 死亡时间,昨夜十点到十点半。 death=2200_2230
fo_3 后脑单次钝器伤,一击毙命。创口嵌有铜屑,凶器是铜器。 weapon=bronze(M3 对立端)
fo_4 死者双手干净,没有搏斗痕迹。 struggle=none
fo_5 鞋底是干的。当夜,死者没出过后门。 无

N6 组 · 反应/被指认/认罪(NPC 平铺 ×11)

id 声部 台词全文 触发/语境
z_react_1 周先生 灯?……许是我记岔了。人上了岁数,记性不济。 真凶第 1 处矛盾坐实
z_react_2 周先生 钥匙的事……他、他有时候,也贴身带着的…… 第 2 处
z_react_3 周先生 秤!秤的事,你们别再问了…… 第 3 处
z_react_4 周先生 ……随你们怎么问。我要回去了。 第 4 处
acc_ge 老葛 我守了一夜门!温太太来借热水,她能作证! 错指老葛
acc_shun 小顺 我宿在城南刘掌柜家,他全家都能作证! 错指小顺(pack A)
acc_wen 温太太 我这把年纪翻墙?先问问那墙答不答应! 错指温太太
acc_zhou 周先生 我十点就到家了!我家婆娘能作证! 错指周先生(pack B)
z_break_1 周先生 别念了……我说。库房短的三件货,是我抵了赌债。 pack A 认罪 1
z_break_2 周先生 他说月底清账,要报官。我求他,他不肯。 认罪 2
z_break_3 周先生 我只想把钥匙放回去,把被盗做真。抡起秤砣的时候,他认出了我。 认罪 3

N7 组 · 变体包 B fork(NPC 平铺 ×12;pack B 真凶=小顺)

id 声部 台词全文 线索标签/用途
b_zhou_1 周先生 我对完账就回家了,夜里雨大,路上没停。 无(替换 z_2 槽位)
b_zhou_2 周先生 钥匙?平时就挂在柴房铜钩上,十年了。 key=hook(M2b 对立端)
b_zhou_3 周先生 柴房我常去,没什么不对劲的。 无
b_shun_1 小顺 我走的时候,顺手熄了店堂的灯。 lamp=off(谎①,M1b)
b_shun_2 小顺 钥匙,师父贴身带着,从不离身。 key=body(谎②,M2b)
b_shun_3 小顺 那伤,八成是柴房劈柴砸的。铜秤早卖给收废品的了。 weapon=wood, scale=sold(谎③④,M3b/M4b)
b_shun_4 小顺 库房的货,我一件都没碰过。 无(欲盖弥彰 filler)
b_shun_react_1 小顺 灯?我、我走的时候明明熄了…… 第 1 处矛盾坐实
b_shun_react_2 小顺 别问了……别问了…… 第 2-4 处(复用)
b_shun_break_1 小顺 匣子是我送的,可我半路折回来了…… 认罪 1
b_shun_break_2 小顺 我把棉袄反穿,弓着背,葛大爷没认出我。 认罪 2(解释 w1_3 访客描述)
b_shun_break_3 小顺 库房的货,我拿过三件换了钱。他说要对账……秤砣下去的时候,他看着我。 认罪 3

合计:158 句 ≤160 上限(旁白 106 ×2 性别 = 212 条 + NPC 平铺 52 条 = 264 条音频 ×2 格式 = 528 文件)。 分组账:G0 11 + G1 12 + G2 20 + G3 6 + G4 8 + G5 18 + G6 9 + G7 12 + V 10 = 106(旁白);N1-N5 29 + N6 11 + N7 12 = 52(NPC)。 指证命中链 = contra_hit(sfx)→ cf_hit → react_n;miss 链 = contra_miss(sfx)→ cf_same/cf_diff/cf_self; 认罪链(pack A)= fin_right → z_break_1..3 → gavel → settle_open → rate_X → st_doubt_n → st_miss_档 → settle_hook; 状态链 = st_asked_n → st_doubt_m;中断复述链 = st_asked_n →(未听 ≤3 时)item_* 名链 → st_doubt_m → recap_go。 矩阵验算与触发逻辑对照 18-detective.md §3-§7;资产规模核对见其 §8。