14 KiB
15 · 《不眠频率》(radio) — 深夜电台热线叙事 RPG
给开发的实现要点摘要
- 交互权威:26-audio-interaction-playbook.md。本文件按附录 C 填写;与旧手势表冲突时以本文为准。范式对齐 26-apply-storyline.md。
- 叙事骨架不变:节点链 onComplete 串行 + seqToken 打断作废 + pendingChoice 缓存;6 宏状态 INTRO / RING / ONAIR / BRIDGE / ENDING + MENU。
- 新手三手势:单击继续/接听、左右滑抉择、上滑「我在哪」。不识别双击。无四向滑动玩法,帮助不上长按。菜单:左右滑切换、单击确认。
- 台词 15-radio-voice-ids.md(132 句:双性别 103 + 平铺 NPC 29)。NPC 电话滤波在资产侧 ffmpeg 带通,引擎零改动。
- 章程:单局 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_itemhint:sys_hint_full/short、gd_ring1/2、status/prog/rep、sys_continue_askfeedback:inv_nosel、inv_generic、z1_bade、k1_lulle、k1_liee- 主动重听前缀:
sys_say_again - 完整清单见
tools/gen_voice_dual.pyRADIO 表(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. 存档
{
"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;无效手势必有回执声(不接受只震)。