Files
SoundGame/docs/design/20-teahouse.md
T
xsl 4b39ae2e49 feat(new8/batch3-4): cipher/teahouse/keeper/bridge 全套交付——new8 八款全部可交付收官
四泳道并行全流水线(资产→开发→测试→玩家迭代闭环),双双 R1-R2 连续达标裁定可交付:
- cipher《暗码》223 断言:摩尔斯解码嵌叙事/四结局矩阵/暴露度逐NIGHT验算/三层兜底;R2 三修(链首标记音/预警震/结局计数句+4句补录)4/4 全满分档
- teahouse《深夜茶馆》205 断言:泡茶时机窗/经济逐晚对账/多晚弧线;连续 2 轮 4/4 愿意玩 P0=0
- keeper《守塔人》257 断言:时空签名教学-兑现/插叙触发回返/trust×truth 档位/4结局;R2 F1/F2 坐实(震型豁免/首播跳句锁)4/4
- bridge《星环舰长》336 断言:巡检节奏逐毫秒/危机×系统态矩阵/仲裁7场景/忠诚差分/评级验算;R1 当场修F1-F4、R2 F5 菜单顺延保护 4/4 上行

公共:index.html 四卡片+profiles.js 四桶+check_all_assets 登记(预接线)、00-program 八款进度账收账、
gen_voice_dual 四游戏段、README/HANDOVER 阵容更新(11 款)、voice_text.json 四游戏键、mureka 台账(累计$1.26/$2.00)

验证:四游戏 playtest 223/205/257/336 全绿 + guide 122/122 + 全项目 15 游戏资产终检绿
遗留:keeper 三代人声滤波人耳试听(最高优先,ASR 对滤波句失明)、bridge 音频 32MB 超软指引 2MB(压缩候选)
2026-09-14 05:48:13 +08:00

48 KiB
Raw Blame History

20 · 《深夜茶馆》完整设计(teahouse / Late Night Teahouse)

给开发者的实现要点摘要

  1. 经营养成 RPG:核心动词=泡茶。一晚=3-5 位客人(本文定 4)≈13-17 分钟=单局;每位客人 2-4 分钟完整小循环(P3 三分钟颗粒)。泡茶小局三步:左右滑选茶+单击选定 → 听水声双击提壶(候汤)→ 听滴答双击出汤(闷泡)——时机步绑双击(即时,规避单击 300ms 延迟,dungeon 格挡先例),选茶步零豁免。
  2. 手势宪法三件套全状态保留(上滑状态/下滑菜单/双击重听);唯一豁免 E1=时机步双击≠重听(重听职责由上滑状态链第一段「重播客人点单句」承接),E2=链播中单击=跳句(12 号既有口径),E3=BREW 态关长按快进。教学讲清。
  3. 听觉分层铁律(本作最大风险):注水/沸腾/滴答三重音时间上串行不重叠,任意时刻≤(1 条主操作音+BGM)=2 声流;语音只出现在步与步之间的静默点;滴答只在闷泡最后 ~2.5s 关键窗;BREW 时机窗内看门狗只发 earcon 不发语音。
  4. 客人=声音群像:5 位弧线客人 NPC 平铺(5 音色,2 处与旁白同 speaker 已标风险)+3 位氛围客人旁白转述零 NPC 句。弧线 3 晚×3 方向(好/普通/错茶),结局按方向累计值三选一——全部从数据单源推导(点单句→茶参数→时机判定→三档结果→方向值),播报值=运行值。
  5. 经济账目真实(radio rep 教训加倍):口碑/收入/房租/欠账每一档播报与累积值一一映射;错茶=免单(收入 0、口碑−1,无其他惩罚);房租不足=「贴钱记账」剧情挫折,无 game over。§7.5 有完整 5 晚剧本逐晚验算。
  6. 随机性:N1-N5 剧本夜固定客序(连续剧结构);seed PRNG(mulberry32)只管 N6+ 氛围客轮换/口味与提示轮询。opts.seed 注入可复现。
  7. 台词表 20-teahouse-voice-ids.md:旁白 98 ×2 性别 + NPC 平铺 65 = 163 句 ≤170 上限;操作提示句键盘变体 _k 集中登记(V 组,gesture.inputMode() 选播)。CLOSE 结算链 800ms 手势死窗+链锁(dungeon H1 / detective VERDICT 同款)。
  8. 规模对标 detective:单文件 game.js 预计 900-1100 行;bgm 3 + sfx ~26 + voice 261 条(×2 格式=522 文件)。断言清单住本文档 §11(13 号文档 §20/§21 先例登记)。

1. 概述

  • 一句话:你接手巷子深处一家亮到后半夜的小茶馆,客人的故事随你泡的茶展开——泡对了,暖的是人心;泡错了,故事照样走,只是方向不同。
  • 题材:经营养成。核心命题「茶是热的,夜是长的」——纯音频天然适合:茶的好坏本来就只能靠听(水声、滴答)与「尝」(客人的声音反应)来感知;经营账目是规整的听觉播报链;客人群像是本作最大资产(8 位客人=8 种声音人生)。
  • 玩法定位(方法论 §4.1 无现成行,状态层重点自定):状态即节拍(一晚=固定客序推进,永不迷失「接下来干嘛」)+ 听觉判定(时机步靠耳朵)+ 账目真实(经济播报与累积值单源)。
  • 单局=一晚:4 位客人,13-17 分钟(首晚含教学 17-20);章程 15-25 分钟区间达标。一章=5 晚(全部弧线收束);每客人 2-4 分钟= P3 自然切分颗粒,任意客人结算后存档退出、回来一句话接上。
  • 无死亡无惩罚:泡错茶=客人免单+吐槽+故事走涩向;房租不足=秦婶记账(贴钱营业),永远没有 game over。轻压力=经济账每晚都要对(口碑档/收入档/欠账)。
  • 与现有 10 游戏的关系:状态档位链承接 dungeon(上滑多段链);双轨看门狗承接 dungeon E0-1/E0-2;NPC 群像+签名 earcon 承接 detective(sig_* 前缀);时机判定承接 rpg 格挡(双击+前摇窗口);「声音演技弧线」承接 radio(多晚连续剧);经营元进度为本作新增系统(8 款新模式探索点)。

2. 手势映射与豁免登记

2.1 每晚开场(OPENING)

手势 首晚(含教学 DRILL) 常规晚
单击 教学步骤作答(D1/D4) 跳句(开场链可跳)
双击 重听教学句 重听当前句
左滑/右滑 D0 步作答;其余 error error 震
上滑 状态链(D5 教后可用) 状态链
下滑 跳过教学(tut_skip;meta.drillDone) 菜单
长按/松开 error error

开场链:lamp_light(点灯 sfx)→ night_N(分档句)→(首晚 intro_1..3→DRILL)→ 1.5s 后门铃,自动进 SERVE。

2.2 堂前(SERVE:WELCOME/TALK/REACT 三个自动链子相位)

