# 15 · 《不眠频率》(radio) — 深夜电台热线叙事 RPG > **给开发的实现要点摘要** > 1. 交互权威:[26-audio-interaction-playbook.md](26-audio-interaction-playbook.md)。本文件按附录 C 填写;与旧手势表冲突时以本文为准。范式对齐 [26-apply-storyline.md](26-apply-storyline.md)。 > 2. 叙事骨架不变:节点链 onComplete 串行 + seqToken 打断作废 + pendingChoice 缓存;6 宏状态 INTRO / RING / ONAIR / BRIDGE / ENDING + MENU。 > 3. 新手三手势:单击继续/接听、左右滑抉择、上滑「我在哪」。**不识别双击**。无四向滑动玩法,帮助不上长按。菜单:左右滑切换、单击确认。 > 4. 台词 [15-radio-voice-ids.md](15-radio-voice-ids.md)(132 句:双性别 103 + 平铺 NPC 29)。NPC 电话滤波在资产侧 ffmpeg 带通,引擎零改动。 > 5. 章程:单局 15–25 分钟、9 抉择点、4 结局、分支局部化。开场砍长规矩:3 秒内动手,10 秒内接听成功。 --- ## 附录 C · 设计单 ### 1. 一句话核心动作 **听一段热线,单击继续或接听;听到选项时左右滑做决定。** ### 2. 玩家能感知的状态(3 个) | 状态 | 听感 | Floor | |---|---|---| | 听讲 | 主播/来电者语音,BGM 整链压低 | SPEAKING | | 轮到你 | 风铃 `turn` → 400ms 后等待声(RING 用铃声循环代替合成等待声) | YOUR_TURN | | (菜单/结算为元状态,`menu`/`settle` earcon + 结算句标识,不占新手三态) | | | RING 的铃声循环即等待声身份;首次出现配一句:「灯亮了,点一下接听。」 ### 3. 新手手势与解锁 | 手势 | 含义 | 解锁 | |---|---|---| | 单击 | 继续 / 接听 / 跳过当前这句 | 阶段 0 | | 左滑 / 右滑 | 抉择(左=走心,右=克制) | 阶段 0 | | 上滑 | 我在哪(通号 → 口碑 → 一个动作,≤20 字) | 阶段 1(第一次抉择后) | | 下滑 | 菜单 | 阶段 2(第一次到达结局) | | 双击 | 新手期不存在,按单击处理。阶段 3 起=重听**当前等待点完整句**(加「再说一遍:」)。禁止绑整节点重播 | 阶段 3(累计 3 局) | | 长按 | 新手期 `invalid`。未占用帮助:旁白加速(12 号) | — | ### 4. 状态 × 手势矩阵(新手期) | 状态 \ 手势 | 单击 | 左/右滑 | 上滑 | 下滑(未解锁) | 双击 | 连点 | |---|---|---|---|---|---|---| | 游戏在说 | 跳过这句 + ok(p* / 链末关键句除外 → busy) | 打断后:抉择点缓存 pendingChoice、不盲选;非抉择点 invalid+解释一次 | 打断,答「我在哪」 | invalid + 首次解释 | 按单击 | 400ms 内 busy | | 等你继续 | 继续 + ok | invalid(「现在不用选。单击继续。」) | 我在哪 | invalid | 按单击 | busy | | RING 等接听 | 接听 + line_connect(silent-ok) | invalid + 首次解释 | 「第 N 通。点一下接听。」 | invalid | 按单击 | 400ms 内 busy | | 等你选择 | 再听选项(「再说一遍:」+ 完整句,hold) | 抉择 + ok | 「正在抉择。左右滑。」 | invalid | 按单击 | 计入迷茫 | | 结算 | 新夜班 + ok | invalid | 重播结局+口碑一句 | 菜单(阶段2) | 按单击 | 只处理第一下 | | 菜单 | **确认当前项** + ok | 右=下一项 / 左=上一项,每项报名 | 重听菜单说明 | 关闭 | 按单击 | busy | 验收:无空格;无「没有声音」;连点无重播/重开。 **跳过纪律(G5,无双击重播)**:首播必完整——p* 不可跳、链末交接句不可跳、ASK 恢复首句锁。复播(关菜单复述)可掐。p* 播放中左右滑只缓存,句尾生效。 ### 5. 等待点配置 | id | 期待 | full | short | 静默 | L2 只留 | L3 演示 | 失败归因 | |---|---|---|---|---|---|---|---| | intro | tap | 「点一下屏幕。」 | 「点一下。」 | 6s / 15s | tap | 替点一下 | — | | ring | tap | 「热线在闪。点一下,接听。」 | 「点一下。」 | 8s / 18s | tap | 替接听 | — | | continue | tap | 「单击,继续。」 | 「单击。」 | 18s / 40s | tap | 替继续 | — | | choice | left/right | 当前 pN | 「左右滑,选。」 | 25s / 50s | 左右滑 | 「左右滑,都可以。现在你来。」 | — | | settle | tap | 「单击,重新开始。」 | 「单击。」 | 20s / 45s | tap | 提示音 | — | | reopen | tap/right | sys_continue_ask | 「单击。」 | 12s / 30s | — | 提示音 | — | | menu | tap/left/right | menu_help | 「左右滑,点一下定。」 | 20s / 45s | — | 提示音 | — | 三档 + 30s 台账去重走引擎 `hints.js`。RING 两级不同句,用尽只留铃声,永不惩罚。 ### 6. 首 3 分钟逐秒脚本 | 时间 | 游戏说 / 播 | 期待 | 没做 | 做错 | |---|---|---|---|---| | 0~3s | onair_sting + amb_studio →「点一下屏幕。」(critical) | 单击 | 6s:「点一下。」 | 滑动:invalid +「先点一下。」 | | 3~8s | ok →「热线灯亮了。」→ 铃声 + turn | 单击接听 | 「点一下,接听。」 | 滑动:invalid | | 8~10s | line_connect + 老周开口(z1_a) | 听 | | | | 10~15s | 「听到这个声音,就是轮到你了。」→ turn + 等待声 | 单击继续 | 三档 | inv_nosel | | 15~45s | z1 链 → p1「左滑,哼歌。右滑,问路。」 | 左/右滑 | 复述 p1 | 滑早了:跳去选项句,不盲选 | | ≈50s | 老周声音稳住 +「对。」解锁上滑:「想知道自己在哪,就向上滑。」 | 上滑 | 「向上滑。」 | 单击=再听选项 | | 50~180s | p2 与 BRIDGE 口碑;第二通铃 | 单击/滑动 | 迷茫 L1→L3 | 归因真话 | 节奏:3s 内动手 ✓;10s 内接听成功 ✓;每 30s 有通号/对方情绪变化 ✓;无开场念规则 ✓。 ### 7. 失败表 | 失败类型 | 判定 | 归因句 | 回到哪里 | 新手期代价 | |---|---|---|---|---| | 非抉择点滑动 | 手势与状态不符 | 「现在不用选。单击继续。」 | 原地 | 无 | | RING 滑错 | RING 左右滑 | 「点一下,接听。」 | 原地 | 无 | | 静默 | 阈值到点 | 三档提示 | 原地 | 无 | | 迷茫 | 信号 ≥2 | L1 短句 / L2 只留期待手势 / L3 演示 | 原地 | 无 | | 负向结果(p1右+p2右) | 计分表 −1 | z1_bade 指向实际选择 | 下一通 | 不扣资源 | 叙事无资源死亡。旧「双击=整节点重播」废除。 ### 8. 台词类别 - `critical`:sys_first_tap(开场 ≤3s);RING 首次接听指令 - `content`:b_*、各通对白、p1–p9、e1–e4、ep_*、sys_turn_teach、sys_unlock_*、menu_item* - `hint`:sys_hint_*_full/short、gd_ring1/2、status/prog/rep_*、sys_continue_ask - `feedback`:inv_nosel、inv_generic、z1_bade、k1_lulle、k1_liee - 主动重听前缀:`sys_say_again` - 完整清单见 `tools/gen_voice_dual.py` RADIO 表(132 句 × 双性别主播/导播 + 29 NPC 平铺 = 235 条,×2 格式 470 文件) ### 9. 断点复述 - 保存:每通 RING、每个抉择后、ENDING、菜单「保存并回大厅」写 `soundgame.radio.save`(phase + node + rep/bond/heardArgument)。 - 回来 5s 内:sys_continue_ask「检测到上次的进度。单击,继续上次。右滑,从头开始。」单击后重播当前节点(局面复述)。 - 上滑复述模板:位置(第 N 通·来电者)。目标(口碑档)。一个动作。 ### 10. 测试记录 - 无头:`web/radio/test/playtest.mjs`。乱点机器人须 `guide=full`:无声操作 0、被动原句重复 0、打断失败 0、第一次操作 ≤3s、第一次成功 ≤10s。 - 真人冷启动:待测(26 §6.3)。 --- ## 1. 概述 - **一句话**:你是午夜档电台热线主播「今夜不眠」,一晚接进五个来电——你说什么、接不接、转不转接,改变五个陌生人的夜,也改变你自己。 - **声音即世界**:来电者永远不露面,只有滤波后的电话声;直播间垫乐与环境音是空间。 - **单局**:完整夜班 15–22 分钟;五通共享主干,分歧在通内局部化;实走 8–9 个抉择,4 结局。 - **核心循环**:铃响接听 → 听 → 左右滑(走心/克制)→ 结果与口碑 → 幕间喘息 → 下一通。跨通积累 `rep` 与各通 `bond`,收播前 p9 决定心结。 ## 2. 状态机 | 状态 | 内容 | BGM | earcon | |---|---|---|---| | INTRO | 极短开场后交 RING | `bgm/onair` | explore | | RING | 铃声循环,等单击接听 | 不切 | turn(铃声承担等待声) | | ONAIR | 通话链 + 抉择 + 结果 | `bgm/onair` | explore;p*=choice | | BRIDGE | 口碑跨档(如有)+ 喘息,auto ≤12s | `bgm/bridge` | settle | | ENDING | 结局 + 五句回响 | `bgm/ending` | settle | | MENU | 模态覆盖,暂停链 | `bgm/menu` | menu | ``` INTRO ──链完──> RING(c1) ──单击接听──> ONAIR ──链完──> BRIDGE ──> RING(c2) … RING(c5) ONAIR(c5) ──> BRIDGE ──> ◆p9 ──> ENDING(e1..e4 + ep) 任意叙事态:阶段2 后下滑 → MENU(左右滑切项,单击确认,上滑重听说明,再下滑关闭) ``` - 仅 `node.auto` 或过场自动衔接;其余 ONAIR 链末等单击。 - ASK:单击继续 / 右滑新夜班。 - 关菜单后重播当前节点(局面复述)。 ## 3. 抉择树 ### 3.1 骨架 ``` INTRO ──> 铃① 【C1 老周】教学通 · p1 p2 ──> BRIDGE ──> 铃② 【C2 小鹿】p3 ──> BRIDGE ──> 铃③ 【C3 糖糖】p4 p5 · 埋 heardArgument ──> BRIDGE ──> 铃④ 【C4 陈姐】p6 p7 · 消费 heardArgument ──> BRIDGE ──> 铃⑤ 【C5 老韩】p8 + 危机拍 ──> ◆p9 ──> ENDING ``` 跨通只传 `rep`、`bond`(5×0/1)、`heardArgument`。无组合节点。最坏/最好路径节点数相同。树约 60 节点、132 句。 ### 3.2 分通(◆=抉择,〔〕=条件差分) **C1 老周**:铃 → z1_ring_in → z1_a/b → ◆p1 左哼歌 / 右问路 → ◆p2 左陪等 / 右转接(仅 p1=右且 p2=右走 z1_bad 归因)→ z1_ok1(全局一次)→ BRIDGE。 **C2 小鹿**:◆p3 左劝上车 / 右还自由 → BRIDGE。 **C3 糖糖**:k1_b 垫 `arg_muffled` → ◆p4 左哄睡(本通结束)/ 右问她 → ◆p5 左真话(heardArgument=true)/ 右谎言 → BRIDGE。 **C4 陈姐**:◆p6 左带话〔heardArgument ? w1_say : w1_say2〕→ ◆p7 左直播 / 右私聊;p6 右劝回家本通结束 → BRIDGE。 **C5 老韩**:◆p8 左陪聊闺女(danger + brake_screech 前置 2s)/ 右服务区;bond_zhou 时插 h1_echo → ◆p9 左直面 / 右回避 → ENDING。 **结局** | 结局 | 条件 | 主题 | |---|---|---| | e1 天亮之前 | rep≥5 且 p9 左 | 话筒接住了这座城 | | e2 热线常亮 | rep≥5 且 p9 右 | 满座夜班,留言机未看 | | e3 一个人的频道 | rep<5 且 p9 左 | 晚安说出去了 | | e4 静音 | rep<5 且 p9 右 | 谁也接不住谁 | epilogue 对五人各播 bond? 救到 : 错过。 注:p4 表列「问她/哄睡」与树形(左=哄睡 / 右=问她)以树形与 p4 提示句为准;p4 右 → heardArgument=true。 ## 4. 数值 | 变量 | 初值 | 说明 | |---|---|---| | `rep` | 0 | 听众口碑 | | `knot` | false | 仅 p9 左 | | `bond_*` ×5 | 0 | 只影响尾声 | | `heardArgument` | false | p4 右,C4 消费 | | 抉择 | 左 | 右 | |---|---|---| | p1 | +1 | 0 | | p2 | +2(p1左)/ +1(p1右) | +1(p1左)/ **−1(p1右)** | | p3 | +2 | +1 | | p4 | 0(哄睡) | +1 + heardArgument | | p5 | +1 | 0 | | p6 | +2(有线索)/ +1 | 0,本通结束 | | p7 | +2 | +1 | | p8 | +1 | 0 | | p9 | knot=解 | 未解 | 收播 `rep≥5` 高口碑。理论上限 12。BRIDGE 跨档播 rep_high / rep_mid / rep_low(rep_low 措辞:「今晚的口碑,还没立起来。」零起步为真)。负向结果句必须指向实际选择。 ## 5. 音频三层 ### 5.1 BGM(4 首,Mureka) | 状态 | 曲目 | 切换 | |---|---|---| | INTRO/RING/ONAIR | `bgm/onair` | 开局淡入 800ms,全夜不切 | | BRIDGE | `bgm/bridge` | crossfade 800ms | | MENU | `bgm/menu` | 500ms 进,关后淡回 | | ENDING | `bgm/ending` | p9 后淡入 1500ms | ### 5.2 SFX onair_sting、phone_ring(循环 ≥4s 间隔,游戏层 BufferSource 持柄)、line_connect、line_drop、amb_studio、amb_rain_city、amb_station、amb_kid_room、arg_muffled、amb_street_rain、amb_cab、brake_screech、tape_static。C5 预警:h1_danger 前 2s 起 brake 渐强,与 danger 签名同窗。回执 ok/invalid/busy 走引擎合成,不靠震动。 ### 5.3 Voice | 组 | 落位 | 数量 | |---|---|---| | 主播 HOST | 双性别 | 21 | | 导播 PROD | 双性别 | 82 | | NPC ×5(老周/小鹿/糖糖/陈姐/老韩) | 平铺 + 电话滤波 | 29 | 滤波:老周 HP500/LP2800;小鹿 400/3400;糖糖 450/3000;陈姐 420/3100;老韩 300/3400。不可读则回退未滤波原声。主播/导播不滤波。 ## 6. 来电音质与 Floor Floor:SPEAKING 整链 duck;YOUR_TURN 才起等待声;RING 用铃声循环当等待声。单击跳句;滑动打断并执行。critical ≤3s 给 busy。hint/feedback 空闲才播,过期丢弃。C5 唯一 danger 点。battle 耳控不用。新手只教 turn(接听/选择)+ 可选 settle/menu 首遇一句。 ## 7. 存档 ```json { "schema": 1, "summary": "第3通·失眠的孩子 · 口碑+2 · 结局1/4", "phase": "ONAIR", "node": "k1_asko", "rep": 2, "knot": false, "heardArgument": true, "bond": { "zhou": 1, "deer": 1, "kid": 0, "wife": 0, "han": 0 }, "endings": { "e2": true }, "nights": 3 } ``` summary:进行中 `第N通·<来电者> · 口碑±X · 结局K/4`;已收播 `已收播·<结局名> · 结局K/4`。 ## 8. 节奏 开场 ≤10s 接到第一通;C1 ~3.5min 教学(学习期零惩罚);C2 呼吸;C3 线索音;C4 最复杂;C5 危机零死亡;签收+回响 ~3min。合计 ≈21min。操作面恒为二选一。 ## 9. playtest 指针 关键路径、四结局、pendingChoice、p* 不可跳、归因真话、资产缺失续链:仍登记 `web/radio/test/playtest.mjs` 与 13 号文档。**改断言**:废除「双击重听整节点」;菜单改为左右滑+单击确认;RING/看门狗改为三档不同句;首次操作 ≤3s、首次成功 ≤10s;无效手势必有回执声(不接受只震)。