21 · 《守塔人》(keeper) — 孤岛灯塔叙事 RPG 设计文档
给开发的实现要点摘要
- 叙事模式(声命线范式,radio/abyss/cipher 同骨架):节点链 onComplete 串行 + seqToken 打断作废 + pendingChoice 缓存;复制
web/radio/ 结构起步,状态机 6 宏状态(INTRO/WATCH/MEMORY/CALM/ENDING + MENU 覆盖层)。
- 手势零豁免:全部走全局默认映射(单击=继续/跳句、双击=重听、左右滑=抉择、上滑=状态、下滑=模态菜单 §5.2 约定、长按=引擎快进)。
- 台词依据 21-keeper-voice-ids.md(148 句:双性别 121 + 平铺 NPC 27);NPC 电台/老唱片滤波在资产侧 ffmpeg 带通(radio 先例),引擎零改动。
- 本作核心差异层=时空双线(§6):现在(风暴+电台静电)/回忆(老唱片底噪+唱片滤波)全靠音色+底噪签名区分;插叙=节点链 auto(≤6 句/≤90s),进入/回返有固定过渡音时序;不新增 guide earcon(统一 8 音词表纪律),时空签名住内容层(sfx+底噪+BGM+锚句)。
- 信任/真相双轻量标量(radio rep 同款纪律,档位措辞逐值为真);软失败=「灯灭过一刻钟/他自己冲滩」叙事差分,零死亡零倒计时(P4);结算链 800ms 手势死窗(abyss/地下城 H1 同款)。
- 章程任务 N4(research/new8/00-program.md §2):单局 15-25 分钟、9 抉择点(实选 8-9)、4 结局、分支局部化。
- 断言清单住本文档 §9(abyss §21 先例;13 号文档 §23 指针待批次测试轮同步登记)。
1. 概述
- 一句话:风暴夜,孤岛灯塔的电台里,一声比一声近的求救,牵出你家三代守塔人的秘密——守灯,还是救人;说出真相,还是守住秘密。
- 题材(声音即世界):黑暗风暴里视觉归零,电台人声=另一条命、风暴与雾角=你的处境、老唱片底噪=过去——「用耳朵守一夜」与纯音频载体天然同构。两个时空只靠音色与底噪区分,声音本身就是叙事本体。
- 单局:一个完整风暴夜(一条抉择路径)21-24 分钟;风暴从起到歇=天然三幕,分歧局部化在每幕内部;9 个抉择点(实选 8-9 个),4 结局。
- 核心循环:值守(塔内叙事链)→ 电台(阿澈对白+抉择点)→ 抉择结果 →(关键抉择触发回忆插叙:唱针落下→父辈/祖辈片段→风声回来)→ 回到现在继续值守 → 幕间喘息。跨幕积累「信任」(阿澈信你有几分)与「真相度」(三代秘密翻开几层),风歇前 p9 决定秘密的归宿。
- 与 radio/abyss 的差异点(骨架同、差异层不同):radio 靠电话音质立「声音即存在」,abyss 靠声呐双通道立「用耳朵找人」;keeper 靠时空音频签名立「回忆会开口说话」——插叙不是过场动画,是给现在抉择供货的信息与重量(发条知识=插叙2 兑现 p7 生死细节;祖父忏悔=插叙3 给 p9 完整真相可说)。
- 风险预防(本作特有,策划期显式设计):① 时空误认=剧情混乱——签名规格显式教学一次(rev_teach)+上滑时位句+中断复述带时空位(§6.4/§6.5);② 家族人物多音色——三代人+求救者共 3 个 NPC 音色 ≤5,区分度逐人标注(§5.3/voice-ids 头表)。
2. 状态机
2.1 状态列表
| 状态 |
内容 |
BGM |
guide.state |
INTRO |
开场链:塔名口播 + 一句规矩 + 今晚目标 |
bgm/storm |
explore |
WATCH |
值守叙事:现在线对白链 + 抉择点 + 结果 |
bgm/storm |
explore;抉择点=choice |
MEMORY |
回忆插叙:auto 链 ≤6 句,首尾锚句,链末自动回 WATCH |
bgm/memory |
explore(不新增签名) |
CALM |
幕间:风暴进度通报(+跨档信任播报),自动链 ≤12s |
bgm/storm(不切) |
settle |
ENDING |
结局链 + 尾声回响(epilogue),结算态 |
bgm/dawn |
settle |
MENU |
模态覆盖层(任意叙事态下滑呼出,暂停一切链) |
bgm/storm(低响度淡入) |
menu |
- CALM 自动链 ≤12s:foghorn → lull_N(风暴进度整句)→(跨档才播)信任档位句 → 自动进下一幕;不切 BGM(风暴进程靠 amb_storm 游戏层 gain 分幕:幕一 0.5 / 幕二 1.0 / 幕三 0.7)。
- 结局链/c3_dark/插叙链入口处盖
_settleGraceUntil = now+800ms 手势死窗(abyss §2.2 同款),窗内手势一律吞掉,关键叙事完整播出。
- MENU 打开时
guide.disarm() + 取消一切看门狗/自动链;关闭后重播当前节点(局面复述;MEMORY 中关闭=重播当前回忆节点,底噪仍 vinyl)。
2.2 转移图(文本)
- 全部叙事态为节点链驱动(radio playNode 模式);CALM 与插叙链
auto:true,WATCH 叙事节点链末等待单击(radio 实现核对 #1 同口径)。
- MEMORY 是显式宏状态(BGM/底噪/存档 timeline 都按它切换),但没有独立等待点:链 auto 完成即回 WATCH;插叙期间开菜单=暂停,关闭=重播当前回忆节点。
2.3 每状态手势映射(6+2 全覆盖,零豁免)
| 手势 |
INTRO |
WATCH |
MEMORY |
CALM |
ENDING |
MENU |
| 上滑 |
帮助+状态,随后重播当前段 |
帮助+状态(时位句+信任/真相档),随后重播当前节点 |
帮助+状态(prog_mem_g/f 时位句先行),随后重播当前回忆节点 |
帮助+状态,自动链继续 |
帮助+状态(结局名+信任档) |
帮助(sys_help) |
| 下滑 |
模态菜单 |
模态菜单 |
模态菜单(停插叙链) |
模态菜单 |
模态菜单 |
关闭菜单 |
| 左滑 |
无效 → error 震+gd_invalid |
无效 → gd_invalid(喂无进展轨) |
无效 → gd_invalid |
无效 → gd_invalid |
无效 → gd_invalid |
无效 → error 震 |
| 右滑 |
无效 → gd_invalid |
无效 → gd_invalid;ASK 态=新风暴夜 |
无效 → gd_invalid |
无效 → gd_invalid |
无效 → gd_invalid |
无效 → error 震 |
| 单击 |
播放中=跳过本句;链末=进 C1 |
播放中=跳过本句(p* 与锚句首播不可跳);链末=继续 |
播放中=跳过本句(锚入/锚出句首播不可跳);无链末等待(auto 回返) |
跳过本句(自动链) |
再来一夜(新风暴夜) |
循环切换选项 |
| 双击 |
重听当前段 |
重听当前节点台词(含抉择提示) |
重听当前回忆节点 |
重听幕间链 |
重听结局链 |
确认执行(菜单约定覆盖重听) |
| 长按 |
引擎接管:旁白临时 1.7×(12 号 §2.2,叙事类不豁免) |
同左 |
同左 |
同左 |
同左 |
同左(快进菜单语音) |
| 长按松开 |
引擎接管:恢复 settings.speed |
同左 |
同左 |
同左 |
同左 |
同左 |
- 豁免登记:无。六个基础手势全部符合全局宪法默认语义;菜单走 §5.2 R3 模态约定(单击循环+双击确认)。
- ASK(存档询问态,radio 同款):单击=继续上次 / 右滑=新风暴夜(两者 runs 均 +1,cipher §8 统一口径);上滑/下滑/左滑/双击=无效(error 震+gd_invalid)。
- 抉择 prompt(voice/p1..p9 及 p8_boat/p8_reef/p9a/p9b 变体)播放中单击不可跳(PROMPT_RE 门)、左右滑缓存
pendingChoice 播完即生效(radio W2 契约照抄)。
- 继承 radio G5 跳过公平契约:首播必完整(p 首播不可跳 / 插叙首尾锚句与链末关键句保护 / ASK 恢复首句锁)、复播可即掐(锁不随复播重新武装、插叙中段句可跳、复播滑动照常预缓存)*。
- 无效手势零静默:所有「无效」格均有 error 震 + gd_invalid(onceKey 同局限次,F1.4 idle-only);longpress/longpressend/tapcancel 全状态合法(radio 实现修复 #2 教训)。
- 键盘通道:三通道并行,游戏代码零改动;操作提示句按
gesture.inputMode() 选 _k 变体资产(§7.3、voice-ids 集中分组)。
3. 抉择树
3.1 全局骨架(三幕共享主干,分歧局部化)
分支纪律:每幕内部分支、幕末收敛到 CALM/签收句;跨幕只传标量(trust、rev1/rev2/rev3、p7/p9 派生枚举),不生成组合节点。最坏路径与最好路径节点数同型。
3.2 分幕结构(◆=抉择点,〔〕=条件差分,【插叙】=MEMORY auto 链)
3.3 分支局部化说明
- 跨幕状态全部是标量:
trust(int 0-4)、rev1/rev2/rev3(bool,插叙完成数=truth)、p7('boat'|'lamp')、p9(bool)。没有任何「幕 i 分支 × 幕 j 分支」组合节点。
- 条件差分全部是节点内选播(radio w1_say/w1_say2、abyss p7 双形态先例):插叙2 兜底(p4 左)、c7_go/c7_go2(rev2)、c9_land/c9_found(trust)、c9_return 后 c3_dark 插播(rev2=false)、p9a/p9b 与 d9_tell_a/b(truth)、ep_* 选播。树形不变。
- 树规模:148 句台词、约 75 个节点;任一路径到达全部 9 个抉择点,p6 在 rev2=false 时被 m6_seal 自动走右(实选 8-9 个)。
3.4 四结局达成条件
| 结局 |
条件 |
主题 |
开环钩子 |
| e1 灯与归人 |
trust ≥ 3 且 p9=左 |
人接住了,真相也说全了 |
「回澜号的账,翻开了第一页」 |
| e2 守夜人 |
trust ≥ 3 且 p9=右 |
人救了,秘密再压一代 |
「有些东西,再压一代人」 |
| e3 半明半暗 |
trust < 3 且 p9=左 |
你说了,他半信半疑 |
「碎片也是真话」 |
| e4 各自的塔 |
trust < 3 且 p9=右 |
隔海两塔,各自沉默 |
「谁也没再提那晚」 |
- 尾声回响(P2 回响感):epilogue 逐项点名——阿澈(接回塔/自渡/天亮被找到,按 p7×trust)、灯的记录簿(满发条自转/灭过一刻钟/整夜未眨眼,按 p7×rev2)、祖父日志(见光/压回黑暗,按 p9×truth≥1)、父亲的班次(rev2=true 替他签字);岸台晨报恒播收尾(b_goal 货轮承诺闭环)。玩家每一层翻开的与守住的都被点名。
4. 数值设计
4.1 变量
| 变量 |
类型 |
初值 |
说明 |
trust(信任) |
int |
0 |
阿澈对你的信任,幕一/二积累,幕三不动 |
rev1/rev2/rev3 |
bool |
false |
插叙1/2/3 完成位;truth = 三者之和 |
p7 |
str |
null |
'boat'(离塔救人)/'lamp'(守灯引渡),核心抉择派生 |
endings{} / runs |
map/int |
— |
结局收集与重玩计数(存档展示用) |
4.2 抉择计分表(左=走心·翻开/说出 / 右=克制·程序/守秘)
| 抉择 |
左(走心) |
右(克制) |
备注 |
| p1 接住人/要船位 |
trust+1 |
0 |
左路阿澈声音稳住(首个正反馈);右路 c1_aske 即时纠偏不扣分 |
| p2 翻暗格/守灯 |
truth+1(rev1=true) |
0 |
左路=插叙1(日志残篇到手,缺最后一页) |
| p3 口诀/岸台 |
trust+1,truth+1(rev2=true) |
0 |
左路=插叙2 主触发(发条知识+缺页线索 c2_key) |
| p4 真话/带过 |
trust+1;rev2=false 时兜底插叙2(truth+1) |
0 |
插叙2 的第二把钥匙(p3 右的补偿路) |
| p5 堵漏/救生衣 |
trust+1 |
0 |
双活路(两路都活着,差分在反应句与尾声心境) |
| p6 读完/合上 |
truth+1(rev3=true) |
0 |
左路=插叙3(祖父忏悔全量);rev2=false 时左路封锁(m6_seal 播出后自动走右,abyss g9_dry 先例——不摆假选项) |
| p7 离塔救人/守灯引渡 |
0(p7='boat') |
0(p7='lamp') |
核心宿命抉择:不动 trust;后果走 rev2(发条)与 trust(引渡)差分 |
| p8_boat 循渔歌/推坐标 |
0 |
0 |
双活路差分(海上找人方式) |
| p8_reef 老航道/新礁缝 |
0 |
0 |
双活路差分(引渡路线) |
| p9 说出/守住 |
真相出口 |
秘密出口 |
不动 trust;提示句按 truth 选 p9a/p9b |
4.3 信任档位表(账目真实:每档句义对每个取值皆为真)
| 档 |
trust 区间 |
整句 |
真实性核验 |
| tr_deep |
3-4 |
「他把命,交给了你的声音。」 |
≥3 时 p7 右他完全照做(c9_land)✓;p7 左他海上应答配合 ✓ |
| tr_half |
1-2 |
「他信一半,疑一半。」 |
1-2 时 p7 右他半路改主意(c9_found)✓ |
| tr_thin |
0 |
「今晚,他只信自己的手。」 |
0 = 四个信任点全失,p7 右必自渡 ✓(附 warning 震,radio G2 同款) |
- 阈值 3 = 「多数走心 + 容忍 1-2 次克制」落在高信任档——把「他是否把命交给你」压在玩家自己的累计上,而非单点(radio rep ≥5 同款纪律)。
- 跨档被动播报(挂 CALM 链尾,跨档才播);上滑 status 随时可查。
真相度逐值表(truth=插叙完成数,每值一句、逐值为真)
| truth |
整句 |
核验 |
| 0 |
「旧账压在灯底,你一页没翻。」 |
rev1/2/3 全 false ✓(暗格未开) |
| 1 |
「灯下的旧账,你翻开了一角。」 |
仅插叙1(日志残篇)✓ |
| 2 |
「祖父和父亲的事,你都翻到了。」 |
插叙1+2 ✓(缺页在手未读) |
| 3 |
「三代人的账,今夜见底了。」 |
插叙1+2+3 ✓(忏悔全文,p9a 解锁) |
4.4 结局与差分验算(设计期穷举,playtest 剧本 A-F 引用)
- trust ∈ {0..4} 全档可达(四个独立 ±1 抉择 p1/p3/p4/p5);e1/e2 ⟺ trust≥3(如 p1左 p3左 p4左 p5右=3),e3/e4 ⟺ trust≤2(全右=0)。
- truth ∈ {0..3} 全档可达:rev1=p2左;rev2=p3左∨p4左;rev3=p6左∧rev2。0(p2右p3右p4右)、1(p2左+双右)、2(p2左+p3左)、3(再 p6左)。
- p6 封锁与 p9 变体联动:rev2=false → m6_seal 自动右;truth=3 → p9a/d9_tell_a(全真相),truth<3 → p9b/d9_tell_b(碎片:只确认「那晚守塔的是我爷爷、灯灭过一下」——前者是家族常识、后者来自阿澈自己的话,truth=0 也句句为真,归因真话律)。
- 灯三态(p7×rev2):p7 左+rev2 → ep_lamp_full(满发条自转,rev_f4 知识兑现);p7 左+¬rev2 → c3_dark+ep_lamp_dark(半卷发条走到头,复刻祖父之夜,归因指向「没听完父亲那一晚」的实际选择);p7 右 → ep_lamp_hold(整夜未停)。
- 阿澈三态(p7×trust):p7 左 → 恒被接回(c9_return,人已上艇不失去);p7 右+trust≥3 → 自渡成功(c9_land);p7 右+trust<3 → 天亮被渔队找到(c9_found,活着,措辞克制——零死亡红线)。
- 最坏路径完整性:剧本 C(全右)仍走完全部 9 抉择点、3 结局分支可差分(ep_amo_dawn/ep_lamp_hold/ep_log 不播)——树深固定,无死路。
- 纸面承诺安全性:trust≥3 ⟹ p3/p4 至少一左 ⟹ rev2=true ⟹ 缺页在手(c2_key)——e1_a「那页纸攥在手里」/e2_b「缺页放回灯底」对 trust≥3 两结局恒为真;e3/e4(trust<3)文案零纸面引用,truth 任意取值皆不穿帮(归因真话律在结局文案侧的落点)。
4.5 家族秘密 gating 顺序(秘密揭示的三把钥匙与三道门)
| 层 |
秘密 |
钥匙(抉择) |
门(插叙) |
兑现(现在线收益) |
| 层1 |
灯下藏着东西 |
p2 左(翻暗格) |
插叙1(祖父:「灯下压着的东西,比灯重」) |
日志残篇 + 缺页悬念(tru_one) |
| 层2 |
父亲的最后一次值守 |
p3 左(口诀)或 p4 左(真话,兜底) |
插叙2(父亲电台:「上满发条能自己转一夜」) |
手电缺页线索(c2_key)+ 发条知识(c7_go 差分) |
| 层3 |
祖父的忏悔(回澜号真相) |
p6 左(前置=层2 已开) |
插叙3(祖父:「我离灯三刻,回澜号,七个人」) |
p9a 完整真相可说 + e1/e2 重量 |
- 顺序不可跳:层3 的门只认层2 的钥匙(m6_seal 封锁);层2 有两把钥匙(p3/p4)保证「错过 p3 仍可全真相」(补偿路,abyss hasLog 双入口同型)。
- 阿澈的回环:amo_c(幕一伏笔「我爷爷……白角的灯灭过一下」)→ amo_g(p9 左揭晓「我爷爷,就在那七个人里」)——玩家的抉择把两条家族线缝上。
5. 音频三层映射
5.1 BGM(状态→曲目,Mureka instrumental,3 首 ≈ $0.09;台账 tools/mureka_log.md)
| 状态 |
曲目 |
切换 |
Mureka prompt 草稿(英文,seamless loop) |
| INTRO/WATCH/CALM |
bgm/storm |
开局淡入 800ms,全夜不切;语音 duck 引擎自理 |
"Storm night lighthouse vigil, tense low piano motif over dark strings, restrained and lonely, distant thunder and wind, no vocals, seamless loop, 60-90 seconds" |
| MEMORY |
bgm/memory |
插叙进入 crossfade 800ms;回返淡回 storm 800ms |
"Old phonograph memory waltz, music box and muted strings with vintage vinyl warmth, fragile nostalgia, slightly out-of-time, no vocals, seamless loop, 60-90 seconds" |
| ENDING |
bgm/dawn |
d9 结果链播完后淡入 1500ms |
"Calm grey dawn after a storm at sea, soft piano and warm strings, gulls far away, quiet relief, no vocals, seamless loop, 60-90 seconds" |
| MENU |
bgm/storm(低响度) |
呼出低响度淡入 500ms;关闭淡回 800ms |
同 storm(省 1 首,塔内场景同构;abyss menu 用 deck 先例) |
bgm=0 时全部静默(引擎约定);幕的推进不靠切曲——靠 amb_storm 游戏层 gain 分幕(0.5/1.0/0.7)+ lull_N 进度整句(账目在语音不在音乐)。
5.2 SFX 清单(SA3=Stable Audio 3 / SYN=程序合成;one-shot 真峰值 ≤-3dBFS;amb 循环由游戏层 buffer.loop 实现,radio phone_ring 先例)
| id |
用途 |
来源 |
prompt(英文)/ 合成参数 |
sfx/amb_storm |
风暴底噪 loop(现在时签名①;分幕 gain 0.5/1.0/0.7) |
SA3 |
"Storm wind and heavy waves hitting a lighthouse rock, sustained gale, night, seamless loop" |
sfx/amb_room |
塔内底噪 loop(炉火+木构+雨打玻璃) |
SA3 |
"Inside a lighthouse room at night, oil stove crackle, wooden beams creak, rain on glass, seamless loop" |
sfx/amb_vinyl |
老唱片底噪 loop(回忆时签名②;插叙期间唯一底噪) |
SA3 |
"Vintage 78 rpm phonograph record surface noise, warm crackle and hiss, no music, seamless loop" |
sfx/memory_in |
插叙进入过渡音:唱针落下+转速走稳 |
SA3 |
"Phonograph needle dropping onto a record, brief run-in groove then steady rotation, 1 second" |
sfx/memory_out |
插叙回返过渡音:唱针抬起+轻划 |
SA3 |
"Phonograph needle lifting off a record with a short scratch, 0.6 seconds" |
sfx/radio_tune |
调频找台(C1 首通/信号重连) |
SA3 |
"Turning an old shortwave radio dial through static, settling on a weak signal, 3 seconds" |
sfx/static_burst |
阿澈信号断续气口(信息音,idle-only) |
SA3 |
"Shortwave radio static burst with faint ghost of a distant voice, 2 seconds" |
sfx/radio_beep |
电台接通确认 |
SYN |
双音上行 0.3s(abyss link_beep 同款) |
sfx/amb_engine |
阿澈侧渔船引擎 loop(通话期对侧 amb,voice 在播时 -6dB) |
SA3 |
"Small fishing boat engine running rough in a storm, water sloshing in bilge, seamless loop" |
sfx/hull_crack |
危机拍1:船板开裂(前置 2s 渐强) |
SA3 |
"Wooden boat hull cracking under stress, splintering and groaning, 3 seconds" |
sfx/wave_wall |
危机拍2:浪墙(前置 2s 渐强) |
SA3 |
"Massive wave wall rising and crashing, deep roar, 4 seconds" |
sfx/lamp_mech |
灯座机械上发条(c7_go;rev_f4 兑现音) |
SA3 |
"Clockwork lighthouse rotation mechanism being wound, heavy ratchet clicks, 3 seconds" |
sfx/hatch_open |
灯座暗格开启(c1_open) |
SA3 |
"Old hidden compartment sliding open, metal and wood scrape, 2 seconds" |
sfx/flash_click |
手电尾盖旋开两响(c3_page) |
SYN |
两次短金属 click(120ms 间隔) |
sfx/foghorn |
雾角两长一短(b_rain 承诺音:开场/幕间×2/ep_shore) |
SA3 |
"Lighthouse foghorn, two long and one short blast, deep brass, distant storm behind, 4 seconds" |
sfx/ui_confirm / ui_menu |
菜单/确认(程序合成兜底) |
SYN |
同全局先例 |
- 预警窗纪律:hull_crack/wave_wall 均前置 2s 起渐强(L2),danger 签名与 danger 震同窗(radio C5/abyss D2-D4 先例);全游戏仅此两处 danger。
- 承诺兑现绑定:foghorn 在 b_rain 口播「两长一短」后,开场/CALM(1)/CALM(2)/ep_shore 四处必播(§6.5 清单 + §9 断言计数)。
5.3 Voice 划分(详见 21-keeper-voice-ids.md)
| 组 |
声部 |
落位 |
数量 |
| 守塔人(你)KEEPER |
双性别(female=Serena / male=Uncle_Fu + KEEPER instruct 常量) |
voice/female|male/ |
42 句 |
| 岸台/系统/向导 SHORE |
双性别(female=Vivian / male=Dylan + SHORE instruct 常量) |
voice/female|male/ |
79 句 |
| NPC 平铺 ×3 |
阿澈=Dylan(电台滤波)/ 父亲=Uncle_Fu(唱片滤波)/ 祖父=Eric(唱片滤波),不做双性别 |
voice/ 根(平铺回退命中)+ 滤波转码 |
27 句 |
- NPC ≤5 约束满足(3 人);玩家自己的声音跟随全局
settings.voice;岸台值班员是向导人设(L4 角色化系统声,radio 导播/abyss 调度同型)。
- 合计 148 句(≤160 预算 ✓,含
_k 键盘变体 8 对);音频文件 = 121×2 + 27 = 269 条(×2 格式 = 538 文件)。
6. 时空双线设计(本作核心差异层)
6.1 引擎能力边界(对照 web-engine-api.md)
| 能力 |
引擎现状 |
方案 |
| voice 运行时 EQ/滤波 |
❌ voice 链无滤波插入点 |
资产侧转码滤波(radio §6.2 先例):ffmpeg highpass+lowpass+压缩器 逐 NPC 定档(§5.3/voice-ids) |
| BGM crossfade |
✅ fadeMs 800ms 内置 |
插叙进入/回返直接 play('bgm/...') 切换 |
| sfx 循环 |
❌ 即发即弃 |
游戏层 buffer.loop=true 持句柄(amb_storm/amb_room/amb_vinyl/amb_engine),插叙切换时淡入淡出(radio _ringSrc 先例) |
| sfx vs voice 互让 |
❌ sfx 总线独立无 duck |
游戏层 idle 门(§6.6 R1):memory_in/out、static_burst 只在 !audio.isVoicePlaying() 时放行,否则挂队列表句间补发 |
| 语音 duck 垫乐 |
✅ 内置(duck 20%,300ms) |
直接依赖 |
| 变速不变调 |
✅ SoundTouch |
直接依赖(长按 1.7× / 2.2× 视障档) |
6.2 时空签名规格(误认=剧情混乱,规格逐维度显式)
| 维度 |
现在(风暴夜) |
回忆(老唱片) |
| BGM |
bgm/storm(低音钢琴+暗弦+远雷) |
bgm/memory(八音盒+老唱片暖染圆舞) |
| 底噪 |
amb_storm(分幕 gain)+ amb_room |
amb_vinyl(唯一底噪:storm/room 双双淡出) |
| 过渡音 |
回返:memory_out + storm 渐起 |
进入:memory_in(唱针落下) |
| 语音音质 |
KEEPER/SHORE 不滤波(塔内近讲);阿澈=电台滤波 |
祖父/父亲=唱片滤波;KEEPER 锚句不滤波(「现在的你」在回忆里旁白——干净人声 vs 唱片人声,强化「你在看回忆」) |
| 时位句 |
prog_m1/m2/m3(上滑链首段) |
prog_mem_g / prog_mem_f(上滑链首段 + 恢复链首段) |
| 台词锚 |
(now 句自然在场) |
锚入 rev_g1/rev_f1/rev_c1 + 锚出 rev_g4/rev_f5/rev_c5 |
- earcon 纪律:时空切换零新增 guide earcon——统一 8 音词表中 MEMORY/WATCH 同用
explore 签名;时空签名住内容层(sfx 过渡音+底噪+BGM+台词锚),语义靠语音(L2 铁律:earcon 只做粗标记,训练 8.5 轮结论不赌)。
- 底噪互斥是硬约束:任意时刻 amb_vinyl 与 amb_storm/amb_room 零重叠(§9 转写断言);插叙期间阿澈的 amb_engine 也停(叙事自洽:插叙都发生在塔内独处拍,电台此刻静默)。
6.3 插叙触发与回返时序(精确到步骤)
| 步 |
事件 |
时序 |
| 1 |
now 结果句播完 → 静默一拍 |
600ms |
| 2 |
memory_in(1.0s,idle 门放行)+ BGM crossfade storm→memory 800ms + amb 切换(storm/room 淡出 400ms / vinyl 淡入 400ms) |
与步 2 同时起 |
| 3 |
插叙链 auto:锚入(KEEPER,不可跳首播)→ NPC 2-3 句(中段可跳)→ 锚出(KEEPER,不可跳首播) |
≤6 句 ≤90s |
| 4 |
memory_out(0.6s)+ crossfade memory→storm 800ms + amb 回切 |
链末即起 |
| 5 |
回返后 now 句接播(c1_diary / c2_key 或 c4_trueo / c6_reade) |
memory_out 播完接 |
- 插叙链入口 800ms 手势死窗(§2.2);链末不设等待(auto 回返——回忆不是关卡,是信息颗粒);「停下来回味」由双击重听当前回忆节点承接(叙事类等待点合法回味 + 可重听,A2/P1)。
- 插叙触发点全集(3 处):p2 左→插叙1;p3 左或 p4 左→插叙2(兜底);p6 左→插叙3(前置 rev2=true)。
6.4 「我在哪」复述机制(P3 打断回来说得清)
| 层 |
机制 |
| 被动 |
底噪+BGM 时空签名 2s 可辨(A1:有无唱片底噪/风声) |
| 主动 |
上滑 status 链首段=时位句:now → prog_m1..3;memory → prog_mem_g(祖父年代)/ prog_mem_f(父亲最后一晚)——「现在是回忆」可随时重听确认 |
| 台词锚 |
每段插叙首尾锚句 = 台词级时空位(「唱针落下。四十年前……」「风声回来了……」) |
| 中断恢复 |
存档带 timeline('now'/'mem_g'/'mem_f');恢复链 = timeline=mem* 时先播 prog_mem_* 再重播当前回忆节点(§9 断言:恢复首句=时位句, ≤5s 回到可玩) |
| 菜单复述 |
MEMORY 中开菜单关闭后重播当前回忆节点,底噪仍 vinyl(timeline 不丢) |
6.5 教学承诺清单(dungeon「铁器=楼梯」教训:每句承诺必须真实存在且可感知)
| 教学句 |
承诺 |
兑现点(断言锁定) |
| rev_teach「听到唱针落下、风声退后,是回忆。风声回来,就是现在」(全局一次,首插叙前) |
时空签名四要素 |
每次插叙必有 memory_in+vinyl+锚入 / memory_out+storm+锚出;全剧本零漏(§9) |
| b_rain「雾角两长一短——塔在,我也在」 |
雾角=塔的报平安音 |
foghorn 播点=开场/CALM(1)/CALM(2)/ep_shore 恰四处 |
| b_rule「风暴夜,灯不能灭」 |
灯=规矩本体 |
灯三态兑现:ep_lamp_full/dark/hold + c3_dark 差分归因(§4.4) |
| b_goal「今夜两艘货轮过境。守住灯,也守住频道」 |
货轮/频道双目标 |
c3_dark「过境的货轮,平安」+ ep_shore 晨报「航道平安」闭环 |
| rev_f4「塔上的机械上满发条,能自己转一夜」 |
发条知识 |
p7 左 rev2 差分:c7_go/c7_go2、ep_lamp_full/ep_lamp_dark(剧本 A/E 对照) |
| prog_m1..3 幕句=风暴三进程 |
「风暴起/到顶/在退」 |
CALM 切幕+amb_storm gain 分幕(0.5/1.0/0.7)一致 |
6.6 通道仲裁规则(并发声流 ≤2)
- R1 过渡音不叠语音:memory_in/out、static_burst 与任何 voice 播放区间零重叠——idle 门只在 voice 空闲放行,在播则排队到句间空隙(abyss sonarGate 同型)。
- R2 插叙主导段:前景=插叙链人声+vinyl 底噪,BGM=memory 曲;电台(阿澈)此刻静默,叙事自洽。
- R3 通话期底噪退位:阿澈通话期间 amb_engine 常驻低响度、voice 在播时游戏层降 -6dB(abyss R3 先例);amb_storm 同步 -4dB——「海况让给人声」。
- R4 危机拍优先:hull_crack/wave_wall 即发即弃可叠底噪;danger 签名+danger 震同窗;当前 voice 句播完后危机链才插续。
- R5 回忆可重听:MEMORY 双击=重听当前回忆节点(关键线索可重听,P1);插叙中段句可跳、首尾锚句首播不可跳(G5)。
- 声流账:任意时刻 ≤2 条前景流(voice 串行 1 + 信息音/底噪 1),BGM/amb 为背景层——ASA ≤2 约束。
7. 向导层接入
7.1 状态签名 earcon / turn cue
| 时机 |
向导动作 |
说明 |
| INTRO 进入 |
guide.state('explore') |
叙事态签名 |
| WATCH/MEMORY 进入 |
guide.state('explore') |
同一枚签名(时空不换 earcon,§6.2 纪律) |
| 每个抉择点 p* 起播 |
guide.state('choice') |
选项句本身即 turn cue(W2 契约零插播) |
| CALM 进入 |
guide.state('settle') |
喘息/结算签名 |
| ENDING 进入 |
guide.state('settle') |
同上 |
| MENU 打开 |
guide.state('menu') |
菜单签名 |
| 危机拍1/2 |
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 档 |
级别内容 |
| INTRO/WATCH/CALM 链末等待 |
[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 |
| MEMORY 链末 |
不挂(auto 回返) |
不挂 |
资产缺失兜底:30s 单句看门狗且 isVoicePlaying()===false 才续(radio N1 先例) |
无进展轨(游戏层计时,dungeon E0-1 ②同型;挂 WATCH 链末与 p* 等待两个可饿死点):
| 项 |
规则 |
| 进展定义 |
节点推进 / 抉择结算 / 重听。无效手势(滑错、空点)不计进展——无操作轨被它们复位、无进展轨不被复位,乱按 96s 必被抢救 |
| 阈值 |
60s → gd_prog1;120s → gd_prog2;用尽即停(每等待点一轮) |
| 有真实进展 |
全程零 prog 播出(不误伤正常玩家) |
| 双轨去重 |
两轨短句内容同级交叉登记;同一等待点先播过 gd_* 同义级则无进展轨跳过 |
- 向导插播一律
queue:true,绝不顶掉在播对白;error/watchdog 类语音 idle-only(在播则跳过且过期丢弃,F1.4)。
7.3 键盘变体机制(PC 键盘玩家)
- 运行时按
gesture.inputMode()(settings.input auto/touch/key)选 _k 变体资产:key → voice/<gender>/<id>_k.*,touch → 无后缀版;auto 跟随最近使用通道。_k 缺失回退无后缀版(check_all_assets 校验配对)。
- 变体清单(8 对,集中分组见 voice-ids §G0.a 与 C1 首个抉择):gd_brief / gd_continue / gd_again / sys_help / sys_menu / sys_skip / sys_continue_ask / p1(首个抉择的键位绑定)。
- 抉择提示 p2..p9 措辞统一「向左滑/向右滑」;键盘玩家由 p1_k 与 sys_help_k 完成首次绑定(左=←,右=→),后续语义不变。启动遮罩文案引擎自理(游戏零改动)。
7.4 继承 radio 三轮验证机制(照抄不重设计)
| 机制 |
来源 |
落点 |
| 帮助链去重(同等待点第 2 次上滑只震+nudge) |
radio G1 |
_helpSeen 按等待点键控(MEMORY 按插叙段键控) |
| 状态链顺序「状态在前、帮助在后」 |
radio G6 |
prog_m* →〔mem: prog_mem_〕→ tr_ → tru_* → sys_help |
| 空点确认轻震(不可跳句上单击补 beat [8]) |
radio G4 |
p*/锚句/F4 锁各 tap 屏蔽分支 |
| tr_thin 播报位附 warning 震 |
radio G2 |
全部 tr_thin 出口(含上滑复听) |
| 菜单报名游戏侧排队零截断 |
radio 实现修复 #3 |
_menuQueue 排水 |
stop() 先 seqToken++ 作废在途链 |
radio 实现修复 #6 |
同款 |
| 新局清 choiceArmed/pendingChoice |
radio 实现修复 #7 |
newNight() |
| 长按误报无效(longpress 全状态合法) |
radio 实现修复 #2 |
仅 left/right(ASK 另含 up/down/doubletap)报无效 |
8. 存档设计
8.1 进度 data 结构(PUT /api/progress {game:'keeper'})
- 写入时机:每幕 CALM 进入、每个抉择结算后、ENDING 进入、菜单「保存并回大厅」。
- 断点续玩:读档 → sys_continue_ask(_k)(单击=继续上次 / 右滑=新风暴夜,runs 均 +1 统一口径);继续 = 恢复 phase+node+timeline+全部数值并局面复述:timeline=mem* 时恢复链 = prog_m* → prog_mem_g/f → 重播当前回忆节点(时位句先行,「我在哪个时空」一句话说清);now 则直接重播当前节点链;重进 ≤5s 可玩(L5);恢复首句受 F4 跳句锁(radio G5 例外条款)。
- summary 格式:进行中
第N幕·<幕名> · 信任<档名> · 结局X/4(幕名=风暴起/风暴顶/风歇前);已收夜 风暴夜已过·<结局名> · 结局X/4(大厅卡片直接显示)。
9. playtest 断言清单(登记 13 号文档 keeper 节,格式同 §21;settings.set({guide:'off'}) 纯玩法验证,向导行为住 guide.test)
关键路径(剧本 A:信任满·全真相·出海接人·说出 → e1,≤60 次手势):
- 遮罩点按 → INTRO 链(gd_brief → b_open → b_rain → b_rule → b_goal,voice 层有播放记录)→ 链末单击 → C1:c1_tune → amo_a → amo_b → ◆p1。
- p1 左 → c1_hold(o)(e)(trust=1,首个正反馈)→ amo_c → p2 左 → c1_open(配 hatch_open)→ rev_teach(全局一次)→ 插叙1 时序断言:memory_in → bgm 切 memory → rev_g1..g4 → memory_out → storm 回 → c1_diary(truth=1)→ CALM(1):foghorn+lull_1+tr_half(跨档)→ C2。
- C2:c2_back → amo_d → p3 左 → c2_song(o) → 插叙2(rev_f1..f5,同款时序)→ c2_key(truth=2)→ amo_e → p4 左 → c4_true →〔插叙2 已完成:兜底不播〕→ c4_trueo(trust=3)→ 危机拍1(hull_crack 前置 2s 与 danger 同窗)→ c2_crack → amo_f → p5 左(trust=4)→ CALM(2)。
- C3:c3_eye → c3_page → p6 左 → 插叙3(rev_c1..c5)→ c6_reade(truth=3)→ p7 左 → c7_go(配 lamp_mech,满发条版)→ 危机拍2(wave_wall+danger+danger 震)→ c3_wall → p8_boat 左 → c8_song(o) → c9_return → g9_in → g9_knot → p9a(truth=3 变体)→ 左 → d9_tell_a → amo_g → d9_telle → ENDING(e1):e1_a/b + ep_lead + ep_amo_home + ep_lamp_full + ep_log_told + ep_dad + ep_shore → 结算单击重开回 INTRO。
边界断言:
- 四结局可达(含信任逐点验算):剧本 B(p1左 p2左 p3左 p4左 p5左 p6右 p7右 p8_reef右 p9右,trust=4/truth=2)→ e2:c9_land + p9b + ep_amo_solo/ep_lamp_hold/ep_log_kept/ep_dad;剧本 C(p1右 p2右 p3右 p4右 p5右 → m6_seal 自动右 → p7右 p8_reef左 p9左,trust=0/truth=0)→ e3:c9_found + p9b/d9_tell_b + ep_amo_dawn/ep_lamp_hold,ep_log_ 两句皆不播*(truth=0 日志未出场)、ep_dad 不播(rev2=false);剧本 D(同 C 但 p9 右)→ e4。各局 trust/truth 逐检查点与 §4.2 一致。
- 插叙触发与回返:p2 左→插叙1、p3 左→插叙2、p6 左→插叙3 的节点顺序断言;剧本 F(p1左 p2左 p3右 p4左 p5左)断言插叙2 兜底在 c4_true 与 c4_trueo 之间播出且 c2_key 随后播出;回返后 now 线下一节点正确(c1_diary / c2_key 或 c4_trueo / c6_reade);插叙链 auto 完成即回 WATCH(无链末等待)。
- 时空签名断言(核心):全剧本转写断言——amb_vinyl 与 amb_storm/amb_room 播放区间零重叠;每次插叙 memory_in/memory_out 成对出现且计数=插叙完成数;锚入句(rev_g1/rev_f1/rev_c1)与锚出句(rev_g4/rev_f5/rev_c5)在位且首播不可跳(单击=beat 轻震不跳句);插叙期间 bgm=memory、回返后 bgm=storm;插叙期间 amb_engine 停播。
- 教学承诺兑现(§6.5 清单逐条):rev_teach 全局恰一次(第二次插叙前不重播);foghorn 计数=开场+CALM(1)+CALM(2)+ep_shore 恰四处;rev_f4→剧本 A 播 c7_go/剧本 E 播 c7_go2(发条差分);b_goal→c3_dark 与 ep_shore 货轮闭环;prog_m1..3 与三幕 amb gain 档一致。
- p6 封锁不摆假选项:rev2=false 时 p6 提示句不播、m6_seal 播出后自动走 c6_shut,该点左右滑无效果(不丢不误触)。
- 信任/真相账目真实:上滑链顺序 prog_m* →〔mem: prog_mem_g/f〕→ tr_* → tru_* → sys_help(G6);档位句与当前值一一对应(tr_deep≥3 / tr_half=1-2 / tr_thin=0;tru 四值逐句);tr_thin 各播报位附 warning 震。
- 看门狗双轨:WATCH 链末 25s/50s → gd_continue/gd_again;p* 播完 25s/50s → 当前 p* 重播两次后静默;乱按 96s(每 2s 注入一个无效滑动):无操作轨零播出 + 无进展轨 60s→gd_prog1、120s→gd_prog2;有真实进展全程零 prog;MEMORY 链末不挂看门狗;
guide=off 全程零定时器零向导事件。
- 键盘变体:settings.input='key' 会话播出 gd_brief_k/sys_help_k/p1_k 且对应无后缀版零播出;'touch' 反之;'auto':keydown 后下一句用 _k。
- 中断复述含时空位:杀进程重进(存档 timeline='mem_f'、node=rev_f3)→ sys_continue_ask → 单击 → 恢复链首句=prog_m2 → prog_mem_f → 重播 rev_f3 起链(恢复首句不可跳,第二句起可跳);now 态存档(node=amo_e)恢复=重播该节点链。
- pendingChoice:p* 播放中左右滑 → 播完立即生效(不丢、不重复、连滑取最后一次)。
- p 不可跳*:p* 播放中单击 → 不跳句(PROMPT_RE 门)+ beat 轻震(G4)。
- idle-only:向导 gd_* 在对白在播时跳过且不占 onceKey(F1.4);queue 句排在当前句后零截断。
- 菜单:下滑开菜单 → 上滑帮助 → 双击「回到值守」→ phase/node 不变、当前节点重播;插叙中开关菜单后底噪仍 vinyl、重播当前回忆节点;单击循环顺序 = [回到值守, 重新开始今夜, 保存并回大厅];确认回大厅 → sys_menu_lobby 播出且 PUT/localStorage 有最新 data。
- 结算链死窗:e* 结局链/c3_dark/插叙链开播后 800ms 内注入在途 tap → 手势被吞、链完整有序播出。
- 危机拍:hull_crack/wave_wall 前置 2s 渐强、danger 签名与音效同窗、danger 震遍间隔 ≥400ms;当前 voice 句播完危机链才插续。
- 资产缺失:屏蔽任意 voice 资产 → 30s 看门狗自动续链到结局不卡死;NPC 滤波资产缺失回退原声可播。
- 数字规范:prog_/tr_/tru_/gd_ 全部整句字面量,静态审计无运行时拼接碎片。
失败即不通过:任何等待 >5s 无声(静默死局);无效手势零反馈;vinyl 与 storm/room 底噪重叠;插叙缺过渡音或缺锚句;结局计数与 §3.4 不符;档位句与 trust/truth 值不符。
10. 节奏曲线(风暴三幕)
| 段 |
内容 |
目标时长 |
设计目标 |
| 开场 |
塔名+规矩+目标+第一声呼救 |
1-1.5 min |
首输入 ~30s(INTRO 链 ~30s 链末单击);规矩一句讲完(P4);雾角承诺音埋下 |
| 幕一 风暴起 |
p1/p2 + 插叙1 + CALM(1) |
4-5 min |
首个正反馈 ≤3min(~2.5min p1 左阿澈声音稳住);时空签名教学+首次兑现(rev_teach→插叙1 四要素全播);两抉择条条有出路 |
| 幕二 风暴顶 |
p3/p4 + 插叙2 + 危机拍1 + p5 |
6-7 min |
情感段(父亲真相 p4);第一危机拍(前置 2s 预警);插叙2 供货发条知识(p7 兑现预告) |
| 幕三 风歇前 |
p6+插叙3 + p7 核心 + 危机拍2 + p8 |
7-8 min |
紧张峰值:三代秘密见底→「守灯还是救人」宿命抉择→浪墙下的执行差分;复刻祖父之夜的暗线(剧本 E 灯灭) |
| 签收+结局 |
p9 + 结局链 + 尾声回响 |
2.5-3 min |
心结抉择(说/瞒×全/碎片)+ ep 逐项点名(P2 回响);开环钩子拉下一夜 |
- 合计 ≈ 21-24 min(15-25 达标);每 30-60s 一个反馈颗粒(阿澈反应句/结果句/档位句/插叙锚句),无沉默尴尬期(P3)。
- 难度曲线 = 情感与信息复杂度(接住人→翻开过去→宿命抉择→秘密归宿),操作复杂度恒定(永远二选一)——P4「规则一遍听懂」由恒定操作面保证;风暴强度=氛围曲线(amb gain 三档),不构成玩法压力(无倒计时无死亡)。
11. 自检清单(策划交付自验;☐ = 待开发/测试轮填)
| # |
硬约束/教训 |
落地 |
✓ |
| 1 |
FTUE 首输入 <60s |
INTRO 链 ~30s 链末单击(§10) |
☑ |
| 2 |
FTUE 首个正反馈 ≤3min |
~2.5min p1 左阿澈稳住(c1_holdo+c1_holde) |
☑ |
| 3 |
学习期零惩罚 |
幕一全组合不扣资源;右路只即时纠偏(c1_aske);无超时惩罚 |
☑ |
| 4 |
失败三问归因+归因真话律 |
c1_aske/c3_dark/c9_found 指向实际选择;d9_tell_b 在 truth=0 仍句句为真;§4.4 无假归因 |
☑ |
| 5 |
资源账目真实(radio rep_low 教训) |
tr_* 三档逐区间为真;tru_* 四值逐值为真;跨档才播 |
☑ |
| 6 |
手势宪法 6 手势默认语义零豁免 |
§2.3 全覆盖;菜单 §5.2 模态约定 |
☑ |
| 7 |
长按显式登记 |
无豁免:长按=引擎快进(12 号叙事类不豁免),§2.3 在案 |
☑ |
| 8 |
向导:签名/turn cue/看门狗两级不同句 |
§7.1/§7.2;gd_continue→gd_again;MEMORY 链末不挂 |
☑ |
| 9 |
看门狗双轨(dungeon E0-1/radio F1 教训) |
无操作轨+无进展轨(§7.2);乱按 96s 必被抢救 |
☑ |
| 10 |
插播 queue 不顶对白;纠错 idle-only 过期丢弃 |
§7.2(F1.4 契约);过渡音 idle 门(§6.6 R1) |
☑ |
| 11 |
死亡/失败结算链完整(dungeon H1 教训) |
e* 链/c3_dark/插叙链 800ms 手势死窗;阿澈恒活着(零死亡红线) |
☑ |
| 12 |
教学承诺兑现(dungeon「铁器=楼梯」教训) |
§6.5 承诺清单 6 条逐条绑兑现点+断言 |
☑ |
| 13 |
单次播报 ≤3 选项 |
全部抉择恒 2 选项;菜单 3 项循环 |
☑ |
| 14 |
并发声流 ≤2 + 通道仲裁 |
voice 串行+底噪/信息音互斥(R1-R5,§6.6);断言零重叠 |
☑ |
| 15 |
earcon ≤7、统一词表、语义靠语音 |
只用统一 8 音中 7 个(battle 不用),零新增;时空签名住内容层 |
☑ |
| 16 |
台词一句一文件 ≤40 字、数字分档整句、无运行时拼接 |
voice-ids 全表 ≤35 字(最长 p7);prog/tr/tru 分档整句;句内数字写死 |
☑ |
| 17 |
多音字规避/同 instruct 常量/无语速词 |
voice-ids 头部+文末自查(落/数/缝/卷/转/重 试听项) |
☑ |
| 18 |
PC 键盘变体(提示句集中+标注) |
8 对 _k 变体集中分组(voice-ids §G0.a);inputMode() 运行时选择 |
☑ |
| 19 |
P1:可打断/重听(含回忆节点)/status key/不当白痴 |
跳句+双击(MEMORY 重听 R5)+上滑时位句链+成功零补救教学 |
☑ |
| 20 |
P2:3 分钟见效/结局回响 |
~2.5min 阿澈声音稳住;ep 逐项点名(阿澈/灯/日志/父亲班次) |
☑ |
| 21 |
P3:3 分钟颗粒/中断复述含时空位/单手 |
一幕=4-8min 段落+边界存档;恢复链 prog_mem_* 时位句先行;全手势免视单手 |
☑ |
| 22 |
P4:一遍懂/容错/无高压倒计时/不骂人 |
一句规矩;零死亡零倒计时;NPC 句 ≤27 字+逗号停顿 |
☑ |
| 23 |
抉择树 4 结局可走通验算 |
§4.4 穷举+§9 剧本 A-D(e1-e4 各一条实路径)+E/F 差分剧本 |
☑ |
| 24 |
单局 15-25 min |
§10 曲线 ≈21-24 min |
☑ |
| 25 |
分支不爆炸(radio 纪律) |
跨幕仅 trust+3 bool+p7/p9 派生;~75 节点固定深度(§3.3) |
☑ |
| 26 |
台词 ≤160、NPC ≤5 单音色 |
148 句(双 121+NPC 27)/3 个 NPC 音色(voice-ids 账目) |
☑ |
| 27 |
引擎边界诚实 |
§6.1 能力表:滤波/loop/互让全写明资产侧或降级方案 |
☑ |
| 28 |
存档带 summary、断点续玩 |
§8:data+summary 格式、timeline 恢复链、≤5s、局面复述 |
☑ |
批 1 教训内化确认(5 条全落地)
| 教训 |
本作机制 |
断言 |
| 教学承诺必须兑现 |
§6.5 六条承诺清单(时空签名/雾角/灯/货轮/发条/三幕) |
§9「教学承诺兑现」块 |
| 看门狗双轨 |
§7.2 无操作轨+无进展轨;无效手势不复位进展轨 |
§9「看门狗双轨」块 |
| 档位措辞真实 |
§4.3 tr 三档逐区间+tru 四值逐值为真 |
§9「信任/真相账目真实」块 |
| 失败结算链完整不被打断 |
800ms 手势死窗盖 e* 链/c3_dark/插叙链;seqToken 作废在途链 |
§9「结算链死窗」块 |
| PC 键盘操作提示 |
8 对 _k 变体+inputMode() 选择+集中分组标注 |
§9「键盘变体」块 |
时空签名教学-兑现验算(本作特有自检)
| 承诺(rev_teach 四要素) |
教学点 |
兑现次数(剧本 A) |
断言位 |
| 唱针落下(memory_in) |
rev_teach 全局一次(首插叙前) |
插叙 1/2/3 各一,共 3 |
§9 插叙触发与回返 |
| 风声退后(vinyl 底噪、storm/room 淡出) |
同上 |
3 段插叙全程,零重叠 |
§9 时空签名断言 |
| 唱针抬起+划针(memory_out) |
同上 |
3 次,与 in 成对 |
§9 时空签名断言 |
| 风声回来(storm 回切+锚出句) |
同上 |
3 次(锚句 rev_g4/rev_f5/rev_c5) |
§9 时空签名断言 |
| 「我在哪」三层兜底 |
上滑时位句(prog_m*/prog_mem_*)+恢复链时位句先行+菜单关闭底噪不丢 |
全程可查;§8/§9 |
§9 中断复述含时空位 |
结局验算(3-4 结局条款 → 定 4)
e1=trust≥3∧p9左(剧本 A:trust4/truth3);e2=trust≥3∧p9右(剧本 B:trust4/truth2,p9b);e3=trust<3∧p9左(剧本 C:trust0/truth0,p9b+d9_tell_b);e4=trust<3∧p9右(剧本 D)。四格互斥完备、各有一条实路径、trust/truth 全档可达(§4.4)。
台词 ≤40 字验算
voice-ids 全表最长 = p7(35 字),次长 p9a/p9b(各 32 字)、d9_tell_a(31 字);NPC 句最长 amo_c(25 字)——全部 ≤40 ✓(逐句账见 voice-ids 文末自查)。