手势 链播中(进门/点单/反应) 空闲(链完待自动转场间隙)
单击 跳句(12 号口径;关键句「不可跳」仅 res_* 结果句与 rent_*) 提前切下一段(加速)
双击 重听当前句(宪法语义保留) 重听末句
左滑/右滑 静默忽略(纯聆听保护,simon playback 先例) 同左
上滑 状态链(queue 排队,链播完后续) 状态链
下滑 菜单(打开即停链;关闭→重播被停句,storyline「节点不丢」先例) 菜单
长按/松开 引擎快进(旁白 1.7×,不豁免)/ 恢复常速 error

2.3 泡茶小局(BREW:TEA 选茶 → WATER 候汤 → STEEP 闷泡三子相位)

手势 TEA(选茶) WATER(候汤) STEEP(闷泡)
左滑/右滑 换茶罐(循环):tea_jar sfx + 茶名句(含口诀) error 震+gd_invalid(不判错步) 同左
单击 选定此茶 → 自动进候汤(scoop sfx) error 震+纠错(等时机) 同左
双击 重听当前茶名句(宪法语义保留) 提壶(时机判定,即时) 出汤(时机判定,即时)
上滑 状态链(第一段=重播当前客人点单句+sig,需求随时可查) 同左(链排队;水声时间线照走,错过=真话归因「水滚老了」) 同左
下滑 菜单(冻结全部计时) 菜单(冻结水声时间线) 菜单(冻结滴答)
长按/松开 error(E3:BREW 全态 setRateBoostEnabled(false)) 同左 同左

菜单关闭恢复(A2 count-in 口径):TEA→重播当前茶名句;WATER→重播 hint_water 口诀;STEEP→重播当前茶名句;水声时间线从冻结点续走。

2.4 打烊(CLOSE)/ 标题(TITLE)

手势 CLOSE(结算链) CLOSE(链完) TITLE
单击 吞掉(800ms 死窗+链锁,§4.4) 睡下→OPENING(night+1)(settle_night 承诺言行一致) 继续(有档)/ 新店(无档)
双击 吞掉 重听结算链 重听 continue_ask
右滑 吞掉 error 重开新店:播 sys_reset_ask,再右滑一次确认(其余手势取消)
上滑 吞掉 重听账目链(st_rep→st_purse→置办清单) 店铺概况(口碑档→存款档→已置办句重播)
下滑 吞掉 菜单(含「打烊置办」项) 菜单
左滑/长按 吞掉 error error

2.5 模态菜单(遵守 00 §5.2 全球约定,无豁免)

下滑呼出(停链/冻结计时)→ 单击循环切项 → 双击确认 → 上滑帮助 → 下滑关闭。选项:返回堂前 / 打烊置办(仅 CLOSE;进二级列表同范式:茶柜/茶具/招牌/算了)/ 保存并回大厅 / 重新听帮助。

2.6 每状态手势映射总表(6 手势+长按松开,全状态覆盖)

手势 TITLE OPENING SERVE BREW-TEA BREW-水 BREW-闷 CLOSE MENU
单击 继续/新店 作答/跳句 跳句/加速 选定茶 error+纠错 error+纠错 吞/睡下 循环切项
双击 重听 重听教学句 重听当前句 重听茶名句 提壶 出汤 吞/重听链 确认执行
左滑 error 教学指定/err 忽略 上一罐 error error 吞/err 上一项
右滑 reset(两次) 教学指定/err 忽略 下一罐 error error 吞/err 下一项
上滑 店铺概况 状态 状态链 状态(含需求) 状态链 状态链 吞/账目链 帮助
下滑 菜单 菜单/跳教学 菜单 菜单(冻结) 菜单(冻结) 菜单(冻结) 吞/菜单 关闭
长按 error error 快进(引擎) error error error 吞/err error
长按松开 — — 恢复常速 — — — — —

无效手势一律 error 震;full 档 gd_invalid(onceKey 同局 1 次);idle-only(引擎 guide 已实现)。

2.7 豁免登记(必须显式)

# 豁免条目 理由(先例)
E1 BREW 时机步(候汤/闷泡)双击=提壶/出汤,非重听 即时判定绑双击规避单击 300ms 延迟(dungeon 战斗双击=格挡、rpg 前摇格挡同款);重听职责不缺位——上滑状态链第一段=重播客人点单句(含 sig),选茶步双击仍=重听茶名句。教学 D2/D3 讲清
E2 SERVE 链播中单击=跳句(非「确认」) 12 号 §1 既有口径(rpg/storyline/escape 先例);关键句(res_、rent_)登记不可跳
E3 BREW 态 setRateBoostEnabled(false) 长按在 BREW 是无效输入;防误触快进(dungeon/rhythm/space 对局期先例)

无 immediateTap;tap 只用于非即时操作(选定/跳句/睡下/菜单)。

3. 核心动词:泡茶小局(信息设计)

3.1 三步手势序列规格

步 输入 选项数 音反馈 错误容限 时长
① 选茶 TEA 左右滑循环+单击选定 茶柜 4 罐(扩容后 6) 每次切换:tea_jar(0.3s)→ 茶名句(含该茶口诀,知识随身播报);选定:tea_scoop 无限切换无时间压力;选定后不可改(错茶=故事走涩向+免单,无惩罚);上滑随时重听客人点单 8-25s
② 候汤 WATER 双击提壶 1(时机) 水声时间线(见 3.2):细密气泡→将沸→滚透→滚老,单条 11s 窗宽 ±1.5s(茶具升级 ±2.3s;首晚 ×1.3);早=「欠火」晚=「过老」均记偏不终止流程;无出手 t=11s 自动过老继续 11s 封顶
③ 闷泡 STEEP 双击出汤 1(时机) 注水 2s→舒展沙沙 2s→静默(仅 BGM)→目标前 2.5s 起 tick 滴答(窗内加速) 窗宽 [目标−1.0, 目标+1.4]s(茶具 +0.8s;首晚 ×1.3);早=「涩」晚=「苦」记偏;无出手 +4s 自动出汤继续 9-21s
  • 判定与结果(数据单源,无独立状态):{茶对错, 水档, 闷档} → 茶错⇒res_wrong;茶对∧水 ok∧闷 ok⇒res_good;茶对∧任一偏⇒res_plain。三档结果→客人反应三方向(§6.4)。
  • 每步结算即归因(真话律):water_early/ok/late、steep_early/ok/late 按真实时机选播;错手势(时机步内滑/单击)不判错步——只有时机本身决定品质,绝不报假归因。

3.2 水声时间线(声学编码,全在引擎能力内)

不用实时 WebAudio 节点(playtest mock 只覆盖 bufferSource/gain):全部=预生成 sfx one-shot + setTimeout 调度 + volume。

