Files
SoundGame/docs/design/00-global-ux.md
T
2026-10-01 23:26:47 +08:00

215 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 00 · 全局交互规范(Global UX)
> **给开发者的实现要点摘要**
> 1. **交互权威**是 [26-audio-interaction-playbook.md](26-audio-interaction-playbook.md)。本文是它在本项目的施工口径。两份冲突时以 26 号为准。`research/02-methodology` 与旧豁免表一律让路。
> 2. 设置项(voice / speed / bgm / guide / input)只在大厅页改,存 `localStorage["soundgame.settings"]`,游戏内只读。
> 3. **每次操作必须有声音回执**(ok / invalid / busy,§2)。震动是补充,不是主通道。电脑和 iPhone 没有震动时,回执声仍要响。
> 4. 旁白整句预生成,禁止数字/碎片拼接。指令句 ≤12 字;叙事句 ≤25 字。
> 5. **新手期只开放三个手势**:单击、左右滑、上滑。双击默认不存在。四向滑动是核心玩法时,帮助统一换到长按(全项目同一条,不许各游戏各换)。
> 6. 用户系统:大厅登录,进度走 REST API,本地 localStorage 离线缓存。
---
## 0. 文档地位与废止清单
本文取代自己 R1~R7 的手势宪法、向导接线、以及「操作反馈一律只靠震动」的旧裁定。下列旧规则**废止**:
| 废止 | 改为 |
|---|---|
| 双击 = 重听(全局默认) | 新手期不识别双击;阶段 3 以后才解锁,且不得绑重播整段、重开 |
| 单击等 300ms 双击窗 | 新手期 `doubleTapWindow: 0`,松手即单击 |
| 无效操作只震不说 | 声音回执 `invalid` + 每个「状态×手势」解释一次 |
| iOS 无震动则无反馈 | 回执声永远出声;震动可有可无 |
| 各游戏豁免表各换帮助入口 | 四向滑动是玩法 → 帮助一律长按 |
| 菜单:单击循环、双击确认 | 菜单:左右滑切换、单击确认(与探索同构) |
| 看门狗原样重播说明书 | 三档提示:完整句 → 短句 → 提示音 |
| 向导语音 `queue:true` 永不打断 | 玩家一动游戏就停(关键句除外,≤3s) |
| 句间恢复 BGM duck | 整条语音链期间保持压低 |
仍有效、未改:设置系统、旁白整句管线、用户进度 API、键盘平行通道的键位表(语义随新手模式变)。
---
## 1. 设置系统(已实现:engine/settings.js + 大厅设置面板)
### 1.1 设置项语义
| 设置项 | 取值 | 精确语义 |
|---|---|---|
| `voice` | `"female"`(默认)/ `"male"` | 切换 voice 资产目录。`play('voice/xxx')` 解析为 `audio/voice/<gender>/xxx.{ogg,m4a,mp3,wav}`,找不到回退平铺 `audio/voice/xxx.*`。两性别 id 集合必须一致。角色/NPC 音走平铺,不切性别。 |
| `speed` | `1.0` / `1.35` / `1.7` / `2.2` | 只作用于 voice 层 playbackRate,从下一句生效。TTS 按 1.0 生成。`2.2` 为视障档。 |
| `bgm` | `1.0` / `0.3` / `0` | BGM 层增益。`0` = 不加载不播放任何 `bgm/`。内容环境音在 sfx 层,不受此项误杀。 |
| `guide` | `"full"`(默认)/ `"standard"` / `"off"` | 向导等级:`full`=等待声+三档提示语音+回执;`standard`=等待声+回执+提示音,无向导语音;`off`=回执仍在,不挂迷茫/看门狗定时器。 |
| `input` | `"auto"` / `"touch"` / `"key"` | 只影响提示文案,不关闭任何输入通道。三通道永远并行。 |
存储 key = `soundgame.settings`。非法键/值逐项丢弃。`speed`/`bgm` 存数值。
### 1.2 修改入口
只在大厅。游戏内菜单可播报当前值,并说「请回到大厅修改」。大厅变更后应播一句样例(voice+speed),未做则补,非阻塞。
### 1.3 服务器同步
设置作为特殊游戏键 `_settings` 走进度接口。登录后服务器覆盖本地。离线纯 localStorage。
---
## 2. 输入回执与震动
### 2.1 回执是主通道(26 号原则 4)
三种合成系统音,全项目统一,接引擎 master,不走 sfx 内容资产:
| 回执 | 何时 | 听感(起步参数) |
|---|---|---|
| `ok` | 操作被接受并生效 | 三角波 1600Hz,35ms,增益 0.08,「嗒」 |
| `invalid` | 收到了,但现在用不上 | 正弦 260→200Hz,120ms,增益 0.10,低沉「咚」 |
| `busy` | 游戏在说关键句或正在处理 | 正弦 520Hz,40ms,增益 0.04,很轻「嗯」 |
规则:
- 100ms 内出声;回执 ≤0.2s。
- 游戏已为这次操作播了明显内容音(脚步、开门),可省 `ok`(记 `silent-ok`)。`invalid` 与 `busy` 永远播。
- 系统音一律合成;内容音一律录音。两类永不混用。
- 单击执行「继续/跳过」后 **400ms 内**再来的单击只给 `busy`,不连跳、不误进下一段。
### 2.2 震动是补充(已实现:engine/haptics.js)
十种震型名不变:`confirm/error/success/warning/swipe/heartbeat/pickup/hit/beat/danger`。语义仍按语义选用,不按游戏选用。
- gesture.js 内置:滑动→`swipe`,tap/doubletap→`confirm`。游戏层不要对「手势被识别」再震一次。
- 单次 ≤500ms;danger 循环间隔 ≥400ms;200ms 窗口去抖。
- 长对白、纯聆听记音阶段不震(节拍锚点 `beat` 除外)。
- iOS 无震动:no-op。**不再把「绝不回退提示音」理解成「无任何声音反馈」**——回执声仍然要响。旧教学口径「iPhone 用户听结果声」改为「听回执声和结果声」。
---
## 3. 旁白质量与台词写作
整句生成、分段数字、同游戏同 speaker+instruct、管线 `tools/gen_voice_dual.py`、双格式 ogg+m4a:沿用原规范。
**26 号增补(写作强制)**:
| 用途 | 规则 | 例子 |
|---|---|---|
| 指令 | 「动作 + 结果」,≤12 字 | 「向左滑,开门。」 |
| 短句档 | ≤6 字,只留动作 | 「向左滑。」 |
| 叙事 | 单句 ≤25 字 | |
| 我在哪 | 位置。目标。一个动作。≤20 字 | 「厨房。找钥匙。左右滑。」 |
| 归因 | 原因 + 下次怎么做;必须真实 | 「慢了。听到就滑。」 |
| 肯定 | ≤4 字 | 「对。」 |
| 解释无效 | 现在怎样。能做什么。每个状态×手势一次 | 「还在讲故事。点一下可以跳过。」 |
每句台词标类别:`critical` / `content` / `hint` / `feedback`(26 §4.6)。`critical` ≤3s。`hint`/`feedback` 空闲才播,过期丢弃。
禁止:「如果」「可以尝试」;一句里教两个手势;游戏主动原样重复。
---
## 4. 用户系统(已实现)
形态、API、`summary` 必填、`_settings` 保留键:不变。
**26 号增补**:退出自动存;重进 5 秒内播一句局面复述(位置 + 目标 + 现在做什么),然后交出话轮。复述句 id 随等待点写入进度。
---
## 5. 手势宪法(26 号原则 6)
### 5.1 新手期三手势(全部游戏共用)
| 手势 | 唯一含义 | 游戏在说时 | 等你操作时 |
|---|---|---|---|
| 单击 | 继续 / 确定 / 听一下 | 只跳过当前这句(`skipVoice`),给 `ok` | 执行继续或确定 |
| 左滑 / 右滑 | 选择 / 移动 | 打断并执行 | 执行 |
| 上滑 | 我在哪、我该干嘛(一句) | 打断后回答 | 回答 |
| 手势 | 新手期 |
|---|---|
| 双击 | **不存在**。`doubleTapWindow: 0`。键盘回车按单击处理 |
| 下滑 | 未解锁:`invalid` + 首次解释 |
| 长按 | 未占用帮助时:旁白加速(12 号)。四向滑动是玩法时:长按=帮助,关闭加速 |
滑动、上滑:打断并执行。单击:只打断(跳句),不顺带执行「继续下一段」。
### 5.2 解锁阶梯(跨局记住,存进度或 `_settings`)
| 阶段 | 条件 | 解锁 |
|---|---|---|
| 0 | 首次进入 | 单击、左右滑 |
| 1 | 第一个小目标 | 上滑(或长按帮助,若滑动是玩法) |
| 2 | 第一局结束 | 下滑=菜单 |
| 3 | 累计 3 局 | 双击=重听**当前等待点完整句**(加「再说一遍:」)。禁止绑整段重播、重开、连跳 |
| 4 | 大厅一键或专属教学 | 游戏专属高级手势 |
大厅提供「全部解锁」给老玩家。
### 5.3 四向滑动是玩法:帮助换长按
适用:escape、space、rhythm/drummer、dungeon、hunt,以及任何四向滑=移动/闪避/演奏的游戏。
- 帮助 = 长按。所有这类游戏同一条,不许再各换双击/上滑。
- 菜单仍到阶段 2 才开放下滑;对局中下滑若与玩法冲突,对局中不开菜单,结算后开。
- 新手期双击仍按单击处理。
**六手势都是音色/答题(simon)**:帮助也换长按;音色按实力渐进开放,一次只学一样。
### 5.4 模态菜单(阶段 2 以后)
**下滑呼出 → 左右滑切换(每项报名)→ 单击确认 → 上滑或长按=重听菜单说明 →「返回游戏」或再下滑关闭。**
废止「单击循环 + 双击确认」。原因:新手期没有双击;单击的全局含义是确定,菜单里不应改成切换。
标准选项:重新开始(破坏性,二次确认)/ 保存并回大厅 / 返回游戏。打开时暂停计时玩法。
RPG 探索菜单与探索同构:左右滑 + 单击,符合本条。战斗态下滑=逃跑,不设菜单。
选曲等非模态选项界面:左右滑 + 单击,不变。
结算:单击=再来一局;菜单已解锁则下滑=菜单。
### 5.5 通则
- 矩阵无空格:每个「可感知状态 × 已解锁手势」都必须有声音(回执或内容音)。见各游戏设计单。
- 连点/乱滑不绑定破坏性操作。
- 引导可跳过:已完成过引导的玩家,开场用一句问「点一下开始」;重听引导放到帮助手势,不占用下滑(新手期下滑未解锁)。
- `immediateTap` 仅 rhythm/drummer 演奏期。新手期其他游戏用 `doubleTapWindow: 0` 获得即时单击,不要开 immediateTap。
- 教学:第一句话就动手;一次只教一个;做对立刻肯定(≤4 字)并进入下一步,禁止成功后再灌补救。
### 5.6 键盘平行通道
键位表不变(方向键/WASD=滑,空格=单击,回车=双击,按住空格=长按)。
新手期差异:
- `doubleTapWindow: 0` 时触屏与空格均立即单击。
- 回车仍发 `doubletap`:游戏层在新手期把它当成 `tap`。
- 提示文案随 `settings.input`:触屏说「点一下」,键盘说「按空格」。
守卫、遮罩解锁、测试约定沿用原实现。
---
## 6. 发言权、等待声、向导
实现骨架见 26 号 §4.1~§4.6;接线裁定见 [14-guide-layer.md](14-guide-layer.md)。
| Floor 状态 | 听感 | 玩家操作 |
|---|---|---|
| `SPEAKING` | 语音;BGM 整链压低;句间不起等待声 | 可打断句:立刻停,按 §5.1 处理;关键句:`busy` |
| `YOUR_TURN` | 交接提示音 `turn` → 400ms 后等待声,直到操作 | 等待声 80ms 淡出,交给游戏 |
| `BUSY` | 只有内容演出,无等待声 | `busy` |
| `ACTION` | 玩法声本身就是状态(节奏、闪避、探索环境音常驻) | 直接交给游戏 |
等待声:合成、轻、全项目一套(26 §4.1 起步参数)。剧情类可用很轻的环境循环替代,但必须全游戏统一。
迷茫:从乱点/连无效/反复重听识别,三级接管(短提示 → 只留一个手势 → 自动演示)。静默看门狗只负责「不动」:动作类 5~8s,剧情类 15~20s,最多两级后安静,只留等待声。
状态签名 earcon(menu/explore/battle/choice/settle/danger + turn/nudge)保留。新手期只教玩家能感知的 ≤3 种,第一次出现配一句解释。
---
## 7. 横切验收(每款游戏开工前)
设计单必须交齐 26 号附录 C:一句话核心动作、≤3 个可感知状态、新手手势与解锁、状态×手势矩阵、等待点、首 3 分钟逐秒脚本、失败表、台词类别、断点复述句。
合格指标见 26 §6.4。出现 26 §7 任一反模式,设计不通过。