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 在途)
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
# 01b · 《暗室》语音台词表(voice ids)
|
||||
|
||||
> 主台词表(80 句,双性别)的唯一事实源是 `tools/gen_voice_dual.py` 的
|
||||
> `ESCAPE_LINES`(R2 重设计全文见 [01-escape-redesign.md](01-escape-redesign.md);
|
||||
> 史源 app/src/escape/gen/gen_voice.py)。本文档登记 P1 键盘变体(输入平权
|
||||
> 路线 a)——变体只覆盖含操作词的句子,id 集合 ⊆ 主表,复用主表同 id 的
|
||||
> instruct/speaker。
|
||||
---
|
||||
|
||||
## 键盘变体(key,P1 输入平权路线 a,30 句)
|
||||
|
||||
「生效输入模式=键盘」(settings.input=key,或 auto 且键盘在跟/纯桌面初始判定,
|
||||
web/engine/gesture.js inputMode())时,引擎 voice 候选链前置加载
|
||||
`web/escape/audio/voice/<gender>/key/<id>.{ogg,m4a}`,变体缺失回退主资产——触屏措辞零改动。
|
||||
>
|
||||
> 措辞规范(02-input-parity.md §4.3 路线 a + P1 裁定):向左滑→按左方向键(四向同理,
|
||||
> WASD 不进台词);单击/轻触屏幕→按空格;双击→按回车;按住/长按→按住空格;
|
||||
> 复合短语(左右滑→左右方向键、滑动→方向键)按语义等价展开;只改操作词,其余
|
||||
> 内容一字不动,不新增「重」类多音字。本表与 `tools/gen_voice_dual.py` 的
|
||||
> `KEY_LINES` 逐字一致(两表一致铁律:改一处必改另一处)。
|
||||
> 资产:×2 性别 = 30×2 条、×2 格式 = 30×4 文件;管线 `gen_voice_dual.py --only-variants`
|
||||
> 生成 → `--convert` 落盘,终检 `tools/check_all_assets.py`(key 两性别一致且 ⊆ 主集)。
|
||||
|
||||
| id | 键盘台词全文(触屏原句见本表上方对应 id) |
|
||||
|---|---|
|
||||
| `g1_move` | 先活动一下。按任意方向键,走一小步。 |
|
||||
| `g2_wall` | 这个房间不大,四面都是墙。再按两下方向键,试试碰碰墙。 |
|
||||
| `g3_left` | 跟着我指的路走。按左方向键。 |
|
||||
| `g4_down` | 对。再按下方向键。 |
|
||||
| `g5_inspect` | 听到水声了吗?按一下空格,仔细检查这个房间。 |
|
||||
| `g6_doubletap` | 钥匙能开锁。按回车,是把物品用出去的用法。现在,按回车试试。 |
|
||||
| `g7_goal` | 找到能用这把钥匙打开的东西。需要帮助时,在原地按回车。 |
|
||||
| `guide_wrong_up` | 不是这个方向。按上方向键。 |
|
||||
| `guide_wrong_down` | 不是这个方向。按下方向键。 |
|
||||
| `guide_wrong_left` | 不是这个方向。按左方向键。 |
|
||||
| `guide_wrong_right` | 不是这个方向。按右方向键。 |
|
||||
| `guide_blunt_up` | 按一下上方向键。 |
|
||||
| `guide_blunt_down` | 按一下下方向键。 |
|
||||
| `guide_blunt_left` | 按一下左方向键。 |
|
||||
| `guide_blunt_right` | 按一下右方向键。 |
|
||||
| `reopen_prompt` | 按上方向键,重新听一遍引导。按空格,直接开始。 |
|
||||
| `stuck_key_2` | 去西南角的储物间,按空格检查,找到钥匙。 |
|
||||
| `stuck_cabinet_2` | 去东边的铁柜房,按回车,用钥匙打开铁柜。 |
|
||||
| `stuck_box_2` | 去西北角的电箱房,按回车,把保险丝装进电箱。 |
|
||||
| `stuck_gate_2` | 去东南角的大门,按回车,打开它,离开这里。 |
|
||||
| `nav_up` | 按上方向键。 |
|
||||
| `nav_down` | 按下方向键。 |
|
||||
| `nav_left` | 按左方向键。 |
|
||||
| `nav_right` | 按右方向键。 |
|
||||
| `start_room` | 你站在设施中央的房间里。方向键移动,按空格检查,按回车使用物品。 |
|
||||
| `inspect_gate_ready` | 电子锁的指示灯亮了,发出微弱的绿光。大门已经通电。按回车,打开它,离开这里。 |
|
||||
| `use_fail` | 这里没有用得上东西的地方。换个房间试试,或者先按空格检查一下周围。 |
|
||||
| `again` | 按空格,再来一次。按下方向键,打开菜单。 |
|
||||
| `help_ops` | 方向键,在房间之间移动。按空格,检查房间,或者重听房间的声音。按回车,使用物品,或者查看背包。 |
|
||||
| `skip_hint` | 按空格可跳过旁白。 |
|
||||
@@ -0,0 +1,52 @@
|
||||
# 02b · 《音序回响》语音台词表(voice ids)
|
||||
|
||||
> 主台词表(78 句,双性别)的唯一事实源是 `tools/gen_voice_dual.py` 的
|
||||
> `SIMON_LINES`(R2 重设计全文见 [02-simon-redesign.md](02-simon-redesign.md))。
|
||||
> 本文档登记 P1 键盘变体(输入平权路线 a)——变体只覆盖含操作词的句子,
|
||||
> id 集合 ⊆ 主表,复用主表同 id 的 instruct/speaker。
|
||||
---
|
||||
|
||||
## 键盘变体(key,P1 输入平权路线 a,28 句)
|
||||
|
||||
「生效输入模式=键盘」(settings.input=key,或 auto 且键盘在跟/纯桌面初始判定,
|
||||
web/engine/gesture.js inputMode())时,引擎 voice 候选链前置加载
|
||||
`web/simon/audio/voice/<gender>/key/<id>.{ogg,m4a}`,变体缺失回退主资产——触屏措辞零改动。
|
||||
>
|
||||
> 措辞规范(02-input-parity.md §4.3 路线 a + P1 裁定):向左滑→按左方向键(四向同理,
|
||||
> WASD 不进台词);单击/轻触屏幕→按空格;双击→按回车;按住/长按→按住空格;
|
||||
> 复合短语(左右滑→左右方向键、滑动→方向键)按语义等价展开;只改操作词,其余
|
||||
> 内容一字不动,不新增「重」类多音字。本表与 `tools/gen_voice_dual.py` 的
|
||||
> `KEY_LINES` 逐字一致(两表一致铁律:改一处必改另一处)。
|
||||
> 资产:×2 性别 = 28×2 条、×2 格式 = 28×4 文件;管线 `gen_voice_dual.py --only-variants`
|
||||
> 生成 → `--convert` 落盘,终检 `tools/check_all_assets.py`(key 两性别一致且 ⊆ 主集)。
|
||||
|
||||
| id | 键盘台词全文(触屏原句见本表上方对应 id) |
|
||||
|---|---|
|
||||
| `t1_up` | 按上方向键,是这个声音。 |
|
||||
| `t2_down` | 按下方向键,是这个声音。 |
|
||||
| `t3_left` | 按左方向键,是这个声音。 |
|
||||
| `t4_right` | 按右方向键,是这个声音。 |
|
||||
| `t5_tap` | 按空格,是这个声音。 |
|
||||
| `t6_double` | 按回车,是这个声音。 |
|
||||
| `t_wrong_up` | 不是这个,按上方向键试试。 |
|
||||
| `t_wrong_down` | 不是这个,按下方向键试试。 |
|
||||
| `t_wrong_left` | 不是这个,按左方向键试试。 |
|
||||
| `t_wrong_right` | 不是这个,按右方向键试试。 |
|
||||
| `t_wrong_tap` | 不是这个,按空格试试。 |
|
||||
| `t_wrong_double` | 不是这个,按回车试试。 |
|
||||
| `t_blunt_up` | 按一下上方向键。 |
|
||||
| `t_blunt_down` | 按一下下方向键。 |
|
||||
| `t_blunt_left` | 按一下左方向键。 |
|
||||
| `t_blunt_right` | 按一下右方向键。 |
|
||||
| `t_blunt_tap` | 轻轻按一下空格。 |
|
||||
| `t_blunt_double` | 按一下回车。 |
|
||||
| `t7_retry` | 答错可以消耗机会重听。按上方向键,可以随时重听。 |
|
||||
| `replay` | 按空格,再来一局。 |
|
||||
| `rules_prompt` | 按上方向键,重听规则。按下方向键,打开菜单。 |
|
||||
| `rules` | 上行音,按上方向键。下行音,按下方向键。左边的音,按左方向键。右边的音,按右方向键。一声轻响,按空格。两声轻响,按回车。 |
|
||||
| `skip_hint` | 按空格可跳过旁白。 |
|
||||
| `gd_relisten` | 需要的话,按上方向键可以重新听一遍序列。 |
|
||||
| `gd_economy` | 记不住就按上方向键,重新听一遍。免费机会有两次,用完要扣一次机会。 |
|
||||
| `gd_occ_up` | 这一轮,按上方向键是作答。 |
|
||||
| `gd_occ_dt` | 这一轮,按回车是作答。 |
|
||||
| `gd_occ_both` | 这一轮,按上方向键和回车都是作答。 |
|
||||
@@ -69,3 +69,30 @@
|
||||
---
|
||||
|
||||
**合计 31 句 × 2 性别 = 62 条**(其中 grade_*、restart 为重录覆盖)。无数字拼接:拍数(九十/一百零五/一百二十)与准确率档位全部写死在整句里。
|
||||
---
|
||||
|
||||
## 键盘变体(key,P1 输入平权路线 a,9 句)
|
||||
|
||||
「生效输入模式=键盘」(settings.input=key,或 auto 且键盘在跟/纯桌面初始判定,
|
||||
web/engine/gesture.js inputMode())时,引擎 voice 候选链前置加载
|
||||
`web/rhythm/audio/voice/<gender>/key/<id>.{ogg,m4a}`,变体缺失回退主资产——触屏措辞零改动。
|
||||
>
|
||||
> 措辞规范(02-input-parity.md §4.3 路线 a + P1 裁定):向左滑→按左方向键(四向同理,
|
||||
> WASD 不进台词);单击/轻触屏幕→按空格;双击→按回车;按住/长按→按住空格;
|
||||
> 复合短语(左右滑→左右方向键、滑动→方向键)按语义等价展开;只改操作词,其余
|
||||
> 内容一字不动,不新增「重」类多音字。本表与 `tools/gen_voice_dual.py` 的
|
||||
> `KEY_LINES` 逐字一致(两表一致铁律:改一处必改另一处)。
|
||||
> 资产:×2 性别 = 9×2 条、×2 格式 = 9×4 文件;管线 `gen_voice_dual.py --only-variants`
|
||||
> 生成 → `--convert` 落盘,终检 `tools/check_all_assets.py`(key 两性别一致且 ⊆ 主集)。
|
||||
|
||||
| id | 键盘台词全文(触屏原句见本表上方对应 id) |
|
||||
|---|---|
|
||||
| `tut_1` | 听,底鼓。在下一小节的同一个位置,按空格。 |
|
||||
| `tut_2` | 这次是左和右。跟着打,按左方向键,按右方向键。 |
|
||||
| `tut_3` | 最后一句,三个音,中间是按回车。 |
|
||||
| `select_hint` | 左右方向键选曲目,按空格开始,按下方向键回大厅。 |
|
||||
| `restart` | 按空格再来一遍,按右方向键下一首,按下方向键回大厅。 |
|
||||
| `menu_main` | 菜单。按空格切换选项,按回车确认。 |
|
||||
| `skip_hint` | 按空格可跳过旁白。 |
|
||||
| `gd_miss_early` | 抢拍了。等声音落下再按。 |
|
||||
| `gd_miss_wrong` | 方向不对。跟着音色按方向键。 |
|
||||
|
||||
@@ -103,3 +103,45 @@
|
||||
**合计 52 句 × 2 性别 = 104 条**(×2 格式 = 208 文件)。
|
||||
|
||||
旧 id 处置:R1 生成的 `num*/n_*/intro1-4/hit1/hit2/gameover/restart` 全部弃用(数字拼接与旧教学);`shield_ready`/`shield_block` 沿用 id 重录。平铺旧文件按 R1 约定在切换验证后统一清理。
|
||||
---
|
||||
|
||||
## 键盘变体(key,P1 输入平权路线 a,24 句)
|
||||
|
||||
「生效输入模式=键盘」(settings.input=key,或 auto 且键盘在跟/纯桌面初始判定,
|
||||
web/engine/gesture.js inputMode())时,引擎 voice 候选链前置加载
|
||||
`web/space/audio/voice/<gender>/key/<id>.{ogg,m4a}`,变体缺失回退主资产——触屏措辞零改动。
|
||||
>
|
||||
> 措辞规范(02-input-parity.md §4.3 路线 a + P1 裁定):向左滑→按左方向键(四向同理,
|
||||
> WASD 不进台词);单击/轻触屏幕→按空格;双击→按回车;按住/长按→按住空格;
|
||||
> 复合短语(左右滑→左右方向键、滑动→方向键)按语义等价展开;只改操作词,其余
|
||||
> 内容一字不动,不新增「重」类多音字。本表与 `tools/gen_voice_dual.py` 的
|
||||
> `KEY_LINES` 逐字一致(两表一致铁律:改一处必改另一处)。
|
||||
> 资产:×2 性别 = 24×2 条、×2 格式 = 24×4 文件;管线 `gen_voice_dual.py --only-variants`
|
||||
> 生成 → `--convert` 落盘,终检 `tools/check_all_assets.py`(key 两性别一致且 ⊆ 主集)。
|
||||
|
||||
| id | 键盘台词全文(触屏原句见本表上方对应 id) |
|
||||
|---|---|
|
||||
| `drill_left` | 听,左边有陨石。按左方向键,把它拨开! |
|
||||
| `drill_right` | 这次在右边。按右方向键! |
|
||||
| `drill_up` | 上面有东西,声音又尖又高。按上方向键! |
|
||||
| `drill_down` | 下面是低沉的轰隆。按下方向键! |
|
||||
| `drill_retry_left` | 那是左边来的,按左方向键。 |
|
||||
| `drill_retry_right` | 那是右边来的,按右方向键。 |
|
||||
| `drill_retry_up` | 声音又高又尖,是上面,按上方向键。 |
|
||||
| `drill_retry_down` | 轰隆声在下面,按下方向键。 |
|
||||
| `protect_left` | 训练护盾接住了。那颗在左边,听到左边的呼啸,按左方向键。 |
|
||||
| `protect_right` | 训练护盾接住了。那颗在右边,听到右边的呼啸,按右方向键。 |
|
||||
| `protect_up` | 训练护盾接住了。那颗在上面,听到高高的呼啸,按上方向键。 |
|
||||
| `protect_down` | 训练护盾接住了。那颗在下面,听到低沉的轰隆,按下方向键。 |
|
||||
| `feat_boost` | 试试按空格,引擎会短促加速,直接冲过空隙。 |
|
||||
| `feat_shield` | 按回车展开护盾,能挡下一次撞击。 |
|
||||
| `hit_left` | 左边撞上的。听到左边的呼啸,按左方向键。 |
|
||||
| `hit_right` | 右边撞上的。听到右边的呼啸,按右方向键。 |
|
||||
| `hit_up` | 上面撞上的。听到高高的呼啸,按上方向键。 |
|
||||
| `hit_down` | 下面撞上的。听到低沉的轰隆,按下方向键。 |
|
||||
| `restart_hint` | 按空格再飞一次,按下方向键回大厅。 |
|
||||
| `second_run_ask` | 按上方向键重新听演练,按空格直接出发。 |
|
||||
| `menu_main` | 菜单。按空格切换选项,按回车确认。 |
|
||||
| `help_recap` | 左边来按左方向键,右边来按右方向键,上面来按上方向键,下面来按下方向键。按空格加速,按回车护盾。 |
|
||||
| `skip_hint` | 按空格可跳过旁白。 |
|
||||
| `gd_hit_hint` | 被撞了。听方位,按对应方向键就能拨开。 |
|
||||
|
||||
@@ -174,3 +174,37 @@
|
||||
---
|
||||
|
||||
**合计:旁白 104 句 × 2 性别 + NPC 16 句 = 224 条音频**(×2 格式 = 448 文件)。对话功能与语气大纲对照见 [05-rpg.md](05-rpg.md) §5.3,场景/战斗触发逻辑见 [05-rpg-chapter1.md](05-rpg-chapter1.md)。
|
||||
---
|
||||
|
||||
## 键盘变体(key,P1 输入平权路线 a,16 句)
|
||||
|
||||
「生效输入模式=键盘」(settings.input=key,或 auto 且键盘在跟/纯桌面初始判定,
|
||||
web/engine/gesture.js inputMode())时,引擎 voice 候选链前置加载
|
||||
`web/rpg/audio/voice/<gender>/key/<id>.{ogg,m4a}`,变体缺失回退主资产——触屏措辞零改动。
|
||||
>
|
||||
> 措辞规范(02-input-parity.md §4.3 路线 a + P1 裁定):向左滑→按左方向键(四向同理,
|
||||
> WASD 不进台词);单击/轻触屏幕→按空格;双击→按回车;按住/长按→按住空格;
|
||||
> 复合短语(左右滑→左右方向键、滑动→方向键)按语义等价展开;只改操作词,其余
|
||||
> 内容一字不动,不新增「重」类多音字。本表与 `tools/gen_voice_dual.py` 的
|
||||
> `KEY_LINES` 逐字一致(两表一致铁律:改一处必改另一处)。
|
||||
> 资产:×2 性别 = 16×2 条、×2 格式 = 16×4 文件;管线 `gen_voice_dual.py --only-variants`
|
||||
> 生成 → `--convert` 落盘,终检 `tools/check_all_assets.py`(key 两性别一致且 ⊆ 主集)。
|
||||
|
||||
| id | 键盘台词全文(触屏原句见本表上方对应 id) |
|
||||
|---|---|
|
||||
| `sys_continue_ask` | 检测到你的旅程记录。按空格继续,按右方向键开始新的旅程。 |
|
||||
| `sys_menu` | 菜单。左右方向键选择,按空格确认。 |
|
||||
| `help_explore` | 左右方向键切换选项,按空格确认。按回车重新听场景,按上方向键查看状态,按下方向键打开菜单。 |
|
||||
| `help_battle` | 战斗中,左右方向键选招式,按空格出手。听到敌人的前摇,按回车格挡。 |
|
||||
| `btl_lose_hint` | 记住,听清前摇,按回车格挡。 |
|
||||
| `tut_b2` | 就是现在,按回车格挡! |
|
||||
| `tut_b3` | 挡住了!轮到你了。左右方向键选攻击,按空格出剑。 |
|
||||
| `shop_open` | 商店。左右方向键看看货,按空格购买。 |
|
||||
| `skip_hint` | 按空格可跳过旁白。 |
|
||||
| `tut_battle_2` | 左右方向键切换招式,攻击、破空斩、防御、金疮药。按空格,出手。 |
|
||||
| `tut_battle_3` | 敌人出手前有一声前摇。听到前摇,马上按回车,就能格挡。 |
|
||||
| `tut_battle_5` | 记住:听清前摇,按回车格挡。开始吧! |
|
||||
| `tut_b0` | 战斗里,左右方向键选招式,按空格出手。听到这个声音,就是你的回合。先按一按方向键,试试。 |
|
||||
| `tut_b6` | 来不及格挡,就选防御。左右方向键,选防御,按空格。 |
|
||||
| `gd_parry_miss` | 前摇声起的时候按回车,才能格挡。 |
|
||||
| `gd_stall` | 想好了吗?左右方向键选择,按空格出手。 |
|
||||
|
||||
@@ -758,3 +758,29 @@
|
||||
菜单暂停冻结、上滑 5 段状态链。
|
||||
|
||||
R1 起每轮的增量断言(修复回归)在各自设计文档的轮次小节追加,不在本文件重复。
|
||||
|
||||
## 21. 新游戏登记:《深海回音》(abyss)(new8 批次 2)
|
||||
|
||||
叙事款(radio 同骨架),断言清单与实现核对**住设计文档**(§20 先例):
|
||||
|
||||
- abyss:[17-abyss.md](17-abyss.md) §9(playtest 清单)。要点:四结局氧气剧本验算(lefts 公式 + 剧本 A-D 逐检查点
|
||||
oxy 档位句)、第四潜氧气门三形态(双载/单载/取消)、氧气账目真实(floor(oxy/3) 档位、补给恰一次、mid-dive
|
||||
floor 干涸链)、声呐双通道仲裁(echo/pipe_knock 与 voice 零重叠 + sonarGate 排队)、教学承诺兑现清单
|
||||
(金属=钢板/单击=脉冲/四潜/氧气门/扣三格/敲管/补给)、看门狗双轨(乱按 96s 必被抢救 + 有进展零打扰)、
|
||||
结算链 800ms 手势死窗(dungeon H1 内化)、键盘 _k 变体按 inputMode 选播、pendingChoice/p* 不可跳、
|
||||
中断复述、存档 schema。
|
||||
|
||||
## 22. 新游戏登记:《暗码》(cipher)(new8 批次 3)
|
||||
|
||||
叙事款(radio/abyss 同骨架 + 电文解码小局),断言清单与实现核对**住设计文档**(§21 先例):
|
||||
|
||||
- cipher:[19-cipher.md](19-cipher.md) §9(playtest 清单)。要点:**摩尔斯固定字符断言**(运行时 SYN 模块 `morse.js`
|
||||
事件钩子,BAY/TOP/HAND/SPY 逐元素 + 时值容差 ±5ms + 三档速度 u=80/110/160;**不随 settings.speed 变**);
|
||||
**三层兜底剧本各自走通**(纯耳朵剧本 A / 纯慢放剧本 F / 提示流剧本 E:T1 免费页 + 3 页逐值 book_2/1/0);
|
||||
**译错归因真话**(T1 dv1_wrong 句内字母与真词一致 + 无限重选零惩罚;正片判定出口零对错语音;ep_* 与
|
||||
t/picks flags 单源对应);**暴露度剧本验算**(剧本 A-D 逐 NIGHT 检查点档位句 = wrong+risk 公式,收网门=hot 档
|
||||
阈值 5);四结局矩阵(expose 档 × p9);morseGate 零重叠(摩尔斯与任一 voice 区间);密码本页数账目(逐值
|
||||
整句、页数 0 翻本=error 震+翻空本音零惩罚);看门狗双轨(纯浏览/重听不计进展,乱按 96s 必被抢救);
|
||||
结算链 800ms 手势死窗(判定出口/NIGHT/d9/e*);键盘 _k 变体 11 对按 inputMode 选播;pendingChoice/p* 不可跳/
|
||||
摩尔斯首播不可跳;中断复述(含 DECODE 态恢复链 prog_t→book 档→gd_tune2);存档 schema(summary 带
|
||||
暴露档名)。
|
||||
|
||||
@@ -228,3 +228,39 @@
|
||||
- 每个结局(e1..e4)专属主句+钩子各 2 句齐备,尾声救/错过双线齐备 ✓。
|
||||
- 归因真话律:负向收尾句(z1_bade/k1_lulle/k1_liee/ep_*_no/e4_b)全部指向玩家实际选择,无假归因句 ✓。
|
||||
- 向导 gd_* 6 句(gd_brief/gd_continue/gd_again/gd_invalid/gd_ring1/gd_ring2)符合 14 号 §6 台词规范(一句一义、无重复句式、单句 ≤15 字)✓。
|
||||
---
|
||||
|
||||
## 键盘变体(key,P1 输入平权路线 a,18 句)
|
||||
|
||||
「生效输入模式=键盘」(settings.input=key,或 auto 且键盘在跟/纯桌面初始判定,
|
||||
web/engine/gesture.js inputMode())时,引擎 voice 候选链前置加载
|
||||
`web/radio/audio/voice/<gender>/key/<id>.{ogg,m4a}`,变体缺失回退主资产——触屏措辞零改动。
|
||||
>
|
||||
> 措辞规范(02-input-parity.md §4.3 路线 a + P1 裁定):向左滑→按左方向键(四向同理,
|
||||
> WASD 不进台词);单击/轻触屏幕→按空格;双击→按回车;按住/长按→按住空格;
|
||||
> 复合短语(左右滑→左右方向键、滑动→方向键)按语义等价展开;只改操作词,其余
|
||||
> 内容一字不动,不新增「重」类多音字。本表与 `tools/gen_voice_dual.py` 的
|
||||
> `KEY_LINES` 逐字一致(两表一致铁律:改一处必改另一处)。
|
||||
> 资产:×2 性别 = 18×2 条、×2 格式 = 18×4 文件;管线 `gen_voice_dual.py --only-variants`
|
||||
> 生成 → `--convert` 落盘,终检 `tools/check_all_assets.py`(key 两性别一致且 ⊆ 主集)。
|
||||
|
||||
| id | 键盘台词全文(触屏原句见本表上方对应 id) |
|
||||
|---|---|
|
||||
| `gd_brief` | 按空格继续节目。请选择的时候,按左或右方向键。 |
|
||||
| `gd_continue` | 按空格,继续。 |
|
||||
| `gd_again` | 还在吗?按空格继续。 |
|
||||
| `gd_ring1` | 热线在闪。按空格,接听。 |
|
||||
| `gd_ring2` | 灯还亮着,听众在等。按空格,接听。 |
|
||||
| `sys_help` | 按空格继续,按回车重新听。按上方向键听状态,按下方向键开菜单。请选择时,左右方向键。 |
|
||||
| `sys_menu` | 菜单。按空格切换选项,按回车确认。 |
|
||||
| `sys_skip` | 想跳过这句,按空格就行。 |
|
||||
| `sys_continue_ask` | 检测到你的夜班记录。按空格继续上次,按右方向键开始新的夜晚。 |
|
||||
| `p1` | 老人在发抖。按左方向键,陪他哼那首老歌。按右方向键,冷静问他路口的路牌。 |
|
||||
| `p2` | 雨声更密了。按左方向键,留在原地陪他等巡逻队。按右方向键,转接派出所。 |
|
||||
| `p3` | 按左方向键,告诉她这趟车值得上。按右方向键,把选择还给她。 |
|
||||
| `p4` | 按左方向键,唱一段摇篮曲哄她睡。按右方向键,轻轻问她怎么了。 |
|
||||
| `p5` | 孩子的声音在抖。按左方向键,告诉她这不是她的错。按右方向键,答应她明天都会好。 |
|
||||
| `p6` | 摔门声你听见了。按左方向键,替孩子给她带句话。按右方向键,劝她回家把话说开。 |
|
||||
| `p7` | 她的呼吸平了。按左方向键,留在直播里,让全城等这个门铃。按右方向键,换垫乐,私下陪她说完。 |
|
||||
| `p8` | 方向盘比话筒危险。按左方向键,陪他聊聊闺女。按右方向键,让他立刻进服务区。 |
|
||||
| `p9` | 留言机红灯在闪,是老主播三年前没播完的那句晚安。按左方向键,替他播出去。按右方向键,照常收播。 |
|
||||
|
||||
@@ -179,3 +179,41 @@
|
||||
通关链 = `settle_win_1 → settle_win_2 → meta_gold_X(同上)→ unlock 段 → settle_again`;
|
||||
上滑局面复述链 = `st_floor_N → st_hp_X → st_gold_X(band1 且金>0 时为 gold_some)→ st_face_X → st_threat_X`。
|
||||
主设计触发逻辑对照 [16-dungeon.md](16-dungeon.md) §4-§11;资产规模核对见其 §9。
|
||||
---
|
||||
|
||||
## 键盘变体(key,P1 输入平权路线 a,20 句)
|
||||
|
||||
「生效输入模式=键盘」(settings.input=key,或 auto 且键盘在跟/纯桌面初始判定,
|
||||
web/engine/gesture.js inputMode())时,引擎 voice 候选链前置加载
|
||||
`web/dungeon/audio/voice/<gender>/key/<id>.{ogg,m4a}`,变体缺失回退主资产——触屏措辞零改动。
|
||||
>
|
||||
> 措辞规范(02-input-parity.md §4.3 路线 a + P1 裁定):向左滑→按左方向键(四向同理,
|
||||
> WASD 不进台词);单击/轻触屏幕→按空格;双击→按回车;按住/长按→按住空格;
|
||||
> 复合短语(左右滑→左右方向键、滑动→方向键)按语义等价展开;只改操作词,其余
|
||||
> 内容一字不动,不新增「重」类多音字。本表与 `tools/gen_voice_dual.py` 的
|
||||
> `KEY_LINES` 逐字一致(两表一致铁律:改一处必改另一处)。
|
||||
> 资产:×2 性别 = 20×2 条、×2 格式 = 20×4 文件;管线 `gen_voice_dual.py --only-variants`
|
||||
> 生成 → `--convert` 落盘,终检 `tools/check_all_assets.py`(key 两性别一致且 ⊆ 主集)。
|
||||
|
||||
| id | 键盘台词全文(触屏原句见本表上方对应 id) |
|
||||
|---|---|
|
||||
| `sys_continue_ask` | 检测到探窟记录。按空格继续,按右方向键重新开始。 |
|
||||
| `tut_d0` | 先学会用耳朵看。按空格,发出声波脉冲。 |
|
||||
| `tut_walk` | 按住空格不放,你就往前走。 |
|
||||
| `tut_turn` | 按左右方向键,可以转身。 |
|
||||
| `tut_replay` | 按回车,再发一次脉冲,不要钱。 |
|
||||
| `tut_status` | 按上方向键,随时听自己的状态。 |
|
||||
| `tut_menu` | 按下方向键,打开菜单。 |
|
||||
| `tut_parry` | 听到它的动静,按回车格挡。 |
|
||||
| `tut_attack` | 现在按空格,挥拳打它。 |
|
||||
| `tut_flee_hold` | 想逃跑,按住空格别松手。 |
|
||||
| `tut_stairs_on` | 楼梯就在脚下。按空格,下潜。 |
|
||||
| `tut_skip` | 已跳过教学。按空格发脉冲,先听听四周。 |
|
||||
| `sys_menu` | 菜单。按空格切换,按回车确认。 |
|
||||
| `help_explore` | 按空格发脉冲,按住空格前进,左右方向键转身。按回车再听,上方向键查状态,下方向键开菜单。 |
|
||||
| `help_battle` | 敌人前摇声响时按回车格挡,按空格挥击。打不过就按住空格逃跑。 |
|
||||
| `die_adv_1` | 下次,前摇声响时就按回车。 |
|
||||
| `die_adv_2` | 打不过,就按住空格逃跑。 |
|
||||
| `gd_pulse` | 按空格发脉冲,听听四周。 |
|
||||
| `gd_turn` | 轮到你了。按空格挥击。 |
|
||||
| `settle_again` | 按空格,再探一次。 |
|
||||
|
||||
@@ -0,0 +1,251 @@
|
||||
# 17b · 《深海回音》(abyss) 语音台词表(voice ids,录音依据)
|
||||
|
||||
> **给音频总监的录制说明**
|
||||
> - **双性别组**(潜航员 DIVER + 调度/系统 DECK,126 句):落 `web/abyss/audio/voice/female|male/<id>.{ogg,m4a}`,两性别 id 集合完全一致(含全部 `_k` 变体)。
|
||||
> - **DIVER(潜航员=玩家)**:female = `Serena`,instruct 常量 `低沉冷静的年轻女声,深潜救援员,干练沉着,水下通讯的轻微气声`;male = `Uncle_Fu`,instruct 常量 `低沉冷静的男声,深潜救援员,干练沉着,水下通讯的轻微气声`。
|
||||
> - **DECK(母船调度/系统音/向导 gd_*)**:female = `Vivian`,instruct 常量 `清晰稳定的女声,母船潜水调度员,专业干脆,隔着耳机下达指令`;male = `Dylan`,instruct 常量 `清晰稳定的男声,母船潜水调度员,专业干脆,隔着耳机下达指令`。
|
||||
> - 区分度设计:玩家(头戴耳机的自语音)与调度(母船通讯声)共用 speaker 池但**不同 speaker 配对**——female 侧玩家 Serena / 调度 Vivian、male 侧玩家 Uncle_Fu / 调度 Dylan,同场景高频对话的两者永不同 speaker。
|
||||
> - **NPC 平铺组**(21 句):单音色、**不做双性别**,平铺落 `web/abyss/audio/voice/<id>.{ogg,m4a}`(引擎平铺回退命中),转码时按 §电台滤波 加带通。船员共 4 人(≤5 约束),同一角色 speaker+instruct 恒定,区分度风险逐个标注:
|
||||
> | 角色 | speaker | instruct 常量 | 区分度风险 |
|
||||
> |---|---|---|---|
|
||||
> | 小舟(23 岁声呐兵,女) | `Serena` | `年轻女声,二十三岁声呐兵,缺氧后发虚,强撑着干脆` | **中**:与 female 玩家同 speaker,靠年龄感 instruct + 电台滤波(420-3200Hz)区分,请试听确认 |
|
||||
> | 老白(50 岁轮机长,男) | `Uncle_Fu` | `沙哑爽朗的中年男声,五十岁轮机长,忍着伤痛开玩笑` | **中**:与 male 玩家同 speaker,靠沙哑 instruct + 滤波(350-3000Hz)区分,请试听确认 |
|
||||
> | 陈医官(45 岁船医,女) | `Vivian` | `平静沙哑的中年女声,四十五岁船医,专业镇定,语气温和` | **低**:与 female 调度同 speaker 不同 instruct + 滤波(400-3100Hz),且从不同场 |
|
||||
> | 高船长(58 岁船长,男) | `Eric` | `低沉苍老的男声,五十八岁船长,疲惫克制,有老舵手的威严` | **低**:male 侧唯一 Eric + 滤波(300-2800Hz) |
|
||||
> - **电台滤波(转码侧)**:NPC 全部走带通+轻压缩(参数见上表,详表见 17-abyss.md §5.3/§6.1);DIVER/DECK 不滤波(母船级音质)——「电台里的人」与「耳机里的人」靠音质差立住。试听不可读的句子回退未滤波原声(宁窄勿脏)。
|
||||
> - **称呼规则**:船员对玩家一律称「救援员/你」,**全表禁用**「姑娘/小哥/大哥/大姐/叔叔」类性别化称呼(玩家性别随用户设置变化)。
|
||||
> - **键盘变体(PC 键盘通道,P1 机制)**:带 `_k` 后缀的 id 为键盘措辞版(「按空格」「回车」「左箭头/右箭头/上箭头/下箭头」),与触屏版**成对生成、成对落盘**(`check_all_assets` 校验 `_k` 配对);运行时由 `gesture.inputMode()` 选择:`key` → `<id>_k`,`touch` → `<id>`,`auto` 跟随最近使用通道,`_k` 缺失回退无后缀版。变体共 **11 对**,全部集中在下方 §G0 操作提示句区与 §D1 首个抉择(dv1_teach / p1),以粗体标注。
|
||||
> - **数字规避**:潜次/氧气全部分档整句(prog_d1..d4、oxy_full/ok/low/crit、oxy_gain);句内数字(三千米/三格/四潜/十二小时/四小时/一小时/三页)写死在整句里,禁止运行时拼接。
|
||||
> - **禁语速词**:instruct 不含任何语速描述(引擎 SoundTouch 变速);NPC 句靠短句+逗号停顿实现「水下慢半拍」听感。
|
||||
> - 管线:`tools/gen_voice_dual.py` 照录(SPEAKERS 表需新增 abyss 行);多音字自查见文末注记。
|
||||
|
||||
## G0 组 · 系统/向导/状态(DECK 双性别 ×37)
|
||||
|
||||
### G0.a 操作提示句(含键盘变体,9 对 18 句——键盘玩家听这一区就够)
|
||||
|
||||
| id | 台词全文 | 触发 |
|
||||
|---|---|---|
|
||||
| `gd_brief` | 单击继续简报。要选择时,向左或向右滑。 | 开场链最前(full 档,F8 先例) |
|
||||
| **`gd_brief_k`** | 按空格继续简报。要选择时,用左右方向键。 | 同上(inputMode=key) |
|
||||
| `gd_continue` | 单击屏幕,继续。 | 叙事链末看门狗第 1 级(full 25s / standard 13s) |
|
||||
| **`gd_continue_k`** | 按空格,继续。 | 同上(key) |
|
||||
| `gd_again` | 还在吗?单击继续。 | 看门狗第 2 级(50s / 30s),新句不逐字重播 |
|
||||
| **`gd_again_k`** | 还在吗?按空格继续。 | 同上(key) |
|
||||
| `gd_ping1` | 声呐待命。单击,发脉冲。 | 搜索等待静默 10s(第 1 级) |
|
||||
| **`gd_ping1_k`** | 声呐待命。按空格,发脉冲。 | 同上(key) |
|
||||
| `gd_ping2` | 回波不会自己来。单击。 | 搜索等待静默 25s(第 2 级,**必须与第 1 级不同句**) |
|
||||
| **`gd_ping2_k`** | 回波不会自己来。按空格。 | 同上(key) |
|
||||
| `sys_help` | 单击继续,双击重新听。上滑听状态,下滑开菜单。选择时,左右滑。 | 上滑帮助 / 菜单内上滑 |
|
||||
| **`sys_help_k`** | 空格继续,回车重新听。上箭头听状态,下箭头开菜单。选择时,左右箭头。 | 同上(key) |
|
||||
| `sys_menu` | 菜单。单击切换选项,双击确认。 | 下滑呼出模态菜单 |
|
||||
| **`sys_menu_k`** | 菜单。空格切换选项,回车确认。 | 同上(key) |
|
||||
| `sys_skip` | 想跳过这句,单击就行。 | 开场每局一次(skip_hint 先例) |
|
||||
| **`sys_skip_k`** | 想跳过这句,按空格。 | 同上(key) |
|
||||
| `sys_continue_ask` | 检测到你的下潜记录。单击继续上次,右滑开始新救援。 | 有存档进游戏 |
|
||||
| **`sys_continue_ask_k`** | 检测到你的下潜记录。空格继续上次,右箭头开始新救援。 | 同上(key) |
|
||||
|
||||
### G0.b 状态/系统句(无手势词,无变体)
|
||||
|
||||
| id | 台词全文 | 触发 |
|
||||
|---|---|---|
|
||||
| `gd_invalid` | 这个手势,水里用不上。 | 无效手势(error 震,idle-only,同局限次) |
|
||||
| `gd_prog1` | 滑动在这里用不上。想想调度刚说的话。 | 无进展轨 60s(第 1 级,乱按抢救) |
|
||||
| `gd_prog2` | 别乱。停一下,想想下一步。 | 无进展轨 120s(第 2 级) |
|
||||
| `sys_menu_resume` | 回到水下。 | 菜单项 |
|
||||
| `sys_menu_restart` | 重新开始这次救援。 | 菜单项 |
|
||||
| `sys_menu_lobby` | 保存并回大厅。 | 菜单项(确认后跳转前播) |
|
||||
| `sys_settings` | 音色、语速、背景音乐,请回大厅修改。 | 菜单内设置提示 |
|
||||
| `sys_new_dive` | 新的一次下潜,开始了。 | 新救援开始 / 菜单重开 |
|
||||
| `prog_d1` | 现在是第一次下潜。 | 上滑状态链(按当前潜次选播) |
|
||||
| `prog_d2` | 现在是第二次下潜。 | 同上 |
|
||||
| `prog_d3` | 现在是第三次下潜。 | 同上 |
|
||||
| `prog_d4` | 现在是最后一次下潜。 | 同上 |
|
||||
| `oxy_full` | 气瓶还足,救得动。 | 氧气 ≥9(跨档时挂上浮结算链;上滑状态链) |
|
||||
| `oxy_ok` | 氧气还够两潜。 | 氧气 6-8(floor(oxy/3)=2,句义逐格为真) |
|
||||
| `oxy_low` | 氧气告急,只够最后一潜。 | 氧气 3-5;此后垫 sfx/breath_loop |
|
||||
| `oxy_crit` | 氧气见底,必须上浮。 | 氧气 0-2;各播报位附 warning 震 |
|
||||
| `oxy_gain` | 应急瓶接上了,多三格。 | D2 上浮后补给(全局唯一一次) |
|
||||
| `dry_a` | 气瓶用干了。立刻上浮。 | mid-dive 氧气 floor 至 0,干涸链首句 |
|
||||
| `dry_b` | 气花在了人身上。人,都上来了。 | 干涸链归因句(真话:气耗在走心选择上) |
|
||||
|
||||
## G1 组 · 开场(双性别 ×4)
|
||||
|
||||
| id | 声部 | 台词全文 | 触发 |
|
||||
|---|---|---|---|
|
||||
| `b_open` | 潜航员 | 风停了。我站在问海号甲板上,下面三千米,是海燕号。 | INTRO(配 sfx/amb_deck) |
|
||||
| `b_rule` | 调度 | 规矩就一条:气不够一潜,人就必须上浮。 | INTRO(一句规矩,P4;与取消门一致) |
|
||||
| `b_goal` | 调度 | 海燕号,五个人。你的双瓶,够下四潜。 | INTRO(氧气预算承诺) |
|
||||
| `b_go` | 调度 | 第一潜,找船。耳朵交给声呐。 | INTRO,随后自动下潜 |
|
||||
|
||||
## D1 组 · 第一潜·找船·小舟(教学潜)(双性别 13 + 小舟平铺 5 = 18)
|
||||
|
||||
| id | 声部 | 台词全文 | 触发 |
|
||||
|---|---|---|---|
|
||||
| `dv1_down` | 调度 | 下潜开始。水会越来越黑,声音会越来越多。 | 下潜链(垫 sfx/amb_deep) |
|
||||
| `dv1_teach` | 调度 | 到深度了。声呐静了。单击,发一枚脉冲。 | 搜索等待武装(教「单击=脉冲」,配 turn cue) |
|
||||
| **`dv1_teach_k`** | 调度 | 到深度了。声呐静了。按空格,发一枚脉冲。 | 同上(key) |
|
||||
| `dv1_metal` | 调度 | 金属回波,钢板。听见这个,就是海燕号的船身。 | 首枚回波解读(**教「金属回波=钢板」,配 echo_metal_l**) |
|
||||
| `dv1_link` | 调度 | 回波后面有杂音,是电台!接通了。 | 通讯接通(配 link_beep) |
|
||||
| `z1_a` | 小舟 | ……有人吗?声呐兵,小舟。我们还活着,全艇五个人。 | 通话主干(垫 sfx/static_burst) |
|
||||
| `z1_b` | 小舟 | 轮机长老白困在机舱,陈医官和小郑在病舱,船长在指挥舱。 | 通话主干 |
|
||||
| `z1_knock` | 小舟 | 等等,你听。管子里,有人在敲。 | 线索音引入(**配 sfx/pipe_knock 两遍**) |
|
||||
| `p1` | 调度 | 管路在响。向左滑,停下来听敲管的暗号。向右滑,先带小舟上浮。 | 抉择提示(播完即可选) |
|
||||
| **`p1_k`** | 调度 | 管路在响。左箭头,停下来听敲管的暗号。右箭头,先带小舟上浮。 | 同上(key;首个抉择的键位绑定) |
|
||||
| `d1_listen` | 潜航员 | 都别出声。管子那头,敲得很稳。 | p1 左(knowsPipe=true,-1 气) |
|
||||
| `d1_code` | 调度 | 是老白的暗号:腿被压住,先泄压,再撬。记住这个敲法。 | p1 左·收(情报句,D2 兑现) |
|
||||
| `d1_up` | 潜航员 | 小舟,抓住我的肩锁。我们上。 | p1 右 |
|
||||
| `z1_bye` | 小舟 | 好。上面……是不是天亮了? | p1 右·反应 |
|
||||
| `p2` | 调度 | 小舟想回去拿声呐日志。向左滑,等她。向右滑,直接上浮。 | 抉择提示 |
|
||||
| `d1_log` | 小舟 | 日志里有失事前,最后一段录音。给你,替我们收好。 | p2 左(hasLog=true,-1 气) |
|
||||
| `d1_nolog` | 潜航员 | 日志可以补,人不能等。走了。 | p2 右 |
|
||||
| `d1_surf` | 调度 | 小舟出水,第一潜收工。往返,扣三格气。 | 上浮结算(配 surf_splash+ascent_chime;教「每潜扣 3」) |
|
||||
|
||||
## D2 组 · 第二潜·机舱·老白(双性别 14 + 老白平铺 4 = 18)
|
||||
|
||||
| id | 声部 | 台词全文 | 触发 |
|
||||
|---|---|---|---|
|
||||
| `dv2_down` | 调度 | 第二潜,机舱。顺着敲管的声音走。 | 下潜链 |
|
||||
| `dv2_found` | 调度 | 碎石回波后面,敲管声密了。机舱到了。 | 搜索解读(配 echo_debris+pipe_knock) |
|
||||
| `bai_a` | 老白 | 哈哈,救援的?我这腿,跟冷却管缠上了。 | 通话主干 |
|
||||
| `bai_b` | 老白 | 艇上的药板烧了。病舱那两个,比我悬。 | 通话主干(埋 D3 险) |
|
||||
| `p3` | 调度 | 钢梁压着腿。向左滑,泄压后慢慢撬。向右滑,切割枪,快切。 | 抉择提示 |
|
||||
| `d2_pry` | 潜航员 | 老白,忍住。先泄压,再撬。 | p3 左 |
|
||||
| `d2_pry_ok` | 调度 | 暗号没白听。管子一松,钢梁抬起来了。 | p3 左·收(**条件 knowsPipe=true,-0 气**) |
|
||||
| `d2_pry_slow` | 调度 | 摸着找泄压阀,多费了一格气。腿,出来了。 | p3 左·收(条件 knowsPipe=false,-1 气) |
|
||||
| `d2_cut` | 潜航员 | 切割枪。老白,闭眼,憋气。 | p3 右 |
|
||||
| `d2_flash` | 调度 | 火花炸了一下,虚惊。老白咳着,腿抽出来了。 | p3 右·收(**危机拍:danger 签名+spark_flash 前置 2s**) |
|
||||
| `bai_out` | 老白 | 腿还在!我的腿还在!走,我给你带路。 | 两路汇合(正反馈) |
|
||||
| `p4` | 调度 | 老白要去关电池舱阀门。向左滑,陪他去。向右滑,直接上浮。 | 抉择提示 |
|
||||
| `d2_valve` | 潜航员 | 电池舱我陪你去。这片海不能脏。 | p4 左(valve=true,-2 气;配 valve_close) |
|
||||
| `d2_valve_e` | 调度 | 阀门关死了。两格气,换一片干净海。 | p4 左·收(账目真实:明说两格) |
|
||||
| `bai_thanks` | 老白 | 这片海养着一村人。这份情,我记一辈子。 | p4 左·反应 |
|
||||
| `d2_leave` | 潜航员 | 阀门交给母船。你先上,腿要紧。 | p4 右 |
|
||||
| `d2_surf` | 调度 | 老白出水。他一直扒着舱门,往水里看。 | 上浮结算 |
|
||||
| `d2_supply` | 调度 | 潜友阿凯捎来应急瓶。甲板上,粥给你温着。 | 补给剧情(随后 oxy_gain +3,全局唯一) |
|
||||
|
||||
## D3 组 · 第三潜·病舱·陈医官/小郑(双性别 12 + 陈医官平铺 4 = 16)
|
||||
|
||||
> 小郑为无台词角色(重伤固定于吊床,radio 老主播「带子里只有电流声」先例);其状态由调度句 d3_chen_e/d3_stay_lost 承载。
|
||||
|
||||
| id | 声部 | 台词全文 | 触发 |
|
||||
|---|---|---|---|
|
||||
| `dv3_down` | 调度 | 第三潜,病舱。海燕号在倾斜,别恋战。 | 下潜链 |
|
||||
| `dv3_groan` | 调度 | 回波发闷。船体在呻吟,它撑不久了。 | 搜索解读(**配 echo_groan,D4 险预告**) |
|
||||
| `chen_a` | 陈医官 | 你来了。小郑股骨断了,我给他固定好了。 | 通话主干 |
|
||||
| `chen_b` | 陈医官 | 救援钟一次带一个。我是医生,我最后走。 | 通话主干(抉择铺垫) |
|
||||
| `p5` | 调度 | 病舱一次只能走一个。向左滑,先带陈医官。向右滑,先带小郑。 | 抉择提示(无气差的双义抉择) |
|
||||
| `d3_chen` | 潜航员 | 陈医官,你的手在抖。这次,听我的。 | p5 左(陈医官上,stayer=zheng) |
|
||||
| `chen_up` | 陈医官 | ……好。小郑,等我,上面给你热粥。 | p5 左·反应 |
|
||||
| `d3_chen_e` | 调度 | 陈医官出水。小郑固定在吊床上,呼吸平稳。 | p5 左·收 |
|
||||
| `d3_zheng` | 潜航员 | 小郑先走。陈医官,下一潜,就是你的。 | p5 右(小郑上,stayer=chen) |
|
||||
| `d3_zheng_e` | 调度 | 小郑吊上去了。他一路,都没敢出声。 | p5 右·收 |
|
||||
| `chen_stay` | 陈医官 | 去吧。我守着灯,灯不灭,人就不散。 | p5 右·留守宣言 |
|
||||
| `p6` | 调度 | 留守的人要空气。向左滑,留下你的备用瓶。向右滑,约定下一潜来接。 | 抉择提示 |
|
||||
| `d3_spare` | 潜航员 | 备用瓶留下。灯,给我亮着。 | p6 左(spareGift=true,-2 气,可触发干涸链) |
|
||||
| `d3_spare_e` | 调度 | 备用瓶挂上了,能多撑十二小时。 | p6 左·收(账目:时间量而非气格) |
|
||||
| `d3_promise` | 潜航员 | 四小时内,我下来。等我。 | p6 右 |
|
||||
| `d3_surf` | 调度 | 病舱的人出水。海燕号的呻吟,隔着水都听得见。 | 上浮结算(随后走氧气门) |
|
||||
|
||||
## D4 组 · 第四潜·指挥舱·高船长(高潮)(双性别 18 + 高船长 7 + 陈医官 1 = 26)
|
||||
|
||||
| id | 声部 | 台词全文 | 触发 |
|
||||
|---|---|---|---|
|
||||
| `dv4_none` | 调度 | 气不够一潜了。第四潜,取消。 | **氧气门·取消形态**(oxy≤2;800ms 手势死窗) |
|
||||
| `gao_final` | 高船长 | 别下来。带他们回家,就算救完了。海燕号,通话结束。 | 取消链·船长的最后通讯(随后直达 ◆p9) |
|
||||
| `dv4_down` | 调度 | 最后一潜,指挥舱。海燕号,撑不住了。 | 下潜链(双载/单载共用) |
|
||||
| `dv4_slide` | 调度 | 它滑了!抓稳索缆,指挥舱里还有人! | 搜索危机拍(**danger 签名+landslide 前置 2s 渐强+danger 震**) |
|
||||
| `gao_a` | 高船长 | 救援员。我船上,还剩两个活人。 | 通话主干 |
|
||||
| `gao_b` | 高船长 | 都带走,我最后上。这是船长的规矩。 | 通话主干 |
|
||||
| `p7` | 调度 | 双人上浮。向左滑,逐站减压慢慢浮。向右滑,违规直浮,搏一把。 | 抉择提示(**双载形态**:oxy≥4) |
|
||||
| `p7_chen` | 调度 | 气只够带一个。向左滑,带船长。向右滑,带陈医官。 | 抉择提示(**单载形态·留守=陈医官**:oxy=3) |
|
||||
| `p7_zheng` | 调度 | 气只够带一个。向左滑,带船长。向右滑,带小郑。 | 抉择提示(单载形态·留守=小郑) |
|
||||
| `d4_slow` | 潜航员 | 逐站停,慢慢浮。规矩不能破。 | p7 左·双载(-2 气) |
|
||||
| `d4_slow_e` | 调度 | 减压站一个个过。气瓶在跳,人稳着。 | p7 左·双载·收 |
|
||||
| `d4_fast` | 潜航员 | 来不及了。直浮! | p7 右·双载 |
|
||||
| `d4_fast_e` | 调度 | 违规快浮。医疗舱的灯,先给你们开好。 | p7 右·双载·收(回响伏笔) |
|
||||
| `d4_pick_gao` | 潜航员 | 船长,抓住我。海燕号的事,上面再说。 | p7 左·单载(带船长) |
|
||||
| `d4_pick_chen` | 潜航员 | 陈医官,轮到你了。抓住,上浮。 | p7 右·单载·留守=陈医官 |
|
||||
| `d4_pick_zheng` | 潜航员 | 小郑,吊床连人一起。走了。 | p7 右·单载·留守=小郑 |
|
||||
| `chen_last` | 陈医官 | 去吧。灯我留着,人齐了就熄。 | 单载·带走船长时留守者=陈医官的留别 |
|
||||
| `d4_stay_lost` | 调度 | 另一位,留在了倾斜的船舱。航标灯,替所有人亮着。 | 单载·带走船长时留守者=小郑的留别(克制措辞) |
|
||||
| `gao_last` | 高船长 | 航标灯替我留着。就说,船长睡了。 | 单载·带走留守者时船长的留别(p8 跳过,直达上浮) |
|
||||
| `gao_c` | 高船长 | 三年前……没什么。走吧,别耽误。 | 心结引入(**条件 hasLog=false**) |
|
||||
| `gao_confess` | 高船长 | 日志你拿了?里面写着。是我下令,多采了一小时。 | 心结引入(**条件 hasLog=true**,替代 gao_c) |
|
||||
| `p8` | 调度 | 船长的话没说完。向左滑,把你听到的说出来。向右滑,什么都不问,拉他上浮。 | 抉择提示(船长在乘时可 达,30 字全表最长句) |
|
||||
| `d4_talk` | 潜航员 | 日志我听完了。海燕号为什么沉,我会带上去。走吧。 | p8 左(gaoPeace=true) |
|
||||
| `gao_peace` | 高船长 | ……好。这一次,听救援员的。 | p8 左·反应 |
|
||||
| `d4_silent` | 潜航员 | 纪律就是纪律。抓住,上浮。 | p8 右 |
|
||||
| `d4_surf` | 调度 | 最后一潜收工。问海号的甲板,从没这么亮过。 | 上浮结算 |
|
||||
|
||||
## F9 组 · 签收抉择(心结)(双性别 ×7)
|
||||
|
||||
| id | 声部 | 台词全文 | 触发 |
|
||||
|---|---|---|---|
|
||||
| `g9_in` | 调度 | 医疗舱躺满了。你的气瓶剩多少,你比我清楚。 | 收队签收引入(SURFACE(4)/取消链之后) |
|
||||
| `g9_knot` | 潜航员 | 三年前,也是这条沟。我按时上浮了,搭档没有。 | 心结自述(玩家背景) |
|
||||
| `p9` | 调度 | 海燕号的船钟,还挂在沉船上。向左滑,用最后的气,下去取。向右滑,进医疗舱。 | 抉择提示(左路需 oxy≥1) |
|
||||
| `g9_dry` | 调度 | 一格气都不剩了。能带的,你都带回来了。 | **p9 左路封锁句**(oxy<1:播出后自动走右,不摆假选项) |
|
||||
| `d9_bell` | 潜航员 | 最后一潜。不为救人,为个交代。 | p9 左(bell=true;配 bell_toll 后接 d9_bello) |
|
||||
| `d9_bello` | 调度 | 船钟出水。海燕号的声音,回家了。 | p9 左·收 |
|
||||
| `d9_rest` | 潜航员 | 交代,留给明天的人。我去医疗舱。 | p9 右 |
|
||||
|
||||
## EP 组 · 结局与尾声回响(双性别 22;结局 8 + 回响 14)
|
||||
|
||||
| id | 声部 | 台词全文 | 触发 |
|
||||
|---|---|---|---|
|
||||
| `e1_a` | 潜航员 | 五个人都在甲板上。船钟的第一声,是替这条沟敲的。 | 结局 e1(saved=5 且 p9=左)主句 |
|
||||
| `e1_b` | 潜航员 | 三年了,我终于敢往下看。明天,想再潜一次。 | e1 收(钩子) |
|
||||
| `e2_a` | 潜航员 | 五个人都救上来了。船钟,留在了沟底。 | 结局 e2(saved=5 且 p9=右)主句 |
|
||||
| `e2_b` | 潜航员 | 没人怪我。可半夜醒来,总听见钟在响。 | e2 收(钩子) |
|
||||
| `e3_a` | 潜航员 | 没能都带回来。可我到底下去了,敲响了那口钟。 | 结局 e3(saved<5 且 p9=左)主句 |
|
||||
| `e3_b` | 潜航员 | 钟声替他们,在沟底响了一声。这样,也好。 | e3 收(钩子) |
|
||||
| `e4_a` | 潜航员 | 我按规矩上浮了。规矩里,没写怎么难过。 | 结局 e4(saved<5 且 p9=右)主句 |
|
||||
| `e4_b` | 潜航员 | 沟底很安静。安静得,像三年前那天。 | e4 收(钩子;心结回环) |
|
||||
| `ep_lead` | 调度 | 收队了。调度台给你记一笔——他们,后来怎样了。 | 结局链后尾声引入 |
|
||||
| `ep_zhou_ok` | 调度 | 小舟:归队报告打了三页。她说,声音都记得。 | 尾声(bond_zhou=1:p1 左或 p2 左) |
|
||||
| `ep_zhou_no` | 调度 | 小舟:声呐日志没了。她凭记忆,重新描了一遍海图。 | 尾声(bond_zhou=0) |
|
||||
| `ep_bai_ok` | 调度 | 老白:腿保住了。阀门那夜之后,见人就夸你。 | 尾声(bond_bai=1:p3 左或 p4 左) |
|
||||
| `ep_bai_no` | 调度 | 老白:腿打了钢钉。他说,瘸着也值。 | 尾声(bond_bai=0) |
|
||||
| `ep_chen_ok` | 调度 | 陈医官:回了医院。诊室里,挂着一盏海底的灯。 | 尾声(陈医官生还) |
|
||||
| `ep_chen_lost` | 调度 | 陈医官:她守着灯,到最后一小时。灯,还亮着。 | 尾声(陈医官留守未归) |
|
||||
| `ep_zheng_ok` | 调度 | 小郑:拆了石膏,第一件事,去看海。 | 尾声(小郑生还) |
|
||||
| `ep_zheng_lost` | 调度 | 小郑:吊床随船,滑进了沟底。他没来得及看日出。 | 尾声(小郑留守未归) |
|
||||
| `ep_gao_peace` | 调度 | 高船长:退役申请自己写的。第一行写着:数据不如人。 | 尾声(船长生还且 p8 左) |
|
||||
| `ep_gao_up` | 调度 | 高船长:上了岸,一直没说话。听说,他在学敲管语。 | 尾声(船长生还且 p8 右) |
|
||||
| `ep_gao_lost` | 调度 | 高船长:随海燕号留在沟底。航标灯,还亮着。 | 尾声(船长未归) |
|
||||
| `ep_trench_bell` | 调度 | 沟底:船钟挂在问海号桅杆上。风一过,就响一声。 | 尾声(bell=true) |
|
||||
| `ep_trench_deep` | 调度 | 沟底:很深,很静。海燕号睡在里面,像睡着了。 | 尾声(bell=false) |
|
||||
|
||||
---
|
||||
|
||||
**合计:148 句**(GPU 预算 ≤170 ✓)
|
||||
- 双性别 127 句(DIVER 潜航员 30 + DECK 调度/系统 97,含 `_k` 键盘变体 11)×2 性别 = 254 文件;
|
||||
- NPC 平铺 21 句(小舟 5 / 老白 4 / 陈医官 5 / 高船长 7)= 21 文件;
|
||||
- 合计 275 条音频 ×2 格式(ogg+m4a)= **550 文件**。
|
||||
- 键盘变体 11 对:gd_brief / gd_continue / gd_again / gd_ping1 / gd_ping2 / sys_help / sys_menu / sys_skip / sys_continue_ask / dv1_teach / p1(成对生成,`check_all_assets` 校验 `_k` 配对与双性别集合一致)。
|
||||
- 每结局专属台词齐备:e1/e2/e3/e4 各 2 句 + 尾声回响 14 句(好感/存活/flag 选播)。
|
||||
- 每局实走抉择 7-9 个(p7 单载右路跳过 p8;D4 取消路径跳过 p7/p8),抉择提示 p1..p9 共 9 个。
|
||||
|
||||
## 多音字 / 发音风险自查注记
|
||||
|
||||
| 风险词 | 处理 |
|
||||
|---|---|
|
||||
| 重听 | 全表写「重新听」(sys_help / sys_help_k),无「重听」字样;「重写」规避为「日志可以补」(d1_nolog) |
|
||||
| 壳(ké/qiào) | 全表不用「壳」,写「钢板 / 船身」(dv1_metal) |
|
||||
| 脏(zāng/zàng) | 「这片海不能脏」(d2_valve)为 zāng 正确常用读法,保留,试听确认 |
|
||||
| 闷(mēn/mèn) | 「回波发闷」(dv3_groan)为 mèn 常用读法,保留,试听确认 |
|
||||
| 颤(chàn/zhàn) | 台词侧用「发抖」(d3_chen);instruct 描述不进语音,不受影响 |
|
||||
| 塞 / 巷 / 挣 / 血 / 露 / 降(jiàng 外义)/ 率 / 传(zhuàn 义) | 全表未使用(「撑住」「股骨断了」替代;下潜 qián 恒用) |
|
||||
| 教(jiāo/jiào) | 未使用;「船长」zhǎng、「数据」shùjù、「调度」diàodù 为固定词 |
|
||||
| 了 / 还 / 得 | 常规句式常见读法,逐句人工试听项(d3_zheng_e「都没敢出声」、d1_surf「扣三格气」等) |
|
||||
| 数字 | 句内数字全部写死(三千米 / 三格 / 四潜 / 两格 / 十二小时 / 四小时 / 一小时 / 三页 / 一盏),序号与档位用分档整句(prog_d1..d4、oxy_*) |
|
||||
|
||||
## 台词侧自查
|
||||
|
||||
- 单句 ≤40 字:全表最长 = p8 与 p9(各 30 字),次长 sys_help_k(28 字)、p6(27 字)✓;NPC 句平均 ≤20 字(P4 语速感靠短句+逗号,不用 instruct 语速词)✓。
|
||||
- 船员 ≤4 人、speaker+instruct 恒定、区分度风险逐个标注 ✓(小舟 Serena / 老白 Uncle_Fu / 陈医官 Vivian / 高船长 Eric)。
|
||||
- 称呼合规:船员对玩家只用「救援员 / 你」,性别化称呼零出现 ✓。
|
||||
- 每个结局(e1..e4)专属主句+钩子各 2 句齐备,尾声救/未救双线齐备 ✓。
|
||||
- 归因真话律:负向收尾句(dry_b / gao_final / chen_last / d4_stay_lost / gao_last / ep_*_lost / e4_b)全部指向玩家实际选择或真实处境,无「运气不好」类假归因、无惩罚性措辞 ✓。
|
||||
- 向导 gd_* 13 句(gd_brief/gd_continue/gd_again/gd_ping1/gd_ping2 各带 _k 变体,gd_invalid/gd_prog1/gd_prog2 无变体)符合 14 号 §6 台词规范(一句一义、无重复句式、单句 ≤18 字)✓。
|
||||
- 氧气档位句与数值一一对应(oxy_full≥9 / ok=6-8 / low=3-5 / crit=0-2,均按 floor(oxy/3) 可下潜次数措辞),账目真实 ✓。
|
||||
@@ -0,0 +1,490 @@
|
||||
# 17 · 《深海回音》(abyss) — 深海救援叙事 RPG 设计文档
|
||||
|
||||
> **给开发的实现要点摘要**
|
||||
> 1. 叙事模式(声命线范式,radio 同骨架):节点链 onComplete 串行 + seqToken 打断作废 + pendingChoice 缓存;复制 `web/radio/` 结构起步,状态机 6 宏状态(INTRO/DIVE/COMMS/SURFACE/ENDING + MENU 覆盖层)。
|
||||
> 2. 手势零豁免:全部走全局默认映射(单击=继续/**检查(搜索等待=发声呐脉冲,宪法 §5.1「检查」义,escape 先例)**/跳句、双击=重听、左右滑=抉择、上滑=状态、下滑=模态菜单、长按=引擎快进)。
|
||||
> 3. 台词依据 [17-abyss-voice-ids.md](17-abyss-voice-ids.md)(148 句:双性别 127 + 平铺 NPC 21);NPC 水声电台滤波在**资产侧** ffmpeg 带通(radio 先例),引擎零改动。
|
||||
> 4. 氧气=步进资源非实时倒计时:只在潜次边界与阈值跨越时播报(分档整句、账目真实);软失败=「被迫取消第四潜/单载」而非玩家死亡,结算链完整播出(含 800ms 手势死窗)。
|
||||
> 5. 声呐双通道:回波类信息音与语音**绝不重叠**(游戏层 sonarGate 空闲门,R1 规则 §6.2);并发声流 ≤2。
|
||||
> 6. 章程任务 N2(research/new8/00-program.md §2):单局 15-25 分钟、9 抉择点(实走 7-9)、4 结局、分支局部化。
|
||||
> 7. 断言清单住本文档 §9(radio §20 先例);13 号文档已登记指针(§21)。
|
||||
|
||||
## 1. 概述
|
||||
|
||||
- **一句话**:你是深潜救援员,声呐里是被困海沟的潜艇「海燕号」——氧气在倒数,每次下潜都是抉择:先救谁、花多少气、留不留、上不上去。
|
||||
- **题材(声音即世界)**:黑暗深海里视觉归零,**声呐回波=空间、电台人声=生命、氧气=代价**——「用耳朵救人」与纯音频载体天然同构。声呐脉冲/回波/管路敲击/船体呻吟是叙事本体,不是装饰。
|
||||
- **单局**:一次完整救援(一条抉择路径)20-22 分钟;四次下潜共享主干,分歧局部化在每潜内部;9 个抉择点(单局实走 7-9 个),4 结局。
|
||||
- **核心循环**:下潜(声呐搜索拍:单击发脉冲→回波→调度解读)→ 通讯(船员对话+抉择)→ 带人上浮 → 水面结算(氧气扣账+档位播报)→ 下一潜。跨潜积累氧气存量与船员生死/好感,最后一潜的氧气余量决定救援形态(双载/单载/取消),收队前 p9 决定你自己的心结。
|
||||
- **与 radio 的差异点**(骨架同、压力源不同):radio 零压力(口碑只涨不跌);abyss 引入**氧气稀缺**——但全部宽限化:无实时倒计时、无中途死亡、软失败只损失「机会」不损失「已有」、最优省气路径恰好全员生还(P4 友好默认)。
|
||||
|
||||
## 2. 状态机
|
||||
|
||||
### 2.1 状态列表
|
||||
|
||||
| 状态 | 内容 | BGM | guide.state |
|
||||
|---|---|---|---|
|
||||
| `INTRO` | 开场链:甲板口播 + 一句规矩 + 今晚目标 | `bgm/deck` | explore |
|
||||
| `DIVE` | 下潜过程:下潜链(auto)→ 搜索等待(单击=发脉冲,声呐主导)→ 回波+接通 | `bgm/dive` | explore;搜索等待由 turn cue 承担 |
|
||||
| `COMMS` | 通讯叙事:船员对白链 + 抉择点 + 结果 | `bgm/comms` | explore;抉择点=choice |
|
||||
| `SURFACE` | 上浮结算:出水确认 + 氧气扣账/档位 + 补给(D2 后),自动链 | `bgm/deck` | settle |
|
||||
| `ENDING` | 结局链 + 尾声回响(epilogue),结算态 | `bgm/ending` | settle |
|
||||
| `MENU` | 模态覆盖层(任意叙事态下滑呼出,暂停一切链) | `bgm/deck`(低响度淡入) | menu |
|
||||
|
||||
### 2.2 转移图(文本)
|
||||
|
||||
```
|
||||
┌──────────── 结算单击=新救援 ─────────────┐
|
||||
▼ │
|
||||
INTRO ──链完单击──> DIVE(1) ──脉冲找到──> COMMS(1) ──链完──> SURFACE(1) ─┤→ DIVE(2)
|
||||
│下潜链 auto;搜索等待=单击脉冲 │ …(D2/D3 同型)…
|
||||
└─────────────────────────────────────────┘
|
||||
SURFACE(3) ──氧气门──┬─ oxy≥4: DIVE(4 双载) ──链完──> SURFACE(4) ──链完──> 签收 ◆p9
|
||||
├─ oxy=3: DIVE(4 单载: p7_chen|p7_zheng) ──链完──> SURFACE(4) ─┘
|
||||
└─ oxy≤2: 终局取消链(dv4_none→gao_final) ─────────────────────┘
|
||||
▼
|
||||
d9 结果链 ──> ENDING(e1..e4 + ep 回响链)
|
||||
|
||||
任意叙事态(INTRO/DIVE/COMMS/SURFACE/ENDING):下滑 → MENU(模态)
|
||||
MENU:单击=循环切换选项 → 双击=确认执行 → 上滑=帮助 → 下滑/「回到水下」项=关闭回原状态(重播当前节点)
|
||||
```
|
||||
|
||||
- INTRO/DIVE/COMMS/SURFACE/ENDING 均为节点链驱动(radio playNode 模式);下潜链与上浮结算链 `auto:true`,COMMS 叙事节点链末等待单击(radio 实现核对 #1 同口径)。
|
||||
- SURFACE 自动链 ≤15s:扣账句(d*_surf)→ 补给句(仅 D2 后)→ 档位句(跨档才播)→ 直接进下一 DIVE;第四潜位置由**氧气门**分三形态(§4.3)。
|
||||
- 终局取消链与结局链入口处盖 `_settleGraceUntil = now+800ms` 手势死窗(dungeon H1 热修同款),窗内手势一律吞掉,结算链完整播出。
|
||||
- MENU 打开时 `guide.disarm()` + 取消一切看门狗/自动链;关闭后重播当前节点(局面复述,radio closeMenu 先例)。
|
||||
|
||||
### 2.3 每状态手势映射(6+2 全覆盖,零豁免)
|
||||
|
||||
| 手势 | INTRO | DIVE(下潜/搜索) | COMMS | SURFACE | ENDING | MENU |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 上滑 | 帮助+状态,随后重播当前段 | 帮助+状态(潜次+氧档),留在搜索等待 | 帮助+状态,随后重播当前节点 | 帮助+状态,自动链继续 | 帮助+状态(结局名+氧档) | 帮助(sys_help) |
|
||||
| 下滑 | 模态菜单 | 模态菜单 | 模态菜单 | 模态菜单 | 模态菜单 | 关闭菜单 |
|
||||
| 左滑 | 无效 → error 震+gd_invalid | 无效 → gd_invalid(喂无进展轨) | 抉择=左 | 无效 → gd_invalid | 无效 → gd_invalid | 无效 → error 震 |
|
||||
| 右滑 | 无效 → gd_invalid | 无效 → gd_invalid(喂无进展轨) | 抉择=右;ASK 态=新救援 | 无效 → gd_invalid | 无效 → gd_invalid | 无效 → error 震 |
|
||||
| 单击 | 播放中=跳过本句;链末=开始下潜 | 播放中=跳过本句;**搜索等待=发一枚声呐脉冲** | 播放中=跳过本句(p* 不可跳);链末=继续 | 跳过本句(自动链) | **再来一局**(新救援) | 循环切换选项 |
|
||||
| 双击 | 重听当前段 | **重听上一条回波+其解读句**(尚无回波=无效,首潜前零静默) | 重听当前节点台词(含抉择提示) | 重听结算链 | 重听结局链 | **确认执行**(菜单约定覆盖重听) |
|
||||
| 长按 | 引擎接管:旁白临时 1.7×(12 号 §2.2,叙事类不豁免) | 同左 | 同左 | 同左 | 同左 | 同左(快进菜单语音) |
|
||||
| 长按松开 | 引擎接管:恢复 settings.speed | 同左 | 同左 | 同左 | 同左 | 同左 |
|
||||
|
||||
- 豁免登记:**无**。六个基础手势全部符合全局宪法默认语义——单击在搜索等待=「检查」(宪法 §5.1 原文即含检查,escape 检查房间同款);菜单走 §5.2 R3 模态约定(单击循环+双击确认)。
|
||||
- ASK(存档询问态,radio 同款):单击=继续上次 / 右滑=新救援;上滑/下滑/左滑/双击=无效(error 震+gd_invalid)。
|
||||
- 抉择 prompt(voice/p1..p9)播放中单击不可跳(PROMPT_RE 门)、左右滑缓存 `pendingChoice` 播完即生效(radio W2 契约照抄)。
|
||||
- 继承 radio G5 跳过公平契约原文:**首播必完整(p* 首播不可跳 / 链末关键句保护 / ASK 恢复首句锁)、复播可即掐(锁不随复播重新武装、链中段句可跳、复播滑动照常预缓存)**;p* 复播(双击重听/看门狗复述)仍不可跳、句尾生效。
|
||||
- 无效手势零静默:所有「无效」格均有 error 震 + gd_invalid(onceKey 同局限次,F1.4 idle-only:语音在播时跳过语音只发震)。
|
||||
- 键盘通道:三通道并行,游戏代码零改动;操作提示句按 `inputMode()` 选 `_k` 变体资产(§7.3、voice-ids 集中分组)。
|
||||
|
||||
## 3. 抉择树
|
||||
|
||||
### 3.1 全局骨架(四潜共享主干,分歧局部化)
|
||||
|
||||
```
|
||||
INTRO: b_open → b_rule → b_goal → b_go ──> 下潜①
|
||||
【D1 找船·教学潜】救小舟 · 2 抉择(p1/p2)──> SURFACE(1) ──> 下潜②
|
||||
【D2 机舱·老白】危机拍#1 · 2 抉择(p3/p4)──> SURFACE(2·补给+3) ──> 下潜③
|
||||
【D3 病舱·生死抉择】回波预警 · 2 抉择(p5/p6)──> SURFACE(3) ──氧气门──> 下潜④ 或 终局取消链
|
||||
【D4 指挥舱·高潮】滑坡危机 · p7(双形态)+ p8 ──> SURFACE(4) ──> 签收 ◆p9(心结)──> ENDING
|
||||
```
|
||||
|
||||
分支纪律:**每潜内部分支、上浮时收敛**到结算句 → SURFACE;跨潜只传标量(oxy、saved{}、stayer、5 个 flag),不生成组合节点。最坏路径与最好路径节点数同型(剧本 A 与剧本 C 深度相同)。
|
||||
|
||||
### 3.2 分潜结构(◆=抉择点,〔〕=条件差分)
|
||||
|
||||
```
|
||||
【D1 找船·小舟】(教学潜)
|
||||
下潜链 dv1_down → dv1_teach →【搜索等待:单击脉冲】→ echo_metal_l + dv1_metal(教「金属回波=钢板」)
|
||||
→ dv1_link → COMMS: z1_a → z1_b → z1_knock(垫 pipe_knock)→ ◆p1
|
||||
├左 听暗号: d1_listen → pipe_knock → d1_code(knowsPipe=true,-1 气)─┐
|
||||
└右 直接上: d1_up → z1_bye ─────────────────────────────────────────┤
|
||||
▼
|
||||
小舟拉住你 → ◆p2
|
||||
├左 等日志: d1_log(hasLog=true,-1 气)─┐
|
||||
└右 不等: d1_nolog ────────────────────┴→ 上浮 → d1_surf(扣 3 格)→ 档位 → SURFACE(1)
|
||||
|
||||
【D2 机舱·老白】
|
||||
dv2_down →【搜索:脉冲 → echo_debris+pipe_knock → dv2_found】→ bai_a → bai_b → ◆p3
|
||||
├左 泄压慢撬: d2_pry →〔knowsPipe ? d2_pry_ok(-0): d2_pry_slow(-1)〕─┐
|
||||
└右 切割快切: d2_cut →【危机拍: danger 签名+spark_flash 前置 2s】→ d2_flash ─┤
|
||||
▼
|
||||
bai_out → ◆p4
|
||||
├左 陪关阀门: d2_valve → valve_close → d2_valve_e(valve=true,-2)→ bai_thanks ─┐
|
||||
└右 直接上浮: d2_leave ──────────────────────────────────────────────────────────┴→ d2_surf
|
||||
→ d2_supply + oxy_gain(应急瓶+3,全局唯一一次)→ 档位 → SURFACE(2)
|
||||
|
||||
【D3 病舱·陈医官/小郑(小郑无台词,吊床固定)】
|
||||
dv3_down →【搜索:脉冲 → echo_groan → dv3_groan(船体呻吟预警)】→ chen_a → chen_b → ◆p5
|
||||
├左 先带陈医官: d3_chen → chen_up → d3_chen_e(小郑留守)─┐
|
||||
└右 先带小郑: d3_zheng → d3_zheng_e → chen_stay(stayer=chen)┤
|
||||
▼
|
||||
◆p6
|
||||
├左 留备用瓶: d3_spare → d3_spare_e(spareGift=true,-2,floor 至 0 触发干涸链)─┐
|
||||
└右 约定来接: d3_promise ────────────────────────────────────────────────────────┴→ d3_surf → 档位 → SURFACE(3)
|
||||
|
||||
【SURFACE(3) 氧气门】oxy≥4 → D4 双载 | oxy=3 → D4 单载 | oxy≤2 → 终局取消链(dv4_none → gao_final,800ms 死窗)→ ◆p9
|
||||
|
||||
【D4 指挥舱·高船长】
|
||||
dv4_down →【搜索:脉冲 → echo_groan 渐强 → 危机拍: danger+landslide 前置 2s → dv4_slide】→ gao_a → gao_b
|
||||
双载形态 → ◆p7(快慢浮)
|
||||
├左 慢浮: d4_slow → d4_slow_e(-2)─┐
|
||||
└右 快浮: d4_fast → d4_fast_e ──────┤
|
||||
单载形态 → ◆p7_chen|p7_zheng(按 stayer 选提示,谁上)
|
||||
├左 带船长: d4_pick_gao →〔stayer=chen ? chen_last : d4_stay_lost〕─┐
|
||||
└右 带留守者: d4_pick_chen|d4_pick_zheng → gao_last(p8 跳过)─────┴→ 直达 d4_surf
|
||||
▼(船长在乘时)
|
||||
〔hasLog ? gao_confess : gao_c〕→ ◆p8
|
||||
├左 说出来: d4_talk → gao_peace(gaoPeace=true)─┐
|
||||
└右 不问: d4_silent ────────────────────────────┴→ d4_surf → 档位 → SURFACE(4)
|
||||
|
||||
【签收】g9_in → g9_knot → ◆p9
|
||||
├左 取船钟(需 oxy≥1): d9_bell → bell_toll → d9_bello(bell=true)─┐
|
||||
└右 进医疗舱: d9_rest ────────────────────────────────────────────────┤
|
||||
〔oxy<1 时左路封锁: g9_dry 播出后自动走右,不摆假选项〕 ▼
|
||||
ENDING: e*_a → e*_b(按 savedCount × p9 四选一)→ ep_lead → ep_*(按好感/存活/flag 选播)
|
||||
```
|
||||
|
||||
### 3.3 分支局部化说明
|
||||
|
||||
- 跨潜状态全部是标量:`oxy`(int)、`saved`(5 个 0/1)、`stayer`(null/chen/zheng)、flag 5 个(knowsPipe/hasLog/valve/spareGift/gaoPeace)+ p9 派生 bell。没有任何「潜 i 分支 × 潜 j 分支」组合节点。
|
||||
- 条件差分全部是**节点内选播**(radio w1_say/w1_say2 先例):d2_pry_ok/slow(knowsPipe)、gao_c/gao_confess(hasLog)、p7 双/单形态(氧气门)、p7_chen/p7_zheng 与留别句(stayer)、ep_* 选播。树形不变。
|
||||
- 树规模:148 句台词、约 70 个节点;任一路径实走 7-9 个抉择点(D4 取消路径少 p7/p8;单载右路少 p8)。
|
||||
|
||||
### 3.4 四结局达成条件
|
||||
|
||||
| 结局 | 条件 | 主题 | 开环钩子 |
|
||||
|---|---|---|---|
|
||||
| e1 海燕归钟 | saved=5 且 p9=左 | 全员生还+船钟出水,告别完整 | 「明天,想再潜一次」 |
|
||||
| e2 满载的黎明 | saved=5 且 p9=右 | 人都救回来了,钟留在沟底 | 「半夜总听见钟在响」 |
|
||||
| e3 最后一潜 | saved<5 且 p9=左 | 没能都救回,但下去敲响了钟 | 「钟声替他们响了一声」 |
|
||||
| e4 按规程上浮 | saved<5 且 p9=右 | 规程之内,难过之外 | 「安静得像三年前那天」 |
|
||||
|
||||
- 尾声回响(P2 回响感):epilogue 逐人点名——小舟/老白/陈医官/小郑/船长各按「好感/生死」双线播(voice-ids EP 组),沟底一句按 bell 二选一;玩家每一潜的救与错过都被点名(radio ep_* 同款)。
|
||||
|
||||
## 4. 数值设计
|
||||
|
||||
### 4.1 变量
|
||||
|
||||
| 变量 | 类型 | 初值 | 说明 |
|
||||
|---|---|---|---|
|
||||
| `oxy`(氧气格) | int | 12 | 步进资源:只在事件点扣(下潜/抉择),无实时倒计时 |
|
||||
| `saved` | map | zhou:0 其余 0 | 小舟/老白/陈医官/小郑/高船长 各 0/1 |
|
||||
| `stayer` | str | null | p5 后留守病舱者('chen'/'zheng') |
|
||||
| `knowsPipe/hasLog/valve/spareGift/gaoPeace/bell` | bool | false | p1 左/p2 左/p4 左/p6 左/p8 左/p9 左 置位 |
|
||||
| `supply` | bool | false | D2 上浮后应急瓶已发(全局唯一) |
|
||||
| `endings{}` / `runs` | map/int | — | 结局收集与重玩计数(存档展示用) |
|
||||
|
||||
### 4.2 抉择计分表(左=走心·多花气 / 右=克制·省气)
|
||||
|
||||
| 抉择 | 左(走心) | 右(克制) | 备注 |
|
||||
|---|---|---|---|
|
||||
| p1 听暗号/直接上 | -1 气,knowsPipe=true | 0 | 左路获 D2 情报(下潜 EFF 的唯一免气左路) |
|
||||
| p2 等日志/不等 | -1 气,hasLog=true | 0 | hasLog 兑现 D4 船长坦白差分 |
|
||||
| p3 慢撬/快切 | knowsPipe?0:-1 气 | 0 | 右路挂危机拍#1(火花虚惊,两路都活着) |
|
||||
| p4 关阀门/直接走 | -2 气,valve=true | 0 | 左路兑现在回响(干净海) |
|
||||
| p5 先带医官/先带小郑 | 0(chen 上,stayer=zheng) | 0(zheng 上,stayer=chen) | 唯一无气差的双义抉择;stayer 决定 D4 单载差分 |
|
||||
| p6 留备用瓶/约定来接 | -2 气,spareGift=true(可触发干涸链) | 0 | 左路兑现在留守者存活回响 |
|
||||
| p7 慢浮/快浮(双载) | -2 气 | 0 | 右路兑现在 e1/e2 回响(医疗舱灯) |
|
||||
| p7 带船长/带留守者(单载) | 0 | 0 | 另一人随海燕号滑入沟底(措辞克制) |
|
||||
| p8 说出来/不问 | 0,gaoPeace=true | 0 | hasLog 时 gao_confess 差分前置 |
|
||||
| p9 取船钟/进医疗舱 | 需 oxy≥1,bell=true | 0 | oxy<1 时左路封锁(g9_dry,不摆假选项) |
|
||||
|
||||
### 4.3 氧气经济(单位/消耗/宽限/软失败)
|
||||
|
||||
| 项 | 规则 |
|
||||
|---|---|
|
||||
| 单位 | 「格」(内部 int)。初始 12(叙事=双瓶满气,够四次往返);D2 上浮后应急瓶 +3(`oxy_gain` 播报,全局唯一),总预算 15 |
|
||||
| 固定消耗 | 每次下潜开始扣 3(往返);D4 双载额外 +1(慢浮+减压成本按 p7 计) |
|
||||
| 抉择消耗 | 见 §4.2;**mid-dive 扣至负数一律 floor 到 0**,不中断当前救援(人已挂上吊索,照常带上) |
|
||||
| 阈值播报 | 分档整句(下表),**只在跨档时播**(挂上浮结算链尾);上滑 status 随时可查;oxy_crit 各播报位附 warning 震(radio G2 同款) |
|
||||
| 第四潜氧气门 | SURFACE(3) 结算时:oxy≥4 → 双载(带船长+留守者);oxy=3 → 单载(p7 谁上);oxy≤2 → **终局取消链**(第四潜取消,船长与留守者随海燕号滑入沟底——措辞克制、零描写) |
|
||||
| 宽限设计 | ① 学习期零惩罚:D1 两个左路合计 -2,恰好被 D2 后应急瓶 +3 兜底,教学潜永不亏局;② 到点不是死:软失败只损失「机会」(少带一人/少下一潜),已救上的人**永不失去**;③ 无实时倒计时、无 mid-dive 打断(P4 无高压);④ p9 左路是「氧气的礼物」——省下的气兑换终局抉择 |
|
||||
| 干涸链(软失败结算) | mid-dive floor 至 0 触发:dry_a →(当前救援照常完成)→ 上浮结算内 dry_b(归因真话:指向实际花掉最后两格的那个左选择)。链入口 800ms 手势死窗 |
|
||||
|
||||
**氧气档位表(账目真实:每格取值下句义皆为真)**
|
||||
|
||||
| 档 | oxy 区间 | 整句 | 真实性核验 |
|
||||
|---|---|---|---|
|
||||
| full | ≥9(floor(oxy/3)≥3) | 「气瓶还足,救得动。」 | ≥3 潜气量 ✓ |
|
||||
| ok | 6-8(floor=2) | 「氧气还够两潜。」 | 恰可下 2 潜 ✓ |
|
||||
| low | 3-5(floor=1) | 「氧气告急,只够最后一潜。」 | 恰可下 1 潜 ✓ |
|
||||
| crit | 0-2(floor=0) | 「氧气见底,必须上浮。」 | mid-dive=必须上浮 ✓ / 水面=一潜都下不去 ✓ |
|
||||
|
||||
- 档位以 `floor(oxy/3)`(可下潜次数)划界而非绝对半数——**句子说的就是判定用的**(radio rep_low 教训内化:措辞与数值对得上)。
|
||||
- 低氧混音签名:tier=low/crit 期间 DIVE/COMMS 垫 `breath_loop`(低响度呼吸声,SA3 循环);引擎无运行时滤波,BGM 闷化降级为该呼吸层(显式降级,不阻塞管线)。
|
||||
|
||||
### 4.4 船员好感/存活矩阵
|
||||
|
||||
| 船员 | 好感来源(bond) | 存活条件 | 回响句 |
|
||||
|---|---|---|---|
|
||||
| 小舟(声呐兵) | p1 左 或 p2 左 | **恒活**(D1 教学潜保底救上) | ep_zhou_ok / ep_zhou_no |
|
||||
| 老白(轮机长) | p3 左 或 p4 左 | **恒活**(D2 恒可成——预算数学保证,见 §9 验算) | ep_bai_ok / ep_bai_no |
|
||||
| 陈医官 | p5 左(当场救上);或留守时 p6 左 | p5 左即活;p5 右留守 → D4 双载或被选则活,否则失 | ep_chen_ok / ep_chen_lost |
|
||||
| 小郑(无台词角色) | —(吊床上的沉默存在,radio 老主播「带子里只有电流声」先例) | p5 右即活;p5 左留守 → D4 双载或被选则活,否则失 | ep_zheng_ok / ep_zheng_lost |
|
||||
| 高船长 | p8 左(gaoPeace) | D4 双载 或 单载选左则活;单载右/终局取消则失 | ep_gao_peace / ep_gao_up / ep_gao_lost |
|
||||
|
||||
- 好感只影响回响选播(情绪差分),**不影响结局判定**——结局由 savedCount × p9 决定,账目单一可验算。
|
||||
- 生死分支覆盖 3 人(陈医官/小郑/高船长),措辞全部克制(「滑进了沟底」「灯还亮着」),无临场描写;失败归因走干涸链/取消链的真话句。
|
||||
|
||||
### 4.5 氧气收支验算(设计期穷举,playtest 剧本 A-D 引用)
|
||||
|
||||
设 `lefts` = 前 3 潜左路气耗之和(p7/p9 不在前 3 潜):
|
||||
|
||||
- SURFACE(3) 时 oxy = 15 − 9(基础)− lefts = **6 − lefts** → 双载 ⟺ lefts≤2;单载 ⟺ lefts=3;取消 ⟺ lefts≥4。
|
||||
- 双载收队 oxy_end = 2 − lefts(p7 右)或 0 −(lefts−2)(p7 左,floor 0)→ p9 左可用 ⟺ lefts≤1。
|
||||
- 单载收队 oxy_end = 3 − lefts = 0(lefts=3)→ p9 左恒封锁 → 单载路径必 e4。
|
||||
- 取消收队 oxy_end = 6 − lefts ∈ {2,1,0}(lefts=4,5,≥6)→ lefts≤5 时 p9 左可用 → e3。
|
||||
- 前 3 潜恒可完成的预算证明:D1 最大支出 5(12→7);D2 最大支出 6(7→1)后应急瓶 +3(→4)≥3 ✓;D3 恒可下(最差 4→1,p6 左 floor 0 走干涸链)✓。**教学潜与机舱潜永不被氧气卡死**(P4)。
|
||||
|
||||
## 5. 音频三层映射
|
||||
|
||||
### 5.1 BGM(状态→曲目,Mureka instrumental,4 首 ≈ $0.12)
|
||||
|
||||
| 状态 | 曲目 | 切换 | Mureka prompt 草稿(英文,seamless loop) |
|
||||
|---|---|---|---|
|
||||
| INTRO/SURFACE/MENU | `bgm/deck` | 开局淡入 800ms;MENU 呼出低响度淡入 500ms | "Night sea surface from a rescue ship deck, sparse cello and low piano over gentle waves, distant rigging creak and engine hum, melancholic but purposeful, no vocals, seamless loop, 60-90 seconds" |
|
||||
| DIVE | `bgm/dive` | crossfade 800ms 进;接通 COMMS 淡至 comms 600ms | "Deep ocean descent ambience, dark ambient drone with a slow sonar-like pulse, immense water pressure, distant whale-like tones, subtle tension, no vocals, seamless loop, 60-90 seconds" |
|
||||
| COMMS | `bgm/comms` | crossfade 600ms;上浮淡回 deck | "Underwater radio contact scene, warm muted piano over a deep water drone, faint hydrophone static, intimate and quietly hopeful, no vocals, seamless loop, 60-90 seconds" |
|
||||
| ENDING | `bgm/ending` | p9 结果链播完后淡入 1500ms | "Dawn on the sea after a deep sea rescue, warm strings and soft piano, exhausted hope and quiet triumph, no vocals, seamless loop, 60-90 seconds" |
|
||||
|
||||
- `bgm=0` 时全部静默(引擎约定);menu 用 deck 同曲(省 1 首,海面场景同构);共性后缀(10 号 §8)照 radio 追加。
|
||||
|
||||
### 5.2 SFX 清单(SA3=Stable Audio 3 / SYN=程序合成;one-shot 真峰值 ≤-3dBFS;amb 循环由游戏层 `buffer.loop` 实现,radio phone_ring 先例)
|
||||
|
||||
| id | 用途 | 来源 | prompt(英文)/ 合成参数 |
|
||||
|---|---|---|---|
|
||||
| `sfx/sonar_ping` | 你发出的声呐脉冲(搜索单击) | SYN | 1.4→0.9kHz 正弦 chirp 220ms,指数衰减,-6dBFS(回波家族统一音头) |
|
||||
| `sfx/echo_metal_l` / `_r` | 钢板回波(左/右声像;「金属回波=海燕号」承诺音) | SA3 | "Sonar echo returning from a steel submarine hull, resonant metallic ping with slow decay, panned slightly left(→right), underwater, 2 seconds" |
|
||||
| `sfx/echo_debris` | 碎石回波(D2 机舱外) | SA3 | "Sonar echo returning from an underwater rubble and debris field, diffuse granular reverberation, 2 seconds" |
|
||||
| `sfx/echo_groan` | 船体呻吟(D3 预警/D4 滑坡前奏,可变增益复用) | SA3 | "Stressed submarine hull groaning deep underwater, long metallic moan under immense pressure, 4 seconds" |
|
||||
| `sfx/pipe_knock` | 管路敲击暗号(老白 SOS) | SYN | 三短三长三短固定节拍金属敲击(节拍精确可复现、断言可数) |
|
||||
| `sfx/link_beep` | 电台接通 | SYN | 双音上行 0.3s |
|
||||
| `sfx/static_burst` | 通讯静电/断续 | SA3 | "Shortwave radio static burst with faint ghost of a distorted voice, 2 seconds" |
|
||||
| `sfx/amb_deep` | 深潜底噪 loop | SA3 | "Deep ocean ambient loop, low pressure hum, distant current wash, occasional far creak, seamless loop" |
|
||||
| `sfx/amb_deck` | 甲板底噪 loop(风+浪+缆绳) | SA3 | "Night ship deck ambience, wind, gentle waves against hull, distant rigging creak and engine hum, seamless loop" |
|
||||
| `sfx/breath_loop` | 低氧呼吸 loop(仅 low/crit 档垫,混音签名) | SA3 | "Slow scuba regulator breathing loop, calm but slightly labored, underwater, seamless loop" |
|
||||
| `sfx/spark_flash` | D2 危机拍:切割火花+氢气虚惊 | SA3 | "Underwater cutting torch sparks with a brief muffled gas pop, 2 seconds" |
|
||||
| `sfx/valve_close` | 重阀关闭(p4 左) | SA3 | "Heavy submarine valve wheel shutting, metal rotation clunk and water seal, 2 seconds" |
|
||||
| `sfx/landslide` | D4 危机拍:海底滑坡轰鸣(前置 2s 渐强) | SA3 | "Underwater landslide rumble, rolling sediment and rocks, ominous low roar building, 4 seconds" |
|
||||
| `sfx/surf_splash` | 破水出水(每潜上浮) | SA3 | "Diver breaking through the sea surface, splash and one gasp, 2 seconds" |
|
||||
| `sfx/ascent_chime` | 出水确认音 | SYN | 上行三音琶音 0.4s |
|
||||
| `sfx/bell_toll` | 船钟(p9 左 payoff 音) | SA3 | "Old ship brass bell, single clean toll with warm resonance, 3 seconds" |
|
||||
| `sfx/ui_confirm` / `ui_menu` | 菜单/确认(程序合成兜底) | SYN | 同全局先例 |
|
||||
|
||||
- 预警窗纪律:D2 火花与 D4 滑坡均**前置 2s 起渐强**(L2),danger 签名与音效同窗(radio C5 刹车先例);D4 另叠 `danger` 震循环(每遍间隔 ≥400ms)。
|
||||
- 承诺兑现绑定:dv1_metal 教「金属回波=钢板」后,凡叙事提到船身/找到船的节点必播 echo_metal*;D2 找人必播 pipe_knock(§6.3 清单 + §9 断言)。
|
||||
|
||||
### 5.3 Voice 划分(详见 17-abyss-voice-ids.md)
|
||||
|
||||
| 组 | 声部 | 落位 | 数量 |
|
||||
|---|---|---|---|
|
||||
| 潜航员(你)DIVER | 双性别(female=Serena / male=Uncle_Fu + DIVER instruct 常量) | `voice/female\|male/` | 30 句 |
|
||||
| 调度/系统/向导 DECK | 双性别(female=Vivian / male=Dylan + DECK instruct 常量) | `voice/female\|male/` | 97 句 |
|
||||
| 船员 NPC ×4 | 平铺单音色(小舟=Serena / 老白=Uncle_Fu / 陈医官=Vivian / 高船长=Eric),**不做双性别** | `voice/` 根(平铺回退命中)+ 电台滤波转码 | 21 句 |
|
||||
|
||||
- 船员 ≤4 个单音色约束满足;玩家自己的声音跟随全局 `settings.voice`;调度是向导人设(L4 角色化系统声,radio 导播同型)。
|
||||
- 合计 148 句(≤170 GPU 预算 ✓,含 `_k` 键盘变体 11 对);音频文件 = 127×2 + 21 = 275 条(×2 格式 = 550 文件)。
|
||||
|
||||
## 6. 声呐双通道设计(本作核心差异层)
|
||||
|
||||
### 6.1 引擎能力边界(对照 web-engine-api.md)
|
||||
|
||||
| 能力 | 引擎现状 | 方案 |
|
||||
|---|---|---|
|
||||
| voice 运行时 EQ/滤波 | ❌(voice 链无滤波插入点) | **资产侧转码滤波**(radio §6.2 先例):ffmpeg `highpass+lowpass+压缩器` 逐船员定档(§5.3/voice-ids) |
|
||||
| sfx 循环 | ❌ 即发即弃 | 游戏层 `buffer.loop=true` 持句柄(amb_deep/amb_deck/breath_loop),切换档位时停(radio `_ringSrc` 先例) |
|
||||
| 语音 duck 垫乐 | ✅ 内置(duck 20%,300ms) | 直接依赖;BGM 不再手工让路 |
|
||||
| sfx vs voice 互让 | ❌ sfx 总线独立,无 duck | **游戏层 sonarGate 空闲门**(§6.2 R1):信息类回波只在 `!audio.isVoicePlaying()` 时播出,否则挂队列表、voice onComplete/句间轮询补发 |
|
||||
| sfx 声像 | ❌ 运行时无 pan API | 资产侧 pan(echo_metal_l/_r 两条,escape 先例);其余方向信息由调度语音明说(「左前方」) |
|
||||
| 变速不变调 | ✅ SoundTouch | 直接依赖(长按 1.7× / 2.2× 视障档) |
|
||||
|
||||
### 6.2 通道仲裁规则(并发声流 ≤2 约束)
|
||||
|
||||
- **通道定义**:声呐通道 = sfx 层的脉冲/回波/敲击/呻吟/环境 loop;通讯通道 = voice 层(调度+船员+你)。BGM 是第三层背景(voice 播时引擎自动 duck)。
|
||||
- **R1 回波不叠语音**:信息类回波(echo_*、pipe_knock、groan 渐强段)与任何 voice 播放区间**零重叠**——sonarGate 只在 voice idle 时放行,在播则排队到句间空隙(≥600ms);玩家主动脉冲只在搜索等待(voice 恒静)受理,按构造不重叠。
|
||||
- **R2 声呐主导段**(DIVE 搜索等待):前景=脉冲+回波余音+amb_deep,BGM=dive 曲低响度;voice 只出调度短句(解读句),且解读句固定在回波**结束后**接播(回波→静默一拍→解读,给耳朵留定位时间)。
|
||||
- **R3 常驻脉冲退位**:语音在播时,环境内的周期性声呐元素(母船远程脉冲垫)降 -6dB 或暂停(游戏层 gain 控制),不消失(保持声场存在感,A2 无静默死局)。
|
||||
- **R4 危机拍优先**:D2/D4 危机音(spark/landslide)为即发即弃 sfx,可叠在 amb 上;danger 签名同窗;当前 voice 句播完后危机链才插续(radio C5 同款;呼救类短句若必须抢时,走 sfx 层不占 voice)。
|
||||
- **R5 回波可重听**:搜索等待双击=重听「上一条回波+其解读句」(P1 关键线索可重听);COMMS 双击=重听当前节点(radio 同款)。
|
||||
- 声流账:任意时刻 ≤2 条前景流(voice 串行 1 + 声呐信息音 1),BGM/amb 为背景层——满足 ASA ≤2 注意流约束。
|
||||
|
||||
### 6.3 教学承诺清单(dungeon「铁器=楼梯」教训:每句承诺的机制必须真实存在且可感知)
|
||||
|
||||
| 教学句 | 承诺 | 兑现点(断言锁定) |
|
||||
|---|---|---|
|
||||
| dv1_metal「金属回波,钢板。听见这个,就是海燕号的船身」 | 金属回波=找到船 | D1 找到/D4 接近指挥舱均播 echo_metal*;全剧本任何「船身」节点零漏播 |
|
||||
| dv1_teach「单击,发一枚脉冲」(+gd_ping1) | 单击=脉冲 | 搜索等待单击恒出 sonar_ping(非跳句、非无效);无超时不惩罚 |
|
||||
| b_goal「五个人。你的双瓶,够下四潜」 | 5 人/4 潜 | 基础消耗恰 3 格×4=12(§4.5 验算);剧本 A 恰 4 潜走完 |
|
||||
| b_rule「气不够一潜,人就必须上浮」 | 氧气门 | 取消门恰在 oxy<3(§4.3/§4.5);剧本 C/D 实证 |
|
||||
| d1_surf「往返,扣三格气」 | 每潜扣 3 | 每次下潜开始扣 3(账目断言) |
|
||||
| d1_code「记住这个敲法」 | 敲管=老白的信号 | D2 搜索以 pipe_knock 引导找到机舱 |
|
||||
| oxy_gain「应急瓶接上了,多三格」 | +3 | 恰一次、恰 +3、恰在 D2 上浮后 |
|
||||
|
||||
## 7. 向导层接入
|
||||
|
||||
### 7.1 状态签名 earcon / turn cue
|
||||
|
||||
| 时机 | 向导动作 | 说明 |
|
||||
|---|---|---|
|
||||
| INTRO 进入 | `guide.state('explore')` | 叙事态签名 |
|
||||
| 搜索等待武装(下潜链末) | `guide.turn({haptic:true})`(无语音) | turn 签名+confirm 震=「轮到你发脉冲」;首次前 dv1_teach 已口播 |
|
||||
| 每个抉择点 p* 起播 | `guide.state('choice')` | 选项句本身即 turn cue(W2 契约零插播) |
|
||||
| SURFACE 进入 | `guide.state('settle')` | 结算签名 |
|
||||
| ENDING 进入 | `guide.state('settle')` | 同上 |
|
||||
| MENU 打开 | `guide.state('menu')` | 菜单签名 |
|
||||
| D2/D4 危机拍 | `guide.state('danger')` | 音效前置 2s 渐强同窗(全游戏仅两处) |
|
||||
| 无效手势 | `guide.error({voice:'gd_invalid', onceKey})` | error 震 + full 档语音,idle-only(F1.4) |
|
||||
|
||||
- earcon 词表:只用全项目统一 8 音(menu/explore/battle/choice/settle/danger/turn/nudge),**零新增**;battle 不用。
|
||||
|
||||
### 7.2 看门狗双轨(radio F1 + dungeon E0-1 教训:乱按也要被抢救)
|
||||
|
||||
**无操作轨**(guide watchdog,任何手势复位;两级不同句、用尽即停、永不惩罚):
|
||||
|
||||
| 等待点 | full 档 | standard 档 | 级别内容 |
|
||||
|---|---|---|---|
|
||||
| 搜索等待无脉冲 | [10, 25] | [10, 25](onEscalate 游戏层补播) | ① gd_ping1 ② gd_ping2(**必须不同句**);两级后仅 amb+余音 |
|
||||
| INTRO/COMMS/SURFACE 链末等待 | [25, 50] | [13, 30] | ① gd_continue ② gd_again(storyline F1.1 同款) |
|
||||
| 抉择点 p* 播完无操作 | [25, 50] | [25, 50] | 重播当前 p* 提示句(13 号 §16 先例;空点单击=重挂计时) |
|
||||
| ENDING 结算等待 | [25, 50] | [13, 30] | gd_continue / gd_again |
|
||||
|
||||
**无进展轨**(游戏层计时,dungeon E0-1 ②同型;仅挂搜索等待与 COMMS 链末两个可饿死点):
|
||||
|
||||
| 项 | 规则 |
|
||||
|---|---|
|
||||
| 进展定义 | 节点推进 / 发出脉冲 / 抉择结算。**无效手势(滑错、空点)不计进展**——无操作轨被它们复位、无进展轨不被它们复位,乱按 96s 也必被抢救 |
|
||||
| 阈值 | 60s → gd_prog1;120s → gd_prog2;用尽即停(每等待点一轮) |
|
||||
| 有真实进展 | 全程零 prog 播出(不误伤正常玩家,dungeon 断言同款) |
|
||||
| 双轨去重 | 两轨短句内容同级交叉登记;同一等待点先播过 gd_ping* 则无进展轨跳过同义级 |
|
||||
|
||||
- 向导插播一律 `queue:true`,绝不顶掉在播对白;error/watchdog 类语音 idle-only(在播则跳过且过期丢弃,F1.4)。
|
||||
- 单句语音看门狗(资产缺失兜底):30s 超时且 `isVoicePlaying()===false` 才自动续链,长句续约不掐(radio N1 先例照抄)。
|
||||
|
||||
### 7.3 键盘变体机制(PC 键盘玩家)
|
||||
|
||||
- 运行时按 `gesture.inputMode()`(settings.input auto/touch/key)选 `_k` 变体资产:key → `voice/<gender>/<id>_k.*`,touch → 无后缀版;**auto 跟随最近使用通道**(keydown 后即切 key)。`_k` 缺失回退无后缀版(资产侧保证成对,check_all_assets 校验)。
|
||||
- 变体清单(11 对,集中分组见 voice-ids §G0):gd_brief / gd_continue / gd_again / gd_ping1 / gd_ping2 / sys_help / sys_menu / sys_skip / sys_continue_ask / dv1_teach / p1。
|
||||
- 抉择提示 p2..p9 措辞统一「向左滑/向右滑」;键盘玩家由 p1_k 与 sys_help_k 完成首次绑定(左=←,右=→),后续提示语义不变。
|
||||
- 启动遮罩文案引擎自理(「按空格开始」/「轻触开始」),游戏零改动。
|
||||
|
||||
### 7.4 继承 radio 三轮验证机制(照抄不重设计)
|
||||
|
||||
| 机制 | 来源 | 落点 |
|
||||
|---|---|---|
|
||||
| 帮助链去重(同等待点第 2 次上滑只震+nudge) | radio G1 | `_helpSeen` 按等待点键控 |
|
||||
| 状态链顺序「状态在前、帮助在后」 | radio G6 | prog_dN → oxy 档 → sys_help |
|
||||
| 空点确认轻震(不可跳句上单击补 beat [8]) | radio G4 | p*/链末句/F4 锁各 tap 屏蔽分支 |
|
||||
| oxy_crit 播报位附 warning 震 | radio G2 | 全部 crit 出口(含上滑复听) |
|
||||
| 菜单报名游戏侧排队零截断 | radio 实现修复 #3 | `_menuQueue` 排水 |
|
||||
| stop() 先 `seqToken++` 作废在途链 | radio 实现修复 #6 | 同款 |
|
||||
| 新局清 choiceArmed/pendingChoice | radio 实现修复 #7 | newRun() |
|
||||
| 长按误报无效(longpress 全状态合法) | radio 实现修复 #2 | 仅 left/right(ASK 另含 up/down/doubletap)报无效 |
|
||||
|
||||
## 8. 存档设计
|
||||
|
||||
### 8.1 进度 data 结构(PUT /api/progress {game:'abyss'})
|
||||
|
||||
```json
|
||||
{
|
||||
"schema": 1,
|
||||
"updatedAt": "2026-09-09T12:00:00Z",
|
||||
"summary": "第2潜·机舱 · 氧气6格 · 结局1/4",
|
||||
"phase": "COMMS",
|
||||
"node": "bai_b",
|
||||
"dive": 2,
|
||||
"oxy": 6,
|
||||
"supply": true,
|
||||
"saved": { "zhou": 1, "bai": 0, "chen": 0, "zheng": 0, "gao": 0 },
|
||||
"stayer": null,
|
||||
"flags": { "knowsPipe": true, "hasLog": false, "valve": false, "spareGift": false, "gaoPeace": false, "bell": false },
|
||||
"endings": { "e2": true },
|
||||
"runs": 3
|
||||
}
|
||||
```
|
||||
|
||||
- 写入时机:每潜 DIVE 进入、每个抉择结算后、SURFACE 进入、ENDING 进入、菜单「保存并回大厅」。
|
||||
- 断点续玩:读档 → sys_continue_ask(_k)(单击=继续上次 / 右滑=新救援);继续=恢复 phase+node+全部数值并**重播当前节点链**=一句话局面复述(L5);重进 ≤5s 可玩;恢复首句受 F4 跳句锁(radio G5 例外条款)。
|
||||
- summary 格式:进行中 `第N潜·<舱段> · 氧气K格 · 结局X/4`;收队 `救援收队·<结局名> · 结局X/4`(大厅卡片直接显示)。
|
||||
|
||||
## 9. playtest 断言清单(登记 13 号 §21 指针;`settings.set({guide:'off'})` 纯玩法验证,向导行为住 guide.test)
|
||||
|
||||
**关键路径**(剧本 A:全右+左p9 → e1,≤70 次手势):
|
||||
1. 遮罩点按 → INTRO 链(b_open 起,voice 层有播放记录)→ 链末单击 → DIVE(1) 下潜链 auto → 搜索等待武装(turn 事件 + amb_deep 循环起播)。
|
||||
2. 搜索单击 → sonar_ping → 回波静默一拍 → echo_metal_l → dv1_metal(承诺音)→ link_beep → COMMS(1):z1_a/b/knock → p1 右 → p2 右 → 上浮:surf_splash+ascent_chime → d1_surf → oxy=12-3=9 → oxy_full 播出(账目断言)。
|
||||
3. DIVE(2):脉冲 → echo_debris+pipe_knock → dv2_found → bai_a/b → p3 右(danger 签名前置 2s 与 spark_flash 同窗断言)→ p4 右 → d2_surf → d2_supply → oxy_gain(6→9,恰一次)。
|
||||
4. DIVE(3):脉冲 → echo_groan → dv3_groan → chen_a/b → p5 右 → p6 右 → d3_surf(oxy=6,ok 档)。
|
||||
5. 氧气门:6≥4 → DIVE(4) 双载:滑坡危机拍(landslide 前置 2s 渐强 + danger 签名 + danger 震)→ gao_a/b → p7 右 → gao_c → p8 右 → d4_surf → oxy=2(crit 档+warning 震)。
|
||||
6. 签收:g9_in → g9_knot → p9 左(oxy=2≥1 可用)→ d9_bell + bell_toll → ENDING(e1):e1_a/b + ep_lead + ep 链 → 结算单击 → 新救援回 INTRO。
|
||||
|
||||
**边界断言**:
|
||||
- **四结局可达(含氧气逐点验算)**:剧本 B(同 A 但 p9 右)→ e2;剧本 C(p1左 p2左 p4左,余右):D1 后 oxy=7(ok)/D2 后 2→supply→5(gain+low 档)/D3 后 2(crit)→ 氧气门走**终局取消链**(dv4_none→gao_final 完整播出)→ p9 左(2≥1)→ e3(saved=3);剧本 D(p1左 p4左,余右):D1 后 8(ok)/D2 后 3→supply→6(ok)/D3 后 3(low)→ **单载形态**(p7 按 stayer 选 p7_chen|p7_zheng)→ p7 左=带船长 → 留守者留别句(chen_last|d4_stay_lost)→ p8 右 → oxy_end=0 → p9 左**封锁**:g9_dry 播出后自动右 → e4(saved=4)。各局 oxy 逐检查点与 §4.5 公式一致。
|
||||
- **氧气账目真实**:每次扣减后播出的档位句与 floor(oxy/3) 桶一致;上滑 status 链顺序 prog_dN → oxy 档 → sys_help(G6);supply 全局恰一次;剧本 E(p2左 p3[无knows]左 p4左 p6左)mid-dive floor 至 0 → dry_a/dry_b 播出且当前救援者照常救上(人已挂上吊索不失去)。
|
||||
- **双通道仲裁**:全剧本转写断言——echo_*/pipe_knock/groan 信息音播出时刻与任一 voice 播放区间**零重叠**(sonarGate 排队语义:晚于在播句结束);搜索等待单击恒=脉冲(sonar_ping 计数=1,无跳句无 error);双击搜索等待=回波+解读句同序重播;语音在播时 amb_deep 持续、远程脉冲垫降 -6dB(R3)。
|
||||
- **教学承诺兑现**(§6.3 清单逐条):dv1_metal 后所有「船身」节点 echo_metal* 零漏播;D2 找到机舱前 pipe_knock 恒在;b_rule 与取消门一致(剧本 C 证明);b_goal 四潜=剧本 A 恰 4 潜;每潜起播扣 3 断言。
|
||||
- **看门狗双轨**:搜索等待快进 10s→gd_ping1、25s→gd_ping2(两级 id ≠,绝不逐字重播;两级后仅 amb);**乱按 96s**(每 2s 注入一个无效滑动):无操作轨零播出(被手势复位)+ 无进展轨 60s→gd_prog1、120s→gd_prog2(乱按饿不死);有真实进展(单击脉冲推进)全程零 prog 播出;COMMS 链末 25s/50s → gd_continue/gd_again;p* 播完 25s/50s 重播 p* 两次后静默;`guide=off` 全程零定时器零向导事件。
|
||||
- **键盘变体**:settings.input='key' 会话播出 gd_brief_k/sys_help_k/gd_ping1_k/dv1_teach_k/p1_k 且对应无后缀版零播出;'touch' 反之;'auto':keydown 后下一句用 _k。
|
||||
- **中断复述**:杀进程重进(存档 node=bai_b)→ sys_continue_ask → 单击 → 重播该节点链(恢复首句不可跳,第二句起可跳);右滑=新救援(runs 口径同结算重开)。
|
||||
- **结算链死窗(H1 内化)**:终局取消链/干涸链/e* 结局链开播后 800ms 内注入在途 tap(mock 补派 touchend+300ms 同款序列)→ 手势被吞、链完整有序播出、结算出口手势照常。
|
||||
- **pendingChoice**:p* 播放中左右滑 → 播完立即生效(不丢、不重复、连滑取最后一次)。
|
||||
- **p* 不可跳**:p* 播放中单击 → 不跳句(PROMPT_RE 门)+ beat 轻震(G4)。
|
||||
- **idle-only**:向导 gd_* 在对白在播时跳过且不占 onceKey(F1.4);queue 句排在当前句后零截断。
|
||||
- **菜单**:下滑开菜单 → 上滑帮助 → 双击「回到水下」→ phase/node 不变、当前节点重播;单击循环顺序 = [回到水下, 重新开始这次救援, 保存并回大厅];确认回大厅 → sys_menu_lobby 播出且 PUT/localStorage 有最新 data。
|
||||
- **资产缺失**:屏蔽任意 voice 资产 → 30s 看门狗自动续链到结局不卡死;NPC 滤波资产缺失回退原声可播。
|
||||
- **数字规范**:prog_*/oxy_*/gd_* 全部整句字面量,静态审计无运行时拼接碎片。
|
||||
- **低氧混音签名**:tier=low/crit 期间 breath_loop 在播、升档/收队即停。
|
||||
|
||||
**失败即不通过**:任何等待 >5s 无声(静默死局);无效手势零反馈;回波与语音重叠;结局计数与 §3.4 不符;氧气档位句与 oxy 值不符。
|
||||
|
||||
## 10. 节奏曲线(每次下潜目标时长)
|
||||
|
||||
| 段 | 内容 | 目标时长 | 设计目标 |
|
||||
|---|---|---|---|
|
||||
| 开场+下潜链 | 甲板简报+第一潜下水+搜索 | 1-1.5 min | 首输入 <60s(开场链 ~20s 链末单击,或 ~40s 搜索首脉冲);规矩一句讲完(P4) |
|
||||
| D1 找船 | 教学潜:脉冲/回波/接通/2 抉择 | 4-4.5 min | **首个正反馈 ≤3min**(~2.5min 金属回波+接通小舟=「看见它了」);两抉择条条有出路;左路气耗被补给兜底=学习期零惩罚 |
|
||||
| D2 机舱 | 老白:撬/切+阀门抉择 | 3.5-4 min | 首个危机拍(火花,前置 2s);补给+3 兑现宽限;暖拍(热粥,P4) |
|
||||
| D3 病舱 | 生死抉择+回波预警 | 3.5-4 min | 船体呻吟埋 D4 险;留守约定=段落边界(P3 中断友好:每潜一个完整存档颗粒) |
|
||||
| D4 指挥舱 | 滑坡高潮+氧气门三形态 | 4-4.5 min | 紧张峰值:danger+滑坡渐强+双人竞速;生死分支收敛 |
|
||||
| 终局+结局 | p9 心结+结局链+逐人回响 | 2.5-3 min | 氧气余量兑换终局抉择;ep 点名(P2 回响);开环钩子拉下一局 |
|
||||
|
||||
- 合计 ≈ 20-22 min(15-25 达标);每 30-60s 一个反馈颗粒(回波/解读短句/结果句/档位句),无沉默尴尬期(P3)。
|
||||
- 难度曲线 = 道德复杂度(教学二选一 → 情报投资 → 生死取舍 → 自己的心结),操作复杂度恒定(永远二选一+单击脉冲)——P4「规则一遍听懂」由恒定操作面保证。
|
||||
|
||||
## 11. 自检清单(策划交付自验;☐ = 待开发/测试轮填)
|
||||
|
||||
| # | 硬约束/教训 | 落地 | ✓ |
|
||||
|---|---|---|---|
|
||||
| 1 | FTUE 首输入 <60s | 开场链 ~20s 链末单击;~40s 搜索首脉冲(§10) | ☑ |
|
||||
| 2 | FTUE 首个正反馈 ≤3min | ~2.5min 金属回波+接通小舟(§10 D1) | ☑ |
|
||||
| 3 | 学习期零惩罚 | D1 左路 -2 被 D2 后 +3 兜底;搜索无超时惩罚;D1/D2 恒可完成(§4.5) | ☑ |
|
||||
| 4 | 失败三问归因+归因真话律 | 干涸链 dry_b 指向实际左选择;gao_final/d4 留别句克制不假安慰;§4.4 无假归因句 | ☑ |
|
||||
| 5 | 资源账目真实(radio rep_low 教训) | 氧档以 floor(oxy/3) 划界、每档句义逐格为真(§4.3 表);补给恰一次 +3;扣 3 恰每次下潜 | ☑ |
|
||||
| 6 | 手势宪法 6 手势默认语义零豁免 | §2.3 全覆盖;单击搜索=「检查」(宪法 §5.1+escape 先例);菜单 §5.2 模态约定 | ☑ |
|
||||
| 7 | 长按显式登记 | 无豁免:长按=引擎快进(12 号叙事类不豁免),§2.3 在案 | ☑ |
|
||||
| 8 | 向导:签名/turn cue/看门狗两级不同句 | §7.1/§7.2;gd_ping1≠gd_ping2;gd_continue→gd_again | ☑ |
|
||||
| 9 | 看门狗双轨(dungeon E0-1/radio F1 教训) | 无操作轨+无进展轨(§7.2);乱按 96s 必被抢救;有进展零打扰 | ☑ |
|
||||
| 10 | 插播 queue 不顶对白;纠错 idle-only 过期丢弃 | §7.2(F1.4 契约) | ☑ |
|
||||
| 11 | 死亡/失败结算链完整(dungeon H1 教训) | 终局取消链/干涸链/结局链 800ms 手势死窗;已救者永不失去(§2.2/§4.3) | ☑ |
|
||||
| 12 | 教学承诺兑现(dungeon「铁器=楼梯」教训) | §6.3 承诺清单 7 条逐条绑兑现点+断言 | ☑ |
|
||||
| 13 | 单次播报 ≤3 选项 | 全部抉择恒 2 选项;菜单 3 项循环 | ☑ |
|
||||
| 14 | 并发声流 ≤2 + 双通道仲裁 | voice 串行+声呐信息音互斥(R1-R5,§6.2);断言零重叠 | ☑ |
|
||||
| 15 | earcon ≤7、统一词表、语义靠语音 | 只用统一 8 音中 7 个(battle 不用),零新增 | ☑ |
|
||||
| 16 | 台词一句一文件 ≤40 字、数字分档整句、无运行时拼接 | voice-ids 全表 ≤30 字(最长 p8=30);prog/oxy 分档整句;句内数字写死 | ☑ |
|
||||
| 17 | 多音字规避/同 instruct 常量/无语速词 | voice-ids 头部+文末自查(重写→补、脏/晃/闷标注试听) | ☑ |
|
||||
| 18 | PC 键盘变体(提示句集中+标注) | 11 对 _k 变体集中分组(voice-ids §G0);inputMode() 运行时选择 | ☑ |
|
||||
| 19 | P1:可打断/重听(含回波)/status key/不当白痴 | 跳句+双击(回波可重听 R5)+上滑状态链+成功零补救教学 | ☑ |
|
||||
| 20 | P2:3 分钟见效/结局回响 | ~2.5min 首个改变世界的时刻;ep 逐人点名+bell 差分;e1 巧妙路径(p1左+p3左 省气取钟) | ☑ |
|
||||
| 21 | P3:3 分钟颗粒/中断复述/单手 | 一潜=3.5-4.5min 完整段落+边界自动存档;重进重播当前节点;全手势免视单手 | ☑ |
|
||||
| 22 | P4:一遍懂/容错/无高压倒计时/不骂人 | 一句规矩;无实时倒计时(步进资源+跨档才播);软失败零死亡;NPC 句 ≤24 字+逗号停顿 | ☑ |
|
||||
| 23 | 抉择树 4 结局可走通验算 | §4.5 公式+§9 剧本 A-D 逐 oxy 检查点(e1:lefts≤1+双载;e2:lefts≤2;e3:lefts=4-5+取消;e4:单载 lefts=3 或取消右) | ☑ |
|
||||
| 24 | 单局 15-25 min | §10 曲线 ≈20-22 min | ☑ |
|
||||
| 25 | 分支不爆炸(radio 纪律) | 跨潜仅标量(oxy/saved/stayer/6 flag);~70 节点固定深度(§3.3) | ☑ |
|
||||
| 26 | 台词 ≤170、船员 ≤4 单音色 | 148 句(双 127+NPC 21)/4 个船员音色(voice-ids 账目) | ☑ |
|
||||
| 27 | 引擎边界诚实 | §6.1 能力表:滤波/loop/声像/互让全写明资产侧或降级方案 | ☑ |
|
||||
| 28 | 存档带 summary、断点续玩 | §8:data+summary 格式、≥5 恢复、局面复述 | ☑ |
|
||||
|
||||
### 批 1 教训内化确认(5 条全落地)
|
||||
|
||||
| 教训 | 本作机制 | 断言 |
|
||||
|---|---|---|
|
||||
| 教学承诺必须兑现 | §6.3 七条承诺清单(金属=钢板/单击=脉冲/四潜/氧气门/扣三格/敲管/补给) | §9「教学承诺兑现」块 |
|
||||
| 看门狗双轨 | §7.2 无操作轨+无进展轨;无效手势不复位进展轨 | §9「看门狗双轨」块 |
|
||||
| 档位措辞真实 | §4.3 档位=floor(oxy/3) 可下潜次数,句义逐格为真 | §9「氧气账目真实」块 |
|
||||
| 失败结算链完整不被打断 | 800ms 手势死窗盖取消链/干涸链/结局链;seqToken 作废在途链 | §9「结算链死窗」块 |
|
||||
| PC 键盘操作提示 | 11 对 _k 变体+inputMode() 选择+集中分组标注 | §9「键盘变体」块 |
|
||||
@@ -0,0 +1,268 @@
|
||||
# 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](18-detective.md) §3-§7;资产规模核对见其 §8。
|
||||
@@ -0,0 +1,600 @@
|
||||
# 18 · 《雨夜专案》完整设计(detective / Rainy Night Case)
|
||||
|
||||
> **给开发者的实现要点摘要**
|
||||
> 1. 本格推理 RPG:**核心动词=听证词找矛盾**。案卷 7 条目(4 证人证词 + 现场勘验 + 法医报告 + 结案陈词),全部音频呈现;证词=证人 NPC 平铺单音色(声音演技核心,5 个 speaker 池满配 + 专属签名 earcon 防混淆),旁白双性别只做系统/指引/现场自勘。每句证词预打**线索轴标签**,指证判定=两句是否「同轴异值」——判定与归因全部从数据单源推导,机制上不可能出现「台词说对得上、逻辑上对不上」的假话。
|
||||
> 2. 手势:证词板左右滑换条目、单击听取/停止、**双击=重听当前句**(证词按句切分,单句 ≤8s,链播句间 0.8s——≤40s 听觉负荷以「句粒度可停可重听」兑现)、上滑状态链(已问几份/疑点几处)、下滑菜单(无豁免)、**长按=进入指证**(仅限无声空闲时受理,与长按快进零冲突,豁免 E1/E2 登记 §2.6)。指证/结案菜单走「左右滑预览+单击两段确认」非模态范式,双击保持全局重听语义——**全游戏零手势偏离,仅 2 条已教学豁免**。
|
||||
> 3. 单局 15-25 分钟;结案=三问(真凶/凶器/动机),指认错误有不在场证明复述+真话归因+无限再机会,**无惩罚性失败,案子保底必结**(无进展轨看门狗三级提示最终直接给出可指证的矛盾对)。评级 S-C 账目全部真实(疑点数/冗余指证分档播报,播报值=运行值)。
|
||||
> 4. 随机性全走种子 PRNG(mulberry32,`opts.seed`/`opts.pack` 可注入):选案包(pack A 周先生真凶 / pack B 小顺真凶——同模板同证词骨架、fork 句替换)、洗牌只动 filler 句位与问题选项顺序、提示轮询顺序。**矩阵不变式:全案卷「同轴异值」语句对集合 ≡ 预设计矛盾表**(dev 断言 + playtest 断言双保险)。
|
||||
> 5. 台词表 [18-detective-voice-ids.md](18-detective-voice-ids.md):旁白 106 句 ×2 性别 + NPC 平铺 52 句 = **158 句 ≤160 上限**;操作提示句带键盘变体(`_k` 后缀,`gesture.inputMode()` 选播,V 组集中登记)。
|
||||
> 6. 规模对标 radio:单文件 game.js 预计 900-1100 行;bgm 3 + sfx 12 + voice 264 条(×2 格式 = 528 文件)。裁决仪式链不可打断(VERDICT 态 800ms 手势死窗 + 链锁,dungeon H1 同款)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 概述
|
||||
|
||||
- **一句话**:你是专案组探长,一桩雨夜命案。翻听六份卷宗,比对证词,指出矛盾,锁定真凶。
|
||||
- **题材**:本格推理。核心命题「证词会撒谎,证据不会」——纯音频天然适合:证词本来就是"说"出来的信息,翻卷宗=翻语音段落,比对=重听+指证;视觉游戏需要的证词板 UI 在这里是一套**规整的听觉导航**(条目→句→指证对)。方法论 §4.1 无现成行(新模式探索),状态层重点自定为:**信息可回读**(每句可重听)+ **导航规整**(同一套左右滑/单击范式贯穿)+ **归因真话**(指证判定从数据推导)。
|
||||
- **为什么适合纯音频**:① 记忆与比对的工作记忆负载全在听觉通道——删 BGM 抢占(对白 duck 引擎自动);② 证人=声音演技(speaker+instruct 区分 + 签名 earcon),认人是听感本身;③ 本格逻辑链可完全用「谁说了什么」表述,无空间/动作信息需要降维。
|
||||
- **单局**:一周目(含教学)约 15-20 分钟;二周目(跳教学+变体案)约 13-15 分钟。结案必达(保底),评级 S-C 由过程质量决定。
|
||||
- **与现有 8 游戏的关系**:选项列表导航承接 rpg(左右滑+单击确认)、证词重听承接 simon/escape(重听=生命线)、状态档位链承接 dungeon(上滑 5 段链)、看门狗双轨承接 dungeon E0-1/E0-2(无操作轨+无进展轨);指证菜单是新交互增量(两级选择+两段确认),变体案包是内容增量。
|
||||
|
||||
## 2. 手势映射与豁免登记
|
||||
|
||||
### 2.1 证词板(BOARD,主循环)
|
||||
|
||||
BOARD 分**空闲**(无语音在播)与**播放**(条目链播中)两个子行为:
|
||||
|
||||
| 手势 | BOARD 空闲 | BOARD 播放 |
|
||||
|---|---|---|
|
||||
| 左滑 | 上一条目(循环):签名 earcon + 条目名 | 静默忽略(纯聆听保护,simon playback 先例) |
|
||||
| 右滑 | 下一条目(循环):签名 earcon + 条目名 | 静默忽略 |
|
||||
| 单击 | 播放当前条目(从首个未听句起,听过的整体重听) | **停止播报**,回空闲 |
|
||||
| 双击 | 重听当前条目最后一句 | **重听当前句**(≤8s,免费零消耗) |
|
||||
| 上滑 | 状态链(§2.5) | 状态链(打断证词;双击可重听当前句) |
|
||||
| 下滑 | 模态菜单(§2.4) | 模态菜单(打开即停播报) |
|
||||
| 长按 | **进入指证**(CONFRONT;仅空闲受理) | 引擎快进(旁白 1.7×,保持默认,不豁免) |
|
||||
| 长按松开 | — | 恢复常速 |
|
||||
|
||||
条目共 7 项:老葛证词 → 小顺证词 → 周先生证词 → 温太太证词 → 现场勘验 → 法医报告 → 结案陈词。每项播报=专属签名 earcon(0.3-0.5s,§8.2)+ 条目名整句;切到「结案陈词」+单击 → FINISH。
|
||||
|
||||
### 2.2 指证(CONFRONT)与结案(FINISH)——同一导航范式
|
||||
|
||||
两态统一为「列表预览 + 两段确认」非模态菜单(00 §5.2 非模态约定,rpg 探索同款),**双击全局语义=重听当前句,不偏离**:
|
||||
|
||||
| 手势 | CONFRONT(选证词对) | FINISH(三问) |
|
||||
|---|---|---|
|
||||
| 左/右滑 | 切换:选条目阶段=6 证词条目(同 2.1 循环);选句阶段=上一句/下一句(播该句全文) | 切换选项(播选项名) |
|
||||
| 单击 | ①选条目阶段=确认条目 → 进选句;②选句阶段=进入确认(重播该句+`cf_confirm`);③确认态=**定下这句**(第一份选定后自动进第二份,流程同前;第二份定下 → 判定) | 凶器/动机问:确认选项即答题;真凶问:进入确认(`fin_who_confirm` 重播+确认,二次单击定下=正式指认) |
|
||||
| 双击 | 重听当前预览句(宪法语义保留) | 重听当前问句/选项 |
|
||||
| 上滑 | 状态链(简版:疑点数) | 同左 |
|
||||
| 下滑 | 菜单(可「返回证词板」退出指证) | 菜单 |
|
||||
| 长按 | error 震(选择语境不作输入) | error 震 |
|
||||
|
||||
指证判定结果(§3.5)播出后自动回 BOARD 空闲。全程无倒计时、无尝试次数上限。
|
||||
|
||||
### 2.3 标题(TITLE)/ 结算(SETTLE)/ 裁决(VERDICT)
|
||||
|
||||
| 手势 | TITLE | VERDICT(认罪链播中) | SETTLE |
|
||||
|---|---|---|---|
|
||||
| 单击 | 继续(有档)/ 新案(无档) | **吞掉**(手势死窗+链锁,§7.4) | 接新案(pack 翻转+新 seed) |
|
||||
| 右滑 | 换一桩新案(重掷 seed/pack,meta 保留,run 清空) | 吞掉 | error |
|
||||
| 双击 | 重听 continue_ask | 吞掉 | 重听结算链 |
|
||||
| 上滑 | 重听案情简介(intro_1..3) | 吞掉 | 重听评级段 |
|
||||
| 下滑 | 菜单 | 吞掉 | 菜单 |
|
||||
| 左滑/长按 | error | 吞掉 | error |
|
||||
|
||||
### 2.4 模态菜单(遵守 00 文档 §5.2 全球约定,无豁免)
|
||||
|
||||
下滑呼出(同时停播报/停看门狗)→ 单击循环切换(每切播项名)→ 双击确认 → 上滑=帮助 → 下滑=关闭。选项 5 项:返回证词板 / 去指证(=长按捷径的菜单冗余入口,P4 容错)/ 保存并回大厅 / 重新听帮助 / 重新查这桩案子。本作无实时玩法,菜单=天然暂停。
|
||||
|
||||
### 2.5 每状态手势映射总表(6 手势 + 长按松开,全状态覆盖)
|
||||
|
||||
| 手势 | TITLE | DRILL | BOARD停 | BOARD播 | CONFRONT | FINISH | VERDICT | MENU | SETTLE |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
| 单击 | 继续/新案 | 步骤作答 | 播放条目 | 停止 | 确认(两段) | 确认/答题 | 吞掉 | 循环切项 | 接新案 |
|
||||
| 双击 | 重听 | 重听教学句 | 重听末句 | 重听当前句 | 重听预览句 | 重听问句 | 吞掉 | 确认执行 | 重听结算链 |
|
||||
| 左滑 | error | 教学指定 | 上一条目 | 忽略 | 上一项/上一句 | 上一项 | 吞掉 | 上一项 | error |
|
||||
| 右滑 | 换新案 | 教学指定 | 下一条目 | 忽略 | 下一项/下一句 | 下一项 | 吞掉 | 下一项 | error |
|
||||
| 上滑 | 案情简介 | 状态(教过后) | 状态链 | 状态链 | 状态链(简) | 重听问句 | 吞掉 | 帮助 | 评级段 |
|
||||
| 下滑 | 菜单 | 跳过教学 | 菜单 | 菜单 | 菜单 | 菜单 | 吞掉 | 关闭 | 菜单 |
|
||||
| 长按 | error | 步骤作答 | 进入指证 | 快进(引擎) | error | error | 吞掉 | error | error |
|
||||
| 长按松开 | — | — | — | 恢复常速 | — | — | — | — | — |
|
||||
|
||||
无效手势一律 error 震;full 档 `gd_invalid`(onceKey 同局 1 次,之后仅 error 震);idle-only(纠错/看门狗句在播时跳过,引擎 guide 已实现)。
|
||||
|
||||
### 2.6 豁免登记(必须显式)
|
||||
|
||||
| # | 豁免条目 | 理由(先例) |
|
||||
|---|---|---|
|
||||
| E1 | BOARD 单击=播放/停止(非"确认") | "检查/翻阅"类非即时操作,300ms tap 延迟无碍(escape 单击=检查、dungeon 单击=脉冲同款);停止播报是纯聆听期的标准出口 |
|
||||
| E2 | BOARD 空闲长按=进入指证(核心动词快捷入口) | 绑定条件=无语音在播(`!audio.isVoicePlaying()`),与长按快进(仅在播时生效)**在时间上互斥、零冲突**,故不需 dungeon E3 式的对局期豁免;播放中长按仍走引擎快进。教学 D5 讲清(tut_confront),菜单另有「去指证」冗余入口 |
|
||||
|
||||
教学(DRILL)逐步讲清 E1/E2;无 immediateTap;模态菜单无豁免。
|
||||
|
||||
## 3. 核心动词:听证词找矛盾(信息设计)
|
||||
|
||||
### 3.1 信息结构总览
|
||||
|
||||
```
|
||||
案卷(7 条目)── 4 证人证词(各 6 句,NPC 平铺)
|
||||
├─ 现场勘验(6 句,旁白=探长自勘)
|
||||
├─ 法医报告(5 句,NPC 秦法医)
|
||||
└─ 结案陈词(FINISH 入口)
|
||||
每句 = 1 个音频文件 + 数据侧「线索轴:值」标签(0-2 个)
|
||||
矛盾 = 两句共享同一轴且值不同;全案卷该集合 ≡ 预设计矛盾表(4 条)
|
||||
```
|
||||
|
||||
- 证词链播:句间 0.8s 停顿;**句粒度重听**(双击)+ 句粒度停止(单击)——单段连续听觉负荷 ≤35s 且随时可停可回,满足「证词单段 ≤40s、可分段」要求。
|
||||
- 三套信息单源自洽(dungeon §3.2 同思路):证词=人的主张、现场/法医=物证主张、状态链=进度账目——进度账目(已问 X/疑点 n)从 `heard/doubts` 实时读出,播报值=运行值(账目真实)。
|
||||
|
||||
### 3.2 线索轴定义(pack A《雨夜·聚宝斋》)
|
||||
|
||||
案情:古董商沈万川死于自家后院柴房,后脑钝器伤,当夜暴雨。
|
||||
|
||||
| 轴 | 含义 | 取值 |
|
||||
|---|---|---|
|
||||
| rain | 雨何时开始 | 21:40 |
|
||||
| dep_s | 小顺离店时刻 | 21:40 |
|
||||
| away_s | 小顺当晚去处 | 城南 |
|
||||
| visitor | 后巷访客 | 22:15 高个微驼男性 |
|
||||
| dep_z | 周先生离店时刻 | 21:50 |
|
||||
| **lamp** | 店堂灯 | 熄 / 亮 |
|
||||
| **key** | 库房钥匙位置 | 挂柴房铜钩 / 贴身 |
|
||||
| **weapon** | 凶器材质 | 松木劈柴 / 铜器 |
|
||||
| **scale** | 铜秤下落 | 已卖 / 在库房 |
|
||||
| wall | 柴房后墙 | 有人翻爬 |
|
||||
| door | 后门开法 | 死者亲自为熟人开(规范值 victim_opened) |
|
||||
| death | 死亡时间 | 22:00-22:30 |
|
||||
| motive | 账上短银 | 月底要清账 |
|
||||
| struggle | 搏斗痕迹 | 无 |
|
||||
|
||||
(粗体 4 轴=矛盾承载轴;其余轴全部同值互证或单断言,见 3.4 验算。)
|
||||
|
||||
### 3.3 案卷正文(pack A;全部台词 ≤31 字,全文与台词表一致)
|
||||
|
||||
**老葛(门卫)**:w1_1「昨儿夜里雨大,我守着街门,一步没敢挪窝。」w1_2「九点四十,雨点子刚砸下来,小顺打着伞出的街门。」w1_3「十点一刻,一位先生收着黑伞进了后巷。个儿高,微驼背。」w1_4「九点五十,周账房出的街门,跟我说了声,回家。」w1_5「后半夜,温太太还来门房借过一回热水。」w1_6「听说店里账上短了银子,沈老板撂了话,月底清账。」
|
||||
|
||||
**小顺(学徒)**:w2_1「夜里,师父打发我去城南,给刘掌柜送匣子。」w2_2「雨太大,刘掌柜留我住的,今早才回店。」w2_3「库房钥匙?师父嫌沉,平日就挂在柴房墙上的铜钩。」w2_4「师父的账,向来只信周先生一个人。」w2_5「后门那闩,生人叫不开。熟人来了,师父才亲自去开。」w2_6「周先生常念叨,账房的活,越到夜里越清静。」
|
||||
|
||||
**周先生(账房,真凶)**:z_1「我七点进店上夜账。九点五十对完,锁了前门回家。」z_2「临走,我顺手熄了店堂的灯。那会儿,店里就剩老板。」z_3「库房钥匙?沈老板贴身带着,从不离身。」z_4「那伤,是松木劈柴砸的。铜秤?上个月卖给收废品的了。」z_5「我到家倒头就睡,夜里的事,一概不知。」z_6「你们要是不信,去问我家婆娘。」
|
||||
|
||||
**温太太(房东)**:wen_1「雨是九点四十下的。我正收晾的衣裳,记得真真的。」wen_2「十点二十,我出门倒垃圾。聚宝斋店堂的灯,亮着呢。」wen_3「刚回屋,柴房后墙咯噔一响,有人爬墙!花盆翻了一个。」wen_4「吓得我蒙头半宿没睡着,天亮才敢吱声。」wen_5「店里短银子的事,街坊都有耳闻。上礼拜他还摔了账本。」wen_6「周账房那人,见人三分笑,账算得比谁都精。」
|
||||
|
||||
**现场勘验(旁白)**:sc_0「你打伞进了后院。雨水顺着瓦檐,淌成一道帘子。」sc_1「柴房门口,沈万川面朝下倒着。后脑一处伤,现场没有凶器。」sc_2「后门门闩完好,是死者自己开的门。生人叫不开这扇门。」sc_3「泥地上只有进来的脚印,没有出去的。墙根的花盆,翻了一个。」sc_4「库房铜秤立在架上,秤砣不见了。」sc_5「柴房墙上,挂钥匙的铜钩,空着。」
|
||||
|
||||
**法医报告(秦法医)**:fo_1「验尸报告,念给你听。」fo_2「死亡时间,昨夜十点到十点半。」fo_3「后脑单次钝器伤,一击毙命。创口嵌有铜屑,凶器是铜器。」fo_4「死者双手干净,没有搏斗痕迹。」fo_5「鞋底是干的。当夜,死者没出过后门。」
|
||||
|
||||
(sc_5 铜钩空为叙事佐证,**不挂 key 轴**——「平日挂墙上」是习惯断言、「今晨钩空」是状态断言,二者不构成值冲突;数据侧 sc_5 clues={}。)
|
||||
|
||||
### 3.4 矛盾预设计表 + 矩阵验算(playtest 直证对象)
|
||||
|
||||
**矛盾表(pack A,4 条)**:
|
||||
|
||||
| # | 轴 | 语句 A(真凶侧) | 值 A | 语句 B | 值 B | hit 反应 |
|
||||
|---|---|---|---|---|---|---|
|
||||
| M1 | lamp | z_2 周先生「顺手熄了店堂的灯」 | 熄 | wen_2 温太太「十点二十……灯,亮着呢」 | 亮 | z_react_1 |
|
||||
| M2 | key | z_3 周先生「贴身带着,从不离身」 | 贴身 | w2_3 小顺「平日就挂在柴房墙上的铜钩」 | 挂墙上 | z_react_2 |
|
||||
| M3 | weapon | z_4 周先生「是松木劈柴砸的」 | 木 | fo_3 法医「创口嵌有铜屑,凶器是铜器」 | 铜 | z_react_3 |
|
||||
| M4 | scale | z_4 周先生「铜秤上个月卖给收废品的了」 | 已卖 | sc_4 现场「铜秤立在架上,秤砣不见了」 | 在 | z_react_4 |
|
||||
|
||||
注:M3/M4 共用语句 z_4(一句两断言),指证时选 z_4 两次、分别对 fo_3 与 sc_4——设计内行为。指证对**无序**(任一端在前都判 hit)。
|
||||
|
||||
**矩阵验算(全轴枚举)**——「同轴异值对 ≡ {M1..M4}」:
|
||||
|
||||
| 轴 | 断言语句(值) | 结论 |
|
||||
|---|---|---|
|
||||
| rain | w1_2(21:40)/ wen_1(21:40) | 同值一致(互证) |
|
||||
| dep_s | w1_2(21:40) | 单断言 |
|
||||
| away_s | w2_1(城南)/ w2_2(城南) | 一致 |
|
||||
| visitor | w1_3 | 单断言 |
|
||||
| dep_z | z_1(21:50)/ w1_4(21:50) | 一致 |
|
||||
| lamp | z_2(熄)/ wen_2(亮) | **M1,唯一冲突对** |
|
||||
| key | z_3(贴身)/ w2_3(挂墙上) | **M2,唯一冲突对** |
|
||||
| weapon | z_4(木)/ fo_3(铜) | **M3,唯一冲突对** |
|
||||
| scale | z_4(已卖)/ sc_4(在架) | **M4,唯一冲突对** |
|
||||
| wall | wen_3(有人爬墙)/ sc_3(翻墙离开) | 一致 |
|
||||
| door | w2_5(victim_opened)/ sc_2(victim_opened) | 一致(习惯断言与状态断言取同一规范值) |
|
||||
| death | fo_2 | 单断言(wen_3 的 22:25 落在窗内,旁证) |
|
||||
| motive | w1_6 / wen_5 | 一致 |
|
||||
| struggle | sc_1(无)/ fo_4(无) | 一致 |
|
||||
| (无轴) | w1_1、w1_5、w2_4、w2_6、z_5、z_6、wen_4、wen_6、sc_0、sc_5、fo_1、fo_5 | 叙事/filler,不参与判定 |
|
||||
|
||||
验算结论:除 M1-M4 外不存在任何同轴异值对;一致对 6 组(cf_same 的真话来源)、无轴句 13 句(cf_diff 的真话来源)——三条归因档全部真实可达。
|
||||
|
||||
### 3.5 指证交互与判定算法
|
||||
|
||||
```
|
||||
judge(a, b):
|
||||
if a.id === b.id → cf_self(同一句,比自己)
|
||||
shared = axes(a) ∩ axes(b)
|
||||
if shared 为空 → cf_miss(钝音)+ cf_diff「说的不是一件事」
|
||||
else if 存在轴 v: a[v] ≠ b[v]:
|
||||
if {a,b} ∈ 矛盾表(无序) → contra_hit + cf_hit + react_n + doubts[m]=true(疑点+1)
|
||||
else → 数据错误(dev 断言禁止;playtest 失败项)
|
||||
else(共享轴全同值) → cf_miss + cf_same「说得一致,不矛盾」
|
||||
每次判定(无论中未中)→ cfMiss 判定计数、自动回 BOARD;无资源惩罚、无次数上限
|
||||
```
|
||||
|
||||
- hit 反应句按真凶**累计被坐实次数**取 z_react_1..4(递进:记岔了→支吾→拒绝→想走),声音演技核心段;pack B 用 b_shun_react_1..2(第 3/4 次复用 react_2)。
|
||||
- 疑点 4/4 齐时播一次 `hint_fin`(引导去结案);疑点数进状态链与存档,账目同源。
|
||||
|
||||
### 3.6 归因真话律(指证/指认双处)
|
||||
|
||||
| 场景 | 播报 | 真话依据 |
|
||||
|---|---|---|
|
||||
| 指证 miss·同轴同值 | cf_same | 轴数据同值(如 w1_2 vs wen_1 都说雨 21:40 起) |
|
||||
| 指证 miss·不同轴 | cf_diff | 无共享轴(绝大多数跨话题句对) |
|
||||
| 指证 miss·同一句 | cf_self | 选择器同一句 |
|
||||
| 指认错人 | 该证人 acc_NPC(自述不在场证明)+ fin_clear | 各无辜者的 alibi 在证词中已铺(w2_1/w2_2 小顺、w1_1/w1_5 老葛、wen_4+visitor 男性访客排除温太太)+ pack B 的 acc_zhou |
|
||||
| 凶器答错 | fin_wp_wrong(「铜屑不答应」) | fo_3 物证 |
|
||||
| 动机答错 | fin_mv_wrong | w1_6/wen_5 账短银 |
|
||||
|
||||
**禁止**:任何「差一点」「再想想」式无信息归因;播报值与数据值必须一致(playtest 失败项锁定)。
|
||||
|
||||
### 3.7 信息密度与记忆设计
|
||||
|
||||
- 单次播报 ≤3 选项:所有列表(条目/句/凶器/动机/嫌疑人)都是**逐项预览**(左右滑一次听一项),绝不通读清单;帮助句(sys_help)例外(dungeon help 先例)。
|
||||
- 证人区分三板斧:① 5 speaker 满配 + instruct 常量(§8.3);② 每证人**专属签名 earcon**(条目切换/指证选择/状态复述时前置,0.3-0.5s);③ 周先生(与男旁白同 speaker)与秦法医(与女旁白同 speaker)是仅有的两处重叠,靠签名+语境+instruct 兜底——重叠从不在相邻句出现(证词链内无旁白插话)。
|
||||
- P1 工作记忆:疑点无需记忆——状态链随时报数;已选第一份证词在选第二份时**自动重播一次**(选句确认后链上接播),不需要玩家脑内持有。
|
||||
|
||||
## 4. 状态机
|
||||
|
||||
### 4.1 状态列表
|
||||
|
||||
`TITLE / DRILL / BOARD / CONFRONT / FINISH / VERDICT / SETTLE` + `MENU`(挂起 overlay,记录返回态)。BOARD 含空闲/播放两子行为(非独立态)。FINISH 子相位:who → weapon → motive;CONFRONT 子相位:item1 → line1 → confirm → item2 → line2 → confirm → judged。
|
||||
|
||||
### 4.2 转移图
|
||||
|
||||
```
|
||||
start ──> TITLE ──单击(有档)──> BOARD(恢复存档+局面复述)
|
||||
│单击(无档) ├──────> DRILL(仅首次, meta.drillDone 控制) ──完成/下滑跳过──> BOARD
|
||||
│右滑=换新案(重掷 seed/pack) ──> BOARD(新案)
|
||||
v
|
||||
BOARD(证词板) ⇄ 条目链播(子行为)
|
||||
│ 长按(空闲) / 菜单「去指证」 │ 选中「结案陈词」条目+单击
|
||||
v v
|
||||
CONFRONT ──判定(hit/miss)──> BOARD FINISH(三问)
|
||||
│(经菜单「返回证词板」退出) ├─指认错→ acc 链 + fin_clear → BOARD
|
||||
│ └─指认对→ 凶器问→动机问→ VERDICT
|
||||
VERDICT(认罪链, 手势死窗+链锁) ──> SETTLE ──单击──> TITLE(新案: pack=1-pack)
|
||||
任意正交态 ──下滑──> MENU ──关闭/返回──> 原状态
|
||||
```
|
||||
|
||||
### 4.3 语音链推进契约
|
||||
|
||||
- 证词链=onComplete 串行(句间 0.8s 定时器);**兜底看门狗**:单句 8s 无 onComplete(资产缺失)→ 告警续链(「屏蔽任意 voice 资产流程不卡死」契约)。
|
||||
- 裁决链(VERDICT)与结算链(SETTLE)为**独占链**:链首停一切看门狗,链内不受理手势(§7.4)。
|
||||
- 教学链 `_speakGuarded` 串行(radio/dungeon 同款,杜绝同 tick 双调度抢占——D0-1 教训已固化引擎保险丝)。
|
||||
|
||||
## 5. 教学编排(DRILL,首局内嵌)
|
||||
|
||||
每步=一句短旁白→等待实操→反馈;做错重教同一步(新短句 ≤2 次)后自动演示通过;下滑=跳过教学(`tut_skip`),`meta.drillDone` 持久化,二周目不再进。教学寄生于真实案卷(D2 就听老葛真实证词,无假内容——教学承诺必须兑现)。
|
||||
|
||||
| 步 | 旁白 | 等待动作 | 通过条件/反馈 |
|
||||
|---|---|---|---|
|
||||
| D0 | intro_1→intro_2→intro_3→tut_d0 | 左滑或右滑任一 | 签名 earcon+条目名;confirm 震。**首输入 ≤60s 达成点 ≈t+20s** |
|
||||
| D1 | tut_listen | 单击 | 老葛证词链播(真实内容) |
|
||||
| D2 | tut_replay | 双击 | 当前句重播(免费) |
|
||||
| D3 | tut_status | 上滑 | 状态链(st_asked_1→st_doubt_0) |
|
||||
| D4 | tut_confront | 长按 | 进 CONFRONT + cf_start |
|
||||
| D5 | tut_cf_try | 选条目1(滑+单击)→选句(滑)→单击确认→选条目2→选句→单击确认 | **判定被教学截获**:任何选择组合都播 tut_cf_ok(练习不算数、不计 cfMiss、不动 doubts),回 BOARD。**首正反馈 ≤3min 达成点(success 震)** |
|
||||
| D6 | tut_done | — | 进 BOARD 自由调查;此后上滑/菜单随时可用 |
|
||||
|
||||
- D5 教学局不真判定的原因:教学时玩家只听过 1 份证词,真判定必 miss,会把「指证=挫败」印进第一印象;练习路径承诺「真矛盾要靠耳朵找」并在 2 份证词听齐后自然兑现(预期玩家首个真 hit 在 t+5-8min)。
|
||||
- FTUE 核对:遮罩→intro 三句(~13s)→D0 完成约 t+20s(<60s ✓);D5 完成 ≈t+2.5min(≤3min ✓);全程零惩罚(无资源、无倒计时)✓。
|
||||
|
||||
## 6. 案卷数据结构与随机性
|
||||
|
||||
### 6.1 JSON 草案(pack A 全量 + pack B fork;台词全文见台词表)
|
||||
|
||||
```json
|
||||
{
|
||||
"schema": 1,
|
||||
"packs": [
|
||||
{
|
||||
"id": 0, "name": "雨夜·聚宝斋", "culprit": "w3", "culpritName": "周先生",
|
||||
"items": [
|
||||
{ "id": "w1", "kind": "witness", "name": "item_w1", "sig": "sig_ge",
|
||||
"intro": null, "lines": [
|
||||
{ "id": "w1_1", "shuffle": false, "clues": {} },
|
||||
{ "id": "w1_2", "shuffle": true, "clues": { "rain": "2140", "dep_s": "2140" } },
|
||||
{ "id": "w1_3", "shuffle": false, "clues": { "visitor": "male_tall_hunched" } },
|
||||
{ "id": "w1_4", "shuffle": true, "clues": { "dep_z": "2150" } },
|
||||
{ "id": "w1_5", "shuffle": true, "clues": {} },
|
||||
{ "id": "w1_6", "shuffle": false, "clues": { "motive": "short" } } ] },
|
||||
{ "id": "w2", "kind": "witness", "name": "item_w2", "sig": "sig_shun",
|
||||
"intro": null, "lines": [
|
||||
{ "id": "w2_1", "shuffle": false, "clues": { "away_s": "south" } },
|
||||
{ "id": "w2_2", "shuffle": true, "clues": { "away_s": "south" } },
|
||||
{ "id": "w2_3", "shuffle": false, "clues": { "key": "hook" } },
|
||||
{ "id": "w2_4", "shuffle": true, "clues": {} },
|
||||
{ "id": "w2_5", "shuffle": false, "clues": { "door": "victim_opened" } },
|
||||
{ "id": "w2_6", "shuffle": true, "clues": {} } ] },
|
||||
{ "id": "w3", "kind": "witness", "name": "item_w3", "sig": "sig_zhou",
|
||||
"intro": "intro_w3", "lines": [
|
||||
{ "id": "z_1", "shuffle": false, "clues": { "dep_z": "2150" } },
|
||||
{ "id": "z_2", "shuffle": false, "clues": { "lamp": "off" } },
|
||||
{ "id": "z_3", "shuffle": false, "clues": { "key": "body" } },
|
||||
{ "id": "z_4", "shuffle": false, "clues": { "weapon": "wood", "scale": "sold" } },
|
||||
{ "id": "z_5", "shuffle": true, "clues": {} },
|
||||
{ "id": "z_6", "shuffle": true, "clues": {} } ] },
|
||||
{ "id": "w4", "kind": "witness", "name": "item_w4", "sig": "sig_wen",
|
||||
"intro": null, "lines": [
|
||||
{ "id": "wen_1", "shuffle": false, "clues": { "rain": "2140" } },
|
||||
{ "id": "wen_2", "shuffle": false, "clues": { "lamp": "on_2220" } },
|
||||
{ "id": "wen_3", "shuffle": false, "clues": { "wall": "climbed" } },
|
||||
{ "id": "wen_4", "shuffle": true, "clues": {} },
|
||||
{ "id": "wen_5", "shuffle": false, "clues": { "motive": "short" } },
|
||||
{ "id": "wen_6", "shuffle": true, "clues": {} } ] },
|
||||
{ "id": "scene", "kind": "scene", "name": "item_scene", "sig": "sig_scene",
|
||||
"lines": [
|
||||
{ "id": "sc_0", "shuffle": false, "clues": {} },
|
||||
{ "id": "sc_1", "shuffle": false, "clues": { "struggle": "none" } },
|
||||
{ "id": "sc_2", "shuffle": false, "clues": { "door": "victim_opened" } },
|
||||
{ "id": "sc_3", "shuffle": false, "clues": { "wall": "climbed" } },
|
||||
{ "id": "sc_4", "shuffle": false, "clues": { "scale": "present" } },
|
||||
{ "id": "sc_5", "shuffle": false, "clues": {} } ] },
|
||||
{ "id": "fore", "kind": "forensic", "name": "item_fore", "sig": "sig_fore",
|
||||
"lines": [
|
||||
{ "id": "fo_1", "shuffle": false, "clues": {} },
|
||||
{ "id": "fo_2", "shuffle": false, "clues": { "death": "2200_2230" } },
|
||||
{ "id": "fo_3", "shuffle": false, "clues": { "weapon": "bronze" } },
|
||||
{ "id": "fo_4", "shuffle": false, "clues": { "struggle": "none" } },
|
||||
{ "id": "fo_5", "shuffle": false, "clues": {} } ] }
|
||||
],
|
||||
"contradictions": [
|
||||
{ "id": "m1", "a": "z_2", "b": "wen_2", "axis": "lamp", "hint": "hint_c1" },
|
||||
{ "id": "m2", "a": "z_3", "b": "w2_3", "axis": "key", "hint": null },
|
||||
{ "id": "m3", "a": "z_4", "b": "fo_3", "axis": "weapon", "hint": null },
|
||||
{ "id": "m4", "a": "z_4", "b": "sc_4", "axis": "scale", "hint": "hint_c2" }
|
||||
],
|
||||
"verdict": { "accuseLine": "fin_right",
|
||||
"break": ["z_break_1", "z_break_2", "z_break_3"] },
|
||||
"wrongAccuse": { "w1": "acc_ge", "w2": "acc_shun", "w4": "acc_wen" },
|
||||
"reacts": ["z_react_1", "z_react_2", "z_react_3", "z_react_4"],
|
||||
"questions": {
|
||||
"weapon": { "options": ["wp_1", "wp_2", "wp_3", "wp_4"], "answer": "wp_2" },
|
||||
"motive": { "options": ["mv_1", "mv_2", "mv_3"], "answer": "mv_1" } }
|
||||
},
|
||||
{
|
||||
"id": 1, "name": "雨夜·聚宝斋(变体)", "culprit": "w2", "culpritName": "小顺",
|
||||
"base": 0,
|
||||
"overrides": {
|
||||
"w2": { "lines": [
|
||||
{ "id": "w2_1", "shuffle": false, "clues": { "away_s": "south" } },
|
||||
{ "id": "w2_2", "shuffle": true, "clues": { "away_s": "south" } },
|
||||
{ "id": "b_shun_1", "shuffle": false, "clues": { "lamp": "off" } },
|
||||
{ "id": "b_shun_2", "shuffle": false, "clues": { "key": "body" } },
|
||||
{ "id": "b_shun_3", "shuffle": false, "clues": { "weapon": "wood", "scale": "sold" } },
|
||||
{ "id": "b_shun_4", "shuffle": true, "clues": {} } ] },
|
||||
"w3": { "lines": [
|
||||
{ "id": "z_1", "shuffle": false, "clues": { "dep_z": "2150" } },
|
||||
{ "id": "b_zhou_1", "shuffle": true, "clues": {} },
|
||||
{ "id": "b_zhou_2", "shuffle": false, "clues": { "key": "hook" } },
|
||||
{ "id": "b_zhou_3", "shuffle": true, "clues": {} },
|
||||
{ "id": "z_5", "shuffle": true, "clues": {} },
|
||||
{ "id": "z_6", "shuffle": true, "clues": {} } ] },
|
||||
"contradictions": [
|
||||
{ "id": "m1b", "a": "b_shun_1", "b": "wen_2", "axis": "lamp", "hint": "b_hint_c1" },
|
||||
{ "id": "m2b", "a": "b_shun_2", "b": "b_zhou_2", "axis": "key", "hint": null },
|
||||
{ "id": "m3b", "a": "b_shun_3", "b": "fo_3", "axis": "weapon", "hint": null },
|
||||
{ "id": "m4b", "a": "b_shun_3", "b": "sc_4", "axis": "scale", "hint": "b_hint_c2" } ],
|
||||
"verdict": { "accuseLine": "fin_right_b",
|
||||
"break": ["b_shun_break_1", "b_shun_break_2", "b_shun_break_3"] },
|
||||
"wrongAccuse": { "w1": "acc_ge", "w3": "acc_zhou", "w4": "acc_wen" },
|
||||
"reacts": ["b_shun_react_1", "b_shun_react_2", "b_shun_react_2", "b_shun_react_2"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 6.2 seed 用法
|
||||
|
||||
```
|
||||
rng = mulberry32(seed) // 与 dungeon 同族
|
||||
pack = opts.pack ?? (opts.seed != null ? seed % 2 : null)
|
||||
正式局:seed = Math.floor(Math.random()*1e9);pack 首局=0,结案后新案 pack = 1 - pack(强制换案)
|
||||
洗牌(生成期一次性,存入 run.layout):
|
||||
① 各证人内部 shuffle:true 的 filler 句在其槽位集合内置换(首句与全部矛盾承载句固定)
|
||||
② 凶器问 4 选项、动机问 3 选项:Fisher-Yates by rng
|
||||
③ 保底提示 hint 轮询顺序:permuted by rng
|
||||
复现断言口径:同 (seed, pack) 两次构造 → game._case 深相等(布局/选项序/提示序逐项相等,不写魔法值)
|
||||
```
|
||||
|
||||
### 6.3 变体生成规则(pack B 逻辑摘要)
|
||||
|
||||
- **同模板**:同一桩雨夜命案、同 4 证人位、同现场/法医/温太太/老葛证词(音频全复用)、同 4 轴矛盾结构(lamp/key/weapon/scale)。
|
||||
- **不同真凶**:pack B 真凶=学徒小顺。fork=替换两份证词的句集:小顺换成 4 句谎(b_shun_1..4,复用其真实离店叙事作伪 alibi),周先生换成 3 句中性真话(b_zhou_1..3,其中 b_zhou_2「钥匙挂铜钩」成为 M2b 的对立端)。
|
||||
- **矩阵自洽**:pack B 的验算与 pack A 同构——lamp 轴唯一冲突对 (b_shun_1, wen_2);key 轴唯一冲突对 (b_shun_2, b_zhou_2);weapon/scale 由 b_shun_3(一句两断言)对 fo_3/sc_4。老葛 w1_3 的访客描述(高个微驼)由 b_shun_break_2「棉袄反穿,弓着背」解释,不产生新轴冲突。
|
||||
- **动机/凶器答案跨包一致**:监守自盗(小顺拿库房货换钱,b_shun_break_3 交代)与铜秤砣——问题反馈句两包共用。
|
||||
- **内容成本**:fork 仅 12 句 NPC + 1 句旁白(fin_right_b)+ 2 句提示(b_hint_c1/2)。
|
||||
|
||||
### 6.4 矩阵不变式(dev/playtest 双保险)
|
||||
|
||||
启动时与测试中断言:`{(a,b,axis) : a,b 同轴且值不同} ≡ contradictions`。任何台词改稿若引入新的同轴异值对,此断言立即失败——防止「文案事故变成指证归因假话」。
|
||||
|
||||
## 7. 评级系统与裁决仪式
|
||||
|
||||
### 7.1 结案三问(FINISH)
|
||||
|
||||
1. **真凶**(4 选 1:老葛/小顺/周先生/温太太;两段确认)。错→该证人 acc_NPC 自述不在场证明 + fin_clear → 回 BOARD;**无限再机会**,wrongWho 计数。
|
||||
2. **凶器**(4 选 1:松木劈柴/铜秤砣/铁门闩/青瓷花盆;选项序由 seed 洗牌)。对=fin_wp_right,错=fin_wp_wrong(真话归因,不重答,记账)。
|
||||
3. **动机**(3 选 1:监守自盗/寻仇泄愤/劫财入户)。同上。
|
||||
|
||||
### 7.2 评级标准(S-C)
|
||||
|
||||
变量:`doubts`(疑点 0-4)、`weaponOk`、`motiveOk`、`wrongWho`(指认错次数)、`cfMiss`(冗余指证次数)、`hints`(保底提示已播数)。
|
||||
|
||||
| 档 | 条件(自上而下首个命中) | 播报 |
|
||||
|---|---|---|
|
||||
| S | doubts=4 ∧ weaponOk ∧ motiveOk ∧ wrongWho=0 ∧ cfMiss≤2 ∧ hints=0 | rate_s「教科书结案。四处疑点,一击即中。」 |
|
||||
| A | doubts≥3 ∧ weaponOk ∧ motiveOk ∧ wrongWho≤1 ∧ hints≤1 | rate_a「干净利落的结案。」 |
|
||||
| B | doubts≥2 ∧ wrongWho≤2 | rate_b「案子结了,卷宗上有疏漏。」 |
|
||||
| C | 其余(案子必然已结) | rate_c「案子是结了,卷宗上补丁不少。」 |
|
||||
|
||||
- 结案必达:无失败态;C 档覆盖「全靠保底提示/疑点<2/指认错 ≥3」。
|
||||
- 措辞-账目对账:S 的「一击即中」=wrongWho 0;「四处疑点」=doubts 4;C 的「补丁」=hints≥2 或 cfMiss≥3 或 wrongWho≥3——每句评级文案与触发条件一一对应(E1-2 档位措辞真实教训)。
|
||||
|
||||
### 7.3 结算账目播报(真实)
|
||||
|
||||
SETTLE 链:`settle_open → rate_X → st_doubt_n(疑点实数)→ st_miss_档(cfMiss: 0/1-2/≥3 → 三档真话)→ settle_hook(单击接新案,键盘态用 settle_hook_k)`。所有分档句按运行值选播,播报值=存储值(playtest 锁定)。
|
||||
|
||||
### 7.4 裁决仪式(VERDICT,结案宣判完整弧线)
|
||||
|
||||
指认正确后进入,**链不可打断**(dungeon H1 教训:结算链不许被在途手势截杀):
|
||||
|
||||
```
|
||||
fin_right(证据链闭合)→ sfx/rain_s swell 起
|
||||
→ z_break_1 → z_break_2 → z_break_3(认罪,声音演技高潮;bgm/verdict)
|
||||
→ sfx/gavel(法槌)→ settle_open → SETTLE(接 §7.3 链)
|
||||
```
|
||||
|
||||
- **手势死窗**:进 VERDICT 即盖 `VERDICT_GRACE_MS=800` 戳(同 dungeon SETTLE_GRACE:touchstart+450ms 长按判定+300ms 双击窗 ≈750ms,800 全盖);死窗内一切手势吞掉(ghost 手势不算输入、不碰看门狗)。
|
||||
- **链锁**:VERDICT→SETTLE 全链播完(settle_hook 落声)前,单击/右滑/长按一律吞掉;链完成后单击=接新案(settle_hook 承诺「单击,接新案」言行一致——simon round1-live 教训)。双击=重听结算链仅在链完成后受理。
|
||||
|
||||
## 8. 音频三层
|
||||
|
||||
### 8.1 BGM(3 首,Mureka instrumental,-20 LUFS,ogg+m4a,无缝循环;雨声底烤进曲目,省第三声流)
|
||||
|
||||
| id | 状态映射 | Mureka prompt(英文) |
|
||||
|---|---|---|
|
||||
| bgm/menu | TITLE / MENU / SETTLE(结算 volume 0.5) | "Rainy night noir jazz ballad, slow brushed drums, lazy saxophone, soft rain ambience, melancholy and calm, no vocals, seamless loop" |
|
||||
| bgm/board | DRILL / BOARD / CONFRONT / FINISH | "Moody jazz trio for a detective's office, muted piano walking, upright bass, soft rain on window, focused and mysterious, no vocals, seamless loop" |
|
||||
| bgm/verdict | VERDICT(认罪链起播,交叉淡入) | "Tense noir jazz climax, brooding low strings under sparse piano, rain intensifying then settling, dramatic restraint, no vocals, seamless loop" |
|
||||
|
||||
切换全走引擎 crossfade;对白 duck 20% 引擎自动。choice/danger 不换曲(状态区分由 guide earcon 承担,氛围连续性优先)。预算:3 曲 ×2 候选 = 6 任务 $0.18(项目上限 $2.00 内)。
|
||||
|
||||
### 8.2 SFX(12 个;SA3=Stable Audio 3,SYN=程序合成;双格式、真峰值 ≤-3dBFS)
|
||||
|
||||
| 类别 | id | 方式 | 说明 |
|
||||
|---|---|---|---|
|
||||
| 卷宗 | `paper_turn` | SA3 | 翻卷宗页(条目切换内容反馈,"single paper page turn on desk, dry, close") |
|
||||
| 证人签名 | `sig_ge` | SA3 | 搪瓷缸顿桌一下(老葛) |
|
||||
| | `sig_shun` | SYN | 布掸子拍柜台两下(小顺) |
|
||||
| | `sig_zhou` | SA3 | 算盘珠拨两响(周先生) |
|
||||
| | `sig_wen` | SYN | 门环叩两下(温太太) |
|
||||
| | `sig_fore` | SYN | 纸页翻动+钢笔划线(法医报告) |
|
||||
| | `sig_scene` | SA3 | 雨中皮鞋踩水两步+伞抖水(现场,0.5s) |
|
||||
| 指证 | `contra_hit` | SYN | 不和谐金属二度相击+盖章尾(矛盾证实音,全游戏最强确认音) |
|
||||
| | `contra_miss` | SYN | 钝木鱼一下(对不上——非 error 音色,不威吓) |
|
||||
| 裁决 | `gavel` | SA3 | 法槌一击("wooden gavel single strike, small room reverb") |
|
||||
| | `rain_swell` | SA3/SYN | 雨声渐强再落(认罪链垫,6s one-shot) |
|
||||
| 看门狗 | `turn_tick` | SYN | 880Hz 木鱼族轻响(无进展轨 L1 复用 dungeon 配方,自存一份) |
|
||||
|
||||
并发纪律:签名 earcon(≤0.5s)→ 条目名语音,串行不叠;contra_hit 先响、cf_hit 语音后接。声流恒 ≤2(BGM + voice)。
|
||||
|
||||
### 8.3 voice(158 句:旁白 106 ×2 性别 + NPC 平铺 52)
|
||||
|
||||
- **旁白**(系统/指引/教学/状态/现场自勘/裁决宣读):female=Serena / male=Uncle_Fu,instruct 常量全表统一(见台词表头);数字全分档整句(st_asked 7 档/st_doubt 5 档/st_miss 3 档),**句序号一律不播**(指证选句用重播该句代替报数——数字拼接禁令的交互侧落实)。
|
||||
- **NPC 平铺单音色**(证词=证人 NPC;不做双性别;落 `voice/` 根目录,引擎平铺回退命中):
|
||||
|
||||
| 角色 | speaker | instruct 常量 | 区分度风险 |
|
||||
|---|---|---|---|
|
||||
| 老葛(门卫 62) | Eric | 苍老沙哑的男声,守夜人,慢悠悠,带倦意 | 低:与两侧旁白均不同 speaker |
|
||||
| 小顺(学徒 19) | Dylan | 年轻清亮的男声,学徒,怯生生的,慌张诚实 | 低:同上 |
|
||||
| 周先生(账房,真凶 A) | Uncle_Fu | 平板谨慎的男声,账房,字斟句酌,被追问时渐慌 | **中**:与 male 旁白同 speaker——靠 sig_zhou 前缀+账房腔 instruct+证词链内零旁白插话;试听确认 |
|
||||
| 温太太(房东 50) | Vivian | 快嘴泼辣的中年女声,房东太太,嗓门亮,热心肠 | 低:与两侧旁白均不同 speaker |
|
||||
| 秦法医 | Serena | 冷静干练的女声,验尸官,临床腔,短句平直 | **中**:与 female 旁白同 speaker——靠 sig_fore 前缀+报告语境固定(只在整个案卷固定条目出现);试听确认 |
|
||||
|
||||
- **声音演技核心**:周先生 z_react_1..4(记岔了→支吾→拒答→想走)与 z_break_1..3(认罪三段)是本作表演高潮;instruct 恒定、情绪写在句内文本(标点与省略号引导),不靠句级 instruct 变体(音色漂移禁令)。pack B 对应 b_shun_react/b_shun_break。
|
||||
- 全表、触发时机、键盘变体(V 组)与多音字自查见 [18-detective-voice-ids.md](18-detective-voice-ids.md)。
|
||||
|
||||
## 9. 向导层接入(engine/guide.js,不新增 earcon 词表)
|
||||
|
||||
### 9.1 状态签名(进入状态时播)
|
||||
|
||||
| 状态 | guide.state() | 时点 |
|
||||
|---|---|---|
|
||||
| TITLE / MENU / SETTLE | `menu` | 进标题、开菜单、进结算 |
|
||||
| DRILL / BOARD | `explore` | 进教学、进证词板(含指证判定后返回) |
|
||||
| CONFRONT / FINISH | `choice` | 进指证、进结案三问 |
|
||||
| VERDICT | `settle` | 认罪链起 |
|
||||
| danger | 不使用 | 本作无生命/倒计时压力(登记) |
|
||||
|
||||
### 9.2 turn cue 与看门狗(双轨——批次 1 教训固化)
|
||||
|
||||
| 等待点 | 机制 | at | say(full 档;第 2 级一律纯 nudge) |
|
||||
|---|---|---|---|
|
||||
| CONFROST/FINISH 各选择相位入口 | guide.turn | — | turn earcon + confirm 震 |
|
||||
| BOARD 空闲 | watchdog 无操作轨 | [10s, 25s] | gd_board / null |
|
||||
| CONFROST 选句/确认 | watchdog 无操作轨 | [15s, 30s] | gd_cf / null |
|
||||
| FINISH 三问 | watchdog 无操作轨 | [20s, 40s] | gd_fin / null |
|
||||
| DRILL 每步 | watchdog 无进展轨(共享) | [30s/60s/90s] | earcon → 短句 → tut_skip 自动滚出(E0-2 先例) |
|
||||
|
||||
### 9.3 无进展轨(调查态卡关三级,**证词板乱按也要被抢救**)
|
||||
|
||||
- 进展事件=听完新条目 / 指证判定 / 结案相位推进(`_progressTrack()` 挂点:条目链 onComplete、judge()、FINISH 相位切换)。**只由进展重置**——乱按(疯狂换条目不听完、播放中狂点停起)永远攒不满进展,三级必达:
|
||||
- [45s] L1:turn_tick earcon(不占台词通道)→ [90s] L2:`hint_a`(还有未听条目时)/ `hint_b`(都听过但疑点未齐)→ [150s] L3:**保底给出可指证的矛盾对**(hint_c1/hint_c2 按未发现清单轮询,seed 定序);4 疑点齐 → `hint_fin`(去结案)。L3 后每 150s 重复(每句全局限 2 次,之后静默——不轰炸)。
|
||||
- 无操作轨(手势重置)与无进展轨并行取先到;两轨短句内容同级交叉登记防重复。纠错/提示 idle-only、过期丢弃(引擎已实现)。
|
||||
|
||||
## 10. 存档设计
|
||||
|
||||
```json
|
||||
{
|
||||
"schema": 1, "game": "detective", "updatedAt": 0,
|
||||
"summary": "雨夜·聚宝斋 · 已问3/6 · 疑点2/4",
|
||||
"meta": { "drillDone": true, "casesClosed": 1, "bestGrade": "A", "lastPack": 0 },
|
||||
"run": {
|
||||
"seed": 42, "pack": 0, "layout": { "w1": [...], "wpOpts": [...], "hintOrder": [...] },
|
||||
"heard": ["w1", "scene", "fore"],
|
||||
"doubts": [false, true, false, false],
|
||||
"cfMiss": 1, "wrongWho": 0, "zHits": 1,
|
||||
"hintsGiven": ["hint_c1"], "weaponAns": null, "motiveAns": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- summary 生成规则:`{案名} · 已问{heard.length}/6 · 疑点{doubts 中 true 数}/4`(结案后 run=null,summary=`已结案{casesClosed}起 · 最佳{bestGrade}`)。
|
||||
- 保存时机:条目链播完 / 指证判定后 / 菜单「保存并回大厅」/ 结案入 meta。localStorage + PUT 服务器。
|
||||
- 读取:有 run → TITLE 播 sys_continue_ask,单击继续 → 恢复(layout 复用存档值,不重洗)→ **局面复述链**:`st_asked_n →(未听条目 ≤3 个时逐个播 item_* 名;>3 个只报计数)→ st_doubt_m → recap_go`,≤10s 回到可操作;右滑=换新案(seed/pack 重掷,meta 保留)。
|
||||
- 归因真话依据:评级各变量全部持久化(doubts/cfMiss/wrongWho/hintsGiven/answers),结算播报从同源读取。
|
||||
|
||||
## 11. playtest 断言清单(登记 13 号文档新增 §detective;mock 对齐 web/rpg/test/playtest.mjs;一律 guide:'off')
|
||||
|
||||
**关键路径**(seed=42, pack=0,≤200 手势):
|
||||
1. 启动→TITLE(无档)→单击→DRILL:D0..D6 逐步断言 voice 序与 drillStep 递进;D5 任意选择组合都播 tut_cf_ok 且 doubts/cfMiss 零变化(教学承诺兑现);下滑跳过路径 + meta.drillDone 二周目不再进。
|
||||
2. **seed 复现**:(42,0) 两次构造 → `_case` 深相等(条目/句序/filler 洗牌/选项序/提示序);(42,1) 与 (43,1) 布局不同。
|
||||
3. **矩阵不变式**:对 `_case` 全句对枚举轴交集——同轴异值对集合 ≡ contradictions(pack A 与 pack B 各验一遍)。
|
||||
4. 听取:6 条目链完整(句序=layout)、双击=当前句重播零消耗、单击停止、播完 st_asked 升档;播放中左右滑静默忽略(无 error 震)。
|
||||
5. **指证 4 矛盾逐条走通**:M1-M4 各自导航→两段确认→contra_hit+cf_hit+react_n(zHits 递进取句)→doubts 置位;M3/M4 共用 z_4(选 z_4 两次分别对 fo_3/sc_4);指证对无序(反向选也 hit)。
|
||||
6. **指证 miss 三档真话**:同轴同值对(w1_2 vs wen_1)→cf_same;无共享轴对(z_5 vs sc_1)→cf_diff;同句→cf_self;cfMiss 计数、无任何资源/次数惩罚。
|
||||
7. **指认全路径**:错指小顺/老葛/温 → acc_NPC+fin_clear+回 BOARD(无限次);对指周先生 → 凶器问(选项序=layout)→ 动机问 → VERDICT。
|
||||
8. **裁决死窗**:指认对瞬间同拍与 +300ms 各补一记在途 tap → 均被吞(仍 VERDICT);认罪链 4 句+gavel+settle 链完整有序;链后单击=接新案(pack 翻转、seed 重掷、meta 入账)。
|
||||
9. **评级账目**:注入 outcomes 矩阵(doubts∈{0..4}×weapon×motive×wrongWho×cfMiss×hints 代表组合 ≥10 组)→ 断言 grade 判定与 §7.2 表一致 + 结算链播报句(rate_X/st_doubt_n/st_miss_档)与运行值一致(假话即失败)。
|
||||
10. **看门狗双轨**:BOARD 10s/25s(gd_board→nudge);无操作 96s 乱按零进展 → 无进展轨 45s earcon/90s 短句/150s hint_c(给出未发现矛盾对且该对可走通指证);有真实进展零提示;4 疑点齐后 150s → hint_fin。
|
||||
11. **中断复述**:存档重进→sys_continue_ask→单击→复述链序(st_asked→未听 ≤3 时 item 名链→st_doubt→recap_go);上滑同链可重放。
|
||||
12. **二周目变体**:seed'/pack=1 → 矛盾表指向 b_shun_*/b_zhou_2、culprit=w2、错指周先生走 acc_zhou、认罪链 b_shun_break、hint 为 b_hint_c1/2;矩阵不变式复验。
|
||||
13. **键盘变体**:`settings.input='key'` 后播 sys_help_k/tut_d0_k 等 V 组(inputMode 联动);'touch' 回基础句。
|
||||
14. 菜单/帮助/存档:模态菜单循环-确认-关闭;「保存并回大厅」→PUT data.summary 命中生成规则;「去指证」= 长按同效。
|
||||
|
||||
**边界断言**:
|
||||
- 教学期零惩罚:D5 任意乱选不产生 cfMiss/doubts 变化;全程无倒计时(全 run 无 timeout 惩罚断言)。
|
||||
- 长按豁免:BOARD 播放中长按=引擎快进(不进指证);空闲长按→CONFRONT;CONFRONT/FINISH 长按=error 震。
|
||||
- 状态链随时可用(含播放中,打断后双击可重听当前句);播报值=heard/doubts 实值。
|
||||
- 指证第二份选择时自动重播第一份选定句(P1 记忆契约)。
|
||||
- 屏蔽任意 voice 资产:链 8s 兜底推进,流程到结案不死锁。
|
||||
- guide=off:全静、零定时器;资产齐套:voice 双性别 id 集合一致 + NPC 平铺存在 + sfx/bgm 双格式。
|
||||
- VERDICT/SETTLE 链内上滑/下滑/双击全部吞掉(链锁),链完成前无任何状态逃逸。
|
||||
|
||||
**失败即不通过**:归因假话(cf_same/cf_diff/评级句与数据实值不符);矩阵外冲突对存在;同 (seed,pack) 两次构造不一致;教学练习计入账目;裁决链被手势截杀或链句缺失;保底 hint 给出的矛盾对走不通指证。
|
||||
|
||||
## 12. 节奏曲线与单局核算
|
||||
|
||||
| 阶段 | 时长 | 内容 | 奖励点(≤60s 一个) |
|
||||
|---|---|---|---|
|
||||
| 开场链 | 0:20 | intro 三句 | — |
|
||||
| DRILL | 0:20-2:40 | D0-D6(老葛证词首听在 D1) | D5 完成 success 震(t+2.5min) |
|
||||
| 自由调查 | 2:40-9:00 | 5 条目听取+句级重听+状态核对 | 每条目听毕 st_asked 升档 |
|
||||
| 指证穿插 | 5:00-12:00 | 4 矛盾(两证词齐后即可开始,玩家自定节奏) | 每个 hit:contra_hit+真凶 react 递进 |
|
||||
| 结案三问 | 12:00-14:00 | 真凶/凶器/动机 | 指认对=fin_right(高潮起) |
|
||||
| 裁决+结算 | 14:00-15:30 | 认罪链+法槌+评级 | 评级播报+开环钩子 |
|
||||
|
||||
- 一周目 15-20 分钟(重听多的松玩家 ≤25);二周目(跳教学+已熟导航)13-15 分钟。15-30 分钟章程达标。
|
||||
- 悬念曲线:听证词(信息积累)→ 首个 hit(「证词会撒谎」兑现)→ react 递进(真凶渐慌)→ 三问(主动权全在玩家)→ 认罪(演技高潮)——每 30-60s 必有可感知进展(条目数/疑点数两个可见账本)。
|
||||
- 开环钩子:settle_hook「同一场雨里,还有别的案子」+ pack 强制翻转(二周目必遇变体真凶)。
|
||||
|
||||
## 13. 自检清单
|
||||
|
||||
| # | 硬约束/教训 | 自检 |
|
||||
|---|---|---|
|
||||
| 1 | FTUE 首输入 <60s | D0 完成约 t+20s ✓(§5) |
|
||||
| 2 | 首个正反馈 ≤3min | D5 教学完成 success 震 ≈t+2.5min;首个真 hit 预期 t+5-8min(本作类型内最近可达)✓ |
|
||||
| 3 | 学习期零惩罚 | 无资源无倒计时全域;D5 练习不算账 ✓ |
|
||||
| 4 | 失败三问归因+真话律 | 指证 miss 三档从轴数据推导;指认错=不在场证明复述;凶器/动机错=物证归因;评级句与账目一一对应 ✓(§3.6/§7,playtest 失败项锁定) |
|
||||
| 5 | 手势宪法三件套不豁免 | 上滑状态/下滑菜单/双击重听全状态保留;仅 E1/E2 登记且教学讲清 ✓(§2.6) |
|
||||
| 6 | 向导层 | 签名 4 态(choice 用、danger 登记不用);双轨看门狗(无操作+无进展,乱按必被抢救);保底 hint 给可走通矛盾对;idle-only/queue/onceKey ✓(§9) |
|
||||
| 7 | 教学承诺兑现 | tut 承诺的每个手势在正片同语义可用;settle_hook「单击接新案」言行一致(死窗+链锁后)✓ |
|
||||
| 8 | 结算链完整 | VERDICT 手势死窗 800ms+链锁,认罪→法槌→评级全链不可截(H1 教训)✓(§7.4) |
|
||||
| 9 | 档位措辞真实 | S-C 条件与文案一一映射;st_asked/st_doubt/st_miss 播报值=运行值 ✓(§7.2/7.3) |
|
||||
| 10 | 信息密度 | 所有列表逐项预览(≤3 选项/次);证词句粒度 ≤8s、链播 ≤35s 可停可重听(≤40s 听觉负荷)✓(§3.7) |
|
||||
| 11 | P4 容错 | 无惩罚性失败;错指无限再机会;保底必破案(hint_c 直接给对子);零新手势 ✓ |
|
||||
| 12 | P1 视障 | 句级免费重听;导航规整(条目→句→指证同一范式);状态链随时可查;账目真实;5 speaker+签名 earcon 防混淆(2 处重叠风险已登记缓解);2.2× 语速引擎既有 ✓ |
|
||||
| 13 | P3 通勤 | 中断复述(已问谁/待问谁 ≤3 名直报/疑点几处);单手免视;任意时刻菜单退出存档;3 分钟颗粒=一份证词完整听取+比对 ✓ |
|
||||
| 14 | P2 大学生 | react 递进/认罪演出钩子;pack 翻转二周目变体;评级 S 追求(全疑点+零冗余)✓ |
|
||||
| 15 | seed 可复现 | (seed,pack) 注入+布局洗牌全 PRNG+深相等断言;变体包数据驱动 ✓(§6.2) |
|
||||
| 16 | 矛盾矩阵验算 | 全轴枚举表:同轴异值对 ≡ M1-M4;一致对 6/单断言/无轴句清单 ✓(§3.4/§6.4 不变式) |
|
||||
| 17 | 指证全路径可走通 | hit(4 矛盾×双向)/miss 三档/同句/错指三人(A)/错指含周(B)/三问对错/保底 hint 对——全部有专属资产与断言 ✓(§11 路径 5-10、12) |
|
||||
| 18 | 台词规范 | 全句 ≤40 字(实测 ≤31);数字全分档整句;句序号不播(重播代替报数);「重新听」写法;同角色 speaker+instruct 恒定;总句数 158 ≤160 ✓(台词表) |
|
||||
| 19 | 键盘通道 | 操作提示句 V 组 10 变体集中登记,inputMode() 选播;空格/回车/方向键全手势可达(§5.5 平行通道,游戏层零改动)✓ |
|
||||
| 20 | 引擎能力边界 | 无实时节点(链播 onComplete+setTimeout);长按快进与长按指证时间互斥;资产缺失静默跳过+8s 兜底;30MB 预算内 ✓ |
|
||||
@@ -0,0 +1,258 @@
|
||||
# 19b · 《暗码》(cipher) 语音台词表(voice ids,录音依据)
|
||||
|
||||
> **给音频总监的录制说明**
|
||||
> - **双性别组**(报务员 OP + 北风电台 WIND,134 句):落 `web/cipher/audio/voice/female|male/<id>.{ogg,m4a}`,两性别 id 集合完全一致(含全部 `_k` 变体)。
|
||||
> - **OP(报务员=玩家)**:female = `Serena`,instruct 常量 `压低而冷静的年轻女声,报务员,值夜班,克制的紧张`;male = `Uncle_Fu`,instruct 常量 `压低而冷静的男声,报务员,值夜班,克制的紧张`。
|
||||
> - **WIND(北风电台=上线联络+系统音/向导 gd_*)**:female = `Vivian`,instruct 常量 `清晰平稳的女声,电台联络声,隔着电流,字字清楚`;male = `Dylan`,instruct 常量 `清晰平稳的男声,电台联络声,隔着电流,字字清楚`。
|
||||
> - 区分度设计:你(耳机旁的自语)与北风(电波里传来的控制声)共用 speaker 池但**不同 speaker 配对**——female 侧你 Serena / 北风 Vivian、male 侧你 Uncle_Fu / 北风 Dylan,同场景高频对话的两者永不同 speaker(radio 主播/导播先例)。
|
||||
> - **NPC 平铺组**(5 句):单音色、**不做双性别**,平铺落 `web/cipher/audio/voice/<id>.{ogg,m4a}`(引擎平铺回退命中)。有台词人物仅 2 人:北风(已并入 WIND 双性别组,向导人设 L4,radio 导播同型)+ 处长(明线上级,本表 NPC)。另有**无台词角色**「快手七」(对家报务手,存在=电波里的手法音,零台词零资产,abyss 小郑先例)。**不加滤波**(detective 先例:处长是当面训话,区分度靠 speaker+instruct+语境;「电波里的人」与「身边的人」靠 WIND/OP 音色对立立住):
|
||||
> | 角色 | speaker | instruct 常量 | 区分度风险 |
|
||||
> |---|---|---|---|
|
||||
> | 处长(明线上级,50 余岁) | `Eric` | `威严冷淡的中年男声,电讯处长,官腔,话里有话` | **低**:male 侧唯一 Eric,与两侧双性别组均不同 speaker |
|
||||
> - **称呼规则**:处长对玩家一律称「值机员/你」,北风称「你」,**全表禁用**「姑娘/小哥/先生/同志」类性别化称呼(玩家性别随设置变化)。
|
||||
> - **键盘变体(PC 键盘通道,P1 机制)**:带 `_k` 后缀的 id 为键盘措辞版(「按空格」「回车」「左箭头/右箭头/上箭头/下箭头」),与触屏版**成对生成、成对落盘**(`check_all_assets` 校验 `_k` 配对);运行时由 `gesture.inputMode()` 选择:`key` → `<id>_k`,`touch` → `<id>`,`auto` 跟随最近使用通道,`_k` 缺失回退无后缀版。变体共 **11 对**,全部集中在 §G0.a 操作提示句区与 §M1 首个候选导航/首个叙事抉择(dv1_teach2 / p2),以粗体标注。
|
||||
> - **数字规避**:电文序号/密码本页数/暴露档位全部分档整句(prog_t1..t4、book_3..0、exp_calm/low/mid/hot);句内数字(民国二十九年/零点/丑时/三时/两点五十九分/一刻钟)写死在整句里,禁止运行时拼接。
|
||||
> - **禁语速词**:instruct 不含任何语速描述(引擎 SoundTouch 变速);NPC 句靠短句+逗号停顿实现「官腔慢半拍」听感。
|
||||
> - **摩尔斯不在本表**:电文/候选/重听/慢放的滴答声为运行时程序合成(`web/cipher/morse.js`,19-cipher.md §2.1),零文件资产,勿排产。
|
||||
> - 管线:`tools/gen_voice_dual.py` 照录(SPEAKERS 表需新增 cipher 行 + CIPHER_NPC 平铺表);多音字自查见文末注记。
|
||||
|
||||
## G0 组 · 系统/向导/状态(WIND 双性别 ×39)
|
||||
|
||||
### G0.a 操作提示句(含键盘变体,9 对 18 句——键盘玩家听这一区就够)
|
||||
|
||||
| id | 台词全文 | 触发 |
|
||||
|---|---|---|
|
||||
| `gd_brief` | 单击继续值机。要选词时,向左或向右滑。 | 开场链最前(full 档,F8 先例) |
|
||||
| **`gd_brief_k`** | 按空格继续值机。要选词时,用左右方向键。 | 同上(inputMode=key) |
|
||||
| `gd_continue` | 单击屏幕,继续。 | 叙事链末看门狗第 1 级(full 25s / standard 13s) |
|
||||
| **`gd_continue_k`** | 按空格,继续。 | 同上(key) |
|
||||
| `gd_again` | 还在吗?单击继续。 | 看门狗第 2 级(50s / 30s),新句不逐字重播 |
|
||||
| **`gd_again_k`** | 还在吗?按空格继续。 | 同上(key) |
|
||||
| `gd_tune1` | 电文在等。左右滑,听候选词。 | DECODE 浏览静默 10s(第 1 级) |
|
||||
| **`gd_tune1_k`** | 电文在等。左右方向键,听候选词。 | 同上(key) |
|
||||
| `gd_tune2` | 双击,把电文再听一遍。再双击,会放慢。 | DECODE 浏览静默 25s(第 2 级,**必须与第 1 级不同句**;同时是慢放机制的常驻教学) |
|
||||
| **`gd_tune2_k`** | 按回车,把电文再听一遍。再按一次,会放慢。 | 同上(key) |
|
||||
| `sys_help` | 单击选定,双击重新听电文。上滑听状态,下滑开菜单。选择时,左右滑。 | 上滑帮助链尾 / 菜单内上滑 |
|
||||
| **`sys_help_k`** | 空格选定,回车重新听电文。上箭头听状态,下箭头开菜单。选择时,左右箭头。 | 同上(key) |
|
||||
| `sys_menu` | 菜单。单击切换选项,双击确认。 | 下滑呼出模态菜单 |
|
||||
| **`sys_menu_k`** | 菜单。空格切换选项,回车确认。 | 同上(key) |
|
||||
| `sys_skip` | 想跳过这句,单击就行。 | 开场每局一次(skip_hint 先例) |
|
||||
| **`sys_skip_k`** | 想跳过这句,按空格。 | 同上(key) |
|
||||
| `sys_continue_ask` | 检测到你的值机记录。单击继续上次,右滑开始新的夜班。 | 有存档进游戏 |
|
||||
| **`sys_continue_ask_k`** | 检测到你的值机记录。空格继续上次,右箭头开始新的夜班。 | 同上(key) |
|
||||
|
||||
### G0.b 状态/系统句(无手势词,无变体)
|
||||
|
||||
| id | 台词全文 | 触发 |
|
||||
|---|---|---|
|
||||
| `gd_invalid` | 这个手势,值机室里用不上。 | 无效手势(error 震,idle-only,同局限次) |
|
||||
| `gd_prog1` | 光切词没有用。双击,先听电文。 | 无进展轨 60s(第 1 级,乱按抢救) |
|
||||
| `gd_prog2` | 别急。停下来,把电文听完整。 | 无进展轨 120s(第 2 级) |
|
||||
| `sys_menu_resume` | 回到电波里。 | 菜单项 |
|
||||
| `sys_menu_book` | 翻密码本,换一个字母。 | 菜单项(长按捷径的冗余入口,P4) |
|
||||
| `sys_menu_restart` | 重新开始今晚。 | 菜单项 |
|
||||
| `sys_menu_lobby` | 保存并回大厅。 | 菜单项(确认后跳转前播) |
|
||||
| `sys_settings` | 音色、语速、背景音乐,请回大厅修改。 | 菜单内设置提示 |
|
||||
| `sys_new_night` | 新的夜班,开始了。 | 新夜班开始 / 菜单重开 |
|
||||
|
||||
### G0.c 分档状态句(整句账目,逐值为真)
|
||||
|
||||
| id | 台词全文 | 触发 |
|
||||
|---|---|---|
|
||||
| `prog_t1` | 现在是今晚第一封电文。 | 上滑状态链(按当前封选播) |
|
||||
| `prog_t2` | 现在是第二封,内部通报。 | 同上 |
|
||||
| `prog_t3` | 现在是第三封,交接电文。 | 同上 |
|
||||
| `prog_t4` | 第四封,最后一封。 | 同上 |
|
||||
| `book_3` | 密码本,还剩三页。 | 状态链(余页=3;开局) |
|
||||
| `book_2` | 密码本,还剩两页。 | 余页=2 |
|
||||
| `book_1` | 密码本,只剩最后一页。 | 余页=1 |
|
||||
| `book_0` | 密码本,一页都不剩了。 | 余页=0 |
|
||||
| `exp_calm` | 这一晚,还没人看你第二眼。 | 暴露度 0(跨档时挂夜结算链尾;状态链) |
|
||||
| `exp_low` | 处长端着茶,多看了你一眼。 | 暴露度 1-2 |
|
||||
| `exp_mid` | 走廊里的脚步声,慢了下来。 | 暴露度 3-4 |
|
||||
| `exp_hot` | 门外,好像有人换了岗。 | 暴露度 ≥5;各播报位附 warning 震 |
|
||||
|
||||
## G1 组 · 开场(双性别 3 + 处长平铺 1)
|
||||
|
||||
| id | 声部 | 台词全文 | 触发 |
|
||||
|---|---|---|---|
|
||||
| `b_open` | 你 | 民国二十九年,江城。电讯处的夜班,从零点的电波声开始。 | INTRO(配 sfx/amb_room) |
|
||||
| `b_rule` | 北风 | 北风问候你。规矩就一条:听不清,就再听一遍。 | INTRO(一句规矩,P4;重听/慢放承诺) |
|
||||
| `b_goal` | 北风 | 今晚频道里有四封密电。每一个字,都要过你的耳朵。 | INTRO(四封承诺;随后第一封起播) |
|
||||
| `b_chief` | 处长 | 四封电文,一封都不许漏。你的耳朵,是处里最值钱的东西。 | INTRO 收尾(处长夜令,明线口径;配 sfx/tea_cup) |
|
||||
|
||||
## M1 组 · 第一封·船期·教学(双性别 19,含 _k 2)
|
||||
|
||||
> 真词 **BAY=货船**;候选 DAY=客车 / RAY=巡逻艇;辨析位=第 1 字母。T1 译错**无限重选零惩罚**,恒收敛真词。
|
||||
|
||||
| id | 声部 | 台词全文 | 触发 |
|
||||
|---|---|---|---|
|
||||
| `rx1_in` | 北风 | 第一封。江上船队的调度,拍得很稳。 | RX 引入(配 sfx/tune_seek,随后摩尔斯首播 BAY) |
|
||||
| `dv1_teach` | 北风 | 电文进来了。先双击,把它重新听一遍。 | 首播后 DECODE 教学 ①(教「双击=重听」) |
|
||||
| `dv1_teach2` | 北风 | 左右滑,听密码本上的候选词。单击,选定一个。 | DECODE 教学 ②(教候选导航+两段确认首击) |
|
||||
| **`dv1_teach2_k`** | 北风 | 左右方向键,听密码本上的候选词。空格,选定一个。 | 同上(key;候选导航键位绑定) |
|
||||
| `dv1_ask` | 北风 | 密码本第一页。三个词,哪个是它? | 抉择提示(choiceArmed;进浏览自动预听候选 1) |
|
||||
| `cand_bay` | 北风 | 货船。 | 候选预听报名(候选摩尔斯 620Hz 对照档之后接播;全 DECODE 复用本封) |
|
||||
| `cand_day` | 北风 | 客车。 | 同上 |
|
||||
| `cand_ray` | 北风 | 巡逻艇。 | 同上 |
|
||||
| `dv1_right` | 北风 | 货船,译对了。药品,装在货船的底舱。 | T1 译对判定(success 震;首个正反馈 ≈t+2min) |
|
||||
| `dv1_wrong` | 北风 | 不对。听清楚:B,一长,三短。 | T1 译错即时归因(真话:真词首字母的摩尔斯写死在句里;无限重选) |
|
||||
| `hint_t1` | 北风 | 我教你一页:第一个字母,是 B。一长,三短。 | T1 翻密码本(**首次免费不扣页**,Prime→Teach;配 sfx/paper_page) |
|
||||
| `cf_confirm` | 北风 | 就这个词?再单击,定下来。 | 两段确认第 1 击(全 DECODE 共用;随后电文重播原速一遍) |
|
||||
| `p2` | 北风 | 药品船,丑时过江。向左滑,把船期报给北风。向右滑,压进值机日志。 | 叙事抉择提示(播完即可选) |
|
||||
| **`p2_k`** | 北风 | 药品船,丑时过江。左箭头,把船期报给北风。右箭头,压进值机日志。 | 同上(key;首个叙事抉择键位绑定) |
|
||||
| `r1a_send` | 你 | 北风,北风。货船,丑时过江,接住。 | p2 左(报船期;配 sfx/key_send) |
|
||||
| `r1a_e` | 北风 | 收到。江上有人等你。第一封,做得稳。 | p2 左·收(med_ok 预埋;expose+0) |
|
||||
| `r1b_hold` | 你 | 先压一压。这一船的事,得看清楚再说。 | p2 右(压日志;expose+1) |
|
||||
| `r1b_e` | 北风 | 日志下面压着的,是三箱药。船,不会等你。 | p2 右·收(诚实复盘,非惩罚) |
|
||||
| `n1` | 北风 | 零点半。挂钟走了半圈,雨没有停。 | NIGHT(1) 过渡句(随后跨档 exp_* 如有) |
|
||||
|
||||
## M2 组 · 第二封·名单(双性别 16 + 处长平铺 1)
|
||||
|
||||
> 真词 **TOP=黑名单**;候选 TAP=窃听令 / TIP=线人费;辨析位=第 2 字母。正片起**译错不揭穿**:rev_* 按玩家所选播「你的认知」;expose +1。
|
||||
|
||||
| id | 声部 | 台词全文 | 触发 |
|
||||
|---|---|---|---|
|
||||
| `rx2_in` | 北风 | 第二封。手法很急,是内部通报。 | RX 引入(摩尔斯首播 TOP) |
|
||||
| `dv2_ask` | 北风 | 密码本第二页。三个词,选一个。 | 抉择提示 |
|
||||
| `cand_top` | 北风 | 黑名单。 | 候选预听报名 |
|
||||
| `cand_tap` | 北风 | 窃听令。 | 同上 |
|
||||
| `cand_tip` | 北风 | 线人费。 | 同上 |
|
||||
| `rev_top` | 北风 | 黑名单。头一个代号,叫码头。 | 译 TOP·揭晓(你的认知:码头=你的交通员;驱动 p4_known) |
|
||||
| `rev_tap` | 北风 | 窃听令。今夜,有人要装耳朵。 | 译 TAP·揭晓(误读分支;expose+1) |
|
||||
| `rev_tip` | 北风 | 线人费。月底之前,有人要收钱。 | 译 TIP·揭晓(误读分支;expose+1) |
|
||||
| `p4_known` | 北风 | 名单上有码头。向左滑,暗号示警,让他连夜搬家。向右滑,按流程呈报处长。 | 抉择提示(**条件 t2=top**) |
|
||||
| `p4_blind` | 北风 | 一封通报。向左滑,压进抽屉,谁的耳朵也别装。向右滑,按流程呈报处长。 | 抉择提示(条件 t2≠top) |
|
||||
| `r2a_act` | 你 | 有的字,不能落进卷宗。 | p4 左·暗处理(known=示警码头 / blind=压下通报;expose+1) |
|
||||
| `r2a_e` | 北风 | 这一页,从今天起,不存在了。 | p4 左·收(ep_list_ok 预埋) |
|
||||
| `r2b_act` | 你 | 通报誊清,呈处长。 | p4 右·呈报(mateListed=true;expose+0) |
|
||||
| `r2b_e` | 北风 | 名单进了卷宗。码头,自己多保重。 | p4 右·收(ep_list_no 预埋) |
|
||||
| `m2_chief` | 处长 | 嗯,译得很全。去吧。 | p4 右·处长收报(配 sfx/pen_scratch;通用真话:你誊了什么它就收什么) |
|
||||
| `hint_t2` | 北风 | 翻到这页:第二个字母,是 O。三长。 | 翻密码本(扣 1 页;辨析位=O ⟹ 候选唯一) |
|
||||
| `n2` | 北风 | 一点整。处长的灯,还亮着。 | NIGHT(2) 过渡句 |
|
||||
|
||||
## M3 组 · 第三封·交接(双性别 16)
|
||||
|
||||
> 真词 **HAND=今夜交接**;候选 SAND=明晨交接 / LAND=地点变更;辨析位=第 1 字母(H 四短 vs S 三短,全作最狠听辨——慢放价值兑现段)。
|
||||
|
||||
| id | 声部 | 台词全文 | 触发 |
|
||||
|---|---|---|---|
|
||||
| `rx3_in` | 北风 | 第三封。很短,手法有点抖。 | RX 引入(摩尔斯首播 HAND) |
|
||||
| `dv3_ask` | 北风 | 密码本第三页。三个词,选一个。 | 抉择提示 |
|
||||
| `cand_hand` | 北风 | 今夜交接。 | 候选预听报名 |
|
||||
| `cand_sand` | 北风 | 明晨交接。 | 同上 |
|
||||
| `cand_land` | 北风 | 地点变更。 | 同上 |
|
||||
| `rev_hand` | 北风 | 今夜交接。丑时,老码头。 | 译 HAND·揭晓(你的行动按「今夜」展开) |
|
||||
| `rev_sand` | 北风 | 明晨交接。天亮再说。 | 译 SAND·揭晓(误读:你按「明晨」行动;expose+1) |
|
||||
| `rev_land` | 北风 | 地点变更。等下一封。 | 译 LAND·揭晓(误读:你按「等」行动;expose+1) |
|
||||
| `p6` | 北风 | 交接在你手里。向左滑,亲自去码头跑一趟。向右滑,留书暗号,托给下一班。 | 抉择提示(固定文本,known/blind 共用——行动时机由你的认知决定) |
|
||||
| `r3a_go` | 你 | 口令我背得出。今夜,我亲自去。 | p6 左·亲自去(expose+2;按你的认知时间出门) |
|
||||
| `r3a_e` | 北风 | 值班室空了一刻钟。值机日志,停了一行。 | p6 左·收(expose+2 的纸面依据;成败留尾声) |
|
||||
| `r3b_act` | 你 | 暗号夹进交接簿,让雨替我跑这一趟。 | p6 右·留书(expose+0) |
|
||||
| `r3b_e_ok` | 北风 | 交接赶上了。袋子,连夜上了船。 | p6 右·收(**条件 t3=hand**;ep_hand_ok 预埋) |
|
||||
| `r3b_e_no` | 北风 | 交接的袋子,在码头放到了天亮。 | p6 右·收(条件 t3≠hand——误译的戏剧性反讽:约定时间本身错了) |
|
||||
| `hint_t3` | 北风 | 翻到这页:第一个字母,是 H。四短。 | 翻密码本(扣 1 页) |
|
||||
| `n3` | 北风 | 一点三刻。雨小了,频道里很静。 | NIGHT(3) 过渡句(随后走氧气门式签收) |
|
||||
|
||||
## M4 组 · 第四封·处置令·高潮(双性别 15 + 处长平铺 3)
|
||||
|
||||
> 真词 **SPY=内线确认**;候选 SAY=约谈 / SLY=内部排查;辨析位=第 2 字母。rev_spy 挂全作唯一 danger 拍(step_halt 前置 2s);RELAY(4) 起 BGM 切 `bgm/closing`。
|
||||
|
||||
| id | 声部 | 台词全文 | 触发 |
|
||||
|---|---|---|---|
|
||||
| `rx4_in` | 北风 | 第四封。最后一个手法,你听过——快手七。 | RX 引入(无台词角色登场=手法音;摩尔斯首播 SPY) |
|
||||
| `dv4_ask` | 北风 | 密码本第四页。三个词,选一个。 | 抉择提示 |
|
||||
| `cand_spy` | 北风 | 内线确认。 | 候选预听报名 |
|
||||
| `cand_say` | 北风 | 约谈。 | 同上 |
|
||||
| `cand_sly` | 北风 | 内部排查。 | 同上 |
|
||||
| `rev_spy` | 北风 | 内线确认,今夜三时收网。代号,耳机。 | 译 SPY·揭晓(**danger 拍**:「耳机」=你自己的代号;expose+0 但驱动 p9_known) |
|
||||
| `rev_say` | 北风 | 明早九时,约谈相关人员。 | 译 SAY·揭晓(误读:危机被读成了例行公事;expose+1) |
|
||||
| `rev_sly` | 北风 | 即日起,排查站内三人。 | 译 SLY·揭晓(误读;expose+1) |
|
||||
| `m4_chief_a` | 处长 | 值机员,今晚的频道,很热闹啊。 | 处长试探 ①(p8 前铺垫;配 sfx/tea_cup) |
|
||||
| `m4_chief_b` | 处长 | 你的耳朵最好。听见什么,记得……要报。 | 处长试探 ②(施压;配 sfx/pen_scratch) |
|
||||
| `p8_known` | 北风 | 三点之前。向左滑,拍一封假电,说北风昨夜已撤。向右滑,手离开放键器,装傻。 | 抉择提示(**条件 t4=spy**;全表最长句 30 字) |
|
||||
| `p8_blind` | 北风 | 收台之前。向左滑,回一封例行电文,搅一搅水。向右滑,什么都不做。 | 抉择提示(条件 t4≠top;p9 将按 blind 版走) |
|
||||
| `r4a_feed` | 你 | 戴上手键。这一封,借快手七的手法。 | p8 左·反喂(**配 sfx/key_send**;expose+2,feed=true) |
|
||||
| `r4a_e` | 北风 | 假电出了门。对家的耳朵,听得出换人了吗。 | p8 左·收(悬而未决——真相在尾声) |
|
||||
| `r4b_act` | 你 | 手,离开放键器。我只是个值机的。 | p8 右·装傻(expose+0) |
|
||||
| `r4b_e` | 北风 | 有时,什么都不做,就是做了。 | p8 右·收 |
|
||||
| `hint_t4` | 北风 | 翻到这页:第二个字母,是 P。短,两长,短。 | 翻密码本(扣 1 页) |
|
||||
| `m4_chief_c` | 处长 | 行。去睡吧,明天还有明天的事。 | p8 右·处长收场(仅右路播出) |
|
||||
|
||||
## F9 组 · 签收抉择·最后一电(双性别 9)
|
||||
|
||||
| id | 声部 | 台词全文 | 触发 |
|
||||
|---|---|---|---|
|
||||
| `g9_in` | 北风 | 频道要收了。最后一件事,是你自己。 | 签收引入(NIGHT(3)/M4 之后) |
|
||||
| `g9_knot` | 你 | 三年前,我译错了一封电。那之后,我再没见过我的上线。 | 心结自述(玩家背景;与「译错也是剧情」主题闭环) |
|
||||
| `p9_known` | 北风 | 收网之前。向左滑,开机,发最后一电。向右滑,关机,装睡到天亮。 | 终局抉择提示(**条件 t4=spy**) |
|
||||
| `p9_blind` | 北风 | 北风在等答复。向左滑,开机,把今晚发出去。向右滑,例行收台。 | 终局抉择提示(条件 t4≠spy——你不知道那是什么电) |
|
||||
| `d9_send` | 你 | 北风,北风。处置令,今夜三时。撤。 | p9 左·发报(**配 sfx/key_send**;expose+2,结局判定用 p9 前值) |
|
||||
| `d9_send_e` | 北风 | 收到了。你的手法,我听了一整晚。快走。 | p9 左·低暴露收(**p9 前 expose≤4**;e1 入口) |
|
||||
| `d9_caught_e` | 北风 | 信号被咬住了。别回头,走水路。快。 | p9 左·高暴露收(**≥5**;danger 签名 + e3 入口) |
|
||||
| `d9_sleep` | 你 | 机关上了。雨声里,只剩挂钟。 | p9 右·关机 |
|
||||
| `d9_sleepe` | 北风 | 天亮之前,还有两个钟头。守住。 | p9 右·收 |
|
||||
|
||||
## EP 组 · 结局与尾声回响(双性别 17;结局 8 + 回响 9)
|
||||
|
||||
| id | 声部 | 台词全文 | 触发 |
|
||||
|---|---|---|---|
|
||||
| `e1_a` | 你 | 电波追不上我了。码头的灯,一盏一盏地灭。 | 结局 e1(≤4 且发报)主句(配 sfx/dawn_bell) |
|
||||
| `e1_b` | 你 | 新的密码本,在城外渡口等我。黎明,比想象中安静。 | e1 收(钩子) |
|
||||
| `e2_a` | 你 | 交了班,一切照旧。没人知道今晚频道里发生过什么。 | 结局 e2(≤4 且关机)主句 |
|
||||
| `e2_b` | 你 | 只是北风的呼叫,到天亮也没人接。下一次,我会接吗。 | e2 收(钩子) |
|
||||
| `e3_a` | 你 | 我把警报拍了三遍。门开的时候,挂钟正好敲三点。 | 结局 e3(≥5 且发报)主句(配 sfx/lock_click) |
|
||||
| `e3_b` | 你 | 审讯室的灯,也很亮。可码头那边,一个人都没少。 | e3 收(钩子;你的暴露换同伴撤尽) |
|
||||
| `e4_a` | 你 | 两点五十九分,脚步停在门口。我把最后一页密码,塞进了炉子。 | 结局 e4(≥5 且关机)主句(配 sfx/lock_click) |
|
||||
| `e4_b` | 你 | 耳机还挂着。里面有一封电文,永远译不完了。 | e4 收(钩子) |
|
||||
| `ep_lead` | 北风 | 天亮了。北风给你记了最后一笔账——今晚的事,都有了去向。 | 尾声引入 |
|
||||
| `ep_med_ok` | 北风 | 药品:货船丑时靠岸,三箱药,一箱不少。 | 尾声(t1=bay 且 p2=左) |
|
||||
| `ep_med_no` | 北风 | 药品:没人接住那三箱药。船,白白过了江。 | 尾声(其余——压下或译错,真话) |
|
||||
| `ep_list_ok` | 北风 | 名单:码头连夜搬了家。卷宗里,少了一个人。 | 尾声(p4=左) |
|
||||
| `ep_list_no` | 北风 | 名单:天亮时,多了一个红圈。 | 尾声(p4=右——呈报的真实代价) |
|
||||
| `ep_hand_ok` | 北风 | 交接:胶卷上了船,手很稳。 | 尾声(t3=hand) |
|
||||
| `ep_hand_no` | 北风 | 交接:码头的灯,白亮了一夜。 | 尾声(t3≠hand) |
|
||||
| `ep_spy_ok` | 北风 | 处置令:你译对了它。北风,撤在你前头。 | 尾声(t4=spy) |
|
||||
| `ep_spy_no` | 北风 | 处置令:差的那三个字母,差了一整条命。 | 尾声(t4≠spy——全作归因真话的收束句) |
|
||||
|
||||
---
|
||||
|
||||
**合计:139 句**(预算 ≤150 ✓)
|
||||
- 双性别 134 句(OP 你 20 + WIND 北风/系统 114,含 `_k` 键盘变体 11)×2 性别 = 268 文件;
|
||||
- NPC 平铺 5 句(处长)= 5 文件;
|
||||
- 合计 273 条音频 ×2 格式(ogg+m4a)= **546 文件**。
|
||||
- 键盘变体 11 对:gd_brief / gd_continue / gd_again / gd_tune1 / gd_tune2 / sys_help / sys_menu / sys_skip / sys_continue_ask / dv1_teach2 / p2(成对生成,`check_all_assets` 校验 `_k` 配对与双性别集合一致)。
|
||||
- 每结局专属台词齐备:e1/e2/e3/e4 各 2 句 + 尾声回响 9 句(译文/抉择 flag 选播)。
|
||||
- 每局实走 9 个抉择点(4 译词 p1/p3/p5/p7 恒 3 候选 + p2/p4/p6/p8/p9 恒 2 选项,无跳点路径)。
|
||||
- 摩尔斯滴答声零文件(运行时 `morse.js` 合成,19-cipher.md §2.1),本表不含。
|
||||
|
||||
## 多音字 / 发音风险自查注记
|
||||
|
||||
| 风险词 | 处理 |
|
||||
|---|---|
|
||||
| 重听 | 全表写「重新听」(sys_help / gd_tune2),无「重听」字样 |
|
||||
| 长(cháng/zhǎng) | 「一长三短」「三长」「两长」为 cháng 正确常用读法,保留,试听确认 |
|
||||
| 处(chǔ/chù) | 「处长」「处置令」为固定词,保留,试听确认 |
|
||||
| 卷(juǎn/juàn) | 「胶卷」juǎn 与「卷宗」juàn 两读并存(ep_hand_ok/r2a_act),逐句人工试听项 |
|
||||
| 塞(sāi/sè) | 「塞进了炉子」(e4_a)为 sāi 常用读法,保留,试听确认 |
|
||||
| 行(xíng/háng) | 「行。去睡吧」(m4_chief_c)为 xíng,试听确认 |
|
||||
| 着(zhe/zháo) | 「耳机还挂着」「守住」为常见读法,逐句试听项 |
|
||||
| 得(de/dé) | 「译得很全」「打得稳」等助词 de,逐句试听项 |
|
||||
| 教(jiāo/jiào) | 「我教你一页」为 jiāo 常用读法,保留 |
|
||||
| 答(dá/dā) | 「在等答复」为 dá,保留 |
|
||||
| 差(chà/chā/chāi) | 「差的那三个字母」「差了一整条命」为 chà,试听确认 |
|
||||
| 圈(quān/juàn) | 「多了一个红圈」为 quān,保留 |
|
||||
| 英文字母 | hint_t1..t4 / dv1_wrong 句内单字母(B/O/H/P)朗读为风险项,逐句试听;误读时改写为「字母 B」式带「字母」前缀重生成 |
|
||||
| 挣/血/露/巷/降/率/传(zhuàn 义) | 全表未使用(「暴露」不进台词,仅存档 summary) |
|
||||
| 了 / 还 / 中 | 常规句式常见读法,逐句人工试听项(「收住了吗」「挂钟走了半圈」等) |
|
||||
| 数字 | 句内数字全部汉字写死(民国二十九年/零点/零点半/一点整/一点三刻/丑时/三时/明早九时/三点/两点五十九分/一刻钟/两个钟头/三箱/三年前),序号与档位用分档整句(prog_t*/book_*/exp_*) |
|
||||
|
||||
## 台词侧自查
|
||||
|
||||
- 单句 ≤40 字:全表最长 = p8_known(30 字),次长 p6/p4_known(29 字)、sys_help(27 字)✓;NPC 处长句 ≤23 字(最长 b_chief,P4 语速感靠短句+逗号,不用 instruct 语速词)✓。
|
||||
- 有台词人物 2 人(北风=WIND 双性别组、处长=平铺),无台词角色快手七零资产 ✓;同一角色 speaker+instruct 恒定、区分度风险逐个标注 ✓。
|
||||
- 称呼合规:处长对玩家只用「值机员/你」,北风称「你」,性别化称呼零出现 ✓。
|
||||
- 每个结局(e1..e4)专属主句+钩子各 2 句齐备,尾声救/错过双线齐备(ep_* 由 flags 单源选播)✓。
|
||||
- 归因真话律:dv1_wrong 的字母/码与真词 BAY 一致;rev_* 只播玩家认知不冒认真相;ep_med_no/ep_hand_no/ep_spy_no 与 flags 一致;无「运气不好」类假归因、无惩罚性措辞 ✓。
|
||||
- 分档账目真实:book_3/2/1/0 与余页一一对应;exp_calm/low/mid/hot 与 0/1-2/3-4/≥5 一一对应;prog_t1..t4 分封整句 ✓。
|
||||
- 向导 gd_* 13 句(gd_brief/gd_continue/gd_again/gd_tune1/gd_tune2 各带 _k 变体,gd_invalid/gd_prog1/gd_prog2 无变体)符合 14 号 §6 台词规范(一句一义、无重复句式、单句 ≤18 字)✓。
|
||||
@@ -0,0 +1,552 @@
|
||||
# 19 · 《暗码》(cipher) — 1940 密战叙事 RPG 设计文档
|
||||
|
||||
> **给开发的实现要点摘要**
|
||||
> 1. 叙事模式(声命线范式,radio/abyss 同骨架):节点链 onComplete 串行 + seqToken 打断作废 + pendingChoice 缓存;复制 `web/radio/`(或 `web/abyss/`)结构起步,状态机 6 宏状态(INTRO/RX/DECODE/RELAY/NIGHT/ENDING + MENU 覆盖层)。
|
||||
> 2. 核心增量 = **电文解码小局嵌叙事**(DECODE 态):摩尔斯音由**运行时程序合成模块**(`morse.js`,guide earcon 同先例)直接排程 oscillator——**不走音频文件**(有损编码在 70-160ms 短音上有 ms 级抖动,毁时值精确);事件钩子供 playtest 固定字符断言。
|
||||
> 3. 手势:全局默认映射 + **唯一豁免 E1**(DECODE 空闲长按=翻密码本求提示,与引擎快进时间互斥,detective E2 同款);菜单走 00 号 §5.2 模态约定。摩尔斯三层兜底:正常译(原速+候选对照)/ 慢放(双击第 2 次 0.5×)/ 提示直译(密码本 3 页,逐值账目)。
|
||||
> 4. 暴露度 = 步进隐藏资源(radio 口碑同型):译错 +1/封(教学封 T1 恒 0)、危险抉择 +1/+2;分档整句、跨档才播、上滑可查;**档位措辞逐值为真**(book_1..0 / exp 四档均按实数措辞)。
|
||||
> 5. 译错归因真话:教学封 T1 译错**即时**归因(真词字母的摩尔斯写死在句里)+ 无限重选零惩罚;正片 T2-T4 译错**不揭穿**(进入剧情误读分支),真相在尾声回响兑现(ep_* 与 flags 单源对应,detective 信息单源思想)。
|
||||
> 6. 台词依据 [19-cipher-voice-ids.md](19-cipher-voice-ids.md)(139 句:双性别 134 + 平铺 NPC 5);键盘变体 11 对 `_k` 集中标注;结算链 800ms 手势死窗(abyss/地下城 H1 同款)。
|
||||
> 7. 章程任务 N3(research/new8/00-program.md §2):单局 15-25 分钟、9 抉择点(4 译词 3 选 + 5 叙事 2 选)、4 结局、分支局部化。断言清单住本文档 §9;13 号文档已登记指针(§22)。
|
||||
|
||||
## 1. 概述
|
||||
|
||||
- **一句话**:1940 年江城,你是电讯处的夜班报务员,也是「北风」安在敌台内部的一双耳朵——一晚四封密电过你的手,每个词怎么译、报不报、报给谁,都由你按下。
|
||||
- **题材(声音即世界)**:谍战的本体就是**听**——摩尔斯的滴答是情报本身、报务员的「手法」是 fingerprint、电台静电是世界底色。「用耳朵当武器」与纯音频载体天然同构:视觉谍战需要的文件/密写/表情,在这里全部是声音。
|
||||
- **单局**:一个完整夜班(一条抉择路径)19-22 分钟;四封电文共享主干(截获→解码→处置→夜结算),分歧局部化在每封内部;9 个抉择点(4 译词 + 5 叙事,全部恒在),4 结局。
|
||||
- **核心循环**:截获(调谐+电文摩尔斯首播)→ 解码小局(听音辨词:候选对照/慢放/提示三层兜底)→ 译文揭晓(**你的认知**,对错不揭穿)→ 处置抉择(报北风/压日志/呈处长/亲自交接/反喂假电)→ 夜结算(暴露度跨档播报)→ 下一封。终局 p9 用「发最后一电」把整晚收在你的电键上。
|
||||
- **与 radio/abyss 的差异点**(骨架同、压力源不同):radio 零压力、abyss 资源稀缺(氧气);cipher 的压力 = **隐藏的怀疑账本**(暴露度)+ **认知风险**(你永远不确定自己译对了没有——译错不是失败,是走另一条真实存在的剧情)。全部宽限化:无倒计时、无中途死亡、软失败只损失「情报效果」不损失玩家已有物。
|
||||
|
||||
## 2. 摩尔斯解码小局(信息设计,本作核心差异层)
|
||||
|
||||
### 2.1 电码呈现规格
|
||||
|
||||
**电码表**(标准摩尔斯;本作 4 封电文只用到 13 个字母,模块内置全 A-Z 表,断言只锁用到的):
|
||||
|
||||
| 字母 | 码 | 字母 | 码 | 字母 | 码 | 字母 | 码 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| A | ·− | H | ···· | O | −−− | T | − |
|
||||
| B | −··· | I | ·· | P | ·−−· | Y | −·−− |
|
||||
| D | −·· | L | ·−·· | R | ·−· | S | ··· |
|
||||
| N | −· | | | | | | |
|
||||
|
||||
**时值与音色(运行时合成,`web/cipher/morse.js`)**:
|
||||
|
||||
| 参数 | 值 | 说明 |
|
||||
|---|---|---|
|
||||
| 单位 u | 原速 80ms(dit=1u 音、dah=3u 音、字内隙 1u、字母隙 3u) | ≈15 WPM 等效;**u 是常量写死,不随 settings.speed**(见边界表) |
|
||||
| 慢放档 | u=160ms(0.5×),字母隙加宽至 6u | 双击第 2 次触发;三层兜底第 2 层 |
|
||||
| 候选对照档 | u=110ms,字母隙 5u | 密码本「念给你听」的质感 |
|
||||
| 音色 | 电文 750Hz / 候选 620Hz,正弦 + 5ms cos 边沿,gain 0.5 | **频率差 = 「电波里的」vs「密码本上的」**,防听感混淆 |
|
||||
| 首尾 | lead-in 400ms 静音,结尾 400ms 静音 | 排程器自然包含 |
|
||||
| 时长例 | BAY 原速 ≈2.6s / HAND ≈2.8s / TOP ≈2.8s;慢放 ≈2× | 单次听觉负荷远低于 40s 红线 |
|
||||
| 事件钩子 | `morse.play(word,{hz,unit})` 逐元素回调 `{type:'dit'|'dah',letter}` | playtest **固定字符断言**挂点(§9) |
|
||||
|
||||
- 为什么运行时合成而非 SA3/SYN 文件:①时值精确是玩法命根(H···· vs S··· 只差一个 80ms 的 dit,ogg/m4a 有损编码在短音上有数 ms 抖动与预卷,文件方案直接否决);②三档速度 × 双频率 × 13 字母的组合用文件不可维护;③零资产缺失风险。guide earcon(14 号裁定 3)运行时合成先例。
|
||||
|
||||
### 2.2 电文与候选设计表(信息单源:真词/候选/辨析位写死)
|
||||
|
||||
| 封 | 电文名 | 真词(义) | 候选(义) | 共享 | 辨析位 | 密码本提示揭示 |
|
||||
|---|---|---|---|---|---|---|
|
||||
| T1 | 船期 | **BAY**(货船) | DAY(客车)/ RAY(巡逻艇) | _AY | 1:B(−···)/D(−··)/R(·−·) | 第 1 字母是 B,一长三短 |
|
||||
| T2 | 名单 | **TOP**(黑名单) | TAP(窃听令)/ TIP(线人费) | T_P | 2:O(−−−)/A(·−)/I(··) | 第 2 字母是 O,三长 |
|
||||
| T3 | 交接 | **HAND**(今夜交接) | SAND(明晨交接)/ LAND(地点变更) | _AND | 1:H(····)/S(···)/L(·−··) | 第 1 字母是 H,四短 |
|
||||
| T4 | 处置令 | **SPY**(内线确认) | SAY(约谈)/ SLY(内部排查) | S_Y | 2:P(·−−·)/A(·−)/L(·−··) | 第 2 字母是 P,短两长短 |
|
||||
|
||||
- **候选纪律**:三候选等字母数、共享其余字母、唯一辨析位;**提示揭示辨析位字母 ⟹ 候选唯一**(每行验算成立,playtest 断言「提示流可全对」)。
|
||||
- **难度曲线**:T1(B/D 差一个尾 dit,教学期有慢放+免费提示兜底)→ T2(中间字母 O/A/I 时值差异大,最易)→ T3(H/S/L:H 与 S 只差一个 80ms 尾 dit,全作最狠听辨)→ T4(P/L 需听完整字母,中高)。曲线说明:难度=听辨精度,操作面恒定(左右滑+单击+双击)。
|
||||
- 电文摩尔斯(固定字符断言对象):BAY=`−··· / ·− / −·−−`;TOP=`− / −−− / ·−−·`;HAND=`···· / ·− / −· / −··`;SPY=`··· / ·−−· / −·−−`。
|
||||
|
||||
### 2.3 解码交互流(DECODE 态内)
|
||||
|
||||
```
|
||||
RX 链:rx*_in(引入)→ sfx/tune_seek → 电文摩尔斯首播(原速 750Hz,auto,不可跳)
|
||||
→ guide.turn → dv*_ask(提示句,choiceArmed)→ 浏览等待
|
||||
浏览:左右滑 = 循环切换候选(每切自动预听:候选摩尔斯 620Hz 对照档 → 静默一拍 → cand_* 词义句)
|
||||
双击 = 重听电文(原速);【再双击】= 慢放 0.5×(两级内容不同:速度即差异)
|
||||
长按(语音空闲)= 翻密码本(§2.5)
|
||||
单击 = 进确认:cf_confirm + 电文重播原速一遍 → 再单击 = 定下(判定出口 800ms 死窗)
|
||||
确认态:左右滑 = 取消回浏览;双击 = 照常重听电文
|
||||
```
|
||||
|
||||
- **三层兜底**(成本递增的梯度,全部可独立走通,P3 嘈杂/P4 疲惫的双保险):
|
||||
|
||||
| 层 | 手段 | 成本 | 覆盖 |
|
||||
|---|---|---|---|
|
||||
| 1 正常译 | 原速电文 + 候选对照预听匹配 | 最快 | 安静环境/耳力好 |
|
||||
| 2 慢放 | 双击第 2 次 0.5×,**无限次免费** | 时间 | 通勤嘈杂听不清长短音(P3);无限兜底层 |
|
||||
| 3 提示直译 | 密码本 3 页,每页直译 1 封的辨析位字母 | 资源(页) | P4 保底:提示+候选对照 ⟹ 唯一解(§2.2 验算) |
|
||||
|
||||
- 教学期(T1):dv1_teach/dv1_teach2 先教「双击重听→再双击慢放」「左右滑候选、单击选定」;T1 判定有**即时反馈**(对=success 震+dv1_right;错=dv1_wrong 即时真话归因+无限重选,零惩罚)——正片 T2-T4 判定**无对错反馈**,直入剧情(译错是你不知道的分支)。教学承诺「练习有答案,正片靠耳朵」在 dv1_right 说破。
|
||||
|
||||
### 2.4 密码本机制(提示额度经济)
|
||||
|
||||
| 项 | 规则 |
|
||||
|---|---|
|
||||
| 页数 | 初始 3 页(叙事=北风给你的三页「电码补遗」);**全局不再补页** |
|
||||
| 兑换 | DECODE 空闲长按(E1 豁免)或菜单「翻密码本」项(P4 冗余入口);消耗 1 页 → 播 hint_*(「第 N 个字母,是 ○」+ 摩尔斯口述),留在浏览态 |
|
||||
| 教学免费 | T1 第 1 次翻页**不扣**(hint_t1:「我教你一页」)——Prime→Teach 承诺兑现 |
|
||||
| 账目真实 | 状态链随时可查:book_3「还剩三页」/ book_2「还剩两页」/ book_1「只剩最后一页」/ book_0「一页都不剩了」——**逐值整句,不拼接** |
|
||||
| 页数用尽 | 再翻 = error 震 + sfx/paper_page(翻空本声),无语音(零静默、不轰炸) |
|
||||
| 与结局关系 | 页数不进结局判定(只换准确度);纯提示流(T1 免费+3 页)可全对(§5.5 剧本 E 验算) |
|
||||
|
||||
### 2.5 译错归因真话(detective 信息单源思想)
|
||||
|
||||
| 场景 | 播报 | 真话依据 |
|
||||
|---|---|---|
|
||||
| T1 译错(教学) | dv1_wrong「不对。听清楚:B,一长,三短。」 | 真词字母的摩尔斯**写死在句里**,与 §2.2 电码表一致;无限重选零惩罚 |
|
||||
| 正片译错 | 不揭穿:rev_* 按你选的候选播「你的认知」(rev_top/tap/tip…) | 旁白只说你以为的事;真词唯一、由数据表单源决定 |
|
||||
| 后果分支 | 你的行动按认知展开(报错船期/留错时间/呈报错令);暴露度 +1 | 「译文进了纸面,与对家底档不符」——事件表单源(§5.2) |
|
||||
| 真相揭晓 | 尾声 ep_hand_no「码头的灯,白亮了一夜」/ ep_spy_no「差的那三个字母,差了一整条命」 | ep_* 由 flags(t3==hand 等)选播,**播报=存储**;禁止「运气不好」类假归因 |
|
||||
|
||||
## 3. 状态机
|
||||
|
||||
### 3.1 状态列表
|
||||
|
||||
| 状态 | 内容 | BGM | guide.state |
|
||||
|---|---|---|---|
|
||||
| `INTRO` | 开场链:夜班开场 + 一句规矩 + 今晚目标 + 处长夜令 | `bgm/radio_room` | explore |
|
||||
| `RX` | 截获:引入句 + 调谐 + 电文摩尔斯首播(auto 链) | `bgm/radio_room`(摩尔斯期间 −6dB) | explore;摩尔斯首播后由 turn cue 承担 |
|
||||
| `DECODE` | 解码小局:浏览/确认/重听/慢放/提示(§2.3) | 同上 | choice |
|
||||
| `RELAY` | 处置叙事:rev_* 揭晓链 + 后果 + 叙事抉择 p2/p4/p6/p8 | `bgm/radio_room`;RELAY(4) 起 crossfade 至 `bgm/closing` | explore;抉择点=choice |
|
||||
| `NIGHT` | 夜结算:n* 过渡句 + 暴露档位跨档播报(如有),auto ≤12s | `bgm/night` | settle |
|
||||
| `ENDING` | 结局链 + 尾声回响(epilogue),结算态 | `bgm/ending` | settle |
|
||||
| `MENU` | 模态覆盖层(任意叙事态下滑呼出,暂停一切链) | `bgm/radio_room` 低响度淡入 | menu |
|
||||
|
||||
- 附 `ASK`(存档询问态,radio 同款):单击=继续上次 / 右滑=新夜班;上滑/下滑/左滑/双击=无效(error 震+gd_invalid)。
|
||||
|
||||
### 3.2 转移图(文本)
|
||||
|
||||
```
|
||||
┌──────────── 结算单击=新夜班 ────────────────┐
|
||||
▼ │
|
||||
INTRO ──链完──> RX(1) ──首播完──> DECODE(1) ──两段确认+判定──> RELAY(1) ──链完──> NIGHT ─┤→ RX(2)
|
||||
(调谐+引入+摩尔斯首播 浏览/确认/重听/慢放/提示 揭晓+p*+结果链 │ …(T2/T3 同型)…
|
||||
auto,首播不可跳) (T1 判定有即时反馈) │
|
||||
└──────────────────────────────────────────────────────────────────────┘
|
||||
RELAY(4) ──链完──> 签收 g9_in → g9_knot → ◆p9 ──> d9 结果链 ──> ENDING(e1..e4 + ep 回响链)
|
||||
|
||||
任意叙事态(INTRO/RX/DECODE/RELAY/NIGHT/ENDING):下滑 → MENU(模态)
|
||||
MENU:单击=循环切换选项 → 双击=确认执行 → 上滑=帮助 → 下滑/「回到电波」项=关闭回原状态
|
||||
(RELAY 关闭后重播当前节点;DECODE 关闭后重挂浏览并自动预听当前候选——局面复述)
|
||||
```
|
||||
|
||||
- RX 首播链与 NIGHT 链 `auto:true`;DECODE 浏览为武装等待;RELAY 叙事节点链末等待单击(radio 实现核对 #1 同口径)。
|
||||
- 判定出口(DECODE 第 2 击确认)、NIGHT 链、d9 结果链、e* 结局链入口处盖 `_settleGraceUntil = now+800ms` 手势死窗(dungeon H1/abyss 同款),窗内手势一律吞掉——揭晓与结算链完整播出。
|
||||
- MENU 打开时 `guide.disarm()` + 取消一切看门狗/自动链 + 停摩尔斯排程;关闭后按原状态复述(L5 局面复述,radio closeMenu 先例)。
|
||||
|
||||
### 3.3 每状态手势映射(6+2 全覆盖)
|
||||
|
||||
| 手势 | INTRO/RX | DECODE 浏览 | DECODE 确认 | RELAY | NIGHT | ENDING | MENU |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| 上滑 | 帮助+状态,随后重播当前段 | 状态链(prog_t→book 档→exp 档→sys_help,状态在前),留在浏览 | 同左 | 帮助+状态,随后重播当前节点 | 帮助+状态,自动链继续 | 帮助+状态(结局名+档) | 帮助(sys_help) |
|
||||
| 下滑 | 模态菜单 | 模态菜单 | 模态菜单 | 模态菜单 | 模态菜单 | 模态菜单 | 关闭菜单 |
|
||||
| 左滑 | 无效 → error 震+gd_invalid | 上一候选(循环,预听);**首播中=beat 轻震**(摩尔斯不可跳) | 取消确认,回浏览 | 抉择=左 | 无效 → gd_invalid | 无效 → gd_invalid | 无效 → error 震 |
|
||||
| 右滑 | 无效 → gd_invalid | 下一候选(循环,预听) | 取消确认,回浏览 | 抉择=右 | 无效 → gd_invalid | 无效 → gd_invalid | 无效 → error 震 |
|
||||
| 单击 | 播放中=跳过本句;链末=继续 | 进确认:cf_confirm + 电文重播 | **定下判定**(800ms 死窗 → 揭晓链) | 播放中=跳过本句(p* 不可跳);链末=继续 | 跳过本句(自动链) | **再来一局**(新夜班) | 循环切换选项 |
|
||||
| 双击 | 重听当前段 | **重听电文(原速);第 2 次=慢放 0.5×**(任何其他手势重置计数) | 同左(确认态保留) | 重听当前节点台词(含抉择提示) | 重听夜结算链 | 重听结局链 | **确认执行**(菜单约定覆盖重听) |
|
||||
| 长按 | 引擎接管:旁白临时 1.7×(12 号 §2.2,叙事类不豁免) | **空闲=翻密码本(E1 豁免)**;语音在播=引擎快进 | 同左 | 引擎快进 | 引擎快进 | 引擎快进 | 引擎快进(菜单语音) |
|
||||
| 长按松开 | 引擎接管:恢复 settings.speed | 同左 | 同左 | 同左 | 同左 | 同左 | 同左 |
|
||||
|
||||
**豁免登记(必须显式,仅 1 条)**:
|
||||
|
||||
| # | 豁免 | 理由(先例) |
|
||||
|---|---|---|
|
||||
| E1 | DECODE 空闲长按 = 翻密码本求提示(核心资源动词快捷入口) | 绑定条件=无语音在播(`!audio.isVoicePlaying()`),与长按快进(仅在播时生效)**时间互斥、零冲突**(detective E2 同款);摩尔斯为 sfx 域不触发快进;菜单「翻密码本」提供冗余入口(P4 容错) |
|
||||
|
||||
- 其余全部符合宪法默认语义:单击=确认/继续(两段确认=确认的两击)、双击=重听(重听对象=电文)、左右滑=选择/移动、上滑=状态、下滑=菜单(00 号 §5.2 模态约定);菜单=单击循环+双击确认。
|
||||
- 继承 radio G5 跳过公平契约原文:**首播必完整**(摩尔斯首播不可跳、p* 不可跳、链末关键句保护、ASK 恢复首句锁)、**复播可即掐**(锁不随复播重新武装、链中段句可跳、复播滑动照常预缓存)。
|
||||
- 抉择 prompt(p2..p9)播放中单击不可跳(PROMPT_RE 门)+ beat 轻震(G4);左右滑缓存 `pendingChoice` 播完即生效(radio W2 契约)。
|
||||
- 无效手势零静默:所有「无效」格 error 震 + gd_invalid(onceKey 同局限次,F1.4 idle-only)。
|
||||
- **首播保护窗**:电文摩尔斯首播发生在 RX 链尾、DECODE 入口前(§3.2),期间一切玩法手势(左右滑/单击/双击)= beat 轻震(G4),不判无效、不惩罚——摩尔斯走 sfx 域本无跳句通道,「不可跳」由构造保证;首播完 400ms 内 guide.turn + dv*_ask 落地,浏览武装。
|
||||
|
||||
### 3.4 摩尔斯/语音双通道仲裁(abyss 声呐双通道 R1-R5 同型)
|
||||
|
||||
- **通道定义**:摩尔斯通道 = morse.js 的 osc 排程(电文+候选)+ sfx 层(静电/电键);语音通道 = voice 层(你+北风+处长)。BGM 第三层背景(voice 播时引擎 duck)。
|
||||
- **R1 摩尔斯不叠语音**:摩尔斯排程只在 `!audio.isVoicePlaying()` 时起振;在播则挂队列表、voice onComplete/句间轮询补发(abyss sonarGate 同款)。候选预听链 = 候选摩尔斯 → 静默一拍(≥500ms)→ cand_* 词义句(给耳朵留对照时间)。
|
||||
- **R2 电文主导段**(首播/重听/慢放):前景=摩尔斯,BGM dip;voice 只在摩尔斯**结束后**接播(dv*_ask 固定在首播后)。
|
||||
- **R3 BGM 退位**:摩尔斯排程期间游戏层把 BGM 降 −6dB(abyss 远程脉冲垫先例),不消失(A2 无静默死局)。
|
||||
- **R4 危机拍优先**:T4 揭晓 danger 拍(step_halt 前置 2s 渐强 + danger 签名 + danger 震);当前 voice 句播完后危机链才插续(radio C5/abyss D2 同款)。
|
||||
- **R5 摩尔斯可重听**:DECODE 双击=重听电文(P1 关键线索可重听;第 2 次=慢放是本作对 R5 的加强)。
|
||||
- 声流账:任意时刻 ≤2 条前景流(voice 串行 1 + 摩尔斯/信息音 1),BGM/amb 为背景层——ASA ≤2 约束 ✓。
|
||||
|
||||
**引擎能力边界(对照 docs/web-engine-api.md)**:
|
||||
|
||||
| 能力 | 引擎现状 | 方案 |
|
||||
|---|---|---|
|
||||
| 摩尔斯精确时值 | sfx 走文件(有损编码 ms 抖动) | **运行时 osc 模块**(§2.1;guide earcon 先例),三档速度一个参数 |
|
||||
| morse 与 voice 互让 | ❌ sfx 总线独立无 duck | 游戏层 morseGate 空闲门(R1) |
|
||||
| BGM 手动 dip | ❌ 引擎只对 voice duck | 游戏层 gain:摩尔斯期间 −6dB(R3) |
|
||||
| voice 运行时滤波 | ❌ | **不使用**(detective 先例:区分度靠 speaker+instruct+语境;处长=当面训话不需滤波) |
|
||||
| sfx 循环 | ❌ 即发即弃 | 游戏层 `buffer.loop=true`(amb_room/static_bed,radio `_ringSrc` 先例) |
|
||||
| 变速不变调 | ✅ SoundTouch(**仅 voice**) | **摩尔斯不受 settings.speed/长按快进影响**(u 恒定)——边界登记:P1 2.2× 档语速下电文仍原速,慢放兜底;列入 live 真人耳测项 |
|
||||
|
||||
## 4. 抉择树
|
||||
|
||||
### 4.1 全局骨架(四封电文共享主干,分歧局部化)
|
||||
|
||||
```
|
||||
INTRO: b_open → b_rule → b_goal → b_chief ──> RX(1)
|
||||
【T1 船期·教学】BAY 译词 ◆p1 + 报/压 ◆p2 ──> NIGHT(1) ──> RX(2)
|
||||
【T2 名单】TOP 译词 ◆p3 + 暗处理/呈报 ◆p4(known/blind 差分)──> NIGHT(2) ──> RX(3)
|
||||
【T3 交接】HAND 译词 ◆p5 + 亲自/留书 ◆p6 ──> NIGHT(3) ──> RX(4)
|
||||
【T4 处置令·高潮】SPY 译词 ◆p7 + 处长试探 ◆p8(反喂/装傻,known/blind 差分)──> 签收 ◆p9 ──> ENDING
|
||||
```
|
||||
|
||||
分支纪律:**每封电文内部分支、夜结算时收敛**;跨电文只传标量(expose、hints、4 个译文 flag、4 个抉择 flag),不生成组合节点。最坏路径与最好路径节点数同型。
|
||||
|
||||
### 4.2 分封结构(◆=抉择点,〔〕=条件差分)
|
||||
|
||||
```
|
||||
【T1 船期·教学】
|
||||
RX(1): rx1_in → tune_seek → 【摩尔斯首播 BAY,不可跳】→ dv1_teach → dv1_teach2 → dv1_ask → 浏览
|
||||
◆p1 译词(3 选 1,两段确认)
|
||||
├候选 BAY(对): dv1_right(success 震)──────────────────────┐
|
||||
└候选 DAY/RAY(错): dv1_wrong(即时真话归因)→ 回浏览无限重选 ┘(T1 恒收敛为 BAY)
|
||||
RELAY: rev 由 dv1_right 承担 → ◆p2
|
||||
├左 报北风: r1a_send → r1a_e(med_ok 预埋)──┐
|
||||
└右 压日志: r1b_hold → r1b_e(expose+1)────┴→ NIGHT(1): n1 → 〔跨档 exp_*〕→ RX(2)
|
||||
|
||||
【T2 名单】
|
||||
RX(2): rx2_in → 首播 TOP → dv2_ask → 浏览 → ◆p3 译词
|
||||
├TOP(对): rev_top「黑名单。头一个代号,叫码头」→ p4_known ──┐
|
||||
└TAP/TIP(错,不揭穿): rev_tap / rev_tip → p4_blind ─────────┤(expose 译错+1)
|
||||
◆p4: ├左 暗处理: r2a_act → r2a_e(expose+1;known=warn 码头 / blind=压下)┐
|
||||
└右 呈报: r2b_act → m2_chief → r2b_e(mateListed)────────────────┴→ NIGHT(2): n2 …
|
||||
|
||||
【T3 交接】
|
||||
RX(3): rx3_in → 首播 HAND → dv3_ask → 浏览 → ◆p5 译词
|
||||
├HAND(对): rev_hand → 〔p6 行动按「今夜」〕────────────┐
|
||||
└SAND/LAND(错): rev_sand / rev_land → 〔按误译时间行动〕┤(expose+1)
|
||||
◆p6: ├左 亲自去: r3a_go → r3a_e(expose+2)──────────────┤
|
||||
└右 留书暗号: r3b_act →〔t3==hand ? r3b_e_ok : r3b_e_no〕┴→ NIGHT(3): n3 …
|
||||
|
||||
【T4 处置令·高潮】
|
||||
RX(4): rx4_in → 首播 SPY → dv4_ask → 浏览 → ◆p7 译词
|
||||
├SPY(对): rev_spy(danger 拍:step_halt 前置 2s+签名+震)→ p8_known ──┐
|
||||
└SAY/SLY(错): rev_say / rev_sly → p8_blind ──────────────────────────┤(expose+1)
|
||||
处长试探: m4_chief_a → m4_chief_b → ◆p8
|
||||
├左 反喂假电: r4a_feed(配 key_send)→ r4a_e(expose+2,feed=true)──┐
|
||||
└右 装傻: r4b_act → m4_chief_c → r4b_e ────────────────────────────────┴→ 签收
|
||||
【签收】g9_in → g9_knot → ◆p9〔t4==spy ? p9_known : p9_blind〕
|
||||
├左 发最后一电: d9_send(key_send)→〔pre≤4 ? d9_send_e : d9_caught_e〕→ ENDING(e1|e3)
|
||||
└右 关机: d9_sleep → d9_sleepe → ENDING(e2|e4)
|
||||
|
||||
ENDING: e*_a → e*_b(按 expose 档 × p9 四选一)→ ep_lead → ep_med_* / ep_list_* / ep_hand_* / ep_spy_*(按 flags 选播)
|
||||
```
|
||||
|
||||
### 4.3 分支局部化说明
|
||||
|
||||
- 跨电文状态全部是标量:`expose`(int)、`hints`(int 0-3)、译文 flag `t1..t4`(每封所选候选 id;T1 恒真词)、抉择 flag `p2..p9`(左/右)。无任何「电文 i × 电文 j」组合节点。
|
||||
- 条件差分全部是**节点内选播**(radio w1_say/w1_say2 先例):p4/p8/p9 的 known/blind 双提示(由 t2/t4 决定)、r3b_e_ok/no(由 t3 决定)、d9_send_e/caught_e(由 expose 档决定)、ep_* 8 句(由 4 组 flag 决定)。树形不变。
|
||||
- 树规模:139 句台词、约 75 个节点;任一路径恒走 9 个抉择点(4 译词 + p2/p4/p6/p8/p9)——比 radio/abyss 更规整(无跳点路径),操作面完全恒定(P4)。
|
||||
|
||||
### 4.4 四结局达成条件
|
||||
|
||||
| 结局 | 条件 | 主题 | 开环钩子 |
|
||||
|---|---|---|---|
|
||||
| e1 最后一电 | p9 前 expose ≤4 且 p9=左 | 警报发出、北风撤尽,你随挑水的队伍出城 | 「新的密码本,在城外渡口等我」 |
|
||||
| e2 值完这个班 | p9 前 expose ≤4 且 p9=右 | 平安交班,一切照旧——但北风的呼叫没人接 | 「下一次呼叫,你接不接?」 |
|
||||
| e3 孤灯 | p9 前 expose ≥5 且 p9=左 | 发报被测向,你拍了三遍警报,坐等门开;码头撤空 | 「审讯室的灯,也很亮」 |
|
||||
| e4 长夜 | p9 前 expose ≥5 且 p9=右 | 两点五十九分,脚步停在门口;最后一页密码进了炉子 | 「耳机里还有一封译不完的电文」 |
|
||||
|
||||
- 处置令的烈度随暴露档缩放(fiction 自洽):低暴露=处长没有足够把握(约谈/排查);高暴露=今夜三时收网。
|
||||
- 尾声回响(P2):ep_lead 后逐封点名——药品(接住/白过江)、名单(少了一个人/多了红圈)、交接(上船/白亮一夜)、处置令(译对/差三个字母)——玩家每一封的译与错都被点名。
|
||||
|
||||
## 5. 数值设计
|
||||
|
||||
### 5.1 变量
|
||||
|
||||
| 变量 | 类型 | 初值 | 说明 |
|
||||
|---|---|---|---|
|
||||
| `expose`(暴露度) | int | 0 | 步进隐藏资源:译错/危险抉择累积,只涨不跌;档位句播报(§5.3) |
|
||||
| `hints`(密码本余页) | int | 3 | 翻一页 −1;T1 首次免费(不扣);全局不补 |
|
||||
| `t1..t4`(译文) | str | null | 各封所选候选 id;T1 教学期恒收敛真词;t2/t3/t4 记玩家认知 |
|
||||
| `p2/p4/p6/p8/p9` | 'L'/'R' | null | 叙事抉择;派生 med_ok/mateListed/handOk/feed 等 flag |
|
||||
| `endings{}` / `runs` | map/int | — | 结局收集与重玩计数(存档展示用) |
|
||||
|
||||
### 5.2 暴露度累积事件表(单源,账目可验算)
|
||||
|
||||
| 事件 | 条件 | Δexpose | 叙事依据(真话) |
|
||||
|---|---|---|---|
|
||||
| T1 译错 | 教学期无限重选,恒收敛 | **0** | 学习期零惩罚(A5) |
|
||||
| T2/T3/T4 译错 | 选非真词(无论后续左右) | **+1/封** | 你的译文进了纸面(值机日志/呈报/交接条),与对家底档不符 |
|
||||
| p2 右·压日志 | T1 | +1 | 值机日志少一封,晨检对不上号 |
|
||||
| p4 左·暗处理 | T2 | +1 | 卷宗缺页/抽屉藏报,暗手的痕迹 |
|
||||
| p6 左·亲自去 | T3 | +2 | 值班室空岗一刻钟,日志停了一行 |
|
||||
| p8 左·反喂 | T4 | +2 | 拍假电的机器记录抹不掉(哪怕手法伪装了) |
|
||||
| p9 左·发报 | 终局 | +2(**结局判定用 p9 前值**) | 开机信号进了值机室的登记 |
|
||||
|
||||
- 上限:3(译错)+1+1+2+2 = 9(p9 前);下限 0。全对全保守 = 0(calm 档),符合「一晚干净值机」。
|
||||
- 每次事件**不播数字**(隐藏资源);危机感由档位句+氛围音承载;状态链随时可查档位(radio 口碑同型)。
|
||||
|
||||
### 5.3 暴露度档位表(措辞逐值为真)
|
||||
|
||||
| 档 | expose | 整句 | 真实性核验 |
|
||||
|---|---|---|---|
|
||||
| calm 平安 | 0 | 「这一晚,还没人看你第二眼。」 | 0 事件 ✓ |
|
||||
| low 疑云 | 1-2 | 「处长端着茶,多看了你一眼。」 | 1-2 个纸面破绽=被注意 ✓ |
|
||||
| mid 被盯 | 3-4 | 「走廊里的脚步声,慢了下来。」 | 3-4 个破绽=例行留意 ✓ |
|
||||
| hot 危局 | ≥5 | 「门外,好像有人换了岗。」 | ≥5=行动级怀疑(与 p9 收网门 ≥5 一致)✓ |
|
||||
|
||||
- 跨档才播(挂 NIGHT 链尾);上滑状态链随时可查;hot 档各播报位附 warning 震(abyss oxy_crit/G2 同款)。
|
||||
- **p9 收网门 = hot 档阈值 5**:档位句说的就是结局判定用的(radio rep_low/abyss floor(oxy/3) 教训内化——措辞与数值同一个源)。
|
||||
|
||||
### 5.4 密码本账(逐值整句)
|
||||
|
||||
| 余页 | 整句 |
|
||||
|---|---|
|
||||
| 3 | 「密码本,还剩三页。」 |
|
||||
| 2 | 「密码本,还剩两页。」 |
|
||||
| 1 | 「密码本,只剩最后一页。」 |
|
||||
| 0 | 「密码本,一页都不剩了。」 |
|
||||
|
||||
### 5.5 暴露度与四结局验算(设计期穷举,playtest 剧本引用)
|
||||
|
||||
设 `wrong` = T2/T3/T4 译错封数(0-3),`risk` = 危险抉择分(p2右1 + p4左1 + p6左2 + p8左2,0-6):
|
||||
|
||||
- **p9 前 expose = wrong + risk** ∈ [0, 9];结局门:≤4 → e1/e2(p9 左/右);≥5 → e3/e4。
|
||||
- **剧本 A(全对全右,p9 左)**:wrong=0,risk=0 → expose=0(calm)→ p9_known 左 → d9_send_e → **e1**;ep 全 ok(med_ok/list_no/hand_ok/spy_ok——p4 右呈报=名单进卷宗,ep_list_no 是呈报的真实代价)。
|
||||
- **剧本 B(同 A,p9 右)**:expose=0 → **e2**(d9_sleep/d9_sleepe)。
|
||||
- **剧本 C(全错全左,p9 左)**:wrong=3,risk=1+2+2=5 → expose=8(hot)→ p9_blind 左 → d9_caught_e(danger 拍)→ **e3**;逐检查点:NIGHT(1) 后 0(p2 左不加分)→ calm;NIGHT(2) 后 2(wrong T2=1 + p4 左=1)→ low;NIGHT(3) 后 4(+wrong T3 +p6 左 2)→ mid;签收前 8(+wrong T4 +p8 左 2)→ hot。跨档播报 3 次。
|
||||
- **剧本 D(同 C,p9 右)**:expose=8 → **e4**。
|
||||
- **剧本 E(提示流 P4)**:T1 免费提示(hints 3 不动)+ T2/T3/T4 各 1 页(3→2→1→0,book_2/1/0 逐值播出)→ 提示揭示辨析位 ⟹ 候选唯一 → 全对;全右 → expose=0 → e1/e2 任选。**纯提示流可通关 ✓**。
|
||||
- **剧本 F(慢放流 P3)**:T2-T4 每封双击×2 慢放后译对,零提示 → 全对;expose=0。**纯慢放可通关 ✓**。
|
||||
- 边界带验算:wrong=2 + risk=2(p2右+p4左)= 4 → 仍 e1/e2(宽容:两处失误不毁局,P4);wrong=1 + risk=4 = 5 → e3/e4(风险路径必热)。
|
||||
|
||||
## 6. 音频三层映射
|
||||
|
||||
### 6.1 BGM(状态→曲目,Mureka instrumental,4 首 ≈ $0.12;共性后缀 10 号 §8 照 radio 追加)
|
||||
|
||||
| 状态 | 曲目 | 切换 | Mureka prompt 草稿(英文,seamless loop) |
|
||||
|---|---|---|---|
|
||||
| INTRO/RX/DECODE/RELAY/MENU | `bgm/radio_room` | 开局淡入 800ms;MENU 低响度淡入 500ms;摩尔斯期间 −6dB(R3) | "1940s late night wireless station room, warm tube radio hum, distant muffled swing jazz through a wall, rain on window, clock tick, smoky and quiet, no vocals, seamless loop, 60-90 seconds" |
|
||||
| RELAY(4) 起(T4 高潮至签收) | `bgm/closing` | crossfade 800ms 进 | "Tense noir waltz for a spy's last night, muted brushed drums, low strings, subtle telegraph tick rhythm, restrained dread, no vocals, seamless loop, 60-90 seconds" |
|
||||
| NIGHT | `bgm/night` | crossfade 600ms 进;进下一 RX 淡回 600ms | "Quiet night interlude, sparse felt piano over warm vinyl static and soft rain, lonely but safe, no drums, no vocals, seamless loop, 60-90 seconds" |
|
||||
| ENDING | `bgm/ending` | d9 结果链播完后淡入 1500ms | "Dawn after a long night of rain, warm strings and soft piano, exhausted hope, quiet resolution, no vocals, seamless loop, 60-90 seconds" |
|
||||
|
||||
- `bgm=0` 时全部静默(引擎约定);menu 用同曲低响度(省 1 首,值班室同场景同构)。
|
||||
|
||||
### 6.2 SFX 清单(SA3=Stable Audio 3 / SYN=程序合成;one-shot 真峰值 ≤-3dBFS;amb 循环由游戏层 `buffer.loop` 实现)
|
||||
|
||||
| id | 用途 | 来源 | prompt(英文)/ 合成参数 |
|
||||
|---|---|---|---|
|
||||
| `sfx/tune_seek` | 调谐找频(每封 RX 起) | SA3 | "Hand turning a vintage radio tuning dial, static sweeps, faint morse ghost, 3 seconds" |
|
||||
| `sfx/static_bed` | 电台静电底噪 loop(RX/DECODE) | SA3 | "Shortwave radio static bed, soft crackle and hum, seamless loop" |
|
||||
| `sfx/amb_room` | 值班室 amb loop(挂钟+雨+暖炉) | SA3 | "1940s office night ambience, wall clock tick, rain on window, faint stove hum, seamless loop" |
|
||||
| `sfx/paper_page` | 密码本翻页(提示兑换/开局发本/页数用尽) | SA3 | "Thin paper page turn of a small codebook, dry, close" |
|
||||
| `sfx/key_send` | 你的电键拍发(p8 左反喂 / p9 左发报) | SA3 | "Vintage brass telegraph key sending morse, spring clatter and clicks, 4 seconds" |
|
||||
| `sfx/pen_scratch` | 处长记事笔(试探戏/呈报) | SA3 | "Fountain pen scratching on paper, short strokes, 2 seconds" |
|
||||
| `sfx/tea_cup` | 茶杯落桌(处长场标记音) | SA3 | "Tea cup set down on wooden desk, porcelain clink, soft" |
|
||||
| `sfx/step_halt` | 门外脚步停住(T4 danger 拍 / hot 档) | SA3 | "Footsteps in corridor stopping outside a door, heavy boots, tense, 4 seconds" |
|
||||
| `sfx/lock_click` | 门锁/枪机(e3/e4 链) | SA3 | "Door lock slowly turning, metal click, ominous, 2 seconds" |
|
||||
| `sfx/dawn_bell` | 黎明远钟(e1/e2 链) | SA3 | "Distant morning bell over light rain, calm after a long night, 4 seconds" |
|
||||
| `sfx/ui_confirm` / `ui_menu` | 菜单/确认(程序合成兜底) | SYN | 同全局先例 |
|
||||
| **(摩尔斯)** | 电文/候选/重听/慢放全部音 | **SYN 运行时模块** | §2.1 时值表;**零文件资产** |
|
||||
|
||||
- 预警窗纪律:T4 danger 拍 step_halt **前置 2s 渐强**(L2),danger 签名与音效同窗(radio 刹车/abyss 滑坡先例);e3 链首 danger 签名一次。
|
||||
- 承诺绑定:rx4_in 教「快手七的手法你听过」后,p9 左 d9_send 与 p8 左 r4a_feed 必播 key_send(§7.5 清单+断言)。
|
||||
|
||||
### 6.3 Voice 划分(详见 19-cipher-voice-ids.md)
|
||||
|
||||
| 组 | 声部 | 落位 | 数量 |
|
||||
|---|---|---|---|
|
||||
| 报务员(你)OP | 双性别(female=Serena / male=Uncle_Fu + OP instruct 常量) | `voice/female\|male/` | 20 句 |
|
||||
| 北风电台(上线联络+系统/向导)WIND | 双性别(female=Vivian / male=Dylan + WIND instruct 常量) | `voice/female\|male/` | 114 句 |
|
||||
| 处长 NPC | 平铺单音色(Eric),**不做双性别** | `voice/` 根(平铺回退命中) | 5 句 |
|
||||
|
||||
- 人物账:有台词人物 = 你 + 北风(上线联络人,向导人设 L4,radio 导播同型)+ 处长(明线上级)——**上级/联络人 ≤2 约束满足**;另有 1 个**无台词角色**「快手七」(对家报务手,存在=电波里的手法音,abyss 小郑先例)。
|
||||
- 合计 139 句(≤150 预算 ✓,含 `_k` 键盘变体 11 对);音频文件 = 134×2 + 5 = 273 条(×2 格式 = 546 文件)。
|
||||
|
||||
## 7. 向导层接入
|
||||
|
||||
### 7.1 状态签名 earcon / turn cue
|
||||
|
||||
| 时机 | 向导动作 | 说明 |
|
||||
|---|---|---|
|
||||
| INTRO 进入 | `guide.state('explore')` | 叙事态签名 |
|
||||
| DECODE 进入(首播后) | `guide.state('choice')` + `guide.turn({haptic:true})` | 摩尔斯首播完 → turn 签名+confirm 震=「轮到你选词」;dv*_ask 随后落地 |
|
||||
| 每个叙事抉择 p* 起播 | `guide.state('choice')` | 选项句本身即 turn cue(W2 契约零插播) |
|
||||
| NIGHT 进入 | `guide.state('settle')` | 夜结算签名 |
|
||||
| ENDING 进入 | `guide.state('settle')` | 同上 |
|
||||
| MENU 打开 | `guide.state('menu')` | 菜单签名 |
|
||||
| T4 揭晓 danger 拍 / e3 链首 | `guide.state('danger')` | 全游戏仅两处(step_halt 前置 2s 同窗 + danger 震) |
|
||||
| 无效手势 | `guide.error({voice:'gd_invalid', onceKey})` | error 震 + full 档语音,idle-only(F1.4) |
|
||||
|
||||
- earcon 词表:只用全项目统一 8 音中的 7 个(menu/explore/choice/settle/danger/turn/nudge),**零新增**;battle 不用。
|
||||
|
||||
### 7.2 看门狗双轨(radio F1 + dungeon E0-1 教训:乱按也要被抢救)
|
||||
|
||||
**无操作轨**(guide watchdog,任何手势复位;两级不同句、用尽即停、永不惩罚):
|
||||
|
||||
| 等待点 | full 档 | standard 档 | 级别内容 |
|
||||
|---|---|---|---|
|
||||
| DECODE 浏览无操作 | [10, 25] | [10, 25](onEscalate 游戏层补播) | ① gd_tune1「电文在等。左右滑,听候选词。」② gd_tune2「双击,把电文再听一遍。再双击,会放慢。」(**必须不同句**) |
|
||||
| INTRO/RELAY 链末等待 | [25, 50] | [13, 30] | ① gd_continue ② gd_again(storyline F1.1 同款) |
|
||||
| 抉择点 p* 播完无操作 | [25, 50] | [25, 50] | 重播当前 p* 提示句(13 号 §16 先例;空点单击=重挂计时) |
|
||||
| ENDING 结算等待 | [25, 50] | [13, 30] | gd_continue / gd_again |
|
||||
|
||||
**无进展轨**(游戏层计时,仅挂 DECODE 浏览一个可饿死点):
|
||||
|
||||
| 项 | 规则 |
|
||||
|---|---|
|
||||
| 进展定义 | 译词判定落定 / 叙事抉择结算 / 节点推进 / 翻密码本。**无效手势与纯浏览(切候选/重听)不计进展**——乱滑 96s 也必被抢救 |
|
||||
| 阈值 | 60s → gd_prog1「光切词没有用。双击,先听电文。」;120s → gd_prog2「别急。停下来,把电文听完整。」;用尽即停(每封一轮) |
|
||||
| 有真实进展 | 全程零 prog 播出(不误伤) |
|
||||
| 双轨去重 | 两轨短句内容同级交叉登记;同一等待点先播过 gd_tune* 则无进展轨跳过同义级 |
|
||||
|
||||
- 向导插播一律 `queue:true`,绝不顶掉在播对白;error/watchdog 类语音 idle-only(在播则跳过且过期丢弃,F1.4)。
|
||||
- 单句语音看门狗(资产缺失兜底):30s 超时且 `isVoicePlaying()===false` 才自动续链,长句续约不掐(radio N1 先例照抄)。
|
||||
|
||||
### 7.3 键盘变体机制(PC 键盘玩家)
|
||||
|
||||
- 运行时按 `gesture.inputMode()`(settings.input auto/touch/key)选 `_k` 变体资产:key → `voice/<gender>/<id>_k.*`,touch → 无后缀版;auto 跟随最近使用通道。`_k` 缺失回退无后缀版(check_all_assets 校验配对)。
|
||||
- 变体清单(11 对,集中分组见 voice-ids §G0.a + M1):gd_brief / gd_continue / gd_again / gd_tune1 / gd_tune2 / sys_help / sys_menu / sys_skip / sys_continue_ask / **dv1_teach2**(首个候选导航绑定)/ **p2**(首个叙事抉择绑定)。
|
||||
- 抉择提示 p4..p9 措辞统一「向左滑/向右滑」;键盘玩家由 p2_k 与 sys_help_k 完成首次绑定,后续语义不变。启动遮罩文案引擎自理,游戏零改动。
|
||||
|
||||
### 7.4 继承 radio/abyss 三轮验证机制(照抄不重设计)
|
||||
|
||||
| 机制 | 来源 | 落点 |
|
||||
|---|---|---|
|
||||
| 帮助链去重(同等待点第 2 次上滑只震+nudge) | radio G1 | `_helpSeen` 按等待点键控 |
|
||||
| 状态链顺序「状态在前、帮助在后」 | radio G6 | prog_t → book 档 → exp 档 → sys_help |
|
||||
| 空点确认轻震(不可跳上单击补 beat [8]) | radio G4 | p*/摩尔斯首播/链末句各 tap 屏蔽分支 |
|
||||
| exp_hot 播报位附 warning 震 | radio G2 / abyss | 全部 hot 出口(含上滑复听) |
|
||||
| 菜单报名游戏侧排队零截断 | radio 实现修复 #3 | `_menuQueue` 排水 |
|
||||
| stop() 先 `seqToken++` 作废在途链 + 停摩尔斯排程 | radio 实现修复 #6 | 同款(摩尔斯句柄一并 stop) |
|
||||
| 新局清 choiceArmed/pendingChoice/双击慢放计数 | radio 实现修复 #7 | newNight() |
|
||||
| 长按误报无效(longpress 全状态合法) | radio 实现修复 #2 | 仅 left/right(ASK 另含 up/down/doubletap)报无效 |
|
||||
|
||||
### 7.5 教学承诺清单(dungeon「铁器=楼梯」教训:每句承诺必须真实存在且可感知)
|
||||
|
||||
| 教学句 | 承诺 | 兑现点(断言锁定) |
|
||||
|---|---|---|
|
||||
| dv1_teach「先双击,把它重新听一遍」 | 双击=重听电文 | DECODE 全程恒可用(原速) |
|
||||
| gd_tune2/dv1_teach「再双击,会放慢」 | 第 2 次双击=慢放 0.5× | 慢放计数器任何封恒在;时值断言 u=160 |
|
||||
| dv1_teach2「左右滑,听候选词。单击,选定一个」 | 候选预览/两段确认 | 全部 DECODE 恒同语义(含确认态取消) |
|
||||
| hint_t1「我教你一页:第一个字母,是 B」 | T1 提示免费 + 提示给辨析位字母 | T1 翻页不扣;hint_* 与 §2.2 辨析位一致 |
|
||||
| b_rule「规矩就一条:听不清,就再听一遍」 | 重听/慢放无限免费 | 全局无重听惩罚;慢放不限次 |
|
||||
| b_goal「今晚频道里有四封密电」 | 恒 4 封 | 剧本 A 恰 4 封走完(断言) |
|
||||
| b_chief「四封电文,一封都不许漏」 | 同上(明线口径) | 同一计数 |
|
||||
| rx4_in「快手七的手法你听过」→r4a_feed「借快手七的手法」 | 提到发报必闻电键声 | p8 左/p9 左必播 key_send(零漏播断言) |
|
||||
| dv1_right「练习有答案」(正片无对错反馈) | 教学期即时反馈、正片不揭穿 | T1 判定出口有反馈句;T2-T4 判定出口零对错语音(断言) |
|
||||
|
||||
## 8. 存档设计
|
||||
|
||||
### 8.1 进度 data 结构(PUT /api/progress {game:'cipher'})
|
||||
|
||||
```json
|
||||
{
|
||||
"schema": 1,
|
||||
"updatedAt": "2026-09-09T12:00:00Z",
|
||||
"summary": "第2封·名单 · 暴露:疑云 · 结局1/4",
|
||||
"phase": "DECODE",
|
||||
"node": "dv2_ask",
|
||||
"tel": 2,
|
||||
"expose": 2,
|
||||
"hints": 2,
|
||||
"t": { "t1": "bay", "t2": null, "t3": null, "t4": null },
|
||||
"picks": { "p2": "L", "p4": null, "p6": null, "p8": null, "p9": null },
|
||||
"endings": { "e2": true },
|
||||
"runs": 3
|
||||
}
|
||||
```
|
||||
|
||||
- 写入时机:每封 RX 进入、译词判定落定后、每个抉择结算后、NIGHT 进入、ENDING 进入、菜单「保存并回大厅」。
|
||||
- 断点续玩:读档 → sys_continue_ask(_k)(单击=继续上次 / 右滑=新夜班;两者 runs 均 +1,统一口径修 radio 遗留);继续 = 恢复 phase+node+全部数值并**局面复述**:RELAY 恢复=重播当前节点链;**DECODE 恢复=prog_t → book 档 → gd_tune2 → 重挂浏览(自动预听当前候选,电文可双击重听)**——一句话 ≤5s 回到可玩(L5);恢复首句受 F4 跳句锁(radio G5 例外条款)。
|
||||
- summary 格式:进行中 `第N封·<电文名> · 暴露:<档名:平安/疑云/被盯/危局> · 结局X/4`;已收台 `已收台·<结局名> · 结局X/4`(大厅卡片直接显示,人话)。
|
||||
|
||||
## 9. playtest 断言清单(登记 13 号 §22 指针;`settings.set({guide:'off'})` 纯玩法验证,向导行为住 guide.test)
|
||||
|
||||
**关键路径**(剧本 A:全对全右+p9 左 → e1,≤60 次手势):
|
||||
1. 遮罩点按 → INTRO 链(b_open 起,voice 层有播放记录)→ rx1_in → tune_seek → **摩尔斯固定字符断言**:事件序列 == BAY 编码(`dah,dit,dit,dit / dit,dah / dit,dah,dah,dah`),750Hz,u=80±5ms,BGM 同时段 −6dB(R3)→ dv1_teach → dv1_teach2 → dv1_ask → choiceArmed。
|
||||
2. DECODE 浏览:右滑 ×3 循环切换,每次预听 = 候选摩尔斯(620Hz,u=110,与 voice **零重叠**——morseGate 断言)→ cand_* 词义句;双击 → 电文原速重播;再双击 → 慢放(u=160,字母隙 6u,750Hz);单击 → cf_confirm + 电文重播 → 单击 → 判定出口 800ms 死窗内注入在途 tap 被吞。
|
||||
3. T1 译对:dv1_right(success 震)→ RELAY:p2 左(pendingChoice 播完生效)→ r1a_send/r1a_e → n1 → NIGHT(expose=0 calm 档,零跨档播报)→ RX(2)。
|
||||
4. T2:摩尔斯==TOP 断言;译对 → rev_top → **p4_known** 播出(t2=='top')→ 右 → r2b_act → m2_chief → r2b_e → n2。
|
||||
5. T3:摩尔斯==HAND;译对 → rev_hand → p6 右 → r3b_e_ok(t3=='hand')→ n3。
|
||||
6. T4:摩尔斯==SPY;译对 → rev_spy(danger 拍断言:step_halt 前置 2s 渐强 + danger 签名 + danger 震)→ m4_chief_a/b → **p8_known** → 右 → r4b_act → m4_chief_c → r4b_e。
|
||||
7. 签收:g9_in → g9_knot → **p9_known** 左 → d9_send + key_send → pre=0 ≤4 → d9_send_e → ENDING(e1):e1_a/b + ep_lead + ep_med_ok/ep_list_no/ep_hand_ok/ep_spy_ok → 结算单击 → 新夜班回 INTRO(runs+1)。
|
||||
|
||||
**边界断言**:
|
||||
- **四结局可达(含暴露度逐点验算)**:剧本 B(同 A,p9 右)→ e2;剧本 C(T2/T3/T4 全译错 + p4/p6/p8 全左):NIGHT(1) 后 expose=0(calm)/NIGHT(2) 后 2(low,跨档播 exp_low)/NIGHT(3) 后 4(mid)/签收前 8(hot,exp_hot+warning 震)→ p9_blind 左 → d9_caught_e → e3;剧本 D(同 C,p9 右)→ e4(lock_click 链)。各检查点档位句与 §5.3 区间一致。
|
||||
- **三层兜底各自可走通**:剧本 E(提示流)——T1 翻页免费(hints 仍 3),T2/T3/T4 各翻 1 页(book_2/1/0 逐值播出,逐页 −1 断言),按提示选定全对 → e1;第 4 封后页数 0 再长按 → error 震 + paper_page,无语音、零惩罚;剧本 F(慢放流)——每封双击×2 慢放后译对,零提示,全对(慢放不限次断言)。
|
||||
- **摩尔斯正确性**:四封电文事件序列逐元素 == §2.2 表(BAY/TOP/HAND/SPY);候选预听 == 所选候选编码;慢放时值 = 原速 2×(容差 ±5ms);**settings.speed=2.2 会话下 u 仍 80ms**(速度边界断言)。
|
||||
- **译错归因真话**:T1 错选 DAY/RAY → dv1_wrong 播出且句内字母/码与真词 B 一致 → 无限重选直至对(expose 零变化);剧本 C/D 的 ep_spy_no/ep_hand_no 与 t3/t4 flags 一致;正片判定出口零对错语音(教学承诺)。
|
||||
- **morseGate**:全剧本转写断言——摩尔斯起振时刻与任一 voice 播放区间零重叠(排队语义:晚于在播句结束);候选词义句在候选摩尔斯结束后 ≥500ms 接播。
|
||||
- **看门狗双轨**:DECODE 快进 10s→gd_tune1、25s→gd_tune2(两级 id ≠,绝不逐字重播;两级后仅静电底噪);**乱按 96s**(每 2s 注入一次切候选滑动+双击重听):无操作轨零播出(被手势复位)+ 无进展轨 60s→gd_prog1、120s→gd_prog2;有真实进展(译词落定推进)全程零 prog 播出;RELAY 链末 25s/50s → gd_continue/gd_again;p* 播完 25s/50s 重播 p* 两次后静默;`guide=off` 全程零定时器零向导事件。
|
||||
- **键盘变体**:settings.input='key' 会话播出 gd_brief_k/sys_help_k/gd_tune1_k/dv1_teach2_k/p2_k 且对应无后缀版零播出;'touch' 反之;'auto':keydown 后下一句用 _k。
|
||||
- **中断复述**:杀进程重进(存档 phase=DECODE, tel=3, hints=1)→ sys_continue_ask → 单击 → 恢复链 prog_t3 → book_1 → gd_tune2 → 浏览重挂 + 当前候选自动预听(电文双击可重听);恢复首句不可跳,第二句起可跳;右滑=新夜班(runs +1 口径同结算重开)。
|
||||
- **pendingChoice**:p* 播放中左右滑 → 播完立即生效(不丢、不重复、连滑取最后一次)。
|
||||
- **p* 不可跳**:p* 播放中单击 → 不跳句(PROMPT_RE 门)+ beat 轻震(G4)。
|
||||
- **idle-only**:向导 gd_* 在对白在播时跳过且不占 onceKey(F1.4);queue 句排在当前句后零截断。
|
||||
- **菜单**:下滑开菜单 → 上滑帮助 → 双击「回到电波」→ phase/node 不变、原状态复述;单击循环顺序 = [回到电波, 翻密码本, 重新开始今晚, 保存并回大厅];菜单「翻密码本」确认 = 长按同效(回 DECODE 执行提示流程);确认回大厅 → sys_menu_lobby 播出且 PUT/localStorage 有最新 data。
|
||||
- **资产缺失**:屏蔽任意 voice 资产 → 30s 看门狗自动续链到结局不卡死;摩尔斯为运行时合成,屏蔽 sfx/bgm 全部不影响电文可听(模块零依赖断言)。
|
||||
- **数字规范**:prog_*/book_*/exp_* 全部整句字面量,静态审计无运行时拼接碎片。
|
||||
|
||||
**失败即不通过**:任何等待 >5s 无声(静默死局);无效手势零反馈;摩尔斯字符序列/时值与 §2.2 表不符;摩尔斯与语音重叠;结局计数与 §4.4 不符;档位句与 expose 实值不符;归因假话(dv1_wrong 字母错、ep_* 与 flags 不符)。
|
||||
|
||||
## 10. 节奏曲线(每封电文目标时长)
|
||||
|
||||
| 段 | 内容 | 目标时长 | 设计目标 |
|
||||
|---|---|---|---|
|
||||
| 开场 | 夜班开场 + 一句规矩 + 处长夜令 | 1-1.5 min | 首输入 <60s(INTRO 链 ~25s 后第一封电文首播,浏览滑动即首输入 ~t+45s);规矩一句讲完(P4) |
|
||||
| T1 船期 | 教学封:两层重听教学 + 免费提示示范 + p2 | 3.5-4 min | **首个正反馈 ≤3min**(译对 dv1_right ≈ t+2min);译错即时归因+无限重选零惩罚 |
|
||||
| T2 名单 | known/blind 差分首现 | 3-3.5 min | 「你不知道自己译没译对」的第一次心跳;呼吸口(听辨最易) |
|
||||
| T3 交接 | 最狠听辨(H vs S 差一个 dit) | 3.5-4 min | 慢放价值兑现段(P3 嘈杂场景实测点);NIGHT(3) 档位句把压力可视化 |
|
||||
| T4 处置令 | 高潮:danger 拍 + 处长试探 + 反喂 | 4-4.5 min | 紧张峰值但无倒计时(P4);bgm/closing 交叉淡入 |
|
||||
| 签收+结局 | 心结 p9 + 发最后一电 + ep 点名 | 2.5-3 min | 整晚的「听」在你自己的电键上闭环(P2 回响);开环钩子拉下一局 |
|
||||
|
||||
- 合计 ≈ 19-22 min(15-25 达标);每 30-60s 一个反馈颗粒(候选预听/摩尔斯/揭晓句/结果句/档位句),无沉默尴尬期(P3)。
|
||||
- 难度曲线 = 听辨精度(教学 B/D → 最易 O/A/I → 最狠 H/S → 中高 P/L)+ 认知重量(练手 → 名单有同伴 → 时间就是命 → 处置令是你),操作复杂度恒定(左右滑+单击+双击,永远如此)——P4「规则一遍听懂」由恒定操作面保证。
|
||||
|
||||
## 11. 自检清单(策划交付自验;☐ = 待开发/测试轮填)
|
||||
|
||||
| # | 硬约束/教训 | 落地 | ✓ |
|
||||
|---|---|---|---|
|
||||
| 1 | FTUE 首输入 <60s | INTRO 链 ~25s 后第一封首播,~t+45s 首次滑动(§10) | ☑ |
|
||||
| 2 | FTUE 首个正反馈 ≤3min | 译对 dv1_right ≈ t+2min(§10 T1) | ☑ |
|
||||
| 3 | 学习期零惩罚 | T1 译错无限重选零资源;DECODE 无超时惩罚;密码本 T1 免费 | ☑ |
|
||||
| 4 | 失败三问归因+归因真话律 | dv1_wrong 字母真话;正片不揭穿+ep_* 单源对应;§2.5 无假归因 | ☑ |
|
||||
| 5 | 资源账目真实(radio rep_low 教训) | book_1..0 逐值整句;exp 四档措辞逐值为真;档位阈值=收网门(§5.3/5.4) | ☑ |
|
||||
| 6 | 手势宪法 6 手势默认语义,豁免显式登记 | §3.3 全覆盖;唯一豁免 E1(长按=密码本,时间互斥 detective E2 同款);菜单 §5.2 模态 | ☑ |
|
||||
| 7 | 长按显式登记 | E1 在案(空闲=提示/在播=引擎快进,互斥);其余长按=快进不豁免 | ☑ |
|
||||
| 8 | 向导:签名/turn cue/看门狗两级不同句 | §7.1/7.2;gd_tune1≠gd_tune2;gd_continue→gd_again | ☑ |
|
||||
| 9 | 看门狗双轨(dungeon E0-1/radio F1 教训) | 无操作轨+无进展轨;纯浏览不计进展,乱按 96s 必被抢救;有进展零打扰 | ☑ |
|
||||
| 10 | 插播 queue 不顶对白;纠错 idle-only 过期丢弃 | §7.2(F1.4 契约) | ☑ |
|
||||
| 11 | 死亡/失败结算链完整(dungeon H1 教训) | 判定出口/NIGHT/d9/e* 链 800ms 手势死窗;seqToken+停摩尔斯(§3.2/7.4) | ☑ |
|
||||
| 12 | 教学承诺兑现(dungeon「铁器=楼梯」教训) | §7.5 九条承诺清单逐条绑兑现点+断言 | ☑ |
|
||||
| 13 | 单次播报 ≤3 选项 | 译词恒 3 候选逐项预听(≤3 ✓);叙事抉择恒 2;菜单 4 项循环 | ☑ |
|
||||
| 14 | 并发声流 ≤2 + 双通道仲裁 | voice 串行+摩尔斯互斥(R1-R5,§3.4);断言零重叠 | ☑ |
|
||||
| 15 | earcon ≤7、统一词表、语义靠语音 | 只用统一 8 音中 7 个(battle 不用),零新增 | ☑ |
|
||||
| 16 | 台词一句一文件 ≤40 字、数字分档整句、无运行时拼接 | voice-ids 全表 ≤30 字(最长 p8_known);prog/book/exp 分档整句;句内数字汉字写死 | ☑ |
|
||||
| 17 | 多音字规避/同 instruct 常量/无语速词 | voice-ids 头部+文末自查(长/处/圈/卷/塞/着 试听项) | ☑ |
|
||||
| 18 | PC 键盘变体(提示句集中+标注) | 11 对 _k 集中分组(voice-ids §G0.a+M1);inputMode() 运行时选择 | ☑ |
|
||||
| 19 | P1:可打断/重听(含电文)/status key/不当白痴 | 跳句+双击(电文重听+慢放 R5)+上滑状态链+成功零补救教学 | ☑ |
|
||||
| 20 | P2:3 分钟见效/结局回响 | ~2min 首个「世界因你而动」(药船接应);ep 逐封点名+真词差分 | ☑ |
|
||||
| 21 | P3:3 分钟颗粒/中断复述/单手/嘈杂 | 一封=3-4min 完整段落+边界存档;重进一句话复述(含 DECODE 态);慢放无限=嘈杂兜底 | ☑ |
|
||||
| 22 | P4:一遍懂/容错/无高压倒计时/不骂人 | 一句规矩;无倒计时无死亡;译错也是剧情;操作面恒定;NPC 句 ≤23 字 | ☑ |
|
||||
| 23 | 抉择树 4 结局可走通验算 | §5.5 公式+剧本 A-D 逐检查点(e1/e2: wrong+risk≤4;e3/e4: ≥5) | ☑ |
|
||||
| 24 | 单局 15-25 min | §10 曲线 ≈19-22 min | ☑ |
|
||||
| 25 | 分支不爆炸(radio 纪律) | 跨封仅标量(expose/hints/t1..t4/picks);~75 节点固定深度(§4.3) | ☑ |
|
||||
| 26 | 台词 ≤150、上级/联络人 ≤2 | 139 句(双 134+NPC 5)/处长+北风两人(voice-ids 账目) | ☑ |
|
||||
| 27 | 引擎边界诚实 | §3.4 能力表:摩尔斯文件方案否决理由/滤波不使用/速度边界写明 | ☑ |
|
||||
| 28 | 存档带 summary、断点续玩 | §8:data+summary 格式、DECODE 态恢复、局面复述 | ☑ |
|
||||
|
||||
### 批 1 教训内化确认(5 条全落地)
|
||||
|
||||
| 教训 | 本作机制 | 断言 |
|
||||
|---|---|---|
|
||||
| 教学承诺必须兑现 | §7.5 九条承诺清单(重听/慢放/候选/单击/免费页/四封/电键声/教学反馈边界) | §9「摩尔斯正确性」「教学承诺」块 |
|
||||
| 看门狗双轨 | §7.2 无操作轨+无进展轨;纯浏览不复位进展轨 | §9「看门狗双轨」块 |
|
||||
| 档位措辞真实 | §5.3 exp 四档逐值为真且阈值=收网门;§5.4 book 逐值 | §9「档位句与实值一致」 |
|
||||
| 失败结算链完整不被打断 | 800ms 死窗盖判定出口/NIGHT/d9/e*;seqToken+停摩尔斯 | §9 关键路径 2 + 死窗断言 |
|
||||
| PC 键盘操作提示 | 11 对 _k+inputMode() 选择+集中分组标注 | §9「键盘变体」块 |
|
||||
|
||||
### 本作特有风险预防(摩尔斯听觉门槛)
|
||||
|
||||
| 风险 | 三层防线 | 验证 |
|
||||
|---|---|---|
|
||||
| P3 通勤嘈杂听不清长短音 | ①双击重听原速(无限)②再双击慢放 0.5×(无限、字母隙加倍)③密码本提示直译辨析位字母(3 页,T1 免费)——**三层均可独立走通** | §9 剧本 E/F + 三层兜底断言 |
|
||||
| P1 视障玩家音频编码接受度高,但语速档位边界 | 摩尔斯不受 settings.speed 影响(u 恒定)——2.2× 档语速下电文仍原速,慢放兜底;**边界登记 + live 真人耳测项**(转写层测不了时值听感,methodology §5 2026-09 教训:媒体播放类必须真人耳测+引擎级断言) | §9「摩尔斯正确性」速度边界断言 + live 轮清单 |
|
||||
| 摩尔斯时值精度 | 运行时 osc 合成(文件方案否决:有损编码 ms 抖动);事件钩子逐元素断言 | §9 固定字符断言 |
|
||||
| 「不知道译对没译错」的认知焦虑 | 教学期说破「练习有答案,正片靠耳朵」;档位句+ep 回响给最终真相;译错零惩罚只是分支 | §9「译错归因真话」 |
|
||||
@@ -15,6 +15,19 @@
|
||||
| [04-space-rebuild.md](04-space-rebuild.md) + [04-space-voice-ids.md](04-space-voice-ids.md) | 《盲航》重构:交互式演练、同向闪避、60 秒保护期、52 句台词表 | ⑨ |
|
||||
| [05-rpg.md](05-rpg.md) + [05-rpg-chapter1.md](05-rpg-chapter1.md) + [05-rpg-ch1-voice-ids.md](05-rpg-ch1-voice-ids.md) + [05-rpg-addendum.md](05-rpg-addendum.md) | 新 RPG《剑与声》:总设计 + 第一章施工稿(场景图/战斗状态机/数值/存档/资产 prompt)+ 120 句台词表 + 增补(战斗震动配合、无声前摇协议、层叠规则) | ⑩ |
|
||||
|
||||
## new8 系列设计文档(8 款新 RPG,research/new8/00-program.md)
|
||||
|
||||
| 文档 | 内容 |
|
||||
|---|---|
|
||||
| [15-radio.md](15-radio.md) + voice-ids | 《不眠频率》深夜电台热线叙事(批次 1 交付,4/4 人设满分档):9 抉择 4 结局、口碑经济、电话滤波资产侧带通 |
|
||||
| [16-dungeon.md](16-dungeon.md) + voice-ids | 《回声地窟》听声辨位 Roguelike(批次 1 交付,0/4→4/4 翻案):脉冲回声、seed 生成、双轨看门狗、元进度遗产 |
|
||||
| [17-abyss.md](17-abyss.md) + voice-ids | 《深海回音》深海救援叙事(批次 2):声呐双通道仲裁、氧气软失败经济(512 组合穷举验算)、148 句 |
|
||||
| [18-detective.md](18-detective.md) + voice-ids | 《雨夜专案》本格推理(批次 2):证词矛盾=数据单源推导、评级 S-C、二周目变体案、158 句 |
|
||||
| [19-cipher.md](19-cipher.md) + voice-ids | 《暗码》1940 密战叙事(批次 3):摩尔斯运行时合成解码、暴露度经济、三层兜底、139 句 |
|
||||
| 20~22 | 《深夜茶馆》《守塔人》《星环舰长》(批次 3/4,设计进行中,落地后补登记) |
|
||||
|
||||
各 voice-ids 文档的「键盘变体」小节由 KEY_LINES 程序化生成(tools/gen_voice_dual.py 单源),含 PC 键盘措辞(按空格/按回车/按方向键)。
|
||||
|
||||
## 审查档案(各轮落实度与裁定记录)
|
||||
|
||||
| 文档 | 内容 |
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
# storyline-voice-ids · 《声命线》语音台词表(voice ids)
|
||||
|
||||
> 主台词表(41 句旁白/系统音,双性别)的唯一事实源是 `tools/gen_voice_dual.py`
|
||||
> 的 `STORYLINE_LINES`(角色台词为平铺单音色,沿用 `web/storyline/audio/voice/`
|
||||
> 原文件,不在双性别管线内;主表史源 app/src/storyline/gen/gen_voice.py)。
|
||||
> 本文档登记 P1 键盘变体(输入平权路线 a)——变体只覆盖含操作词的句子,
|
||||
> id 集合 ⊆ 主表,复用主表同 id 的 instruct/speaker。
|
||||
---
|
||||
|
||||
## 键盘变体(key,P1 输入平权路线 a,19 句)
|
||||
|
||||
「生效输入模式=键盘」(settings.input=key,或 auto 且键盘在跟/纯桌面初始判定,
|
||||
web/engine/gesture.js inputMode())时,引擎 voice 候选链前置加载
|
||||
`web/storyline/audio/voice/<gender>/key/<id>.{ogg,m4a}`,变体缺失回退主资产——触屏措辞零改动。
|
||||
>
|
||||
> 措辞规范(02-input-parity.md §4.3 路线 a + P1 裁定):向左滑→按左方向键(四向同理,
|
||||
> WASD 不进台词);单击/轻触屏幕→按空格;双击→按回车;按住/长按→按住空格;
|
||||
> 复合短语(左右滑→左右方向键、滑动→方向键)按语义等价展开;只改操作词,其余
|
||||
> 内容一字不动,不新增「重」类多音字。本表与 `tools/gen_voice_dual.py` 的
|
||||
> `KEY_LINES` 逐字一致(两表一致铁律:改一处必改另一处)。
|
||||
> 资产:×2 性别 = 19×2 条、×2 格式 = 19×4 文件;管线 `gen_voice_dual.py --only-variants`
|
||||
> 生成 → `--convert` 落盘,终检 `tools/check_all_assets.py`(key 两性别一致且 ⊆ 主集)。
|
||||
|
||||
| id | 键盘台词全文(触屏原句见本表上方对应 id) |
|
||||
|---|---|
|
||||
| `help` | 操作说明。按空格:继续剧情。按回车:重听刚才的台词。按上方向键:听这段说明和当前进度。按下方向键:呼出菜单,菜单里可以重新开始。当旁白说“请选择”的时候,按左方向键或者按右方向键,做出你的决定。选择无法撤销。 |
|
||||
| `menu` | 菜单。按左方向键:重新开始整个故事。按右方向键,或者按空格:回到故事。按上方向键:听操作说明。 |
|
||||
| `p1` | 请选择。按左方向键:先检查背包里的收音机。按右方向键:先摸黑寻找出口。 |
|
||||
| `p2` | 请选择。按左方向键:钻进旁边的通风管道。按右方向键:躺进路边的尸体堆里装死。 |
|
||||
| `p3` | 请选择。按左方向键:循着哭声过去看看。按右方向键:不去管它,直接去北区。 |
|
||||
| `p4` | 请选择。按左方向键:带上小满一起走。按右方向键:留下食物,独自上路。 |
|
||||
| `p5` | 请选择。按左方向键:走桥下的污水涵洞。按右方向键:爬桥上悬着的钢索。 |
|
||||
| `p6` | 请选择。按左方向键:交出坐标,保命要紧。按右方向键:拒绝他,想办法周旋。 |
|
||||
| `p7` | 请选择。按左方向键:追上去,警告避难所。按右方向键:自己逃命,越远越好。 |
|
||||
| `p8` | 请选择。按左方向键:用公开频道广播,让全城都听见。按右方向键:用加密频段,只发给避难所。 |
|
||||
| `n00_intro` | 大停电后的第三十天,城市陷入彻底的黑暗。没有电,没有网络,只有收音机里偶尔闪过的沙沙声,像垂死者的呼吸。你是林晚,一名前急救员。在这个故事里,你用声音活下去。请记住:按空格,继续剧情;按回车,重听上一句;按上方向键,听你的状态和帮助;按下方向键,呼出菜单。当我说“请选择”的时候,按左方向键,或者按右方向键,做出你的决定。选择一旦做出,就无法回头。现在,按空格,睁开眼睛。 |
|
||||
| `e1_dawn` | 加密频道那头沉默了三秒。然后,一个你等了三十天的声音响了起来:“姐?姐!是你吗?”天亮之前,避难所的救援队打开了大门。猎狗的人,在北区的高墙下溃散了。你抱着晨晨,听见广播塔里,重新响起了音乐。后来人们说,这座城市,是从一个女人的声音开始,重新活过来的。——好结局:黎明。感谢你,陪林晚走完了这条路。按空格,可以回到故事开始的地方。 |
|
||||
| `e2_price` | 你赶在车队前面,撞进了避难所的大门。“关掉广播!关灯!猎狗来了——!”那一夜,北区守住了。探照灯熄灭的时候,晨晨从人群里扑出来抱住你,才发现你胳膊上的血,已经把半边袖子浸透了。坐标是你交出去的,命,是你抢回来的。你赢了,用一条胳膊的代价。——结局:代价。按空格,重新开始。 |
|
||||
| `e3_alone` | 你逃了。一路向南,没有回头。三天后,收音机里关于北区的广播,停了。又过了七天,你在一个废弃的加油站里,听见最后一个频段,也变成了沙沙声。你活下来了。只是从此以后的每一个夜里,你都会想起那声口哨,和你报出坐标时,自己发抖的声音。——坏结局:孤声。按空格,重新开始。 |
|
||||
| `e4_static` | 公开频道,把所有人都引来了——幸存者,还有猎狗。塔顶的风很大,你看见山下火把连成的长龙,也看见避难所方向亮起的防御火光。猎狗的刀抵上来的时候,你对着麦克风笑了:“听见了吗,晨晨?姐姐的声音,全城都听见了。”信号中断了。但那晚之后,北区,再没有人投降。——结局:静默。按空格,重新开始。 |
|
||||
| `skip_hint` | 按空格可跳过旁白。 |
|
||||
| `gd_continue` | 按空格,继续。 |
|
||||
| `gd_brief` | 按空格继续剧情。请选择的时候,按左右方向键。 |
|
||||
| `gd_again` | 还在吗?按空格继续。 |
|
||||
Reference in New Issue
Block a user