t=0    water_pour 注水 one-shot(2s)
t=2.0  boil_blip 单泡音起播:间隔 700ms(温水段)
t=3.5  ── 将沸窗开(绿茶/银针的提壶窗)──  blip 间隔 350ms + boil_simmer 低鸣 one-shot 链
t=6.5  ── 滚透窗开(茉莉/铁观音/滇红/普洱的提壶窗)── boil_roar 连片 one-shot 链(2s/段)
t=9.5  窗闭:boil_over 剧烈嘶鸣(滚老)
t=11.0 无出手→自动过老,播 water_late,进闷泡
  • 两窗共用一条时间线,茶种决定用哪扇窗(茶名句口诀即判据:「将沸就提」vs「滚透才冲」)。
  • 闷泡时间线:pour(2s)→ steep_rustle 沙沙(2s)→ 静默(BGM only)→ 目标前 2.5s tick_slow 起(1s/拍)→ 入窗 tick_fast(0.6s/拍)→ 窗后 +4s 自动出汤。
  • 目标闷时(自注水毕):快 7s(龙井/茉莉)/ 中 11s(铁观音/银针)/ 久 15s(滇红/普洱)。

3.3 听觉分层表(本作最大风险预防:并发声流 ≤2)

时刻 声流①(内容) 声流②(床) 语音 断言口径
客人进门/点单/反应 —— BGM serve 客人句(1 条) BGM+voice=2 ✓
选茶 tea_jar/scoop one-shot(≤0.3s,串行于语音前) BGM serve 茶名句 one-shot 与 voice 不叠(jar 先响完再播句)
候汤 boil_blip/roar 调度流 BGM brew 零语音(设计禁止) 水声期间 voice 播放事件=0
闷泡静默段 无 tick BGM brew 零语音 1 声流(最安静段=呼吸感)
滴答关键窗 tick 滴答 BGM brew 零语音(看门狗也只发 earcon,§9.2) tick 活跃窗内 voice 事件=0
打烊结算 coin/lamp one-shot BGM menu 账目句链 串行
  • 频带分离:沸腾=低频(150-500Hz 咕嘟)、滴答=高频木鱼(~880Hz 族)、人声=中频——即偶发瞬时叠听也不糊(Brewster 指南)。
  • 滴答只在关键窗(需求原文兑现):静默闷泡段绝不加节拍器。

4. 状态机

4.1 状态列表

TITLE / OPENING / SERVE / BREW / CLOSE + MENU(挂起 overlay,记录返回态)。SERVE 子相位=WELCOME/TALK/REACT(自动链);BREW 子相位=TEA/WATER/STEEP;CLOSE 子相位=TALLY(链)/SHOP(菜单内置办)。

4.2 转移图

start ──> TITLE ──tap(有档)──> OPENING(night_N) ──自动──> SERVE(客人1)
            │tap(无档)              │
            │右滑×2=重开新店(run+meta 清)              │点单链完,自动
            v                                         v
        (大厅)                             SERVE ⇄ BREW(每位客人一圈)
   SERVE(末位客人反应毕) ──自动──> CLOSE(打烊链)
   CLOSE ──tap──> OPENING(night+1)   [N5 链含 chapter_end;N6+ 无尽营业]
   任意正交态 ──下滑──> MENU ──关闭──> 原状态(SERVE 重播被停句;BREW 冻结后恢复)

4.3 语音链推进契约

  • 客人链/结算链=onComplete 串行(句间 0.8s);单句 8s 无 onComplete(资产缺失)→ 告警续链(「屏蔽任意 voice 流程不卡死」契约)。
  • 教学链 _speakGuarded 串行(radio/dungeon D0-1 同款,杜绝同 tick 双调度抢占)。
  • CLOSE 结算链为独占链:链首停看门狗;链内不受理手势(§4.4)。

4.4 打烊死窗与链锁(dungeon H1 / detective VERDICT 内化)

  • 进 CLOSE 即盖 CLOSE_GRACE_MS=800 死窗戳(touchstart+450ms 长按判定+300ms 双击窗 ≈750ms,800 全盖);死窗内一切手势吞掉(ghost 手势不算输入、不碰看门狗)。
  • 链锁:close_open→账目句→(房租/欠账句)→(chapter_end)→settle_night 落声前,单击/右滑/长按一律吞掉;链完成后单击=睡下(settle_night「单击,睡下」言行一致——simon round1-live 教训)。双击=重听链仅链完成后受理。

5. 教学编排(DRILL,首晚寄生于第 1 位客人=老周①)

每步=一句短旁白→等待实操→反馈;做错重教同一步(新短句 ≤2 次)后自动演示通过;下滑=跳过(tut_skip),meta.drillDone 持久化。教学客老周①明示茶名(龙井)+首晚窗口 ×1.3 → 好茶近乎保送、账目照常(首胜≤3min,A5)。

步 旁白 等待动作 通过条件/反馈
D0 intro_1..3 + tut_d0 左滑或右滑任一 tea_jar+茶名句;confirm 震。首输入 ≈t+20s(<60s ✓)
D1 tut_tea 单击 tea_scoop → 自动坐水
D2 tut_water(对照口径:泡泡细密是将沸,咕嘟连片是滚透——听到细密,双击提壶) 双击(将沸窗内) water_ok(偏了也继续:water_early/late 真话归因+重教短句)
D3 (水毕自动)tut_steep(滴答由稀到密,密起来就是将好——双击出汤) 双击(滴答密时) steep_ok(同上容错)
D4 tut_serve 单击 pour_cup → 老周 r1 反应句。首正反馈 ≈t+2.5-3min(≤3min ✓)
D5 tut_status(含需求重播入口:客人要的茶,上滑灶上随时再听) 上滑 状态链(st_guest→st_rep→st_purse)
D6 (老周出门后)tut_done — 第 2 位客人门铃,自由营业
  • 滚透窗(茉莉等 4 茶)不设专门教学步:靠茶名句口诀+hint_water+首晚宽窗自然过渡(知识单源=茶名句,承诺必兑现)。
  • 教学无进展轨(E0-2 先例):30s earcon → 60s 短句 → 90s 自动替打当前步(自动选定/提壶/出汤,演示通过不卡流程)。

6. 客人系统

6.1 客人档案 JSON 草案(数据单源:点单句→茶参数→判定→方向→结局)

