Files
SoundGame/docs/design/05-rpg-addendum.md
T
SoundGame Dev cc0f8c008d HTML5 重写:6 款游戏 + 用户系统 + 全局设置 + 5 轮迭代重构
- 新增 web/ 纯音频 HTML5 平台:共享引擎(手势/WebAudio 三层/设置/震动)、
  Node 零依赖服务器(静态 + 注册登录 + 进度存档 API)
- 游戏:剑与声(RPG 新作)、声命线、暗室(重设计)、音序回响(重设计)、
  节拍行者(跟随领奏重构)、盲航(同向闪避重构);声东击西删除
- 全局功能:男声/女声双套 TTS 资产、三档语速、BGM 音量三档、
  震动反馈语言(10 种震型)、服务器进度同步
- 资产:899 ogg + 899 m4a(Qwen3-TTS 双性别语音、Stable Audio 3 音效、
  Mureka BGM 4+3 首),终检零缺失
- 文档:docs/design/ 13 篇设计审查文档、docs/audio/ 资产管线、
  web/server/README.md API 文档
2026-08-29 21:55:44 +08:00

107 lines
8.6 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.
# 05c · 《剑与声》增补规范(rpg addendum,R3 补漏)
> 本文件补 [05-rpg-chapter1.md](05-rpg-chapter1.md) 的施工遗漏:①战斗事件 × 音效 × 震动配合总表;②Boss 无声前摇的震动协议;③音频层叠规则修正(amb 与 BGM 冲突);④若干流程细节。与主文档冲突处以本文件为准。
---
## 1. 战斗事件 × 音效 × 震动配合总表(施工对照表)
震动一律用 `engine/haptics.js` 预定义名;手势识别震动(swipe/confirm)由 gesture.js 内置,下表不再重复列出。
| 战斗事件 | sfx | 震动 | 语音 |
|---|---|---|---|
| 遭遇开始 | `tel_<enemy>`(登场即第一次前摇不播,登场用 `enemy_die` 无——登场无专属 sfx,直接语音) | — | `btl_start_<enemy>` |
| 指令切换(左右滑) | — | (内置 swipe) | 指令名 `cmd_*` |
| 攻击命中 | `atk_swing` + `atk_hit` | — | —(敌方半血/死亡见下) |
| 技能·破空斩 | `skill_slash` | — | mp 不足时 `btl_nomp` |
| 防御指令 | — | — | —(标记生效,无播报,下回合减伤自明) |
| 使用金疮药 | `potion` | `pickup` | 无药时 `btl_noitem` |
| **敌方前摇(有声敌人)** | `tel_<enemy>`(1.0s) | 窗口开启同时 `beat` 一次(提示"现在可以格挡",不干扰听觉辨音) | — |
| **格挡成功** | `parry` | `confirm`(即时,双击无延迟) | — |
| 格挡窗口内做错手势 | — | `error` | — |
| 受击(未格挡) | `hurt` | `hit` | 血量档位降档时 `st_hp_mid` / `st_hp_low`(降档才播,不每击都播) |
| 敌方半血 | — | — | `npc_*_half`(有半血句的敌人)/ Boss 见 §4 |
| 击杀 | `enemy_die` | `success` | `btl_enemy_die` |
| 战斗胜利 | — | — | `btl_win` + `btl_loot_*`(分档) |
| 升级 | `levelup` | `success` | `btl_levelup` |
| 逃跑成功 | `flee` | — | `btl_flee` |
| 逃跑失败(Boss/剧情战) | — | `error` | `btl_noflee` |
| 战败 | `hurt`(最后一击) | `hit` + 300ms 后 `error` | `btl_lose` → `btl_lose_hint` |
要点:**前摇窗口的 `beat` 轻震是"格挡窗口已开"的通道标识**——有声敌人靠前摇音辨招式、靠 beat 确认窗口时机,两者分工。iOS 无震动时靠前摇音本身即可(前摇音起始即窗口起始),无信息损失。
## 2. Boss 无声前摇 · 震动协议(影卫 / 白无瞳三阶段)
无声敌人是第三章核心机制(耳朵最强的剑客遇到没有声音的敌人),触觉成为唯一提示通道。协议:
| 时刻 | 震动 | 说明 |
|---|---|---|
| 窗口开启(t=0) | `danger` [25,40,25,40,25] | 代替前摇音——**无声前摇的"声音"就是这段震型** |
| 窗口中点(t=0.5s) | `heartbeat` [40,100,40] | 催促:窗口过半,不出手就来不及了 |
| 格挡成功 | `confirm` | 同有声敌人 |
| 窗口关闭未格挡 | `hit` | 受击 |
规则:
1. **只有无声敌人**用这套协议;有声敌人前摇窗口只震一次 `beat`(§1 表),绝不用 danger——danger 语义专属于"无声威胁",玩家一听(一感)就知道是影卫/白无瞳。
2. iOS 无震动降级:**静默降级,不回退提示音**(00 §2.5)。无声敌人在 iOS 上不可格挡是已知代价,设计上用数值兜住——影卫 ATK16 对 lv7+ 铁鳞甲玩家 dmg≈10,52+ HP 可吃 5 击,不格挡也能硬打过普通影卫;白无瞳三阶段前由 NPC 台词明示(见 §5),iOS 玩家知情后可用"防御"指令(减伤 50%,不需要时机)作为等效手段。**防御指令因此对 iOS 是必要兜底,不是可选项。**
3. 听风剑(格挡窗口 1.0s→1.3s)对无声敌人同样生效:heartbeat 顺延到 t=0.65s。
4. 无声敌人的 `_resolve` 判定窗口与有声一致(1.0s/1.3s 内双击有效),仅提示通道不同——代码上前摇 = `{ sfx: tel_<enemy> | null, haptic: 'beat' | 'danger+heartbeat' }` 二元组。
## 3. 音频层叠规则修正(amb 与 BGM 冲突)
05-rpg-chapter1.md §7.2 让 `amb_*` 走 bgm 层 loop,与 `bgm/explore` 等同层冲突(引擎 BGM 层同时只有一首)。裁定为:
| 场景/状态 | bgm 层播放 | 说明 |
|---|---|---|
| village | `bgm/village`(音乐) | 安全区给音乐,情绪锚点 |
| 其他探索场景 | `amb_<scene>`(环境音循环,volume 0.6) | **探索期不放音乐**——纯环境音,战斗音乐进来才有对比 |
| 普通战斗 | `bgm/battle` | 进战斗 crossfade 替换 amb;战后 crossfade 回当前场景 amb |
| Boss 战 | `bgm/boss` | 同上 |
| 章结算/剧情(evt_ch1_end 等) | `bgm/ending` | 播完回场景 amb |
资产清单变动:`bgm/explore` **取消**(探索期用 amb,不需要探索音乐),BGM 从 5 首减为 4 首(village/battle/boss/ending);`amb_village` 保留(village 的音乐若停播设置 bgm=0 时用 amb_village 垫底——bgm=0 时 bgm 层整体静默,village 也播 amb_village)。sfx 总数 35 不变。
`bgm=0`(设置关闭音乐)时的行为:village/battle/boss/ending 全部静默,探索场景 amb 照播(amb 属内容环境音不是 BGM——**例外裁定**:amb_* 虽走 bgm 层,但不受 bgm 设置关闭影响;实现上 amb 用 `play(id, {volume})` 时引擎按 bgm 层处理会被设置关停,因此 **amb 改走 sfx 层 loop**——sfx 层即发即弃不支持 loop,需要开发在 game.js 里用 `audio._load` + 手动 BufferSource loop 接 `_sfxBus`(rhythm 现版手动接总线已有先例)。这是本增补对实现的唯一新要求。)
## 4. Boss 阶段转换表现
| Boss | 阶段 | 触发 | 表现 |
|---|---|---|---|
| 黑风寨主 | 二阶段(ATK 10→12) | HP ≤50% | `warning` 震动 + `npc_boss1_2` + 前摇音 `tel_boss1` 从单声双刀变急促(同一 sfx 以 playbackRate 1.2 重播即可,不加资产) |
| 腐沼祭主 | 二阶段 | HP ≤50% | `warning` + 召唤 2 毒蛛(连战队列插入),播专属半血句(R4 补录) |
| 白无瞳 | 三阶段(完全无声) | HP ≤50% / ≤25% | 每阶段 `warning`;三阶段进场播 §5 教学句,此后前摇走 §2 震动协议 |
## 5. 补充台词需求(R4 录不进 ch1 表的,列入 ch2/3 台词表)
| id | 角色 | 台词全文 | 用途 |
|---|---|---|---|
| `npc_boss3_warn` | 旁白 | 他没有声音。闭上眼睛没用,竖起耳朵也没用。这一次,相信你的手。 | 白无瞳三阶段进场(同时向 iOS 玩家暗示:防御指令是兜底) |
| `btl_half_shaman` | 蛊师 | 蛊师半血句(R4 写 ch2 台词表时补全文) | 半血钩子 |
| `btl_half_shadow` | 影卫 | 影卫半血句 | 同上 |
| `menu_hint_escape` | — | (属 escape,见 round2-review §5.1,非本游戏) | — |
规则:ch2/3 台词表沿用 05-rpg-ch1-voice-ids.md 格式,R4 由策划补发;上表是必须包含的最小集。
## 6. 流程细节补遗
1. **上滑状态播报链顺序**(探索态与战斗态共用):`st_lv_*` → `st_hp_*` → `st_gold_*` → `st_weapon_*` → `st_armor_*`,链播可被打断(再次上滑重播,下滑进菜单)。
2. **战斗态上滑**:`st_hp_*` + 敌方血量档位(敌方档位句复用 st_hp_* 文案?——**不复用**,敌人档位用:`foe_hp_high`"敌人气焰正盛。"/`foe_hp_mid`"敌人露出疲态。"/`foe_hp_low`"敌人撑不住了。"——R4 补录 3 句 ×2 性别,列入上表最小集)。
3. **连战转换**(enc_bandits 等):第一只死亡 → `btl_enemy_die` → 不停 BGM → 直接播下一只 `btl_start_<enemy>` + 前摇,玩家 HP/MP 不回、指令重置为攻击。
4. **`stats.playSec` 口径**:累计探索态+战斗态实际时长(菜单/结算暂停不计),存档时累加。
5. **存档 schema 迁移**:R5 内允许丢弃重来(读档 schema≠1 时播 `sys_new_game` 重开,stats 保留)。
6. **菜单豁免确认**:RPG 探索态菜单=左右滑切换+单击确认(00 §5.2 豁免条款,round2-review 裁决②);战斗态下滑=逃跑,不设菜单——与 05-rpg.md §2.2 一致,不变。
## 7. R4/R5 施工就绪核对单
- [x] 场景图 JSON / 遭遇战表 / 战斗状态机(05-rpg-chapter1.md §1-3)
- [x] 全数值表 + 装备节点(05-rpg-chapter1.md §4-5)
- [x] 存档字段 + summary(05-rpg-chapter1.md §6)
- [x] 第一章 120 句台词表(05-rpg-ch1-voice-ids.md)
- [x] 战斗音效/震动配合(本文件 §1)
- [x] 无声前摇协议 + iOS 兜底(本文件 §2)
- [x] 音频层叠规则(本文件 §3,含 amb 走 sfx 层的实现要求)
- [x] BGM 4 首 + sfx 35 个 prompt 草稿(05-rpg-chapter1.md §7 + 本文件 §3 修正)
- [ ] ch2/3 台词表(R4 策划补发,最小集见本文件 §5)
- [ ] ch2/3 场景正文(R5 开发按 ch1 模板扩写)