Files
SoundGame/docs/design/12-skip-and-longpress-ux.md
T

94 lines
8.0 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.
# 12 · 跳过旁白 + 长按加速 · 全局 UX 规范(含男女声边界核查)
> **给开发的实现要点摘要**
> 1. 单击跳过当前句:§1 逐游戏裁定表——核心规则是"**voice 播放中单击=跳过本句;无 voice 时单击=原语义**",语音链衔接统一"跳下一句"(不是跳到节点末)。
> 2. 长按加速(引擎临时 1.7× voice 语速):§2 豁免表——rhythm 演奏阶段全局豁免,其余游戏默认允许。引擎层拦截 longpress,游戏不收此手势。
> 3. 首局提示时机:§3——不进语音资产,教学自然涵盖 + 大厅 footer 文案。
> 4. §4 男女声边界核查结论:storyline/rpg 实际行为**符合**"只有旁白跟随设置、角色音固定",无需修复;两处命名/计数勘误。
---
## 1. 单击跳过当前句
### 1.1 总则
- **语境判定**:`voice` 层有音频在播时,单击 = 跳过当前句(`stopVoice()` 截断当前句,链播自然进下一句——引擎语义"被打断不触发 onComplete",因此**实现上不是 stopVoice 而是"截断当前句但保住链"**:需引擎或游戏层支持 `skipVoice()`(截断当前句并触发 onComplete 续链)。若引擎暂无此 API,游戏层用等价实现:手动推进链。以引擎最终提供的 API 为准)。
- **无 voice 时单击 = 各游戏原语义**(检查/确认/继续),两态有明确的听觉区分(有语音在播 vs 没有),不混淆。
- **跳到节点末 vs 跳下一句**:统一**跳下一句**。跳到节点末会让玩家误过后续信息且实现要感知"节点"边界;"逐句跳"心智最简单:不想听就多点几下。
- 跳过不给震动(跳过是浏览操作不是确认;双击=重听的对偶操作,保持安静)。
### 1.2 逐游戏裁定表
| 游戏 | 阶段 | 单击=跳过本句? | 说明 |
|---|---|---|---|
| storyline | 剧情对白 | ✅ 可跳 | 节点最后一句被跳 = 进下一节点(现有"单击继续"语义自然延伸) |
| storyline | 抉择提示(prompt) | ❌ 不可跳 | 左右滑抉择前的选项说明必须听完(盲玩公平性) |
| escape | 引导 G0-G7 | ❌ 不可跳(下滑=跳整个引导,已有) | 引导句即操作指令,跳句会破坏步骤机 |
| escape | PLAY 检查描述/卡关提示/背包 | ✅ 可跳 | 熟练玩家快速刷检查 |
| escape | 关键获得(found_key/unlock_cabinet/fix_box/escape) | ❌ 不可跳 | 谜题链进展的叙事回报,总长 <10s |
| simon | 教学 T0-T7 | ❌ 不可跳(下滑=跳教学,已有) | 同 escape 引导 |
| simon | 轮次播报 round_*、成绩播报 | ✅ 可跳 | 高轮次玩家最需要 |
| simon | input 阶段 | — 无语音 | 无冲突 |
| rhythm | intro/tut/结算/选曲 | ✅ 可跳 | 演奏阶段(main)无语音,无冲突 |
| rhythm | mid_song | ❌ 不可跳(仅 2s,不值得跳) | 演奏中,手势是演奏输入 |
| space | 演练 D0-D5 | ❌ 不可跳(下滑=跳演练,已有) | 教学即玩法 |
| space | feat_boost/feat_shield 引入句 | ✅ 可跳 | 二周目熟练玩家 |
| space | 归因/保护期/结算播报 | ✅ 可跳 | |
| rpg | 场景 desc、NPC 对白、事件句 | ✅ 可跳 | 刷图玩家核心诉求 |
| rpg | 战斗指令名 cmd_*、教学战 tut_b* | ❌ 不可跳 | 指令名 <1s 且正在选指令,跳过会打乱选择节奏;教学句同引导逻辑 |
| rpg | 状态播报链(st_*) | ✅ 可跳 | 逐句跳过即"快进状态查询" |
### 1.3 与"单击 300ms 延迟"的相容性
跳过是非即时操作,300ms 延迟无影响。注意双击=重听与单击=跳过的对偶关系:引擎的双击窗口保证两者不误判(现有机制天然支持)。
## 2. 长按加速(引擎:按住 = voice 层临时 1.7×)
**核查注记**:本规范按用户声明的既定事实("引擎已实现长按=临时 1.7 倍速")撰写;当前 `web/engine/gesture.js` 输出仍为 6 手势、未见 longpress 实现——若引擎接口与本节假设不同,**以引擎实际 API 为准**,游戏侧豁免规则不变。
### 2.1 总则
- 长按由**引擎层拦截**:按住 ≥400ms 未位移 → 当前 voice 句 playbackRate 临时 1.7(松手或句终恢复 settings.speed),**不产生手势回调**(游戏永远收不到 longpress)。BGM/sfx 不受影响。
- 与设置语速的关系:长按倍率 = max(1.7, 当前 settings.speed) 之上的"再快一档"语义——settings.speed=1.7 时长按无效果(已是特快)。
- 加速中的 onComplete 时序自然提前(句长缩短),语音链不断。
### 2.2 豁免表
| 游戏 | 豁免 | 理由 |
|---|---|---|
| rhythm | **main(演奏)+ tut(教学跟打)阶段全局豁免**(游戏向引擎注册关闭 rate boost) | 演奏中手指可能长按屏幕边缘蓄力;且 mid_song 加速会破坏"语音提示与节拍网格对齐"的幻觉。教学跟打同理 |
| rhythm | select/end/菜单正常允许 | 结算播报快进是刚需 |
| simon | playback(序列播放)阶段豁免 | 序列是记忆对象,虽然 tone 是 sfx 不受 rate 影响,但该阶段无 voice,豁免无成本;input/announce/结算允许 |
| space | playing 阶段豁免 | 对局中无长语音(归因句 2-3s),豁免避免长按与连续滑动的手势边界模糊;演练/结算允许 |
| escape / storyline / rpg | 不豁免(全局允许) | 叙事类游戏正是长按加速的主战场 |
| RPG 战斗 | 允许但有边界:敌方前摇是 **sfx**(tel_*)不受 rate 影响,格挡窗口时长不变——加速 voice 不影响战斗判定,安全 | 裁定:允许 |
豁免实现:游戏在阶段切换时调引擎开关(如 `audio.setRateBoostEnabled(false)`,以引擎实际 API 为准);默认开启。
## 3. 首局提示时机(两个功能的发现性)
原则:**不新增语音资产、不打断首局沉浸**。
1. **大厅 footer 文案**(可视化,零成本):footer 已有"单击判定有约 300ms 延迟"一行,追加一行:"播放旁白时:单击=跳过本句,按住=加速播放"。
2. **各游戏教学内自然涵盖**:
- 有交互教学的游戏(simon/space/rhythm/rpg/escape)教学本身已教六手势;跳过/长按是**增强功能而非必需操作**,不教——玩家从大厅文案或摸索中发现即可(发现成本低:单击本来就常用)。
- storyline(无教学)在首个抉择点 prompt 播完后追加一次现有系统提示?——**不加**。storyline 的"单击继续"已是事实上的跳过来由,长按从大厅文案发现。
3. 若后续数据显示玩家长语音中途退出率高,再考虑在第二局长语音加一次性提示句(届时补录 `sys_skip_hint`,本规范预留 id)。
## 4. 附:男女声设置边界核查(用户反馈"可选男女声只是旁白,不是游戏内容")
核查方法:读 `web/storyline/game.js`、`web/rpg/game.js` 实际播放路径 + 资产目录结构 + `tools/gen_voice_dual.py` 台词表归属。
### 结论:符合规范,无需修复
| 检查项 | storyline | rpg |
|---|---|---|
| 旁白/系统音在 `voice/<gender>/` 双目录 | ✅ 36 id 双性别 | ✅ 旁白 id 双性别 |
| 角色/NPC 音平铺 `voice/`(固定音色,引擎平铺回退命中) | ✅ n02_linwan(Serena)、n07_dog(Dylan)、e1_child/n03_msg/n05_bcast(Vivian) 均只存在于平铺 | ✅ npc_* 14 id 只存在于平铺,female/male 目录均无 npc_ 文件 |
| 角色音被错误切性别的路径 | **未发现** | **未发现** |
### 两处勘误(非 bug)
1. **storyline `n11_child` 命名误导**:该 id 在两个性别目录都存在,初看像角色"小满"被切性别——实际它是**旁白句**(`gen_voice_dual.py:95`,speaker 组 `_SL_NARR`,文本是旁白叙述中嵌入小满的话)。行为正确,但文件名易误读;**维持不改**(改 id 要动代码+资产两端,无实际收益),此处留档说明。
2. **RPG NPC 台词计数勘误**:05-rpg-ch1-voice-ids.md 表头写"NPC 16 句",实际表内 14 id(村长 4 + 猎人 4 + 头目 3 + 寨主 3)。以 14 为准,音频资产已按 14 落盘,文档表头笔误不另改文件,记于此。