{
  "schema": 1,
  "teas": {
    "longjing":   { "name": "tea_longjing",   "price": 6,  "water": "simmer", "steep": "fast",  "shelf": true },
    "moli":       { "name": "tea_moli",       "price": 4,  "water": "rolling", "steep": "fast",  "shelf": true },
    "tieguanyin": { "name": "tea_tieguanyin", "price": 8,  "water": "rolling", "steep": "mid",   "shelf": true },
    "dianhong":   { "name": "tea_dianhong",   "price": 5,  "water": "rolling", "steep": "long",  "shelf": true },
    "puer":       { "name": "tea_puer",       "price": 7,  "water": "rolling", "steep": "long",  "shelf": "cabinet" },
    "yinzhen":    { "name": "tea_yinzhen",    "price": 10, "water": "simmer", "steep": "mid",   "shelf": "cabinet" }
  },
  "arcGuests": [
    { "id": "zhou", "name": "老周", "sig": "sig_zhou",
      "enter": "zhou_enter", "orders": ["zhou_o1", "zhou_o2", "zhou_o3"],
      "teaByVisit": ["longjing", "dianhong", "longjing"],
      "reactions": [["zhou_r1_good", "zhou_r1_plain", "zhou_r1_wrong"],
                    ["zhou_r2_good", "zhou_r2_plain", "zhou_r2_wrong"], null],
      "endings": ["zhou_e_a", "zhou_e_b", "zhou_e_c"] },
    { "id": "su",  "name": "苏晚", "sig": "sig_su",  "enter": "su_enter",
      "orders": ["su_o1", "su_o2", "su_o3"],
      "teaByVisit": ["dianhong", "moli", "dianhong"],
      "reactions": [["su_r1_good","su_r1_plain","su_r1_wrong"],
                    ["su_r2_good","su_r2_plain","su_r2_wrong"], null],
      "endings": ["su_e_a", "su_e_b", "su_e_c"] },
    { "id": "shi", "name": "陈拾", "sig": "sig_shi", "enter": "shi_enter",
      "orders": ["shi_o1", "shi_o2", "shi_o3"],
      "teaByVisit": ["moli", "longjing", "yinzhen"],
      "reactions": [["shi_r1_good","shi_r1_plain","shi_r1_wrong"],
                    ["shi_r2_good","shi_r2_plain","shi_r2_wrong"], null],
      "endings": ["shi_e_a", "shi_e_b", "shi_e_c"] },
    { "id": "bai", "name": "白老先生", "sig": "sig_bai", "enter": "bai_enter",
      "orders": ["bai_o1", "bai_o2", "bai_o3"],
      "teaByVisit": ["tieguanyin", "puer", "puer"],
      "reactions": [["bai_r1_good","bai_r1_plain","bai_r1_wrong"],
                    ["bai_r2_good","bai_r2_plain","bai_r2_wrong"], null],
      "endings": ["bai_e_a", "bai_e_b", "bai_e_c"] },
    { "id": "he",  "name": "何雨眠", "sig": "sig_he", "enter": "he_enter",
      "orders": ["he_o1", "he_o2", "he_o3"],
      "teaByVisit": ["longjing", "puer", "yinzhen"],
      "reactions": [["he_r1_good","he_r1_plain","he_r1_wrong"],
                    ["he_r2_good","he_r2_plain","he_r2_wrong"], null],
      "endings": ["he_e_a", "he_e_b", "he_e_c"] }
  ],
  "ambientGuests": [
    { "id": "postman", "order": "amb_1", "teaPool": ["moli"] },
    { "id": "embroider", "order": "amb_2", "teaPool": ["longjing"] },
    { "id": "drunk", "order": "amb_3", "teaPool": ["dianhong"] }
  ],
  "nights": [
    ["zhou", "amb:postman", "su", "shi"],
    ["zhou", "bai", "he", "shi"],
    ["zhou", "su", "bai", "amb:drunk"],
    ["he", "shi", "su", "amb:postman"],
    ["bai", "he", "amb:embroider", "amb:postman"]
  ],
  "nightsEndless": { "pool": ["amb:postman", "amb:embroider", "amb:drunk"], "size": 4 },
  "economy": { "tipGood": 2, "rentEvery": 3, "rent": 20,
               "repGain": { "good": 1, "plain": 0, "wrong": -1 },
               "pay": { "good": "price+2", "plain": "price", "wrong": 0 },
               "upgrades": [
                 { "id": "cabinet", "voice": "upg_cabinet", "cost": 15 },
                 { "id": "teaware", "voice": "upg_teaware", "cost": 12 },
                 { "id": "sign",    "voice": "upg_sign",    "cost": 20, "repReq": 12 } ] }
}
  • 氛围客人点单句由旁白转述(amb_1..3,句内已含茶名与参数暗示);判定同弧线客人(teaPool/口味由 seed 决定 N6+ 变体,N1-N5 用表内固定值)。
  • 矩阵不变式(dev/playtest 双保险):每晚每位客人的点单句 ⇒ (tea, water窗, steep窗) 三元组与 teas[teaByVisit[i]] 严格一致;任何台词改稿若使点单句暗示的茶与 teaByVisit 不符,断言立即失败(防「文案事故变成归因假话」)。

6.2 弧线节点表(5 位客人 × 3 晚;方向值 好茶+1 / 普通 0 / 错茶−1)

客人 晚1 相遇 晚2 深入 晚3 收束(结局=按累计 sum)
老周(修车师傅,儿子在外多年) 点龙井去火;r1×3 点浓暖的(滇红);r2×3 起「儿子来电」话头 「头一回那盏再来一份」(龙井回环);sum≥2=A 父子回来帮工 / B 电话拌嘴日子照过 / C 关铺去投儿子
苏晚(夜班护士,去留抉择) 点暖的不冲(滇红);r1×3 点香的(茉莉);r2×3 讲科室一夜 「还是头一回那种」(滇红回环);A 调白天班白天来 / B 再值一季看看 / C 递辞呈但记住这盏灯
陈拾(高三生,大考) 点香提神不浓(茉莉);r1×3 点清火的(龙井);r2×3 问「还能考上吗」 「喝口金贵的犒劳自己」(银针,需茶柜);A 超常发挥请全馆 / B 听家里安排 / C 考砸但灯还亮着
白老先生(独居,老伴忌日) 点刮油经泡的(铁观音);r1×3 点陈味(普洱,需茶柜);r2×3 忆四十年前一盏普洱 「就馋那口陈味」(普洱);A 搬棋盘天天来「当她在看着」 / B 空屋但有茶垫梦 / C 搬去养老院留壶给茶馆
何雨眠(夜班出租车司机,攒学费) 点清口不浓(龙井);r1×3 点最浓的(普洱,需茶柜);r2×3 讲闺女照片贴方向盘 「一盏柔的收收心」(银针,需茶柜);A 学费齐了去看闺女 / B 差一点再跑一月 / C 退了夜班「这盏喝得最慢」
  • 结局映射:sum = Σ方向值(3 晚);sum≥2 → A(暖);−1≤sum≤1 → B(平);sum≤−2 → C(涩)。
  • 茶柜锁与弧线的 roguelike 纹理:白老②③/何②③/陈③ 需要「茶柜扩容」解锁的普洱/银针——没置办的玩家必然错过好茶档,弧线自然走平/涩向(这是经营决策的重量,不是 bug;§7.5 剧本 B 验算)。全 A 路径可行性:N2 打烊置办茶柜(15 文)即解锁全部弧线茶(§7.5 剧本 A)。
  • 晚 3 收束夜=「反应与结局合一」:结局句本身回应今晚的茶(A 段必有对茶的正面回应、C 段必有遗憾——见台词表 N 组)。

