- 新增 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 文档
107 lines
8.6 KiB
Markdown
107 lines
8.6 KiB
Markdown
# 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 模板扩写)
|