- abyss:声呐双通道仲裁/氧气软失败经济 512 组合穷举/148 句;detective:证词矛盾数据单源推导/158 句;cipher:摩尔斯运行时合成/暴露度经济/139 句;teahouse:泡茶三步小局听觉分层/5 晚经济逐晚验算/163 句 - 全部内化批次 1 教训(教学承诺兑现/双轨看门狗/档位措辞真实/结算死窗/键盘变体标注)
528 lines
45 KiB
Markdown
528 lines
45 KiB
Markdown
# 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](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 草案(数据单源:点单句→茶参数→判定→方向→结局)
|
||
|
||
```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](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. 存档设计(跨晚进度)
|
||
|
||
```json
|
||
{
|
||
"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 自动推进无真空 ✓ |
|