6.3 声音群像:区分度(本作最大资产风险,逐人标注)

角色 speaker instruct 常量 区分度风险
旁白(掌柜系统音) female=Serena / male=Uncle_Fu 见台词表头 基准
老周(58 修车师傅) Eric 沙哑洪亮的男声,修车铺老师傅,大嗓门,直爽热乎 低:与两侧旁白均不同 speaker
苏晚(29 夜班护士) Vivian 轻柔平稳的女声,夜班护士,温和疲惫,吐字干净 低:同上
陈拾(17 高三生) Dylan 年轻清亮的男声,高三学生,紧张,语速快,有点怯 低:同上
白老先生(74) Uncle_Fu 苍老缓慢的男声,独居老先生,慢条斯理,带茶韵 中:与 male 旁白同 speaker——靠 sig_bai 前缀+苍老腔 instruct+人称差(客人第一人称/旁白第三人称「客人」)+句间 0.6s;试听确认
何雨眠(36 的姐) Serena 低哑爽利的女声,夜班出租车司机,利落,带笑带倦 中:与 female 旁白同 speaker——同上缓解;试听确认
氛围客人 ×3 旁白转述 同旁白 无(零 NPC 句,成本与风险双省)

NPC 音色数=5 ≤6(radio/detective 满配先例);每位弧线客人专属签名 earcon(sig_*,0.3-0.5s)在进门句/状态链需求重播/反应句前必响——认人是「sig+speaker+instruct」三层冗余。

7. 经营数值(口碑/收入/房租经济表)

7.1 每晚事件表(N1-N5 剧本夜)

晚 客序 事件
1 老周①/邮差/苏晚①/陈拾① 教学;首胜保送;无房租
2 老周②/白老①/何①/陈拾② 普洱银针需求首次逼近(茶柜压力);打烊可置办
3 老周③/苏晚②/白老②/醉汉 房租夜①(20 文);老周弧线收束
4 何②/陈拾③/苏晚③/邮差 苏晚/陈拾弧线收束
5 白老③/何③/绣娘/邮差 房租夜②;白老/何收束;chapter_end

N6+(无尽营业):4 席=氛围客轮换(seed 定序/口味),房租照收,经济维持。

7.2 累积公式

rep:初始 0,clamp ≥0。每客 good +1 / plain 0 / wrong −1。每晚 Δ∈[−4,+4]。
purse(存款):初始 0。CLOSE 时 income 计入 → 先还债(debt 清零播 debt_clear)→ 房租夜扣 rent
      (不足 → 差额入 debt,播 rent_short + danger 签名)→ 可置办(不透支)。
income(当晚):Σ 每客 pay = good: 茶价+2 打赏 / plain: 茶价 / wrong: 0(免单)。
方向值(弧线):good +1 / plain 0 / wrong −1,sum 三晚 → 结局 A/B/C。
upgrades:cabinet 15(普洱+银针上柜)/ teaware 12(时机窗 +0.8s)/ sign 20(需 rep≥12,每晚结算 rep+1)。

7.3 档位播报措辞与账目一一映射(radio rep 教训:播报值=运行值,跨档才播、双向都播)

账本 档 阈值 播报句(id) 措辞↔账目
口碑 rep 1 冷清 0-4 st_rep_1「口碑还没立起来」 「没立起来」=rep<5
2 回头 5-11 st_rep_2「有了回头客」 「回头客」=rep≥5
3 名声 12-19 st_rep_3「巷子口都在传」 「传」=rep≥12
4 招牌 ≥20 st_rep_4「一盏难求」 「难求」=rep≥20
当晚收入 1 <15 close_coin_1「不到十五文」 与逐客 pay 之和相等
2 15-24 close_coin_2「十五到二十五文」 同上
3 ≥25 close_coin_3「二十五文往上」 同上
存款 purse 1 <10 st_purse_1「钱箱见底」 结算后实值
2 10-24 st_purse_2「周转得开」 同上
3 ≥25 st_purse_3「手头宽裕」 同上
欠账 debt — >0 st_debt_1「账上还欠着秦婶的钱」 CLOSE 链内、还清播 debt_clear
房租 — 每 3 晚 20 文 rent_due→rent_ok / rent_short 不足额=差额入账,无 game over

7.4 店铺升级树(roguelike 跨晚进度,localStorage+服务器双存)

茶柜扩容 15 ──> 普洱(7文·滚·久)+白毫银针(10文·将沸·中)上柜 ──> 解锁白老②③/何②③/陈③ 的好茶路径
新茶具 12 ──> 候汤/闷泡窗各 +0.8s(容错拉满,P4)
立招牌 20(需 rep≥12 且 debt=0)──> 每晚结算 rep+1(口碑发酵)

7.5 完整 5 晚剧本验算(剧本 A「用心掌柜」——口碑/收入逐晚对账)

晚 逐客结果(茶·三档) 逐客收入 当晚收入 rep 流程(跨档播报点) purse 流程
1 周好(龙井)/邮好(茉莉)/苏好(滇红)/陈好(茉莉) 8/6/7/6 27(coin_3) 0→4(无跨档) 0→27
2 周普(滇红)/白好(铁观音)/何错(泡了茉莉)/陈好(龙井) 5/10/0/8 23(coin_2) 4→5(st_rep_2)→4(st_rep_1,何错跌回)→5(st_rep_2) 27+23=50;置办茶柜 −15 → 35
3 周好(龙井)/苏好(茉莉)/白好(普洱)/醉普(滇红) 8/6/9/5 28(coin_3) 5→8;老周 sum=+1+0+1=2 → 结局 A 35+28=63;房租 −20 → 43;置办茶具 −12 → 31
4 何好(普洱)/陈好(银针)/苏错(泡了龙井)/邮普(茉莉) 9/12/0/4 25(coin_3) 8→9→10→9(st_rep_2下沿内,不跨档)→9;陈 sum=3→A;苏 sum=+1+1−1=1→B 31+25=56
5 白好(普洱)/何好(银针)/绣普(龙井)/邮好(茉莉) 9/12/6/6 33(coin_3) 9→10→11→11→12(末客后st_rep_3);白 sum=3→A;何 sum=−1+1+1=1→B 56+33=89;房租 −20 → 69;立招牌 −20(rep=12 恰达标)→ 49

终局:rep 12(档3)/ purse 49 / 升级 3/3 / debt 0 / 结局 3A+2B;chapter_end → N6+ 无尽营业。 对账断言:每晚 close_coin 档=逐客 pay 之和所在档;每次 st_rep 播报时的 rep 实值=该档阈值区间;置办价=upg 表——playtest 锁定(假话即失败)。

7.6 剧本 B「贴钱营业」验算(欠账机制可达性)

N1-N3 全错(每客免单+rep−1,rep clamp 0):income 0/0/0,purse 0;N3 房租 20 > 0 → rent_short+danger,debt=20(贴钱营业,无 game over);无茶柜 → N4 何②/陈③必然错茶(普洱/银针缺位,弧线走涩向——经营决策的真实重量);N4 苏好+邮普 income 11 → 还债 11(debt 9);N5 绣普+邮好 income 12 → 还债 9(debt_clear)→ purse 3 → 房租 → debt 17。终局 rep 2(档1)、结局 2C+3B——活着,且每一句播报与账本一致。

8. 音频三层

8.1 BGM(3 首,Mureka instrumental,-20 LUFS,ogg+m4a,无缝循环)

id 状态映射 Mureka prompt(英文)
bgm/menu TITLE / MENU / CLOSE(结算 volume 0.5) "Cozy late night tea house, soft guzheng and bamboo flute duet, warm kettle hum and faint vinyl crackle, intimate and unhurried, no drums, no vocals, seamless loop"
bgm/serve OPENING / SERVE "Gentle Chinese tea house evening theme, sparse pipa and soft erhu, distant crickets and quiet old-street ambience, warm storytelling mood, no vocals, seamless loop"
bgm/brew BREW(三子相位) "Minimalist zen tea brewing music, very sparse guqin notes over soft water ambience, meditative, wide and quiet dynamics, no vocals, seamless loop"

切换全走引擎 crossfade;voice duck 20% 引擎自动。预算:3 曲 ×2 候选=6 任务 $0.18(上限 $2.00 内)。brew 曲特意稀疏——给操作音让频带(§3.3)。

8.2 SFX(~26 个;SA3=Stable Audio 3,SYN=程序合成;双格式、真峰值 ≤-3dBFS)

类别 id 方式 说明
进门 door_bell SA3 铜铃两响(0.5s,客人进门/出门)
steps_in steps_out SA3 布鞋脚步 1.2s(in 由远及近预 pan 派生,dungeon 工艺)
客人签名 sig_zhou SYN 扳手磕搪瓷缸一响
sig_su SYN 指尖叩桌面两下
sig_shi SYN 拉链+书本落桌
sig_bai SYN 棋子落木盘一响
sig_he SYN 车钥匙串抖两下
选茶 tea_jar tea_scoop SYN 木罐启盖+茶叶沙沙 / 铜勺入壶
候汤 water_pour SA3 注水 one-shot 2s
boil_blip boil_simmer boil_roar boil_over SA3+SYN 单泡/低鸣/连片滚沸/过老嘶鸣(one-shot 链调度,§3.2;不用循环 sfx——引擎 sfx 层无 loop)
kettle_lift SYN 提壶离火蒸汽「呲」
闷泡 steep_rustle SYN 干茶舒展沙沙(2s,低响度)
tick_slow tick_fast SYN 木鱼滴答两档(880Hz 族;只进关键窗)
上茶 pour_cup SA3 茶汤入盏+盏托轻磕
账目 coin_soft coin_stack SYN 单枚铜钱/三枚铜钱落桌(plain/good);wrong=无币声(免单静默+反应句)
rep_chime rep_fall SYN 上行/下行双音(口碑跨档瞬时标记,配合档句)
仪式 lamp_light lamp_off SYN 开灯「嗒」/熄灯(每晚开张与睡下)
shop_buy upg_install SYN 算盘+钱柜抽屉 / 木工轻敲(置办)
看门狗 turn_tick SYN 880Hz 木鱼族轻响(无进展轨 L1,dungeon 配方自存一份)

SA3 任务 ~10 个(door_bell/steps×2/water_pour/boil 家族 2 条/pour_cup);其余 SYN 兜底。

8.3 voice(163 句:旁白 98 ×2 性别 + NPC 平铺 65)

  • 旁白(系统/教学/状态/账目/氛围客转述):female=Serena / male=Uncle_Fu,instruct 全表统一(台词表头);数字全分档整句(st_guest 5 档/st_rep 4/st_purse 3/close_coin 3/night 6 档),无运行时拼接。
  • NPC 平铺(弧线客人台词):5 speaker+instruct 恒定(§6.3 区分度表);不做双性别;落 voice/ 根目录(引擎平铺回退命中)。台词全文、触发、键盘变体、多音字自查见 20-teahouse-voice-ids.md。
  • 声音演技核心:晚 3 结局句(A/B/C 三方向 ×5 客人)与晚 2 反应句的递进(故事感全在句内文本+标点引导,instruct 恒定)。

9. 向导层接入(engine/guide.js,不新增 earcon 词表)

9.1 状态签名(进入状态时播)

状态 guide.state() 时点
TITLE / MENU / CLOSE 链 menu(CLOSE 链完) 进标题、开菜单、进结算
OPENING / SERVE explore 开场、每位客人进门
BREW battle 选茶步起(「小局起」的统一签名)
CLOSE 链内 settle 打烊链首
danger danger rent_short 当刻(每欠账事件 1 次)

choice 不使用(无抉择态,登记)。

9.2 turn cue 与看门狗(双轨——批次 1 教训固化)

等待点 机制 at say(full 档;第 2 级一律纯 nudge)
BREW 各子相位入口 guide.turn — turn earcon + confirm 震
SERVE 空闲 无操作轨 [10s, 25s] gd_serve / null
BREW-TEA 无操作轨 [12s, 30s] gd_brew / null
BREW-WATER/STEEP 时机窗内 只 earcon [12s] 语音一律不发(§3.3 分层铁律;语音会占第 3 声流)
CLOSE 链完 无操作轨 [15s, 35s] gd_close / null
DRILL 每步 无进展轨 [30/60/90s] earcon→短句→自动替打(§5)

9.3 无进展轨(营业态卡关三级——「乱按也要被营业」)

进展事件=客人相位推进(进门/点单/上茶/反应毕)/BREW 步骤推进/打烊/置办(_progressTrack() 挂点:各链 onComplete、判定函数、状态进入)。只由进展重置——乱按(狂切茶罐不听、反复开菜单)永远攒不满进展,三级必达:

  • [45s] L1:turn_tick earcon(不占台词通道)→ [90s] L2:hint_water(泡茶口诀)/gd_serve(堂前)→ [150s] L3:重播当前客人点单句(BREW/堂前通用的真话提示——把线索原句还给玩家,不替选茶);L3 后每 150s 重复(每句全局限 2 次,之后静默)。
  • 无操作轨与无进展轨并行取先到;两轨短句内容同级交叉登记防重复;纠错/提示 idle-only、过期丢弃(引擎已实现)。

10. 存档设计(跨晚进度)

{
  "schema": 1, "game": "teahouse", "updatedAt": 0,
  "summary": "第3晚 · 客人2/4 · 口碑·有了回头客 · 存款35文 · 欠账0文",
  "meta": { "drillDone": true, "nightsClosed": 2, "rep": 5, "purse": 35, "debt": 0,
            "upgrades": ["cabinet"], "chapterEnd": false },
  "run": { "night": 3, "guestIdx": 2,
           "results": ["good", "plain"],
           "incomeTonight": 5,
           "guestStory": { "zhou": 1 },
           "rentCharged": false }
}
  • summary 生成规则:第{night}晚 · 客人{guestIdx+1}/4 · 口碑·{rep 档名} · 存款{purse}文 · 欠账{debt}文(打烊后 run 清空,summary=第{nightsClosed}晚打烊 · 口碑·{档名} · 存款{purse}文)。
  • 保存时机:每客反应毕 / 打烊链完 / 置办后 / 菜单「保存并回大厅」。localStorage + PUT 服务器。
  • 读取:有 run → TITLE 播 sys_continue_ask,单击继续 → 客人粒度恢复(当前客人从进门链重放,已结算客人不重复)→ 局面复述链 st_guest_n → st_rep → (BREW 则加 sig+点单句) → recap_go,≤5s 回到可操作。右滑 ×2=重开新店(run+meta 清零,播 sys_reset_ask 二次确认)。

11. playtest 断言清单(登记 13 号文档新增 §teahouse;mock 对齐 web/rpg/test/playtest.mjs;一律 guide:'off')

关键路径(seed=42,N1-N3,≤120 手势;全章 N1-N5 ≤200):

  1. 启动→TITLE(无档)→单击→OPENING(night_1):intro 三句+D0..D6 逐步 voice 序与 drillStep 递进;D2/D3 时机步双击;首晚窗口 ×1.3 断言;下滑跳过路径+meta.drillDone 二周目不再进。
  2. 泡茶小局三步:TEA 左右滑循环(wrap)+茶名句播报+单击选定→WATER 时间线(blip 间隔 700/350ms、roar 链、窗位=茶参数)→双击在窗内=water_ok/窗前=water_early/窗后=water_late;t=11s 无出手自动过老;STEEP tick 只在目标前 2.5s 起、窗内加速、同三档+超时自动出汤;判定三元组与 §3.1 映射(good/plain/wrong)逐组合注入验证(含「茶对双偏=plain」「茶错=wrong 即水闷全 ok」)。
  3. 矩阵不变式:全弧线客人×全部访问 → teaByVisit 与 teas 表参数一致;氛围客 teaPool 同;同 seed 两次构造 run._schedule(N6+ 轮换序)深相等。
  4. 客人弧线三方向:逐客注入三晚结果矩阵(全好/混合/全错)→ 结局句=A/B/C 与 sum 映射一致;反应句三方向与当晚结果一致(假话即失败);晚 3 结局句替换反应句路径。
  5. 经济账目验算:按 §7.5 剧本 A 逐晚走(茶种/时机注入)→ close_coin 档=逐客 pay 和;rep 跨档播报点与实值一致(含双向跌档);置办扣款与 upg 表;N3/N5 房租扣款;剧本 B:全错→免单→rent_short+danger+debt 流转+debt_clear+rep clamp 0。
  6. 听觉分层:WATER/STEEP 时机窗内 voice 播放事件=0(看门狗 suppressed 断言);语音 start 事件与 boil/tick 活跃区间零相交;语音只在步间静默点。
  7. 打烊死窗+链锁:进 CLOSE 同拍与 +300ms 各补一记在途 tap → 均被吞;结算链完整有序(close_open→coin→[rent]→[debt]→[chapter_end]→settle_night);链完成后单击=睡下→OPENING(night+1);N5 后 night_more+氛围客轮换。
  8. 看门狗双轨:SERVE 10s/25s、BREW-TEA 12s/30s;乱按 96s 零进展 → 45s earcon/90s 短句/150s 重播点单句;有真实进展零提示;BREW 时机窗内只 earcon 无语音。
  9. 中断复述:存档重进(客人粒度)→ sys_continue_ask→单击→复述链序 st_guest→st_rep→(BREW 加 sig+点单句)→recap_go;上滑同链可重放。
  10. E1 豁免:BREW 时机步双击=提壶/出汤(非重听);选茶步双击=重听茶名句;上滑状态链第一段=sig+点单句重播;BREW 长按=error(rateLog 断言 E3)。
  11. 菜单/置办/存档:模态菜单循环-确认-关闭;CLOSE 菜单「打烊置办」二级列表;teaware 购后窗口 +0.8s 实测;sign 的 rep≥12 与 debt=0 门(upg_lock/upg_none 真话);「保存并回大厅」PUT data.summary 命中生成规则。
  12. 键盘变体:settings.input='key' 后播 sys_help_k/tut_water_k 等 V 组(inputMode 联动);'touch' 回基础句。

边界断言:

  • 零惩罚:全 run 无 game over 路径;错茶免单但仍推进故事;rep clamp ≥0;purse 不透支。
  • 归因真话:water/steep 三档句与注入时机严格对应;res_wrong 只在茶错时播;「没出手」归「水滚老了/闷过了」(真实:未操作)。
  • SERVE 链播中单击=跳句(res_/rent_ 不可跳)、双击=重听当前句、左右滑静默忽略;菜单关闭重播被停句。
  • BREW 菜单冻结:水声时间线/滴答全停(快进虚拟时钟断言零调度);关闭恢复从冻结点续走+复述句。
  • 屏蔽任意 voice 资产:链 8s 兜底推进,流程到打烊不死锁。
  • guide=off:全静、零定时器;资产齐套:voice 双性别 id 集合一致+NPC 平铺存在+sfx/bgm 双格式。
  • 首晚 FTUE:首输入 <60s(D0 ≈t+20s);首正反馈 ≤3min(D4 老周反应)。

失败即不通过:归因假话(档位句/结局句/反应句与数据实值不符);点单句与 teaByVisit 矛盾;同 seed 两次构造不一致;教学计入惩罚;CLOSE 链被手势截杀;时机窗内出现语音;免费重听(状态链)被收费或受限。

12. 节奏曲线(一晚/一弧线两级)

一晚(单局 13-17 分钟;首晚 17-20)

阶段 时长 内容 奖励点(≤60s 一个)
开场 0:20-0:35 点灯+night 句(首晚 intro+教学) —
客人 ×4 各 2.5-4 分钟 进门 15s→点单 20s→泡茶 45-75s→反应 25s 每步 water_ok/steep_ok 即时确认;res 三档;反应句+币声;口碑跨档 chime
打烊 1:30 账目链→(房租/欠账)→(置办)→睡下 账目+置办+settle 钩子
  • 每位客人=一个完整起承转合(P3 三分钟颗粒:任意客人结算后退出,回来一句话接上)。
  • 紧张度曲线温和:泡茶小局是每 3 分钟一个的「微专注峰」(时机步),其余是聆听叙事谷——峰谷交替,不疲劳(P4)。

一条弧线(3 晚,跨局)

晚 1 相遇(立谜:他是谁/他要什么)→ 晚 2 深入(话头展开+方向累计)→ 晚 3 收束(结局三方向)。跨晚钩子=反应句留白(「儿子的事,改天再说吧」)+ 结算 settle_night「明晚,茶馆还等你开门」;5 晚后 chapter_end 收第一章,无尽营业+二周目变体空间(氛围客 seed 轮换)。

13. 自检清单

# 硬约束/教训 自检
1 FTUE 首输入 <60s D0 ≈t+20s ✓(§5)
2 首正反馈 ≤3min D4 老周反应 ≈t+2.5-3min(首晚宽窗保送好茶)✓
3 学习期零惩罚 首晚窗口 ×1.3+教学明示茶名;全域无 game over;错茶免单非死亡 ✓
4 失败三问归因+真话律 水闷各三档句按真实时机;res_wrong 只在茶错;「没出手」归「滚老/闷过」;§11 失败项锁定 ✓
5 手势宪法三件套不豁免 上滑状态/下滑菜单/双击重听全状态保留(时机步双击偏离=豁免 E1 登记+教学讲清+状态链承接重听)✓
6 教学承诺兑现 tut_water/tut_steep 承诺的双击时机语义正片恒成立;settle_night「单击睡下」死窗+链锁后言行一致;upg 句报价=扣款 ✓
7 结算链完整 CLOSE 800ms 死窗+链锁(dungeon H1 内化)✓(§4.4)
8 档位措辞真实 §7.3 表:每句措辞↔阈值区间一一映射;跨档双向播报;播报值=运行值(radio rep 教训+经营玩家对账最敏感)✓
9 经济账目验算 §7.5 剧本 A 五晚逐晚验算(27/23/28/25/33 收入、rep 0→12、purse 0→49、3A+2B)+ §7.6 剧本 B 欠账可达 ✓
10 弧线三方向可走通 sum 映射 A(≥2)/B(−1..1)/C(≤−2);每客注入全好/全错/混合三路径(§11.4);茶柜锁=设计内经营重量(剧本 A 证明全 A 可达)✓
11 听觉负荷(本作特有风险) 三重音时间串行零重叠;语音只在步间;滴答只进关键窗;时机窗内看门狗只 earcon;频带分离;并发声流恒 ≤2(§3.3 表+断言 6)✓
12 信息密度 列表逐项预览(茶罐循环一次一罐一句);状态链 ≤4 段+需求重播;客人链句粒度可停可跳可重听 ✓
13 向导层 签名 5 态(choice 登记不用);双轨看门狗(乱按必被抢救+时机窗静默特例);提示 idle-only/queue/onceKey ✓(§9)
14 seed 可复现 mulberry32+opts.seed;N1-N5 表驱动剧本夜;N6+ 轮换洗牌全 PRNG+深相等断言 ✓
15 P1 视障 双击=即时时机键(读屏手速友好);状态链=需求+第几位+口碑+存款随时可查;账目真实;5 音色群像+sig 三层冗余认人;2.2× 语速引擎既有 ✓
16 P3 通勤 每客人 2-4 分钟完整颗粒;中断复述「今晚第几位/口碑档」;菜单随时存档退出 ✓
17 P4 工人 零新手势;时机窗 ±1.5s 宽+超时自动继续(绝不卡死不挨骂);错茶故事照样走 ✓
18 P2 大学生 弧线三方向收集+章节完结+升级树+招牌追求(rep≥12)✓
19 台词规范 163 句 ≤170;全句 ≤40 字(实测 ≤36);数字全分档整句(guest 5/rep 4/purse 3/coin 3/night 6);「重新听」写法;同角色 speaker+instruct 恒定 ✓(台词表)
20 键盘通道 V 组 10 变体集中登记,inputMode() 选播;方向键/空格/回车全手势可达(§5.5 平行通道,游戏层零改动)✓
21 引擎能力边界 无实时节点(one-shot 链+setTimeout 调度);sfx 无 loop 需求(调度链实现);tap 延迟只用于非即时;资产缺失静默跳过+8s 兜底;30MB 预算内 ✓
22 密度下限(dungeon D0-3 教训) 一晚=固定客序节拍器(结构性密度);营业态无进展轨兜底;客人间隙 1.2s 自动推进无真空 ✓

14. 修订记录(实施裁定)

对开发自查发现的内部张力逐条登记(旧文不回改,以此为准):

  1. 招牌置办门的欠账条件:§7.2 与 §6.1 JSON(economy.upgrades sign 仅 repReq:12)未提欠账;§7.4 升级树与 upg_lock 台词明言「口碑得十二分往上,欠账也得清」。裁定为 rep≥12 且 debt=0 双门(以 §7.4/台词为准)——欠账时选招牌播 upg_lock(真话归因),upg_none 只管钱不够;§7.5 剧本 A 验算里 debt 恒 0,两口径对账结果一致,不影响验算数。
  2. 菜单固定项与态差异:§2.5 选项列四项(返回堂前/打烊置办/保存并回大厅/重新听帮助),其中「打烊置办」仅 CLOSE 态出现(SERVE/BREW/TITLE 态菜单为其余三项);实现按态裁剪菜单项,模态交互范式(单击循环/双击确认/上滑帮助/下滑关闭)不变。
  3. summary 口碑档名取值:§10 示例「口碑·有了回头客」。档名映射取各档措辞短式——档1「还没立起来」/档2「有了回头客」/档3「小有名气」/档4「一盏难求」(与 st_rep_* 句首措辞同源),播报与存档共用同一映射函数(单源)。
  4. 房租夜定义:§6.1 JSON rentEvery:3 与 §7.1 事件表(房租夜①=N3、房租夜②=N5)/§7.5/§7.6 验算(N5 均扣房租 20)矛盾——5 晚章节内「每 3 晚」只会命中 N3。裁定为 本章内房租夜 = 第 3、5 晚(以 §7.1/§7.5/§7.6 为准,N5 是章节收束夜的双重压力事件);N6+ 无尽营业起回到每 3 晚节奏(N6、N9……)。rentEvery:3 字段视为遗漏,不改旧文。
  5. §7.6 终局 rep 算术修正:剧本 B 事件列(N1-N3 全错 12 次 −1、N4 两错一好、N5 白老③/何③ 无茶柜必错)按 §7.2 公式与 clamp≥0 复算,终局 rep = 1(N4 苏好 +1 → 1;N5 邮好 +1、白老/何雨眠错茶各 −1 相抵);§7.6 原文「rep 2」系算术笔误。实现以 §7.2 公式为唯一准绳(假话即失败),本裁定不回改正文。
  6. R1 台词修订(F1/F3 落地):tut_water/tut_steep 对照口径前移(将沸/滚透、滴答由稀到密的判别句写进教学句本身,hint_water 口诀保留作无进展轨复诵,同文复用不算漂移);tut_status 补需求重播入口明示(「客人要的茶,上滑灶上随时再听」)。三句连同 key 变体重录;§5 教学表与 20b 台词表已同步,正文旧行不回改。