1Giới thiệu & bản đồ tài liệu
Mục đích: hợp đồng âm thanh đủ để 1 agent/nhà làm âm thanh tìm nguồn, sản xuất, mix và nối vào Unity MỌI sound/nhạc của Bladewake 1.0 mà không cần hỏi lại. Phụ thuộc: GDD/Full/docs/00-Design-Bible.md + GDD/Full/data/_bible.json (canon: INV-02 tell, §5 hero, §7 biome/quái, §10.3 ngân sách, §11 ID) · demo GDD/07-Game-Feel.md §7 · skill .claude/skills/create-sfx/ (synth + Freesound + QA) · MCP bf-sfx. Được dùng bởi: agent audio (nguồn/synth/mix), dev code Audio* (mixer, hook, nhạc thích nghi), VFX/anim (frame kích SFX), QA (test tai + LUFS), loc (phụ đề tell, text bark), sản xuất (thuê ngoài nhạc 4 PM + SFX 4 PM).
Mục lục chi tiết (## và ###)
- 0. Phạm vi & thứ bậc
- 1. Trụ cột âm thanh (AP1–AP6)
- 2. Bản sắc âm (sonic identity)
- 2.1 Tell — 3 lớp INV-02 (khoá, mọi hero/quái/boss/hazard/Khăn Tang/mutator/Tro Nhớ)
- 2.2 Bảng timbre theo phe
- 2.3 Bảng timbre 12 hero (chất liệu chủ không trùng; AP5)
- 2.4 Bảng timbre kẻ địch theo biome
- 3. Âm nhạc
- 3.1 Hướng chung
- 3.2 Bảng hướng nhạc theo khu (bpm/meter/key/nhạc cụ khoá)
- 3.3 Leitmotif (nốt chuẩn; hoà âm/nhạc cụ tự do trong luật §3.1)
- 3.4 Hệ nhạc thích nghi (class MusicDirector)
- 3.5 Đồng bộ H12 Ambrin (120 BPM)
- 3.6 Mẫu cue nhạc (FINAL) — mỗi cue 1 khối trong GDD/Full/data/audio_music.json (agent audio tạo; khoá field)
- 3.7 Danh sách cue 1.0 (18 bản canon + 4 bộ stem H12) — 1 dòng/cue
- 4. SFX — đặt tên, mẫu spec, khuôn sự kiện
- 4.1 Đặt tên (canon §11)
- 4.2 Mẫu spec SFX (FINAL) — 1 hàng/sự kiện trong GDD/Full/data/audio_sfx.csv (agent audio tạo; khoá cột)
- 4.3 Mục tiêu độ to theo loại (PC; momentary-max, trước bus fader)
- 4.4 Khuôn sự kiện theo chủ (sinh audio_sfx.csv từ khuôn; số khớp canon §10.3)
- 5. Mixer Unity, ưu tiên, voice, suy giảm, ducking, độ to
- 5.1 Cây bus (Assets/_Project/Audio/Mixer/BW_Main.mixer, 1 AudioMixer; fader mặc định)
- 5.2 Snapshot (chuyển 0.15 s trừ khi ghi khác)
- 5.3 Ưu tiên (Unity priority, 0 = cao) & giới hạn voice (Project Settings › Audio: Real Voices 64, Virtual 256, DSP buffer Best latency = 256 mẫu)
- 5.4 Ngân sách tell đồng thời (từ token INV-08)
- 5.5 Suy giảm khoảng cách (góc 3/4, không 3D)
- 5.6 Ducking / sidechain
- 5.7 Đồng hồ & slow-mo
- 5.8 Độ to chương trình & tuỳ chọn người chơi
- 6. Luật bầy (horde) — gộp, lớp, ngẫu nhiên (class HordeAudio, chạy cuối frame sau Combat)
- 6.1 Gộp cú trúng của hero (mỗi frame, mỗi nguồn sát thương)
- 6.2 Kill-crunch (cửa sổ trượt 100 ms)
- 6.3 Âm quái thường trong bầy
- 6.4 Ngẫu nhiên & chống lặp
- 6.5 Kiểm hiệu năng âm (Lát Chịu Tải MS01b)
- 7. UI & hub
- 7.1 UI (37 sự kiện SFX_UI_ = 29 lõi + 8 thêm 2026-11-07; bus UI; clock UI; chất liệu giấy/gỗ/đồng nhỏ, AUD-01; spec đủ field ở data/av/UI.json)
- 7.2 Hub (29 sự kiện = 13 lõi SFX_HUB_ + 16 SFX_ENV_HUB_ thêm 2026-11-07; bus World/Ambience; spec đủ field ở data/av/ENV_HUB.json)
- 8. Thư viện SHARED (57 mục SFX_SHARED_<slug>; R = nguồn dùng lại cho sự kiện hero/quái, S = sự kiện hệ thống tính trong nhóm Khác §4.4)
- 9. Bark & giọng (VO) — chính sách
- 10. Ambience & hazard theo biome
- 10.1 Bed ambience (1 loop stereo ≥ 60 s/biome, SFX_<Bn>_amb_bed, bus Ambience, −30 LUFS-I) + spot ngẫu nhiên (sự kiện amb_spot riêng theo data/av/ENV_.json, AmbienceSpot chọn 1 spot / 6–14 s, pan ngẫu nhiên ±0.6)
- 10.2 Hazard (46 sự kiện = 14 lõi + 32 thêm 2026-11-07 theo data/av/ENV_.json; theo INV-18: dùng đúng Y/P/N, nhịp ≥ 1.0 s, trúng cả quái)
- 10.3 Đạo cụ, mục tiêu, phòng & cảnh theo biome (64 sự kiện SFX_ENV_<Bn>_, thêm 2026-11-07; spec đủ field ở data/av/ENV_<Bn>.json; bus World trừ ghi khác; hook theo §12.2)
- 11. Nguồn, định dạng, nhập Unity
- 11.1 Thang nguồn SFX (đúng thứ tự, theo skill create-sfx)
- 11.2 Định dạng & mastering
- 11.3 Bộ nhớ & dung lượng (Steam Deck là trần)
- 12. Nối vào code (hook sự kiện → id)
- 12.1 Kiến trúc runtime (thay Systems/Sfx.cs demo)
- 12.2 Bảng hook (EventName → id; {H} = hero đang chơi, {E} = enemy id, {B} = biome, {BOSS} = id mini/boss)
- 13. Ngân sách âm thanh theo mốc (đếm sự kiện SFX theo §4.4; nhạc theo §3.7)
- 14. Kiểm nghiệm (AT = acceptance test; chạy trước mỗi MS)
- Quy tắc cho dev/AI
- Quyết định đã chốt
20. Phạm vi & thứ bậc
- Canon thắng doc này: id, số lượng (SFX ~880 sự kiện = 336 + 195 + 104 + 245, DEC-2026-11-07-17, chi tiết §4.4/§13; nhạc 18 bản + 4 bộ stem 120 BPM H12), tempo/nhạc cụ biome trong
_bible.json biomes[].theme. - Doc này sở hữu: luật timbre, cấu trúc nhạc thích nghi, mixer, giới hạn voice, LUFS, mẫu spec, thư viện
SFX_SHARED_*, hook sự kiện → id, quy trình nguồn. - Không có trong 1.0 (canon §13): voice có nghĩa (lời thoại đọc), video cutscene, nhịp theo nhạc ngoài bộ stem H12, middleware âm thanh ngoài Unity AudioMixer.
- Nền tảng mix: PC Steam (loa ngoài + tai nghe) → Steam Deck (loa nhỏ, tai nghe) cùng 1 bản mix + preset "Loa nhỏ" (§5.8). Port console sau dùng nguyên bus/snapshot.
31. Trụ cột âm thanh (AP1–AP6)
| ID | Trụ cột | Luật cứng | KPI kiểm |
|---|---|---|---|
| AP1 | Tell nghe là biết | "tinh" = vàng = ĐÁP; "ù" = tím = Lướt; vùng đọng N không tiếng tell. 2 âm này độc quyền dải phổ của nó (§2.1) | playtest nhắm mắt: ≥ 90% gọi đúng Y/P sau 10 phút; 0 âm khác bị gọi nhầm là tell |
| AP2 | Bầy là một khối | 250 quái nghe như 1 cơn sóng, không như 250 nguồn: gộp trúng/chết (§6), không lặp đều | 0 méo/clipping ở 250 quái + Ult; p95 voice thật ≤ 56/64 |
| AP3 | Hero luôn nổi | hero > địch 6 dB cùng loại; ĐÁP thành công = âm to nhất mix (demo canon) | ĐÁP thắng mọi âm khác về LUFS ngắn hạn tại khung đó |
| AP4 | Đã tay | mỗi cú trúng có SFX trong ≤ 1 frame (INV-10); onset ≤ 12 ms; trễ input→âm ≤ 40 ms | đo thu loopback: input→onset âm p95 ≤ 40 ms |
| AP5 | Mỗi Kẻ Thức một tiếng | 12 bảng timbre không trùng chất liệu chủ (§2.3); nghe 3 s nhận ra hero | ≥ 80% nhận ra hero chỉ qua âm (khớp P6 canon) |
| AP6 | Tang mà ấm | nhạc u buồn có hơi ấm, hài đen ở NPC; cảm hứng tang lễ Á Đông thành fantasy gốc, không tái hiện nghi lễ/bài kinh có thật | review tông: 0 lời kinh thật, 0 giai điệu dân ca có thật trích nguyên |
42. Bản sắc âm (sonic identity)
2.1 Tell — 3 lớp INV-02 (khoá, mọi hero/quái/boss/hazard/Khăn Tang/mutator/Tro Nhớ)
| Lớp | Id âm | Khi phát | Timbre (bắt buộc) | Thời lượng | LUFS mmax | Ghi chú |
|---|---|---|---|---|---|---|
| Y glint 1 | EnemyWindupStart tellClass=Y (frame đầu windup = glint 1); lịch PlayS… SFX_SHARED_tell_y_glint1 | frame đầu windup (glint 1) | ping kim loại nhỏ, cùng họ "tinh" nhưng nhẹ: partial 2.6/4.1/6.3 kHz, attack 2 ms, decay 90 ms | 120 ms | −22 | báo "sắp có đòn vàng" |
| Y "tinh" | EnemyWindupStart tellClass=Y → lịch PlayScheduled đỉnh transient đúng… SFX_SHARED_tell_y_tinh | đỉnh transient ĐÚNG 0.12 s trước frame va chạm (cùng glint 2) | sáng, kim loại, gõ: chuông tay nhỏ đồng-thiếc bị gõ, fundamental 2.8 kHz, partial bất hoà 1.0/1.47/2.09/2.76, attack ≤ 2 ms, decay 180 ms, không reverb dài (≤ 120 ms room) | 220 ms | −14 | âm tell to nhất; mỗi nhịp đòn Y×n = 1 "tinh" riêng, nhịp k cao hơn nhịp đầu +1 bán cung × (k−1), tối đa +3 |
| P "ù" | EnemyWindupStart tellClass=P (cả hazard/Khăn Tang/mutator P); chọn bả… SFX_SHARED_tell_p_swell | từ frame đầu windup tím tới ĐÚNG frame va chạm, cắt cứng tại va chạm | trầm, ngược, phồng lên: gong/chuông lớn đảo ngược + sub 45 Hz, fundamental 70–110 Hz, cao độ trượt +2 bán cung suốt windup, độ to tăng tuyến tính dB (−30 → −16) | = windup (0.45–1.5 s; co giãn bằng 3 bản 0.45/0.8/1.2 s + vòng sustain) | −16 tại cuối | va chạm tím = EnemyImpact tellClass=P (frame va chạm tím) SFX_SHARED_tell_p_impact (thump trầm 120 ms) |
| N vùng đọng | — | — | KHÔNG âm tell (canon); vùng phát loop môi trường vùng đọng N (hazard/đòn/MRN15 vũng) tồn tại → loop; dừng khi vùng tắt SFX_SHARED_zone_n_loop ≤ −30 LUFS, không onset | — | — | mỗi tick sát thương N không phát âm riêng |
| Nhịp lừa (INV-15) | EnemyFeint (frame bắt đầu nhịp trì ≤ 0.35 s, INV-15) SFX_SHARED_tell_feint | frame bắt đầu nhịp trì (≤ 0.35 s) | gỗ khô "cạch" + hít hơi, KHÔNG kim loại | 150 ms | −20 | "tinh" thật vẫn phát đúng 0.12 s trước va chạm thật |
| Đạn tím (INV-13) | EnemyProjectileFire purple=true → loop tới khi đạn biến mất/bị dội SFX_SHARED_tell_p_proj | loop khi đạn tím bay | ù rung 90 Hz + nhiễu lọc 300 Hz, AM 6 Hz | loop | −22 | ≤ 2 viên/màn → ≤ 2 voice |
Luật sở hữu phổ (tương đương INV-01 cho âm; mã AUD-01..AUD-04):
- AUD-01 Dải "tinh": âm không phải tell vàng KHÔNG được có partial tonal kim loại 2.2–3.6 kHz decay > 60 ms với mức ≥ −12 dB so với đỉnh của chính âm đó. Áp cho: chuông H03, đe H05, xu H09, chũm chọe H12, chuông hazard B1/B4, chuông mục tiêu BELLS, UI. Đồng xu/chũm chọe = nhiễu (noise) hoặc decay ≤ 60 ms → hợp lệ.
- AUD-02 Dải "ù": âm không phải tell tím KHÔNG được là swell đảo ngược/tăng dần có năng lượng chính < 140 Hz dài > 0.25 s. Âm trầm khác phải có transient (thump) hoặc mức ổn định (drone không phồng).
- AUD-03 Tell không bị bóp: bus
EnemyTellmiễn mọi trần đám đông, mọi duck, mọi snapshot bóp (kể cả BS_TRUE P2 "Nuốt Tiếng"); pitch không theo slow-mo (luôn 1.0); không ngẫu nhiên pitch > ±1%. - AUD-04 Chỉ kẻ thật phát tell: ảnh giả MB_B4_2, bóng sàn không thật, hình nhân trang trí → 0 âm tell. Token (INV-08) quyết định ai được windup → số voice tell tối đa = 4 cận chiến + 3 loạt đạn + 5 tím = 12 (§5.4).
- Trợ năng
meta.accessibility: "âm tell theo vị trí" bật → tell pan đầy ±1.0 theo x màn + cao độ "tinh" +2 bán cung khi nguồn ngoài màn; "phụ đề tell" → chữ[tinh ↖]/[ù ↓]ở mép màn theo hướng.
2.2 Bảng timbre theo phe
| Phe | Chất liệu | Dải chủ | Đặc tính | Cấm |
|---|---|---|---|---|
| Hero (12) | vũ khí riêng (§2.3) + lửa/hơi nóng | 150 Hz–8 kHz, transient sắc | "nóng, đặc, gần": khô, gần mic, lớp sweetener sáng; tương ứng FX lõi trắng nóng | ping kim loại 2.2–3.6 kHz dài (AUD-01) |
| Quái thường | tro, xương, vải khô, đất mộ, bùn, sắt nguội | 200 Hz–4 kHz, −6 dB so với hero cùng loại | "lạnh, rỗng, xa": hơi ẩm phòng, lớp hiss tro; tương ứng FX lõi tối viền sáng | tiếng người rõ chữ; gầm kiểu quái vật điện ảnh quá to |
| Tinh Anh/mini | như quái biome + 1 chất liệu nặng (gỗ quan, xích, đồng) | 80 Hz–5 kHz | trọng lượng: sub thump ở đòn, giọng thú/hơi thở | — |
| Boss | chất liệu chữ ký riêng (§3.4) | toàn dải | mỗi boss 1 "giọng" không lời: thở, rên, gầm biến âm | lời nói có nghĩa |
| Thế giới/hazard | theo biome (§10) | — | hazard dùng đúng Y/P/N (INV-18) | swell trầm ngoài tell tím |
Ma #9ff3ff | thuỷ tinh lạnh lấp lánh | 3–9 kHz nhiễu mịn | actor có lõi ma #9ff3ff trong view (≤ 3 gần hero nhất) → loop SFX_SHARED_ghost_core loop rất nhỏ | tonal 2.2–3.6 kHz |
| UI | giấy, gỗ, đồng xu nhỏ, chuông gió trầm | 300 Hz–6 kHz | ngắn, ấm, không ồn | âm "game điện tử" vuông/chiptune |
2.3 Bảng timbre 12 hero (chất liệu chủ không trùng; AP5)
Mỗi hero: 1 chất liệu chủ (vũ khí) + 1 chất liệu tài nguyên + âm ĐÁP riêng xếp trên lớp chung HeroAnswerSuccess (lớp chung dưới SFX_{H}_answer) + send Answer SFX_SHARED_answer_core (người chơi học: lớp chung = thành công; lớp riêng = hero). Motif hero dùng ở chọn hero, Ult, thẻ kết (§3.3).
| Hero | Chất liệu chủ (vũ khí) | Tài nguyên → âm | ĐÁP · verb giữ | Ult (UL1) | Motif LM_Hxx (nốt, nhạc cụ) | Cấm |
|---|---|---|---|---|---|---|
| H01 Varek | thép mỏng cong song liềm: cạo thép 3–6 kHz 4 ms + whoosh 400–1.800 Hz quét xuống | Dòng Chảy: hơi thở gió ấm tăng dần; ≥ 50 Cuồng Lưu = lớp tim đập 2 nhịp | Gạt: thép gạt thép + đuôi ngân ngắn (demo parry_1/2) · Thủ: chặn trầm gỗ-thép, Phản đòn: chém kép | Trăng Máu: whoosh tròn trầm + chuỗi chém + nổ cuối | D–F–E–A, đàn dây cung trầm méo | dao phay nặng, tiếng quạt |
| H02 Bodan | gỗ quan tài dày + đai sắt: thud gỗ 120–300 Hz, kẽo kẹt | Đinh: tiếng đóng đinh búa; xả nổ = tiếng nứt gỗ + bùm | Chặn Nắp: va gỗ lớn "rầm" · Dựng Quan: cắm nắp xuống đất + bụi | Đóng nắp lớn + 6 đinh dồn | G–D–G–A–G, tuba/kèn đồng trầm hát ru | kim loại sáng |
| H03 Halka | gỗ cán dài + chuông tay đồng ĐÃ BỊT (fundamental ≤ 600 Hz, decay ≤ 400 ms, AUD-01) | Vang: mỗi tầng 1 tiếng ngân bịt cao dần 1 quãng 5; Vỡ Âm = chuông vỡ nứt + sub | Gõ Chuông: gõ bịt trầm tại kẻ tấn công · Nhảy Sào: tre uốn "vút" | Hồi chuông bịt dây chuyền | A–E–A–B–C, chuông đồng bịt + sáo trúc trầm | ping cao trong dải tinh |
| H04 Sậu | sắt compa: bản lề "tách/khép" + phấn cào, búng dây mực | Mực: giọt mực rơi; 5 Mực → Kẻ Mực = búng dây mực căng "pưng" trầm + xé giấy | Khép Compa: kéo cắt "xoẹt" kim loại khô ngắn ≤ 60 ms · Kẻ Vòng: phấn vẽ vòng loop | đường mực khổng lồ xé | E–G–B–A, đàn tranh gẩy khô | ngân kim loại |
| H05 Oska | đe gang + xích: xích quay loop (cao độ theo Đà 0→100 = +0→+7 bán cung), đe va "đùng" 200–400 Hz | Đà: hum quay; Đà 100 = rít xích căng | Quay Chắn: xích quất vòng · Quỹ Đạo: vù vù liên tục | đe rơi + vùng hút trầm hút ngược (chỉ 0.25 s, AUD-02) | C–C–G–F, trống đồng + bễ thổi | đe ngân dài (decay ≤ 300 ms) |
| H06 Ruvan | găng sắt nung: đấm thịt dày + xèo hơi | Nhiệt: lò rít cao dần; Nung/Chảy = lớp lửa ầm; Tôi = xì hơi lớn | Bắt Đòn: tóm "chát" + bóp vỡ · Hấp Nhiệt: lửa hút vào | lò nổ hơi lớn | F–A♭–G–C, trống da + tù và | cạo thép mỏng |
| H07 Veyra | gỗ-xương cung: dây cung xương kẽo kẹt (cao độ tăng theo thời gian kéo), tên rít | Hơi: hít vào theo kéo; Đỉnh Hơi = "nín" tắt mọi lớp 0.12 s + 1 tiếng gõ nhẹ dây | Bắn Ngắt: phựt nhanh · Lùi Lắp: bước lùi + kéo | mưa tên + hơi thở dài | B–D–F♯–E, sáo xương + dây buông | tên kim loại "ding" |
| H08 Dov | hoả mai nòng loa: nổ thuốc súng trầm + đạn chì, khói phụt | 2 ổ × 3: lẫy cơ khí; Nạp Nóng đúng = "cạch" sáng gỗ-sắt; 9 phản ứng = 9 lớp màu (Muối rắc, Ma Trơi xèo xanh, Đinh lách cách) | Nổ Chặn: nổ ngắn nón · Tì Báng Nạp: báng gỗ dậm | phát đại bác | D–D–A–G–F, trống trận nhỏ + kèn sừng | súng hiện đại, tiếng vỏ đạn đồng ngân |
| H09 Kessa | dây gai + chuỗi xu: dây quất "vút", xu xủng xoẻng = nhiễu ngắn ≤ 60 ms (AUD-01) | Vòng: mỗi quái bị quấn 1 nút thắt "sột"; Ném Bó = khối thịt rơi | Quăng Vòng Xu: quất dây + giật · Lưới Xu: lưới thả loạt xu | bó 6 quật ngã | A–C–D–E–D, đàn nguyệt gẩy + mõ | xu ngân tonal dài |
| H10 Ingra | lư trầm đồng + xích: khói "phù", xích lắc, thì thầm không lời | Khói: mỗi vùng 1 lớp hơi thở thấp; Châm = châm lửa "xoẹt" + mọi vùng phụt cùng lúc lệch 30 ms | Màn Khói: khói phụt tại kẻ đánh · Hoá Khói: tan khí | vùng khói đồng loạt bùng | E–F–E–B, đàn nhị kéo + giọng hum | lời tụng có nghĩa |
| H11 Wenna | xẻng sắt + đất: xúc đất, đập phẳng "bép", sỏi | Đất: đất đổ; Hố: đào sâu 0.4 s loop; Bia Sụt = đất sụt ầm dài | Hất Đất: hất đất rào · Cắm Xẻng: cắm sắt vào đất | mặt đất sụt diện rộng | G–A–C–A–G, đàn gáo + trống đất | tiếng hồn/ma, chuông |
| H12 Ambrin | kèn đưa tang (kèn dăm kép) + phường ma: trống sóng, chũm chọe (nhiễu), cờ phướn vải, kèn phụ | Nhịp: đúng phách = nốt kèn đúng cao độ hợp âm stem; lệch = nốt lạc nửa cung, Nhịp/2 = kèn hụt hơi | Thổi Dội: sóng kèn ngắn · Nốt Ngân: kèn giữ hơi | cả phường thổi tutti | D–A–C–D (đỉnh 120 BPM), kèn dăm + trống | quantize âm đánh (trễ input) |
Luật hero: (1) swing phát ở frame CUT kể cả đánh hụt; trúng là âm riêng (§6). (2) ≥ 3 biến thể cho mọi âm lặp; pitch ±6%, volume ±1.5 dB. (3) Dạng Rèn AS2/AS3 đổi vũ khí → đổi bộ swing/hit (cùng hero, 6 sự kiện swap, tính trong 28 sự kiện/hero qua biến thể). (4) Skin = cùng âm (LUT chỉ đổi màu).
2.4 Bảng timbre kẻ địch theo biome
| Biome | Chất liệu chung quái | Giọng (không lời) | Lớp chung bầy (crowd_bed) |
|---|---|---|---|
| B1 Đồi Mộ Tro | xương khô, vải mục, đất mộ, tro rơi | rên khàn, gió qua hàm | lê chân trên đất + rắc xương |
| B2 Đầm Vải Liệm | vải ướt, bùn, nước nông, tre | ọc nước, ếch trầm, cánh bướm vải | lội nước lép bép |
| B3 Lò Đúc Câm | sắt nguội, xỉ, than, hơi nước (decay ngắn, AUD-01) | ho xỉ, thở bễ | guốc sắt lạch cạch + xì hơi xa |
| B4 Thành Chuông Treo | đá phiến, xích lạnh, cánh đá, gió | rít gió qua lỗ, kêu chim than khàn | bước đá + xích leng keng NHIỄU (không tonal) |
| B6 Bờ Lặng | vắng: hút âm (nhiễu lọc thở vào), nước gương | không giọng | không; im lặng là chất liệu |
Boss & mini — giọng chữ ký (1 giọng/boss, không lời):
| Id | Giọng/chất liệu | Âm chữ ký |
|---|---|---|
| MB_B1_1 Xà Ích Xe Tang | bánh gỗ nghiến, ngựa xương thở, roi da | Lao Xe: bánh lăn tăng tốc + "ù" tím |
| MB_B2_1 Mẹ Kén Tơ Tro | tơ kéo căng, kén nứt ướt | Đẻ Kén: xoáy trung tính + kén nứt |
| MB_B2_2 Cá Voi Xác | rên cá voi trầm 40–80 Hz qua tro (không swell, AUD-02), vây rẽ | Trồi Vồ: tro phun + hàm đóng |
| MB_B3_1 Cỗ Máy Bước | piston, khớp sắt, giáp tấm dồn "cang" ngắn | Dậm: búa máy |
| MB_B3_2 Gã Hai Đầu Lò | 2 giọng ho lò lệch 1 quãng 3 | Giọt Đồng: đồng sôi |
| MB_B4_1 Rồng Hai Đầu | 2 hơi thở rồng (lửa-tro / sừng) | Phun / Húc |
| MB_B4_2 Kiếm Sĩ Gương | gương rạn, kiếm rút; ẢNH GIẢ: chỉ tiếng sột gương, không tell (AUD-04) | Rút kiếm |
| BS_B1 Người Gác Chuông | búa chuông verdigris, áo giáp nặng, hơi thở già | Hồi Chuông Tang: chuông lớn TRẦM 110 Hz (đòn tím → kèm "ù") |
| BS_B2 Lão Lái Đò Không Bến | sào tre vào nước, bè kẽo kẹt, giọng hát ngâm không lời | Sóng Đò: sóng nước lớn |
| BS_B3 Thợ Cả Đúc Chuông | lò, búa rèn, xích, giáo (Rèn Phản = 3 âm rèn khác nhau theo vũ khí) | Rèn Phản: 3 nhát rèn + tôi nước |
| BS_B4 Yvra & Rồng Khàn | giáp kỵ, thương, rồng khàn (khò khè, mất giọng) | Bổ Nhào: rít gió từ cao |
| BS_FINAL Vua Dravos | Mũ Chuông: chuông câm (gõ ra "thịch" không ngân), áo choàng tro, thở nặng | Hồi Câm: mọi âm hero bị lọc 0.5 s; đòn cuối Hồi Chuông = tiếng chuông THẬT duy nhất của game (ngân 8 s) |
| BS_TRUE Cái Lặng | không giọng; hút âm: âm khác bị "nuốt" (lowpass quét xuống) quanh nó | Lặng Nuốt Sân: tiếng chuông nhỏ báo rẻ kế (bịt, 660 Hz, attack 20 ms, AUD-01) |
53. Âm nhạc
3.1 Hướng chung
- Bảng nhạc cụ gốc: dây cung trầm (cello/bass bowed, méo nhẹ), trống khung/trống da, đe & chiêng (decay ngắn ở combat), kèn dăm kép, sáo trúc/xương, đàn gẩy một dây & dây buông, hợp xướng nguyên âm "a/o" (không lời có nghĩa, không trích kinh), drone bễ/harmonium trầm.
- Cấm toàn game: chiptune sóng vuông làm lead, wobble/dubstep bass, nhạc điện tử EDM drop, giai điệu dân ca/tôn giáo có thật trích nguyên, lời hát có nghĩa, piano trữ tình kiểu phim.
- Nhạc không theo slow-mo
World(giữ tốc, chỉ lọc); không bị hitstop; pitch luôn 1.0. - Mọi cue combat nằm trong 1 lưới tempo cố định, stem dài bằng nhau, lặp mẫu-chính-xác (§11.3). Key gốc của game = D (Hồi I và Kết cùng D → vòng tròn truyện).
3.2 Bảng hướng nhạc theo khu (bpm/meter/key/nhạc cụ khoá)
| Khu · cue | BPM · nhịp | Key | Nhạc cụ (canon in đậm) | Cảm xúc | Leitmotif dùng |
|---|---|---|---|---|---|
| Tiêu đề · TITLE · màn tiêu đề + menu chính (Cài đặt/Credits mở từ đây giữ nguyên cue dưới SN_DRAFT)… MUS_title_mute_night | 66 tự do | D Aeolian | chuông câm (gõ "thịch"), hợp xướng xa, cello solo | Đêm Câm, mất mát | LM_BELL (vỡ), LM_DRAVOS |
| Hub · HUB · HUB_BELL_TOWER Tháp Chuông Gãy (mọi trạm ST_*) · S0 + stem GĐ Phục Dựng đã mở (GD1–… MUS_hub_bell_tower | 72 · 3/4 | F Lydian → D (GD5) | lửa canh (ambience), đàn gẩy, kèn bầu, harmonium; mỗi GĐ Phục Dựng +1 stem | ấm, nghỉ ngơi | LM_ULLA, LM_LEM; GD5: LM_BELL trọn vẹn |
| Bến giữa Hồi · DOCK · Bến Giữa Hồi (nút DOCK sau boss Hồi I–IV, ≤ 20 s, Sạp Rong + chở đò Calla sang Hồi… MUS_dock_crossing | 84 · 6/8 | D Dorian | mái chèo (bộ gõ nước), sáo trúc, dây buông | trôi, chuyển chương | LM_CALLA |
| B1 · EXPLORE/COMBAT · Hồi I B1 Đồi Mộ Tro · bản đồ + mọi nút CMB/ELT/CHL/RSC/EVT/SHP/RST/SEC c… MUS_b1_grave_hill | 132 · 4/4 | D Phrygian | trống khung + dây trầm, đe nhẹ phách 2–4, đàn gẩy 16 nốt | dồn dập, u tối | LM_BELL vỡ (ostinato) |
| B2 · EXPLORE/COMBAT · Hồi II B2 Đầm Vải Liệm · bản đồ + mọi nút chiến/tiện ích B2 · lớp theo I MUS_b2_shroud_marsh | 96 · 6/8 | E Aeolian | đàn một dây + gõ nước, trống cơm, hợp xướng nữ thấp | nặng, ngộp, đung đưa | LM_CALLA đảo (biến dạng) |
| B3 · EXPLORE/COMBAT · Hồi III B3 Lò Đúc Câm · bản đồ + mọi nút chiến/tiện ích B3 · lớp theo I MUS_b3_mute_foundry | 140 · 4/4 | C Phrygian dominant | đe, chiêng, kèn đồng, bễ thổi (bass sidechain giả) | công nghiệp, cuồng tín | LM_FOUNDER |
| B4 · EXPLORE/COMBAT · Hồi IV B4 Thành Chuông Treo · bản đồ + mọi nút chiến/tiện ích B4 · lớp t… MUS_b4_hanging_city | 7/8 · 120 (2+2+3) | B Aeolian | hợp xướng + chuông (chuông trầm, AUD-01), timpani, dây cao tremolo | uy nghi, chóng mặt | LM_DRAVOS (kèn), LM_YVRA |
| Kết B5 · FINALE · B5 Đỉnh Chuông Câm (Kết, act V): ải 60 s trộn quái 4 Hồi (lớp theo I) + BS_FINAL… MUS_finale_crown | 120 · 4/4 | D Aeolian → D Dorian (P3) | chủ đề Varek + hợp xướng, toàn dàn; stem L4 = motif hero đang chơi | đỉnh điểm, bi tráng | LM_H01 + LM_Hxx + LM_DRAVOS + LM_BELL |
| Bí mật B6 · SECRET · B6 Bờ Lặng (Bí mật, act VI, cần FLAG_SHORE_OPEN): ải 45 s quanh Tiếng Câm EN_B6_… MUS_quiet_shore | không nhịp | không key (drone A 55 Hz rất nhỏ) | gần như im: nước, 1 giọng hum xa −36 LUFS; chỉ tell có âm | trống rỗng, rợn | LM_SILENCE |
| Boss B1 · BOSS · nút BOS Hồi I · BS_B1 Người Gác Chuông · stem theo pha (không theo I) · P3 "Chuông… MUS_boss_b1_bell_warden | 120 · 4/4 | D Phrygian | trống khung lớn, búa đe, dây trầm, hợp xướng nam | bổn phận mù quáng | LM_BELL (đảo, chậm) |
| Boss B2 · BOSS · nút BOS Hồi II · BS_B2 Lão Lái Đò Không Bến · stem theo pha · P3 "Nước Dâng": S0 t… MUS_boss_b2_ferryman | 120 · 12/8 (chấm đen = 120) | E Aeolian | đàn một dây khuếch, trống nước, giọng ngâm không lời | tuyệt vọng | LM_CALLA (thứ) |
| Boss B3 · BOSS · nút BOS Hồi III · BS_B3 Thợ Cả Đúc Chuông · stem theo pha · S2 có 3 biến thể theo … MUS_boss_b3_founder | 120 · 4/4 | C Phrygian dominant | đe 3 tầng (Rèn Phản đổi lớp theo vũ khí), kèn đồng, chiêng | cuồng tín | LM_FOUNDER |
| Boss B4 · BOSS · nút BOS Hồi IV · BS_B4 Thống Lĩnh Yvra & Rồng Khàn · stem theo pha · P2 tách thân:… MUS_boss_b4_yvra | 120 · 4/4 (accent 3+3+2) | B Aeolian | hợp xướng, timpani, kèn kỵ binh, tiếng rồng khàn mẫu hoá | trung thành bi kịch | LM_YVRA, LM_DRAVOS |
| Mini-boss · GATE_MINI · nút MBS (Cổng) mọi biome · mọi MB_ (MB_B1_1, MB_B2_1, MB_B2_2, MB_B3_1, MB_B3… MUS_miniboss_gate | 120 · 4/4 | theo key biome (4 bộ stem chuyển giọng D/E/C/B) | trống nặng, drone biome, ostinato ngắn 8 ô | cổng nguy hiểm | — |
| Chết · DEATH · hết Lửa Gửi trong run (mọi biome, mọi mode) · bắt đầu đồng bộ thẻ recap INV-16 = … MUS_death_epitaph | 60 tự do | D Aeolian | cello + chuông câm 1 tiếng, gió | thua mà ấm | LM_ULLA (ngắn) |
| Kết thường · ENDING · END_BELL_TOLL Hồi Chuông (Gióng chuông sau BS_FINAL) · phần tuyến tính 180 s = f… MUS_end_bell_toll | 76 · 4/4 | D major (duy nhất trưởng) | toàn dàn + chuông thật ngân | giải thoát, dư âm buồn | LM_BELL trọn, LM_H01 |
| Kết thật · ENDING · END_QUIET_SHORE Bến Bình Yên (hạ BS_TRUE ở B6) · 210 s tuyến tính đi cùng 12 thẻ… MUS_end_quiet_shore | 64 · 3/4 | D Lydian | 12 nhạc cụ 12 hero lần lượt vào, chuông lõi | bình yên | 12 LM_Hxx + LM_LEM + LM_BELL |
| Kết phụ · ENDING · END_ASH_CROWN Mũ Tro (chọn "Giữ lõi" ở BS_FINAL) · 120 s tuyến tính: hero đội Mũ… MUS_end_ash_crown | 56 · 4/4 | D Locrian | chuông câm, hợp xướng thì thầm, drone | cam chịu | LM_DRAVOS (trên đầu hero) |
H12 Ambrin: B1–B4 thay bằng 4 bộ stem 120 BPM EXPLORE/COMBAT · Hồi I B1 KHI CHƠI H12 Ambrin (thay MUS_b1_grave_hill; biomes[].music.h12… MUS_b1_grave_hill_h12 … EXPLORE/COMBAT · Hồi IV B4 khi chơi H12 (thay MUS_b4_hanging_city) · 7/8 → 4/4 120, giữ a… MUS_b4_hanging_city_h12 (canon). Mọi boss cue + mini + finale = 120 BPM nên dùng chung với máy nhịp, không cần bộ riêng (§3.6).
3.3 Leitmotif (nốt chuẩn; hoà âm/nhạc cụ tự do trong luật §3.1)
| Id | Chủ | Nốt (độ dài) | Nhạc cụ chuẩn | Xuất hiện |
|---|---|---|---|---|
| LM_BELL | Đại Chuông Vọng | D–A–G–D (trắng, trắng, đen, tròn) — quãng 5 xuống "hồi chuông" | chuông lớn + hợp xướng | tiêu đề (vỡ: thiếu nốt cuối), hub GD5, kết |
| LM_DRAVOS | Vua Dravos | A–G♯–G–F♯–F (bè trầm chromatic đi xuống, đen đều) | kèn đồng trầm, cello | B4, finale P1/P3, tiêu đề |
| LM_SILENCE | Cái Lặng | E → B♭ (tritone) chỉ 2 nốt, nốt 2 bị cắt sau 1 phách | âm đảo ngược mờ (KHÔNG < 140 Hz, AUD-02) | B6, finale cuối (gợi ý) |
| LM_ULLA | Bà Ulla | F–G–A–C–A (3/4, ru) | giọng hum nữ, đàn gẩy | hub, chết |
| LM_CALLA | Calla | D–E–F–A–G–F (6/8, chèo) | sáo trúc | dock, B2 (đảo), boss B2 (thứ) |
| LM_LEM | Nhóc Lem | A5–C6–D6–C6 (hộp nhạc) | hộp nhạc, celesta gỗ | hub GD1+, kết thật |
| LM_HOL | Thầy Hol | 3 tiếng chuông bịt cùng cao độ D2, không giai điệu | chuông bịt trầm | hub ST_LEDGER |
| LM_GREM | Lão Grem | nhịp đe 3+3+2 (không cao độ) | đe nhỏ | hub ST_FORGE |
| LM_MOTT | Bà Mott | C–D–E♭–D–C láy | đàn nguyệt | Sạp Rong (SHP), Chợ Đò |
| LM_RAM | Bù Nhìn Răm | G–F♯–G (lạc điệu, hài) | sáo méo + mõ | Sân Tập |
| LM_FOUNDER | Thợ Cả | C–D♭–E–F (Phrygian dominant, đen nhấn) | kèn đồng + đe | B3, boss B3 |
| LM_YVRA | Thống Lĩnh Yvra | B–F♯–A–B (kèn kỵ, chấm dôi) | kèn sừng | B4, boss B4 |
| LM_H01–LM_H12 | 12 Kẻ Thức | bảng §2.3 cột Motif | nhạc cụ chủ hero | chọn hero (stinger 3 s), Ult (stinger 1 ô), finale L4, kết thật |
Luật motif: ≤ 6 nốt; nhận ra trong 2 s; không nhạc cụ trùng giữa 2 motif hero; motif hero không dùng nhạc cụ có partial 2.2–3.6 kHz decay dài (AUD-01).
3.4 Hệ nhạc thích nghi (class MusicDirector)
Stem chuẩn mỗi cue combat (biome/boss/mini/finale) — 5 stem, dài bằng nhau, cùng điểm lặp:
| Stem | Vai | Ví dụ B1 |
|---|---|---|
S0 bed | drone/pad, luôn chạy | dây cung trầm + hợp xướng "a" + drone bễ |
S1 pulse | nhịp nhẹ | trống khung phách 1–3 |
S2 drive | bộ gõ đầy | tom, đe phách 2–4, trống khung 16 nốt |
S3 ostinato | hình nốt lặp | dây staccato + đàn gẩy 16 nốt |
S4 lead | giai điệu/motif | dây cung méo/kèn swell, LM_BELL vỡ |
Tham số cường độ I (0–1), tính mỗi 0.25 s (Hero clock): I_raw = clamp01(0.50·D + 0.25·T + 0.15·E + 0.10·H)
D = min(alive_view, 200) / 200— quái sống trong khung 480×270 art px quanh camera.T = 0.5·(melee_tokens_used / 4) + 0.5·(proj_tokens_used / 3)— token INV-08 đang dùng.E = 1nếu Tinh Anh/mini/boss sống trong khung, else 0.H = 1nếu HP hero < 35%, else 0.- Làm mượt: lên
τ_up = 1.0 s, xuốngτ_down = 4.0 s(EMA). Ví dụ: 120 quái, 4/4 token cận chiến, 1/3 đạn, 1 Tinh Anh, HP 80% →0.5·0.6 + 0.25·(0.5·1 + 0.5·0.333) + 0.15·1 + 0 = 0.30 + 0.167 + 0.15 = 0.617→ bật S0–S3, S4 chưa (ngưỡng 0.70) nhưng E = 1 ép S4 (bảng dưới).
Bảng lớp (hysteresis; đổi lớp chỉ ở vạch ô nhịp kế; vào 1 ô fade, ra 2 ô fade):
| Lớp | Bật khi | Tắt khi | Mức stem |
|---|---|---|---|
| S0 | luôn (trạng thái COMBAT/EXPLORE) | — | 0 dB |
| S1 | I ≥ 0.15 hoặc EXPLORE | I < 0.10 và không EXPLORE | EXPLORE −6 dB, COMBAT 0 dB |
| S2 | I ≥ 0.40 | I < 0.32 | 0 dB |
| S3 | I ≥ 0.55 | I < 0.45 | 0 dB |
| S4 | I ≥ 0.70 hoặc E = 1 | I < 0.60 và E = 0 | 0 dB |
Trạng thái nhạc (máy trạng thái):
| State | Vào khi | Stem | Thoát |
|---|---|---|---|
TITLE | màn tiêu đề | TITLE · màn tiêu đề + menu chính (Cài đặt/Credits mở từ đây giữ nguyên cue dưới SN_DRAFT)… MUS_title_mute_night | nhấn bắt đầu → fade 2 s |
HUB | vào HUB_BELL_TOWER | HUB · HUB_BELL_TOWER Tháp Chuông Gãy (mọi trạm ST_*) · S0 + stem GĐ Phục Dựng đã mở (GD1–… MUS_hub_bell_tower S0 + stem GĐ đã mở | tới ST_DOCK xuất phát → stinger depart |
EXPLORE | bản đồ, phòng tiện ích SHP/RST/EVT/SEC, phòng chiến chưa spawn | cue biome S0 + S1 (−6 dB); SHP thêm lớp LM_MOTT | spawn đầu phòng → COMBAT ở vạch ô kế |
COMBAT | phòng CMB/CHL/RSC/ELT | cue biome theo I | xong phòng → stinger room_clear (2 ô) → EXPLORE |
GATE_MINI | MBS | GATE_MINI · nút MBS (Cổng) mọi biome · mọi MB_ (MB_B1_1, MB_B2_1, MB_B2_2, MB_B3_1, MB_B3… MUS_miniboss_gate (key biome) | thắng → stinger victory → EXPLORE |
BOSS | BOS | cue boss, S0–S4 theo pha (bảng dưới) | thắng → stinger victory 4 ô → im 2 s → DOCK |
DOCK | Bến Giữa Hồi | DOCK · Bến Giữa Hồi (nút DOCK sau boss Hồi I–IV, ≤ 20 s, Sạp Rong + chở đò Calla sang Hồi… MUS_dock_crossing | chở đò → crossfade cue biome Hồi kế (8 s) |
DRAFT | mở draft/tạm dừng/menu trong run | cue hiện tại tiếp tục, snapshot SN_DRAFT (lowpass 800 Hz, −6 dB) | đóng → bỏ snapshot 0.3 s |
DEATH | hết Lửa Gửi | dừng cue (fade 0.5 s) → DEATH · hết Lửa Gửi trong run (mọi biome, mọi mode) · bắt đầu đồng bộ thẻ recap INV-16 = … MUS_death_epitaph | "Thức Lại" → HUB/RUN |
ENDING | END_* | cue kết tương ứng, không lặp | credit xong → TITLE |
Chuyển cảnh (đều lượng tử hoá theo vạch ô nhịp, đồng hồ DSP AudioSettings.dspTime):
- Cùng cue: bật/tắt stem tại vạch ô kế (≤ 1 ô trễ: ≤ 1.82 s ở 132 BPM, ≤ 2.0 s ở 120 BPM).
- Khác cue cùng tempo: crossfade ở vạch ô kế, dài 1 ô.
- Khác tempo: stinger thoát (≤ 2 ô) → cue mới bắt đầu ô 1 mẫu 0; không bao giờ trộn 2 tempo > 1 ô.
- Vào BOSS: im 0.5 s (khoảnh khắc thở) → stinger
boss_introcủa cue boss đồng bộ với khung giới thiệu tên boss → S0+S1 vòng P1.
Stinger (asset con của cue, <cueId>__stg_<slug>; bus Music_Stinger; luôn đúng key cue; dài ≤ 4 ô):
| Slug | Khi | Có ở cue |
|---|---|---|
elite_in | Tinh Anh/Ấn xuất hiện (cùng chữ "TINH ANH XUẤT HIỆN") | 4 biome |
surge | TIDE đợt mới, MESO dịch spawn, mutator kích hoạt | 4 biome |
| room_clear | phòng xong | 4 biome + miniboss_gate |
ash_read | Tro Nhớ đổi thế (đi kèm AshVariantOn (Tro Nhớ đổi thế: khựng 0.6 s + ◆ Mắt Tro, ≥ 1.0 s trước… SFX_SHARED_ash_read, khựng 0.6 s) | 4 biome + 4 boss + finale |
boss_intro | vào trận boss | 4 boss + finale + quiet_shore |
phase2 / phase3 | boss đổi pha (khoảnh khắc quỳ bất tử) | 4 boss + finale + quiet_shore |
victory | hạ boss/mini | 4 boss + miniboss_gate + finale |
depart | rời hub/ra bến | hub |
hero_<Hxx> | chọn hero ở ST_HEARTH (3 s, LM_Hxx) | hub (12 stinger) |
ult_<Hxx> | Ult kích hoạt (1 ô, LM_Hxx trên S4 của cue đang chạy, trộn key cue) | dùng chung: 12 stinger viết ở D, MusicDirector chọn bản chuyển giọng gần nhất (D/E/C/B: 48 file) [ASSUMED] |
Boss — cue theo pha (mọi boss Hồi; finale/quiet_shore theo cột riêng):
| Pha | Stem | Đổi pha |
|---|---|---|
| P1 | S0 + S1 + S3 | — |
| P2 | + S2, S3 đổi biến thể B (hình nốt nhanh gấp đôi) | __stg_phase2 đúng lúc boss quỳ bất tử, nhạc cắt sang S0 1 ô rồi P2 |
| P3 (BS_B1 Chuông Vỡ Hẳn; boss khác ở pha cuối) | + S4 (motif boss) | __stg_phase3, 1 ô im trừ S0 |
| Vỡ Thế boss | S2 + S3 −6 dB trong 3 s, S4 giữ | — |
| Boss windup tím chữ ký | S1–S3 −3 dB suốt windup (để "ù" nổi) | — |
| Hạ | __stg_victory 4 ô, cắt mọi stem | — |
- FINALE · B5 Đỉnh Chuông Câm (Kết, act V): ải 60 s trộn quái 4 Hồi (lớp theo I) + BS_FINAL… MUS_finale_crown: ải 60 s = S0–S3 theo
I; BS_FINAL P1 = S0+S1+S3 + LM_DRAVOS; P2 = S2 bật + S4 phát motif của boss bóng đang gọi (4 biến thể S4: b1/b2/b3/b4 ở D); P3 Mũ Chuông Nứt = toàn dàn + LM_H01 + motif hero đang chơi (S4h, 12 biến thể); đòn cuối Hồi Chuông → cắt nhạc, chỉ còn tiếng chuông thật ngân 8 s →MUS_end_*. - SECRET · B6 Bờ Lặng (Bí mật, act VI, cần FLAG_SHORE_OPEN): ải 45 s quanh Tiếng Câm EN_B6_… MUS_quiet_shore: ải 45 s = S0 (drone + nước) ≤ −34 LUFS-I; BS_TRUE P1 = S0 + nhịp tim trầm S1 (60 BPM, chỉ thump, AUD-02); P2 Nuốt Tiếng = nhạc tắt hẳn, chỉ tell + phụ đề; P3 Gương Lặng = S4 = motif hero đang chơi chơi ngược phách, rất nhỏ.
3.5 Đồng bộ H12 Ambrin (120 BPM)
- Máy nhịp chạy trên đồng hồ Hero (canon); nhạc chạy DSP. Nguồn sự thật = DSP:
beatPhase = ((dspTime − musicStartDsp) mod 0.5 s); máy nhịp đọcbeatPhase+audioOffsetMs(hiệu chỉnh trễ, Thương Xót). - Khi H12 chơi: cue biome = bộ
_h12; boss/mini/finale vốn 120 BPM → khoá pha với máy nhịp. EXPLORE/DOCK/DRAFT: máy nhịp tiếp tục, nhạc giữ lưới 120 (DOCK DOCK · Bến Giữa Hồi (nút DOCK sau boss Hồi I–IV, ≤ 20 s, Sạp Rong + chở đò Calla sang Hồi… MUS_dock_crossing 84 BPM → khi H12 thay bằng S0 của cue biome kế dạng_h12). SECRET · B6 Bờ Lặng (Bí mật, act VI, cần FLAG_SHORE_OPEN): ải 45 s quanh Tiếng Câm EN_B6_… MUS_quiet_shore không nhịp → máy nhịp phát click (biến thểclickcủa HeroResource heroId=H12 kind=gain (Nhịp +1/+2) · nhạc công Trống Sóng… SFX_H12_res_gain) −18 LUFS trong B6. - Đúng phách ±0.12 s (Thương Xót ±0.16 s) tính theo DSP; âm đánh hero KHÔNG lượng tử hoá (giữ AP4); chỉ nốt kèn "đúng/lạc" chọn cao độ theo hợp âm ô hiện tại (bảng hợp âm theo ô trong file cue).
- Tuỳ chọn "click nhịp H12": mặc định tắt; tự bật khi thanh Music = 0.
- Bộ
_h12(4): B1 132 → 120 (4/4, giữ hình trống khung); B2 6/8 96 → 12/8 chấm đen = 120; B3 140 → 120 (hi-hat kép); B4 7/8 → 4/4 120, giữ accent 3+3+2 trên 8 móc. Mỗi bộ đủ 5 stem + stinger như cue gốc.
3.6 Mẫu cue nhạc (FINAL) — mỗi cue 1 khối trong GDD/Full/data/audio_music.json (agent audio tạo; khoá field)
| Field | Kiểu | Định nghĩa |
|---|---|---|
id | string | MUS_<slug> snake_case (canon §11); bộ H12 = MUS_<slug>_h12 |
context | string | state §3.4 + khu + điều kiện phát |
bpm · meter · key | số · string · string | tempo cố định; meter 4/4, 6/8 (ghi rõ phách = chấm đen); key + mode |
chords | file | <id>.chords.json: hợp âm từng ô (H12 chọn nốt kèn, ult stinger chọn bản chuyển giọng) |
intro_bars · loop_bars · loop_samples | int | loop_samples = round(loop_bars × beats_per_bar × 60 / bpm × 44100); intro là file riêng __intro |
stems | list | S0..S4 + biến thể (S3b, S4b1..b4, S4h01..h12); mỗi stem 1 file stereo, dài đúng loop_samples |
adaptive | object | ngưỡng I hoặc bảng pha (§3.4); mặc định = bảng lớp chuẩn |
stingers | list | slug §3.4; mỗi stinger: độ dài ô, ô vào (next_bar/next_beat), cắt stem nào |
transitions | object | quantize (bar/beat), fade_in_bars 1, fade_out_bars 2, exit_to |
leitmotifs | list | LM_* |
banned | list | timbre cấm riêng cue (ngoài §3.1) |
mix | object | lufs_i_full (mọi stem, I = 1): −16 combat, −20 hub/dock, −24 death, −18 kết; true_peak −1 dBTP; ducked_by |
files | path | Assets/_Project/Audio/Music/<id>/<id>__S0.ogg … |
status | enum | brief / demo / final / approved |
Ví dụ đủ field — EXPLORE/COMBAT · Hồi I B1 Đồi Mộ Tro · bản đồ + mọi nút CMB/ELT/CHL/RSC/EVT/SHP/RST/SEC c… MUS_b1_grave_hill: context COMBAT/EXPLORE Hồi I B1 · 132 · 4/4 · D Phrygian, chords: i–♭II–i–♭VII lặp 4 ô · intro 2 ô (3.64 s) · loop 32 ô = 58.18 s = 2.565.818 mẫu · S0 dây cung trầm + hợp xướng "a" + drone bễ; S1 trống khung phách 1–3; S2 tom + đe phách 2–4 + trống khung 16 nốt; S3 dây staccato + đàn gẩy 16 nốt; S4 dây cung méo/kèn swell, LM_BELL vỡ (D–A–G, thiếu nốt D cuối) · adaptive chuẩn · stingers elite_in (2 ô), surge (1 ô), room_clear (2 ô), ash_read (1 ô, cắt S2–S4 trong 1 ô) · quantize bar, vào 1 ô, ra 2 ô, exit_to BOSS · nút BOS Hồi I · BS_B1 Người Gác Chuông · stem theo pha (không theo I) · P3 "Chuông… MUS_boss_b1_bell_warden qua im 0.5 s · banned: lead sóng vuông, hợp xướng có lời · mix −16 LUFS-I full, ducked_by ĐÁP −4 dB 0.4 s, stinger boss −6 dB 1 s · files Assets/_Project/Audio/Music/MUS_b1_grave_hill/MUS_b1_grave_hill__S0.ogg…__S4.ogg, __intro.ogg, __stg_elite_in.ogg.
3.7 Danh sách cue 1.0 (18 bản canon + 4 bộ stem H12) — 1 dòng/cue
id · state · bpm/meter/key · intro + loop (ô = giây) · stem · stinger · ghi chú
- TITLE · màn tiêu đề + menu chính (Cài đặt/Credits mở từ đây giữ nguyên cue dưới SN_DRAFT)… MUS_title_mute_night · TITLE · 66 tự do / D Aeolian · loop 90 s (không lưới) · S0 + S4 · — · cũng dùng teaser MS01 "Đêm Câm".
- HUB · HUB_BELL_TOWER Tháp Chuông Gãy (mọi trạm ST_*) · S0 + stem GĐ Phục Dựng đã mở (GD1–… MUS_hub_bell_tower · HUB · 72 3/4 / F Lydian (GD5 → D) · loop 40 ô = 100.0 s · S0 + 5 stem GĐ (GD1 hộp nhạc LM_LEM, GD2 đàn nguyệt chợ, GD3 kèn bầu, GD4 dây, GD5 chuông LM_BELL) · depart, hero_H01..H12 · 18 hộp nhạc (Nến Canh) = phát lại 18 cue này ở hub.
- DOCK · Bến Giữa Hồi (nút DOCK sau boss Hồi I–IV, ≤ 20 s, Sạp Rong + chở đò Calla sang Hồi… MUS_dock_crossing · DOCK · 84 6/8 (chấm đen = 84) / D Dorian · loop 16 ô = 22.86 s · S0–S2 · — · crossfade 8 s sang cue Hồi kế.
- EXPLORE/COMBAT · Hồi I B1 Đồi Mộ Tro · bản đồ + mọi nút CMB/ELT/CHL/RSC/EVT/SHP/RST/SEC c… MUS_b1_grave_hill · EXPLORE/COMBAT B1 · 132 4/4 / D Phrygian · 2 + 32 ô = 58.18 s · S0–S4 · elite_in, surge, room_clear, ash_read · ví dụ §3.6.
- EXPLORE/COMBAT · Hồi II B2 Đầm Vải Liệm · bản đồ + mọi nút chiến/tiện ích B2 · lớp theo I MUS_b2_shroud_marsh · B2 · 96 6/8 (chấm đen = 96) / E Aeolian · 2 + 48 ô = 60.0 s · S0–S4 · như B1 · LM_CALLA đảo trên S4.
- EXPLORE/COMBAT · Hồi III B3 Lò Đúc Câm · bản đồ + mọi nút chiến/tiện ích B3 · lớp theo I MUS_b3_mute_foundry · B3 · 140 4/4 / C Phrygian dominant · 2 + 32 ô = 54.86 s · S0–S4 · như B1 · đe ở S2 decay ≤ 150 ms (AUD-01).
- EXPLORE/COMBAT · Hồi IV B4 Thành Chuông Treo · bản đồ + mọi nút chiến/tiện ích B4 · lớp t… MUS_b4_hanging_city · B4 · 7/8 đen = 120 (2+2+3) / B Aeolian · 2 + 32 ô = 56.0 s · S0–S4 · như B1 · chuông trầm ≤ 600 Hz.
- BOSS · nút BOS Hồi I · BS_B1 Người Gác Chuông · stem theo pha (không theo I) · P3 "Chuông… MUS_boss_b1_bell_warden · BOSS BS_B1 · 120 4/4 / D Phrygian · 1 + 32 ô = 64.0 s · S0–S4 + S3b · boss_intro, phase2, phase3, ash_read, victory · P3 "Chuông Vỡ Hẳn".
- BOSS · nút BOS Hồi II · BS_B2 Lão Lái Đò Không Bến · stem theo pha · P3 "Nước Dâng": S0 t… MUS_boss_b2_ferryman · BOSS BS_B2 · 120 12/8 (chấm đen = 120) / E Aeolian · 1 + 32 ô = 64.0 s · S0–S4 + S3b · như #8 · P3 Nước Dâng: S0 thêm sóng nước.
- BOSS · nút BOS Hồi III · BS_B3 Thợ Cả Đúc Chuông · stem theo pha · S2 có 3 biến thể theo … MUS_boss_b3_founder · BOSS BS_B3 · 120 4/4 / C Phrygian dominant · 1 + 32 ô = 64.0 s · S0–S4 + S2 3 biến thể (búa/xích/giáo theo Rèn Phản) · như #8.
- BOSS · nút BOS Hồi IV · BS_B4 Thống Lĩnh Yvra & Rồng Khàn · stem theo pha · P2 tách thân:… MUS_boss_b4_yvra · BOSS BS_B4 · 120 4/4 accent 3+3+2 / B Aeolian · 1 + 32 ô = 64.0 s · S0–S4 + S3b · như #8 · P2 tách thân: S4 tách 2 bè (Yvra kèn / rồng khàn mẫu).
- GATE_MINI · nút MBS (Cổng) mọi biome · mọi MB_ (MB_B1_1, MB_B2_1, MB_B2_2, MB_B3_1, MB_B3… MUS_miniboss_gate · GATE_MINI · 120 4/4 / 4 bộ key D/E/C/B · 1 + 16 ô = 32.0 s · S0–S3 × 4 key · room_clear, victory · dùng cho mọi MB_.
- FINALE · B5 Đỉnh Chuông Câm (Kết, act V): ải 60 s trộn quái 4 Hồi (lớp theo I) + BS_FINAL… MUS_finale_crown · B5 ải + BS_FINAL · 120 4/4 / D Aeolian → D Dorian · 2 + 32 ô = 64.0 s · S0–S3 + S4 (LM_DRAVOS) + S4b1..b4 + S4h01..h12 · boss_intro, phase2, phase3, ash_read, victory · đòn cuối = chuông thật ngân 8 s.
- SECRET · B6 Bờ Lặng (Bí mật, act VI, cần FLAG_SHORE_OPEN): ải 45 s quanh Tiếng Câm EN_B6_… MUS_quiet_shore · B6 + BS_TRUE · không nhịp / drone A · loop 120 s · S0, S1 (tim 60 BPM), S4h01..h12 (P3) · boss_intro, phase2, phase3 · P2 tắt nhạc.
- DEATH · hết Lửa Gửi trong run (mọi biome, mọi mode) · bắt đầu đồng bộ thẻ recap INV-16 = … MUS_death_epitaph · DEATH · 60 4/4 / D Aeolian · loop 12 ô = 48.0 s · S0 + S4 · — · bắt đầu đồng bộ thẻ recap INV-16.
- ENDING · END_BELL_TOLL Hồi Chuông (Gióng chuông sau BS_FINAL) · phần tuyến tính 180 s = f… MUS_end_bell_toll · ENDING END_BELL_TOLL · 76 4/4 / D major · 180 s tuyến tính + credit loop 32 ô = 101.05 s · stereo full · — · chuông thật mở bài.
- ENDING · END_QUIET_SHORE Bến Bình Yên (hạ BS_TRUE ở B6) · 210 s tuyến tính đi cùng 12 thẻ… MUS_end_quiet_shore · ENDING END_QUIET_SHORE · 64 3/4 / D Lydian · 210 s tuyến tính · 12 lớp nhạc cụ hero vào lần lượt · — · đi cùng 12 thẻ kết theo hero.
- ENDING · END_ASH_CROWN Mũ Tro (chọn "Giữ lõi" ở BS_FINAL) · 120 s tuyến tính: hero đội Mũ… MUS_end_ash_crown · ENDING END_ASH_CROWN · 56 4/4 / D Locrian · 120 s tuyến tính · stereo full · — · chuông câm "thịch" thay chuông thật.
19–22. EXPLORE/COMBAT · Hồi I B1 KHI CHƠI H12 Ambrin (thay MUS_b1_grave_hill; biomes[].music.h12… MUS_b1_grave_hill_h12 · EXPLORE/COMBAT · Hồi II B2 khi chơi H12 (thay MUS_b2_shroud_marsh) · 6/8 96 → 12/8 chấm đ… MUS_b2_shroud_marsh_h12 · EXPLORE/COMBAT · Hồi III B3 khi chơi H12 (thay MUS_b3_mute_foundry) · 140 → 120, hi-hat k… MUS_b3_mute_foundry_h12 · EXPLORE/COMBAT · Hồi IV B4 khi chơi H12 (thay MUS_b4_hanging_city) · 7/8 → 4/4 120, giữ a… MUS_b4_hanging_city_h12 · B1–B4 khi chơi H12 · 120 (B2 12/8 chấm đen = 120; B4 4/4 accent 3+3+2) / key như gốc · 2 + 32 ô = 64.0 s · S0–S4 + stinger như gốc · không tính vào 18 bản (canon "+ 4 bộ stem").
64. SFX — đặt tên, mẫu spec, khuôn sự kiện
4.1 Đặt tên (canon §11)
- Sự kiện:
SFX_<ownerId>_<slug>;ownerId= id chủ (Varek H01, Hàng Cọc Tro H01_SK03, Trăng Máu H01_UL1, Quỷ Rãnh EN_B1_02, Vồ EN_B1_02_A01, Thợ Cả Đúc Chuông BS_B3, Sương Giá STS_FROST, Mưa Chuông MUT03, Tro Sống MRN15) hoặcUI/HUB/SHARED; sự kiện môi trường trongdata/av/ENV_*.jsondùng ownerENV_B1…ENV_B6/ENV_HUB(vd HazardTrigger hazardId=HZ_B6_mirror_shallows phase=state: bước chân h… SFX_ENV_B6_hz_wade,ownerGroupWorld), bed/hazard lõi giữ owner biome cũ (HazardTrigger hazardId=HZ_B1_open_grave (nắp bật cuối ấn tro 0.6 s; n… SFX_B1_hz_open_grave, BiomeEnter biome=B3 (vào phòng B3, fade 1.0 s) SFX_B3_amb_bed); slug snake_case thường. Ví dụ: UltActivate ultId=H01_UL1 (H01_UL1_BLINK 8 nhát + H01_UL1_BURST trăng… SFX_H01_UL1_moon,SFX_EN_B1_02_A01_swing, DraftPick rarity=COMMON|RARE|EPIC (biến thể 01 COMMON, 02 RARE, 03 EP… SFX_UI_card_pick. - File:
<eventId>_<nn>.ogg(nn = biến thể 01..), lớp thứ 2:<eventId>__<layer>_<nn>.ogg. Thư mục:Assets/_Project/Audio/SFX/<ownerGroup>/<ownerId>/(ownerGroup=HeroesEnemiesBossesSharedUIHubWorld). - Không đặt 2 sự kiện cho cùng 1 âm: sự kiện khác chủ dùng âm chung → field
asset_reftrỏ tớiSFX_SHARED_*(tính "dùng lại"). - Map tên demo → 1.0:
tell_gold→ EnemyWindupStart tellClass=Y → lịch PlayScheduled đỉnh transient đúng… SFX_SHARED_tell_y_tinh ·tell_violet→ EnemyWindupStart tellClass=P (cả hazard/Khăn Tang/mutator P); chọn bả… SFX_SHARED_tell_p_swell ·swing_l1/l2/swing_heavy→ HeroAttackCut heroId=H01 moveIndex=1 (H01_COMBO_A_1; H01_UL3_ECHO dư … SFX_H01_a1_swing/a2_swing/a3_swing·hit_blade/hit_heavy→ HeroHitBatch heroId=H01 (HordeAudio §6.1 gộp mỗi frame; + hit_heavy c… SFX_H01_hit / HeroHitBatch hasHeavyTarget=true (Tinh Anh/mini/boss trong cụm) + đòn… SFX_SHARED_hit_heavy ·parry_1/2→ HeroAnswerSuccess heroId=H01 (H01_ANSWER Gạt + H01_ANSWER_REFLECT; lớ… SFX_H01_answer ·perfect→ HeroAnswerSuccess (lớp chung dưới SFX_{H}_answer) + send Answer SFX_SHARED_answer_core ·riposte→SFX_H01_riposte·block→SFX_H01_hold_block·dash→ HeroDash frame 0 (lớp chung dưới SFX_{H}_dash) SFX_SHARED_dash_base ·crescent/leap→ SkillCast skillId=H01_SK01 rank=I|II|III (+ lớp __impact khi trúng; H… SFX_H01_SK01_cast/SkillCast skillId=H01_SK02 rank=I|II|III (H01_SK02_LEAP bật nhảy + H0… SFX_H01_SK02_cast ·slam→ nguồn reuse: nện đất/tiếp đất nặng (hero, Tinh Anh, boss) SFX_SHARED_slam_ground ·ult→ UltActivate ultId=H01_UL1 (H01_UL1_BLINK 8 nhát + H01_UL1_BURST trăng… SFX_H01_UL1_moon ·surge→SFX_H01_res_surge·bell→SFX_BS_B1_*·roar→ EliteSpawn (+ SFX_{E}_vocal + stinger elite_in); biến thể theo EM01–E… SFX_SHARED_elite_affix/boss intro ·cast/reflect→ EnemyProjectileFire (enemyId=EN_B1_03, attackId=EN_B1_03_A01) — khung… SFX_EN_B1_03_A01_cast / EnemyProjectileReflected (đạn bị ĐÁP dội, lõi trắng) SFX_SHARED_proj_reflect ·boom→ nguồn reuse: Xác Trương EN_B1_05, bom, Đinh nổ; ≤ 3/80 ms, dư cộng +2… SFX_SHARED_explode_s ·break→ PoiseBroken (Vỡ Thế Tinh Anh/mini/boss) SFX_SHARED_poise_break ·hurt→ HeroDamaged (kèm SFX_{H}_vo_hurt) SFX_SHARED_hero_hurt_impact ·death1/2→ EnemyKilledBatch (HordeAudio cửa sổ trượt 100 ms, doc 32 §6.2) SFX_SHARED_kill_crunch ·pickupchestcardlevelupresonance→ PickupCollected type=xp (chuỗi 0.5 s: pitch +1 bán cung mỗi nhặt, tối… SFX_SHARED_xp_pickuprelic_chest/ DraftPick rarity=COMMON|RARE|EPIC (biến thể 01 COMMON, 02 RARE, 03 EP… SFX_UI_card_pick / LevelUp (trước DraftOpen; nhạc stinger level_up của MusicDirector) SFX_SHARED_level_upresonance·music_drums→ bỏ (thay §3) ·amb_dungeon→ RunStart/ActChanged biome=B1 + RoomStart B1 (phòng ngoài trời) SFX_B1_amb_bed (§10). 9 file chưa có credit (chest, hurt, levelup, pickup, resonance, riposte, roar, swing_enemy, ult) → thay mới hoặc xác minh nguồn trước MS02.
4.2 Mẫu spec SFX (FINAL) — 1 hàng/sự kiện trong GDD/Full/data/audio_sfx.csv (agent audio tạo; khoá cột)
| Field | Kiểu | Định nghĩa / giá trị hợp lệ |
|---|---|---|
id | string | SFX_<ownerId>_<slug> |
owner | id | chủ; SHARED/UI/HUB cho âm chung |
hook | string | EventName phát (§12) + điều kiện (vd HeroAttackCut khi move=A1) |
frame | string | frame kích: cut (frame chém), contact, windup_start, T-0.12, spawn, end; hoặc event |
kind | enum | swing hit cast shot impact explode tell_y tell_p answer move vocal loop ui_short ui_jingle stinger amb_spot |
layers | text | transient (0–6 ms, chất liệu) / body (150–450 Hz trọng lượng, chất liệu) / tail (lấp lánh, phòng); mỗi lớp 1 chất liệu; tối đa 3 |
length_ms | int | tổng; one-shot ≤ 1.500 ms trừ ult/boss ≤ 4.000 |
variants | int | ≥ 3 cho mọi âm lặp (hit, swing, shot, step, death); 1 cho UI/stinger |
pitch_rand · vol_rand | % · dB | mặc định ±6% · ±1.5 dB; tell ±1% · 0 dB |
priority | 0–255 | Unity AudioSource.priority, 0 = cao nhất (bảng §5.3) |
max_voices · cooldown_ms · steal | int · int · enum | trần voice cho id; khoảng tối thiểu giữa 2 lần; oldest/quietest/none |
spatial | enum | center (hero, UI) / screen_pan (pan theo x màn ±0.6, suy giảm §5.5) / screen_pan_full (tell trợ năng) |
clock | enum | World (pitch theo slow-mo §5.7) / Hero / UI (không pitch) |
bus | enum | nhóm mixer §5.1 |
ducks · ducked_by | text | id snapshot/send (§5.6) |
lufs_mmax | dB | momentary-max BS.1770 (cửa sổ 400 ms) theo bảng §4.3; đỉnh ≤ −1 dBTP; onset ≤ 12 ms (trừ swell/charge) |
loop · loop_start · loop_end | bool · mẫu · mẫu | loop mẫu-chính-xác; file loop không fade đầu/cuối |
tell_class | enum | Y / P / N / none (âm Y/P chỉ được là asset tell chung hoặc lớp phụ ≤ −12 dB so với nó) |
asset_ref | id | trỏ âm chung (SFX_SHARED_*) khi dùng lại; rỗng = âm riêng |
source | enum | reuse / freesound / synth / foley / outsource |
brief | text | vật gì, chất liệu gì, làm gì, vào gì, cỡ nào + "KHÔNG được nghe như …" |
freesound_query | text | query + bộ lọc (license, max_duration, single_event, sort, min_num_ratings) |
synth_recipe | text | recipe create-sfx + element + tham số (--pitch --life --tint --seed) |
credit | text | dòng credit CC BY (rỗng nếu CC0/synth) |
status · verdict | enum | brief/sourced/mastered/wired/final · pending/ok/redo (nghe theo lô) |
Ví dụ đủ field — HeroAttackCut heroId=H01 moveIndex=1 (H01_COMBO_A_1; H01_UL3_ECHO dư … SFX_H01_a1_swing: owner H01 · hook HeroAttackCut move=A1 · frame cut (cả khi hụt) · kind swing · layers: transient 4 ms cạo thép sáng 3–6 kHz / body 120 ms whoosh bandpass 400–1.800 Hz quét xuống / tail 80 ms ngân sống lưỡi ~2.4 kHz ở −18 dB (decay ≤ 60 ms → hợp lệ AUD-01) · 220 ms · 4 biến thể, ±6%, ±1.5 dB (A2 = gốc +4%; A3 = HeroAttackCut heroId=H01 moveIndex=3 (H01_COMBO_A_3, H01_HEAVY_1 Bổ C… SFX_H01_a3_swing riêng) · priority 40, max 2, cooldown 60 ms, steal oldest · center · clock World · bus HeroAttack · ducked_by send Answer · −19 LUFS mmax · loop no · tell none · source freesound · brief "lưỡi liềm thép mỏng chém không khí, nhanh, nhẹ; KHÔNG nghe như dao phay nặng, quạt máy, tiếng zip hoạt hình" · query "sword whoosh swing fast blade", license cc0, max_duration 0.6, single_event, sort rating_desc, min_num_ratings 5 · synth fallback dash_whoosh --element neutral --tint metal · status final · verdict pending.
4.3 Mục tiêu độ to theo loại (PC; momentary-max, trước bus fader)
| Kind | LUFS mmax | Dài | Biến thể | Cooldown mặc định |
|---|---|---|---|---|
| tell_y "tinh" | −14 | 220 ms | 1 (±1%) | 0 (token giới hạn) |
| tell_p swell (đỉnh) | −16 | = windup | 3 độ dài | 0 |
| answer (lớp chung + hero) | −12 (tổng) | 250–450 ms | 3 | 80 ms |
| hero swing | −19 | 150–300 ms | 4 | 60 ms |
| hero hit (1 mục tiêu) | −20 | 120–250 ms | 4 | 50 ms (≤ 3/50 ms, demo) |
| hero cast kỹ năng | −17 | 300–900 ms | 2–3 | 150 ms |
| hero ult | −13 | 1.0–4.0 s | 1–2 | — |
| enemy swing (không tell) | −25 | 150–300 ms | 3 | 80 ms |
| enemy vocal | −26 | 200–800 ms | 4 | 250 ms |
| kill crunch đơn / cụm / gặt | −24 / −20 / −17 | 150 / 300 / 500 ms | 4 / 3 / 3 | 25 / 100 / 250 ms |
| explode nhỏ / lớn | −20 / −16 | 400 / 900 ms | 3 | 80 ms |
| boss chữ ký | −15 | ≤ 2.5 s | 2 | — |
| ui_short / ui_jingle | −22 / −16 | 60–300 ms / 0.8–2.0 s | 1–3 / 1 | 40 ms / — |
| vocal hero (gắng sức) | −20 | 150–500 ms | 5 | 400 ms |
| amb loop / spot | −30 / −26 (LUFS-I loop) | ≥ 20 s / 1–6 s | — / 4 | — / 3 s |
4.4 Khuôn sự kiện theo chủ (sinh audio_sfx.csv từ khuôn; số khớp canon §10.3)
Hero — 28 sự kiện/hero × 12 = 336 (slug cố định, Hxx thay id):
| # | Slug | Frame/hook | Ghi chú |
|---|---|---|---|
| 1–3 | a1_swing a2_swing a3_swing | cut mỗi đòn chuỗi (hero chuỗi dài hơn: đòn 4+ dùng a2 pitch +4%/bước) | đòn kết chuỗi = a3 (nặng) |
| 4 | hit | contact | chất liệu vũ khí; gộp bầy §6 |
| 5 | combo_special | nhánh combo chữ ký (H01 Đánh sau Lướt · H02 Xoay Quan · H03 cắm sào · H04 đổi thế Tách/Ghép · H05 giật đe về · H06 ném bowling · H07 Tên Hồi · H08 phản ứng cặp ổ (9 lớp) · H09 Ném Bó · H10 Châm · H11 lấp hố · H12 khúc 4 phách) | |
| 6 | dash | Lướt frame 0 | lớp hero trên HeroDash frame 0 (lớp chung dưới SFX_{H}_dash) SFX_SHARED_dash_base |
| 7 | answer | ĐÁP thành công | lớp hero trên HeroAnswerSuccess (lớp chung dưới SFX_{H}_answer) + send Answer SFX_SHARED_answer_core |
| 8 | counter | đòn COUNTER sau ĐÁP (Phản đòn, Dội, ném…) | |
| 9–11 | hold_start hold_loop hold_end | verb giữ RB/RMB | loop dừng ngay khi thả/huỷ (INV-11) |
| 12–14 | res_gain res_full res_spend | tài nguyên tăng (cooldown 120 ms) / đạt ngưỡng (Cuồng Lưu, 6 Đinh, 3 Vang, 5 Mực, Đà 100, Chảy, Đỉnh Hơi, ổ đầy, 6 Vòng, 5 Khói, 5 Đất, 16 Nhịp) / xả | |
| 15–22 | SK01_cast … SK08_cast | kỹ năng (owner = Hxx_SKnn, vd SkillCast skillId=H01_SK01 rank=I|II|III (+ lớp __impact khi trúng; H… SFX_H01_SK01_cast); va chạm riêng = lớp __impact | hạng II–III = cùng âm + lớp sweetener (biến thể) |
| 23–25 | UL1_* UL2_* UL3_* | Ult (slug riêng, canon vd UltActivate ultId=H01_UL1 (H01_UL1_BLINK 8 nhát + H01_UL1_BURST trăng… SFX_H01_UL1_moon); kèm stinger ult_Hxx | duck §5.6 |
| 26–28 | vo_effort vo_hurt vo_death | gắng sức (≤ 1/1.2 s) · trúng đòn · chết | giọng không lời §9 |
- Dạng Rèn AS2/AS3 đổi vũ khí → bộ biến thể thay cho #1–#4 (+8 file/hero), không thêm id. Đòn Vọng (BS_TRUE/EN_B6_01) = âm kỹ năng hero + lọc đảo (§5.6
fx_reverse_tint), 0 âm mới.
Quái thường + Tinh Anh — 5 sự kiện × 39 = 195: atk (thân đòn không phải tell; mỗi đòn _Ann 1 lớp con __A01…) · impact (đạn/đòn trúng) · vocal (aggro/idle, cooldown 250 ms toàn loài) · hurt (chỉ Tinh Anh phát mỗi lần; quái thường gộp vào hit của hero) · death (Tinh Anh riêng; quái thường = asset_ref → kill_* + lớp chất liệu biome). Tell luôn là asset chung (AUD-03). Mini/boss/kết — 8 sự kiện × 13 = 104: intro · move_loop · sig_a · sig_b · sig_c (3 đòn chữ ký; đòn khác = lớp con __Ann) · phase · broken (Vỡ Thế) · death. BS_B3 sig_a có 3 lớp búa/xích/giáo; BS_FINAL sig_c = Hồi Chuông thật; BS_TRUE phase = nuốt âm. Nhóm khác — lõi canon 95: hệ thống SFX_SHARED_* nhóm S (27, §8) · UI 29 (§7) · HUB 13 (§7.2) · hazard 14 (§10.2) · trạng thái 6 loop SFX_STS_<NAME>_loop · ambience 6 bed RunStart/ActChanged biome=B1 + RoomStart B1 (phòng ngoài trời) SFX_B1_amb_bed…BiomeEnter biome=B6 (cảnh đò giây 9) → loop tới BS_TRUE P2; fader bus… SFX_B6_amb_bed (hub bed trong HUB). Nhóm khác — mở rộng theo data AV (2026-11-07) +150 → 245: UI +8 (§7.1, data/av/UI.json) · HUB +16 (§7.2, ENV_HUB.json) · hazard +32 (§10.2, tổng 46) · bed hầm B1 +1 (§10.1) · spot ambience biome 29 (§10.1) · đạo cụ/mục tiêu/phòng/cảnh biome 64 (§10.3). Tổng: 336 + 195 + 104 + 245 = 880 = canon ~880 (DEC-2026-11-07-17; nhóm khác = lõi 95 + 150 mở rộng). Nhóm R của SHARED (30 asset, §8) là nguồn "dùng lại" của sự kiện hero/quái, không cộng thêm id. Ngoài 880 (không phải sự kiện SFX): nhạc 18 + 4 bộ H12 · stinger nhạc (asset con); click máy nhịp H12 = biến thể click của HeroResource heroId=H12 kind=gain (Nhịp +1/+2) · nhạc công Trống Sóng… SFX_H12_res_gain.
75. Mixer Unity, ưu tiên, voice, suy giảm, ducking, độ to
5.1 Cây bus (Assets/_Project/Audio/Mixer/BW_Main.mixer, 1 AudioMixer; fader mặc định)
| Group | Cha | Fader | Hiệu ứng (thứ tự) | Exposed param |
|---|---|---|---|---|
Master | — | 0 dB | Highpass Simple 25 Hz → Compressor (thr −10 dB, ratio 3:1, attack 10 ms, release 120 ms) → Compressor-giới hạn (thr −2 dB, ratio 20:1, attack 1 ms, release 50 ms) | vol_master |
Music | Master | −4 dB | Lowpass (snapshot), Duck Volume (nhận send Answer, Ult, VO, TellP) | vol_music, music_lp_hz |
Music_Stem | Music | 0 | — | — |
Music_Stinger | Music | −2 dB | — | — |
Ambience | Master | −8 dB | Lowpass (snapshot), Duck Volume (nhận VO) | vol_amb |
SFX | Master | 0 dB | Duck Volume (nhận Answer) | vol_sfx |
HeroAttack | SFX | 0 | — | — |
HeroDefense | SFX | +2 dB | Send Answer (khi answer phát) | — |
HeroSkill | SFX | 0 | Send Ult (khi Ult) | — |
Enemy | SFX | −6 dB | Duck Volume (nhận TellY, TellP, Ult) | — |
EnemyCrowd | Enemy | −2 dB | Compressor (thr −18 dB, 4:1) — "keo" đám đông | — |
EnemyHeavy | Enemy | 0 | — (Tinh Anh/mini/boss) | — |
EnemyTell | SFX | +3 dB | Send TellY/TellP; miễn duck và snapshot bóp (AUD-03) | vol_tell (Trợ năng, sàn −6 dB) |
World | SFX | −3 dB | hazard, đạo cụ, mục tiêu | — |
Status | SFX | −6 dB | loop trạng thái | — |
UI | Master | −2 dB | bỏ qua pause | vol_ui |
VO | Master | 0 dB | Send VO | vol_vo |
Ghi chú: Unity không có fader trên send-receive riêng; Duck Volume cài: threshold −30 dB, ratio 4:1 (mức giảm đích ở §5.6 đạt bằng attenuation của từng duck), attack 5 ms, release theo bảng §5.6.
- Luật B6 Bờ Lặng (2026-11-07, từ
biomes/B6.json): khi hero ở B6 (act VI), faderHeroAttackvàHeroSkill= −6 dB so với mặc định (đặt thẳng exposed param quaAudioSettingsService, chuyển 1.0 s khi vào/ra; không thêm snapshot); cộng dồn vớiSN_WEDGE/SN_MUTE_SKILLnếu chúng bật.HeroDefense(ĐÁP) vàEnemyTellgiữ nguyên mức (INV-02, AUD-03). Đi kèm: send reverb mọi bus = 0 ở B6 (§10.1). [ASSUMED, khớp codex Bờ Lặng CDX_b6 "nhỏ hơn một nửa"]. - Giá trị
bustrong data AV (enum schema) → group mixer:Tell→EnemyTell·Stinger→Music_Stinger·EnemyHorde→EnemyCrowd·Boss→EnemyHeavy·Hero→HeroAttack· các giá trị trùng tên (MasterMusicSFXHeroAttackHeroDefenseEnemyWorldAmbienceUIVO) → group cùng tên. Kỹ năng hero vàoHeroSkilltheo hookSkillCast/UltActivate(§12.2), không theo fieldbus.
5.2 Snapshot (chuyển 0.15 s trừ khi ghi khác)
| Snapshot | Khi | Thay đổi |
|---|---|---|
SN_DEFAULT | chơi | như §5.1 |
SN_DRAFT | draft/tạm dừng/menu trong run | Music LP 800 Hz −6 dB · SFX −12 dB · Ambience LP 1.200 Hz · UI 0 |
SN_HUB | hub | Music −6 dB (dưới lửa + giọng NPC) · Ambience −4 dB |
SN_BOSS_INTRO | 2.0 s khung tên boss | SFX −8 dB · Ambience −12 dB |
SN_DEATH | chết | SFX LP 600 Hz −10 dB trong 1.5 s → −40 dB · Music → DEATH · hết Lửa Gửi trong run (mọi biome, mọi mode) · bắt đầu đồng bộ thẻ recap INV-16 = … MUS_death_epitaph |
SN_SWALLOW | BS_TRUE P2 "Nuốt Tiếng" | MỌI bus trừ EnemyTell/UI: LP 400 Hz, −18 dB; Music −80 dB (canon "SFX bóp trừ tell") |
SN_WEDGE | hero trong rẻ quạt BS_TRUE P1 | HeroAttack/HeroSkill/HeroDefense −40 dB ("không âm"), EnemyTell giữ |
SN_MUTE_SKILL | Hồi Câm BS_FINAL / Tiếng Câm EN_B6_02 (câm kỹ năng) | HeroSkill LP 300 Hz −12 dB cho tới hết câm |
SN_SMALL_SPEAKER | tuỳ chọn "Loa nhỏ" / tự đề xuất trên Deck không tai nghe | Master HP 150 Hz, Compressor thr −16 dB 4:1, EnemyTell +2 dB |
5.3 Ưu tiên (Unity priority, 0 = cao) & giới hạn voice (Project Settings › Audio: Real Voices 64, Virtual 256, DSP buffer Best latency = 256 mẫu)
| Nhóm | Priority | Voice thật tối đa | Cooldown/throttle | Steal |
|---|---|---|---|---|
Tell Y (tinh, glint1) | 0 | 7 (= token 4 cận chiến + 3 đạn) | — | none (dành chỗ) |
| Tell P (swell, proj) | 1 | 5 (= token tím ≤ 5) | — | none |
| ĐÁP / Né Hoàn Hảo / Phản | 2 | 2 | 80 ms | oldest |
| Ult hero / boss chữ ký | 5 | 3 | — | quietest |
| Music stem + stinger | 8 | 12 (2 cue × 5 stem khi crossfade + 2 stinger) | — | none |
| Hero swing/skill/combo | 20 | 6 | 60 ms/id | oldest |
| Hero hit (gộp §6) | 30 | 4 | 3/50 ms | oldest |
Boss/mini/Tinh Anh (EnemyHeavy) | 40 | 6 | 80 ms/id | quietest |
| VO hero/NPC | 45 | 2 | 400 ms | oldest |
| Kill (gộp §6) | 60 | 4 | 4/100 ms | oldest |
| Explode/slam | 70 | 3 | 80 ms | quietest |
Enemy thường atk/vocal/impact (EnemyCrowd) | 100 | 6 | 80 ms/id, vocal 250 ms/loài | quietest |
| World/hazard | 110 | 4 | 1.0 s/id (nhịp ≥ 1.0 s INV-18) | quietest |
| UI | 120 | 4 | 40 ms | oldest |
| Ambience bed + spot | 150 | 4 | spot 3 s | quietest |
| Status loop | 160 | 3 | — | quietest |
| Pickup (XP/vàng/máu) | 180 | 2 | gộp chuỗi 0.5 s | oldest |
Trần nhóm cộng = 77 > 64 (cố ý): khi đầy, Unity ảo hoá nguồn priority cao số nhất trước (Pickup → Status → Ambience → EnemyCrowd). Tổng chỗ dành: 7 + 5 + 2 + 3 + 12 = 29 voice không bao giờ bị cướp; còn 35 cho phần còn lại; mục tiêu p95 voice thật ≤ 56 khi 250 quái + Ult (AP2). Pool AudioSource: 48 one-shot + 12 music + 4 ambience (thay 24 nguồn round-robin của demo).
5.4 Ngân sách tell đồng thời (từ token INV-08)
Cận chiến ≤ 4 windup nhắm hero (≤ 2 khi Elite/Boss windup) + ≤ 3 loạt đạn → ≤ 7 "tinh" chồng; tím sàn ≤ 5 tổng. Hai "tinh" trong 40 ms → phát cả hai nhưng cái sau −3 dB và +1 bán cung (không gộp: mỗi tell là 1 thông tin). Đòn Y×n: mỗi nhịp 1 "tinh" riêng (INV-02).
5.5 Suy giảm khoảng cách (góc 3/4, không 3D)
spatialBlend = 0cho mọi nguồn; pan bằngpanStereo; không Doppler, không reverb theo vị trí.- Khoảng cách
dđo trên mặt sàn (x, z) bằng art px từ hero (người nghe = hero, không phải camera, để tâm luôn đúng nhân vật). Màn 480×270 art px; tầm sàn nửa ngang 240. - Pan:
pan = clamp((x_src − x_hero) / 240, −1, 1) × 0.6(screen_pan);× 1.0khiscreen_pan_full. - Gain:
d ≤ 120→ 0 dB ·120 < d ≤ 300→ tuyến tính dB tới −12 dB ·d > 300(ngoài màn) → −18 dB và CHỈ phát nếu priority ≤ 40; tell ngoài màn: −6 dB tối đa (không bao giờ dưới), pan đầy, "tinh" +2 bán cung (trợ năng bật). - Trục dọc màn bị nén 0.5 (
screenY = z·0.5): khoảng cách tính bằng z thật, nên quái trên/dưới cách 60 px màn = 120 px sàn → đúng cảm giác 3/4. - Hero và UI:
center, không suy giảm.
5.6 Ducking / sidechain
| Nguồn (send) | Đích | Mức | Attack / giữ / nhả |
|---|---|---|---|
Answer (ĐÁP, Né Hoàn Hảo, Phản) | SFX trừ HeroDefense + EnemyTell | −8 dB | 5 ms / 250 ms / 200 ms |
Answer | Music | −4 dB | 10 ms / 400 ms / 400 ms |
Ult (hero Ult toàn anim) | Music −6 dB · Enemy −6 dB | 20 ms / theo anim / 500 ms | |
TellY | EnemyCrowd | −3 dB | 2 ms / 150 ms / 150 ms |
TellP | EnemyCrowd −4 dB · Music −2 dB | 50 ms / tới va chạm / 300 ms | |
| Boss windup tím chữ ký | Music S1–S3 −3 dB (MusicDirector, §3.4) | theo windup | |
VO (bark/giọng NPC/hero) | Music −4 dB · Ambience −3 dB | 30 ms / theo clip / 300 ms | |
| Stinger boss_intro/phase | Music_Stem −6 dB | 20 ms / 1.0 s / 500 ms |
fx_reverse_tint(Đòn Vọng của bóng hero/Gương Lặng): âm kỹ năng hero phát quaEnemy+ Lowpass 2.5 kHz + pitch −2 bán cung; tell của đòn đó vẫn dùng asset tell chung.
5.7 Đồng hồ & slow-mo
clock = World:pitch = max(0.75, 0.5 + 0.5 × worldScale)(World 25% Né Hoàn Hảo → 0.625 → kẹp 0.75); hitstop KHÔNG đổi pitch.clock = Hero/UI/ Music / VO / EnemyTell: pitch 1.0 cố định.- Lịch tell:
PlayScheduled(dspNow + (t_impact − 0.12 − t_now)/worldScale − outputLatency − audioOffsetMs); tính lại mỗi frame nếuworldScaleđổi trong windup. - Tạm dừng: mọi nguồn
World/Heropause; UIignoreListenerPause = true; nhạc tiếp tục dướiSN_DRAFT.
5.8 Độ to chương trình & tuỳ chọn người chơi
| Đo | Mục tiêu | Cách đo |
|---|---|---|
| Combat (Hồi I, 5 phút, 150–250 quái) | −16 LUFS-I ±1 | thu Master offline (Sfx offline mix của demo) |
| Hub/menu | −18 LUFS-I ±1 | 3 phút hub |
| Đỉnh | ≤ −1 dBTP | toàn bộ phiên |
| LRA combat | 6–12 LU | — |
Loa nhỏ (SN_SMALL_SPEAKER) | −14 LUFS-I, LRA ≤ 6 | Steam Deck loa trong |
Tuỳ chọn: Master/Music/SFX/Ambience/UI/VO 0–100% (bước 5) · Âm tell 50–150% (sàn −6 dB) · Dải động: Rộng / Thường (mặc định) / Hẹp (= SN_SMALL_SPEAKER) · Mono · Âm tell theo vị trí · Phụ đề tell · Click nhịp H12 · Hiệu chỉnh trễ âm −100..+100 ms (màn gõ theo nhịp 8 lần, lấy trung vị) · Tắt âm khi cửa sổ mất focus (mặc định bật).
86. Luật bầy (horde) — gộp, lớp, ngẫu nhiên (class HordeAudio, chạy cuối frame sau Combat)
6.1 Gộp cú trúng của hero (mỗi frame, mỗi nguồn sát thương)
n = số mục tiêu hero trúng trong frame từ 1 đòn/1 sóng VFX (sóng lan §6.1 demo: đếm theo frame mặt sóng chạm).
| n | Phát | Mức thêm | Ghi chú |
|---|---|---|---|
| 1 | SFX_<Hxx>_hit | 0 | |
| 2–5 | SFX_<Hxx>_hit + HeroHitBatch n = 2–5 (cộng +1.5 × log2(n) dB, ≤ +3.5) SFX_SHARED_hit_multi | +1.5 × log2(n) dB (≤ +3.5) | 1 voice mỗi lớp |
| ≥ 6 | SFX_<Hxx>_hit + HeroHitBatch n ≥ 6 (cộng +3 × log2(n/3) dB, trần +6) SFX_SHARED_hit_mass | +3 × log2(n/3) dB, trần +6 | hit_mass có thân trầm 80–200 Hz |
| chí mạng trong cụm | + HeroHitBatch critCount ≥ 1 (1 lần/frame) SFX_SHARED_hit_crit 1 lần/frame | 0 | không nhân theo số chí mạng |
| Tinh Anh/boss trong cụm | + HeroHitBatch hasHeavyTarget=true (Tinh Anh/mini/boss trong cụm) + đòn… SFX_SHARED_hit_heavy riêng (bus EnemyHeavy) | 0 | luôn nghe được đòn vào kẻ lớn |
- Throttle sau gộp: ≤ 3 lần phát
hit/ 50 ms toàn cục (demo canon); vượt → cộngnvào lần kế (không mất cảm giác "nặng"). - INV-10: frame có ≥ 1 cú trúng của hero mà bị throttle → lần phát kế dời ≤ 1 frame, không bỏ hẳn.
6.2 Kill-crunch (cửa sổ trượt 100 ms)
k = số quái thường chết trong 100 ms gần nhất.
| k | Lớp phát (1 lần cho cả cửa sổ) | Mức |
|---|---|---|
| 1 | kill_crunch (xương gãy + tro phụt, chất liệu biome qua lớp __B1..B6) | −24 |
| 2–4 | kill_crunch × 2 lệch 15–35 ms ngẫu nhiên + rắc xương | −22 |
| 5–11 | kill_cluster (đã trộn sẵn 4–6 lớp) + 1 kill_crunch | −20 |
| ≥ 12 | kill_reap (thump trầm 60 Hz + mưa xương + tro "xào") ≤ 1/250 ms + kill_cluster | −17 |
- Cao độ
kill_crunch: ngẫu nhiên ±8%; khi chuỗi gặt liên tục ≥ 2 s (≥ 12 kill/100 ms mỗi lần) →kill_reaplên +1 bán cung mỗi 2 s, tối đa +3, về 0 sau 1.5 s không gặt (thưởng cảm giác dọn bầy, P2 canon). - Tinh Anh/mini chết: luôn phát
deathriêng (không gộp) + EnemyKilled Tinh Anh+/mini (tan dither 0.4 s, sau death riêng) SFX_SHARED_corpse_dissolve. - Xác Trương EN_B1_05 nổ dây chuyền: gộp như explode — ≤ 3
explode_s/ 80 ms, còn lại cộng mức +2 dB vào lần kế.
6.3 Âm quái thường trong bầy
- Bước chân: KHÔNG có âm từng con. HordeAudio mỗi frame: crossfade 4 lớp theo alive_view 0–20/20–80/80–1… SFX_SHARED_crowd_bed (loop 4 lớp: ít/vừa/đông/rất đông) crossfade theo
alive_view: 0–20 / 20–80 / 80–160 / 160–250, mỗi biome 1 lớp chất liệu (bảng §2.4), busEnemyCrowd−30 → −22 LUFS. vocalaggro/idle: mỗi loài ≤ 1 / 250 ms toàn cục, ≤ 3 voice tổng; chọn con gần hero nhất trong khung.atk(thân đòn không tell): chỉ con đang giữ token mới phát (token = đúng những con nguy hiểm) → ≤ 7 + quái không token im.hurtquái thường: không phát (cú trúng của hero đã đủ).- Spawn:
spawn_ash≤ 2 voice; ≥ 6 ấn spawn trong 0.3 s → 1 lầnspawn_ash+3 dB (đợt TIDE nghe như 1 đợt sóng).
6.4 Ngẫu nhiên & chống lặp
- Biến thể: chọn ngẫu nhiên không lặp lại biến thể vừa phát (round-robin xáo trộn, "shuffle bag").
- Pitch ±6% / vol ±1.5 dB mặc định; quái thường ±8% / ±2 dB; tell ±1% / 0 dB; UI 0%.
- Lệch thời gian (micro-offset) cho lớp gộp: 0–20 ms ngẫu nhiên để 2 lớp không trùng pha.
- Seed: dùng RNG riêng âm thanh (không dùng RNG gameplay → không ảnh hưởng seed DAILY).
6.5 Kiểm hiệu năng âm (Lát Chịu Tải MS01b)
Kịch bản MS01b (250 quái + H01 Ult + 1 Tinh Anh + MESO) trên Steam Deck: CPU audio thread ≤ 1.0 ms/frame p95 · voice thật p95 ≤ 56 · 0 clipping Master (đỉnh ≤ −1 dBTP) · HordeAudio ≤ 0.10 ms/frame main thread · 0 cấp phát GC/frame.
97. UI & hub
7.1 UI (37 sự kiện SFX_UI_* = 29 lõi + 8 thêm 2026-11-07; bus UI; clock UI; chất liệu giấy/gỗ/đồng nhỏ, AUD-01; spec đủ field ở data/av/UI.json)
| Id | Khi | Âm (≤ 1 dòng) | LUFS |
|---|---|---|---|
| UiNavigate (focus đổi; cooldown 40 ms khi giữ hướng) SFX_UI_nav_move | di chuyển focus | gõ gỗ nhỏ khô 30 ms | −26 |
| UiConfirm (A / Enter / click trái) SFX_UI_nav_confirm | xác nhận | giấy gấp + gỗ "cộc" | −22 |
| UiBack (B / Esc / click phải) SFX_UI_nav_back | quay lại | giấy lật ngược | −24 |
| UiError (hành động không được phép: thiếu tiền, khoá, ô đầy) SFX_UI_nav_error | không được phép | gỗ bịt 2 nhịp trầm | −22 |
| UiTabSwitch (LB/RB, Q/E, click tab) SFX_UI_tab_switch | đổi tab (LB/RB) | lật trang sổ | −24 |
| UiSliderStep (mỗi bước thanh trượt; pitch = −6..+6 bán cung theo giá … SFX_UI_slider_tick | thanh trượt mỗi bước | tích gỗ nhỏ, pitch theo giá trị | −28 |
| UiHoldStart → loop cháy dần (1.0 s mặc định) → UiHoldComplete 'phụt';… SFX_UI_hold_confirm | giữ để xác nhận (loop + chốt) | tro cháy dần + "phụt" | −22 |
| UiPopupOpen / UiPopupClose (biến thể 01 open, 02 close) SFX_UI_popup | mở/đóng popup (2 biến thể open/close) | vải phủ / vải kéo | −24 |
| UiPause open/close (Start / Esc; snapshot SN_DRAFT; UI ignoreListener… SFX_UI_pause | mở/đóng tạm dừng | chuông gió trầm 1 tiếng (≤ 600 Hz) | −22 |
| DraftOpen (sau LevelUp; 3 thẻ rút ra lệch 60 ms; snapshot SN_DRAFT) SFX_UI_draft_open | mở draft (3 thẻ) | 3 lá giấy rút ra lệch 60 ms | −20 |
| UiCardHover (focus/rê sang thẻ trong draft, shop, chọn Relic) SFX_UI_card_hover | rê thẻ | giấy sột nhẹ | −28 |
| DraftPick rarity=COMMON|RARE|EPIC (biến thể 01 COMMON, 02 RARE, 03 EP… SFX_UI_card_pick | chọn thẻ thường/hiếm | giấy dập + tro loé; RARE/EPIC thêm lớp ấm | −18 |
| DraftPick rarity=LEGENDARY (Then Chốt) hoặc chọn thẻ Tiến Hoá SFX_UI_card_pick_legend | chọn Then Chốt/LEGENDARY | dập + hợp xướng 1 hợp âm ngắn | −16 |
| DraftPick/hiện thẻ Relic Lời Nguyền RL049–RL060 SFX_UI_card_cursed | thẻ/Relic Lời Nguyền | giấy cháy xèo + thì thầm | −18 |
| DraftReroll (Đổi, biến thể 01) · DraftBanish (Xoá, 02) · DraftHold (G… SFX_UI_card_edit | Đổi · Xoá · Giữ (3 biến thể) | xào bài · xé giấy · kẹp giấy | −20 |
| SkillLearned / SkillSwapped / SkillRankUp (draft SKILL, hub chọn 2 kỹ… SFX_UI_skill_learn | học/đổi/nâng hạng kỹ năng | dập ấn gỗ + motif hero 2 nốt | −18 |
| MapOpen (sau phòng xong / nút bản đồ) SFX_UI_map_open | mở bản đồ | cuộn giấy dài | −22 |
| MapNodeChosen (chọn nút CMB/ELT/CHL/EVT/SHP/RST/SEC/RSC/MBS/BOS/DOCK) SFX_UI_map_node | chọn nút bản đồ | mực chấm | −22 |
| LevelQueued (pip '+N cấp chờ' trên HUD khi lên cấp giữa giao tranh) SFX_UI_level_queue | pip "+N cấp chờ" | nhịp tro nhỏ | −26 |
| CurrencyChanged delta>0 curId ∈ {CUR_SOUL_ASH 01, CUR_ECHO_SHARD 02, … SFX_UI_currency_gain | cộng Tro Hồn/Mảnh Vọng/Nến Canh (biến thể theo CUR_*) | tro rơi · mảnh đồng va (nhiễu) · sáp nhỏ giọt | −20 |
| CurrencyChanged delta<0 (mọi tiền meta; Phục Dựng, nâng trạm, mở hero… SFX_UI_currency_spend | tiêu tiền meta | tro thổi bay | −20 |
| UnlockGranted (hero 01 · Dạng Rèn 02 · ult 03 · mode 04 · trang codex… SFX_UI_unlock | mở hero/Dạng Rèn/ult/mode/trang codex (biến thể) | rèn 1 nhát + hợp âm ấm | −16 |
| MasteryRankUp (lên MR01–MR20 / xong TT1–TT5) SFX_UI_mastery_rank | lên MR / xong TT | trống khung 2 nhịp + motif hero | −16 |
| AchievementUnlocked (ACH_*; toast góc phải trên) SFX_UI_achievement | thành tựu | chuông câm "thịch" + tro sáng | −18 |
| DeathRecapLine / dòng 'Tro đã học' (INV-16), 1 lần/dòng, cách ≥ 0.25 s SFX_UI_recap_line | mỗi dòng recap INV-16 / "Tro đã học" | bút lông gạch | −24 |
| EpitaphShown (bia mộ đóng dấu cuối recap, TMB_Hxx) SFX_UI_epitaph | bia mộ đóng dấu | đá khắc 2 nhát | −18 |
| MourningBandChanged (buộc/cởi MRN01–MRN15: lớp vải; tổng Độ Tang đổi:… SFX_UI_mourning_band | buộc/cởi Khăn Tang (biến thể theo MRN) + tổng Độ Tang đổi | vải thắt nút; tổng: trống khung trầm | −20 |
| ScoreCount (đếm điểm DAILY/ENDLESS/BOSS_RUSH; pitch +1 bán cung mỗi 1… SFX_UI_score_tick | đếm điểm DAILY/ENDLESS/BOSS_RUSH | tích gỗ tăng nhịp, pitch +1 bán cung/10% | −24 |
| BarkShown (mỗi 3 ký tự 1 blip; 8 bộ: 7 NPC + hero; giọng NPC lấy SFX_… SFX_UI_bark_blip | chữ bark hiện (mỗi 3 ký tự 1 blip; 8 bộ biến thể: 7 NPC + hero) | blip giọng không lời ngắn 40 ms | −28 |
| SkillCastDenied (input kỹ năng khi đang hồi chiêu; HUD nháy ô 0.2 s, … SFX_UI_skill_denied | SkillCastDenied: bấm kỹ năng đang hồi (HUD nháy ô 0.2 s) | gỗ bịt 1 nhịp 220 Hz, decay 40 ms; nhỏ hơn nav_error 4 dB | −26 |
| LinchpinTaken (nhặt Then Chốt H{xx}_E37–E40; callout 'THEN CHỐT: <tên… SFX_UI_linchpin | LinchpinTaken: nhặt Then Chốt E37–E40 (callout "THEN CHỐT: <tên>" 1.0 s) | ấn ngà dập + hợp âm treo D–G–A dây gảy 700 ms + tro sáng; sau card_pick_legend 0.4 s nếu từ draft | −16 |
| ResonanceCallout tier=I ('CỘNG HƯỞNG: <tên>' 1.2 s) SFX_UI_resonance_1 | ResonanceCallout bậc I ("CỘNG HƯỞNG: <tên>" 1.2 s) | 2 nốt hoà âm gỗ-dây quãng 5, 300 ms (lớp UI, khác ResonanceTriggered (Cộng Hưởng bậc I/II kích, trong combat) SFX_SHARED_resonance) | −18 |
| ResonanceCallout tier=II ('CỘNG HƯỞNG II: <tên>' 1.2 s) SFX_UI_resonance_2 | ResonanceCallout bậc II ("CỘNG HƯỞNG II: <tên>") | 3 nốt hoà âm (thêm quãng 8), 300 ms + gió lửa nhẹ | −17 |
| EvolutionFuse (draft đóng → World ×0 0.8 s EVO1–3 / 1.5 s EVO4; 2 ico… SFX_UI_evo_fuse | EvolutionFuse: 2 icon nguồn bay vào nhau (World ×0 0.8 s EVO1–3 / 1.5 s EVO4) | 2 nhát rèn chạm (decay ≤ 60 ms) + lửa lò phồng + tôi nước xèo; 01 EVO1–3 1.2 s, 02 EVO4 1.5 s; trước EvolutionTriggered (Tiến Hoá trên hero sau khi màn draft đóng) SFX_SHARED_evolution | −16 |
| HeroSelected (Lửa Canh: xác nhận hero / ult / Dạng Rèn / 2 kỹ năng kh… SFX_UI_hero_select | HeroSelected ở Lửa Canh (biến thể 01 hero, 02 loadout ult/Dạng Rèn/2 kỹ năng) | lửa canh "phụt" + motif LM_<hero> 1 nốt gảy dây, 300 ms | −18 |
| ShopPurchase (Sạp Rong SHP/DOCK, mua bằng Vàng Mã; Chợ Đò mở pool dùn… SFX_UI_shop_buy | ShopPurchase: mua ở Sạp Rong SHP/DOCK bằng Vàng Mã (hết tiền = nav_error; Chợ Đò mở pool = currency_spend) | giấy tiền đặt xuống + Bà Mott tặc lưỡi đếm 2 tờ, 220 ms | −20 |
| RewardPanelOpen (thưởng phòng: chọn Relic 1/2 hoặc 1/3 ELT_RISK, thẻ … SFX_UI_reward_reveal | RewardPanelOpen: bảng thưởng phòng (Relic 1/2 hoặc 1/3 ELT_RISK, thẻ kỹ năng, Lễ Vật) + bảng tiền meta cuối run | vải đỏ xỉn kéo khỏi khay gỗ + tro sáng 3–6 kHz 80 ms, 280 ms (khác draft_open) | −20 |
Luật UI: không âm UI nào > 300 ms trừ unlock/mastery_rank/achievement/card_pick_legend/linchpin/evo_fuse (≤ 2.0 s); điều hướng nhanh liên tục → nav_move cooldown 40 ms; đọc thẻ < 3 s (P5) → âm thẻ không che giọng đọc màn hình.
7.2 Hub (29 sự kiện = 13 lõi SFX_HUB_* + 16 SFX_ENV_HUB_* thêm 2026-11-07; bus World/Ambience; spec đủ field ở data/av/ENV_HUB.json)
SceneLoaded Hub_BellTower (phát suốt; lớp GD1–GD5 bật theo FLAG Phục … SFX_HUB_amb_bed (lửa canh lép bép + sông + gió qua tháp gãy; lớp GD1–GD5 cộng dồn: đèn chuông thử, chợ đông, lò rèn xa, vải tủ áo, chuông treo lại hum 98 Hz) · HubWake: hero ngồi dậy cạnh Lửa Canh (t=0 frame 0 clip wake) SFX_HUB_hearth_wake (thức dậy: hít sâu + lửa bùng) · GremStrike (idle 6–9 s, nhịp 3+3+2 = LM_GREM) SFX_HUB_forge_strike (Grem rèn, LM_GREM 3+3+2) · ForgeUnlock (rèn mở hero): 3 nhát cách 0.3 s + tôi nước t=0.9 s SFX_HUB_forge_unlock (rèn mảnh hero: 3 nhát + tôi nước) · DepartConfirmed ở ST_DOCK (t=0 cảnh 6 s) SFX_HUB_dock_depart (đò rời bến, mái chèo) · LedgerPageTurn (Hol idle 8–12 s; đổi tab/trang Sổ Tang) SFX_HUB_ledger_page (Sổ Tang lật trang) · TestBellStruck (INTERACT Chuông Thử, đổi Nến Canh, buộc Khăn Tang) SFX_HUB_test_bell (Chuông Thử gõ — chuông trầm 196 Hz, AUD-01) · MarketPurchase + Mott idle đếm tiền (10–14 s) SFX_HUB_market (Bà Mott đếm tiền giấy + ghế kẽo kẹt) · YardDummyHit (đòn hero trúng NPC_RAM) SFX_HUB_yard_dummy (bù nhìn rơm trúng đòn, biến thể Y/P cho bài tập dùng đúng asset tell) · WardrobeOpen / SkinEquipped SFX_HUB_wardrobe (vải tang giũ) · RestoreStageBought GD1–GD5 (t=0 cảnh) SFX_HUB_restore_stage (Phục Dựng GĐ: 4 s, gỗ dựng + lửa + LM_BELL 1 nốt thêm mỗi GĐ) · FastTravel t=0 (rời chỗ cũ) SFX_HUB_fast_travel (tro cuốn) · BarkShown speaker=NPC_* (1 lần khi bark mở) SFX_HUB_npc_murmur (giọng không lời, 7 bộ biến thể = 7 NPC, §9).
- Ambience hub (8, bus Ambience): spot
AmbienceSpothub (1 spot / 6–14 s chung nhóm, pan ±0.6): AmbienceSpot hub (1 spot/6–14 s chung cho cả nhóm spot hub, pan ngẫu … SFX_ENV_HUB_river_lap (sông vỗ) · AmbienceSpot hub SFX_ENV_HUB_tower_creak (tháp gãy kẽo kẹt) · AmbienceSpot hub SFX_ENV_HUB_ash_gust (gió cuốn tro) · AmbienceSpot hub SFX_ENV_HUB_rope_knock (dây neo gõ cọc) · HeroOverlap ENV_HUB_river_reeds / ENV_HUB_ash_shrub (+ là spot) SFX_ENV_HUB_reed_rustle (cảHeroOverlapsậy/bụi tro) · AmbienceSpot hub, ưu tiên khi hero trong r160 Lửa Canh SFX_ENV_HUB_fire_pop (ưu tiên khi hero trong r160 Lửa Canh) · AmbienceSpot hub (chỉ trước GD5; sau GD5 thay bằng lớp hum 98 Hz tron… SFX_ENV_HUB_far_bell_hum (chỉ trước GD5; sau GD5 thay bằng lớp hum 98 Hz trong bed); loop vị trí Positional loop tại ENV_HUB_canal_sluice (suy giảm r 320 px) SFX_ENV_HUB_canal_flow (cống kênh, suy giảm r320 px). - Sự kiện hub (8, bus World/Music_Stinger): Loop khi đò chạy (RM_HUB_departure, RM_HUB_ferry_deck) — gắn VFX_ENV_… SFX_ENV_HUB_ferry_creak (loop đò chạy, Cảnh Xuất Phát RM_HUB_departure/Boong Đò Calla (nút DOCK) RM_HUB_ferry_deck) · HubArrive t=0 (mảnh lưỡi kéo về lửa) SFX_ENV_HUB_blade_return (
HubArrive: mảnh lưỡi kéo về lửa) · ScarCleansed SFX_ENV_HUB_scar_cleanse (ScarCleansed) · StationUnlocked SFX_ENV_HUB_station_unveil (StationUnlocked) · EpitaphCandleLit SFX_ENV_HUB_candle_light (EpitaphCandleLit) · StatuePlaced / PaintingHung / MusicBoxPlaced SFX_ENV_HUB_plinth_place (StatuePlaced/PaintingHung/MusicBoxPlaced) · GD5 cảnh treo chuông (t=6 s) SFX_ENV_HUB_bell_raise (GD5 treo chuông t = 6 s, Stinger −14) · Chuyển cảnh màn tro (VFX_ENV_HUB_act_fog) t=0 SFX_ENV_HUB_act_fog (màn tro chuyển cảnh).
119. Bark & giọng (VO) — chính sách
| Mục | Luật |
|---|---|
| Lời có nghĩa | 0 câu thoại đọc ở 1.0 (canon §13). Mọi thoại = chữ (bark ≤ 1 dòng + phụ đề), 10 ngôn ngữ ở 1.0 qua loc; không cần ghi âm theo ngôn ngữ |
| Hero (12) | chỉ giọng không lời: vo_effort (gắng sức, 5 biến thể, ≤ 1/1.2 s, chỉ trên đòn nặng/kỹ năng/Ult), vo_hurt (5, cooldown 400 ms), vo_death (2). Không la hét ở mỗi nhát thường |
| NPC (7) | BarkShown speaker=NPC_* (1 lần khi bark mở) SFX_HUB_npc_murmur = lầm rầm/ngân không lời theo giọng NPC (Ulla hum trầm ấm · Grem càu nhàu + ho · Calla thở dài ngắn · Hol lẩm bẩm không tròn chữ (điếc) · Lem cười khúc khích nhỏ · Mott tặc lưỡi đếm tiền · Răm rơm sột + giọng mũi hài); phát 1 lần khi bark mở + BarkShown (mỗi 3 ký tự 1 blip; 8 bộ: 7 NPC + hero; giọng NPC lấy SFX_… SFX_UI_bark_blip theo chữ |
| Boss | giọng không lời §2.4 (thở, gầm, ngâm); thẻ "X nhớ: bạn Gạt 72%" + 48 đối đáp hero↔boss = chữ, kèm 1 tiếng giọng boss |
| Kẻ địch | grunt/vocal chung loài (§6.3); không câu chữ |
| Ngôn ngữ giả | KHÔNG tạo ngôn ngữ bịa có cấu trúc (tránh loc ngầm); murmur phải không nhận ra được âm tiết của ngôn ngữ thật nào |
| Ghi âm | diễn viên giọng thuê theo giờ hoặc giọng nhóm, ký hợp đồng chuyển nhượng quyền toàn cầu, mọi nền tảng; không giọng AI tổng hợp |
| Text bark | hiện trên đầu nhân vật, pixel font, ≤ 1 dòng (≤ 48 ký tự EN), sống 2.5 s + 0.05 s/ký tự; ≤ 1 bark/4 s trong combat; ưu tiên: boss > Tro Nhớ callout > NPC > hero |
| Phụ đề | bark + "NÓ ĐÃ ĐỌC BẠN: <thói quen>" + phụ đề tell (trợ năng) cùng hệ chữ; cỡ 100–150% |
| Ngân sách | hero 12 × 12 file = 144 · NPC 7 × 6 = 42 · boss/mini 13 × 6 = 78 (trong 8 sự kiện boss) · tổng ~264 file giọng không lời |
1210. Ambience & hazard theo biome
10.1 Bed ambience (1 loop stereo ≥ 60 s/biome, SFX_<Bn>_amb_bed, bus Ambience, −30 LUFS-I) + spot ngẫu nhiên (sự kiện amb_spot riêng theo data/av/ENV_*.json, AmbienceSpot chọn 1 spot / 6–14 s, pan ngẫu nhiên ±0.6)
| Biome | Bed | Spot (4–6) | Cấm |
|---|---|---|---|
| B1 Đồi Mộ Tro | gió đồi khô qua cỏ, tro rơi xào nhẹ, hầm mộ vang thấp (Sân Hầm Tro: phòng đá) | quạ khàn xa (gốc), bia đá nứt, xích cổng mộ, lửa ma lép bép | chuông làng kêu trong bed (chuông chỉ là hazard) |
| B2 Đầm Vải Liệm | nước nông vỗ, côn trùng đêm, vải ướt đung đưa, tre kẽo kẹt | ếch trầm, đò mục va, giọt nước, bọt bùn | tiếng mưa to che tell |
| B3 Lò Đúc Câm | lò ầm 40–120 Hz ổn định (không swell, AUD-02), băng chuyền xa, xì hơi | búa xa, xích cẩu, xỉ rơi, khuôn nguội "tách" | đe ngân dài, chuông |
| B4 Thành Chuông Treo | gió vực cao, xích căng rên, chuông lớn rất xa (hum ≤ 150 Hz, ổn định) | cờ phần phật, đá rơi xuống vực, cầu treo kẽo kẹt, chim than | chuông gió cao |
| B5 Đỉnh Chuông Câm | tro rơi ngược (nhiễu đảo nhẹ, năng lượng > 1 kHz), gió đỉnh, vành chuông hum 55 Hz ổn định | đồng xỉn co nhiệt, tro xoáy | swell trầm |
| B6 Bờ Lặng | gần im: nước gương liếm bờ −40 LUFS, không reverb, không vang ("không vọng" canon) | 1 giọt nước, 1 hơi thở xa | mọi tiếng vọng; reverb trên mọi bus khi ở B6 = 0; HeroAttack/HeroSkill −6 dB (§5.1) |
Id bed + spot (7 bed + 29 spot; spec đủ field ở data/av/ENV_<Bn>.json):
Spot: cấm partial tonal 2.2–3.6 kHz decay > 60 ms (AUD-01) và swell < 140 Hz (AUD-02).
10.2 Hazard (46 sự kiện = 14 lõi + 32 thêm 2026-11-07 theo data/av/ENV_*.json; theo INV-18: dùng đúng Y/P/N, nhịp ≥ 1.0 s, trúng cả quái)
| Id | Hazard | Lớp tell | Âm riêng (thêm vào asset tell chung) |
|---|---|---|---|
| HazardTrigger hazardId=HZ_B1_open_grave (nắp bật cuối ấn tro 0.6 s; n… SFX_B1_hz_open_grave | Mộ Mở sinh quái | — (spawn INV-14) | đất mộ bật nắp + spawn_ash |
| HazardTrigger hazardId=HZ_B1_bell (ngân sau sway 0.25 s; cũng nguồn r… SFX_B1_hz_village_bell | chuông làng gõ được → choáng r100 | — (do hero kích) | đồng 220 Hz ngân 2 s (= objective_bell biến thể) + sóng |
| HazardTrigger hazardId=HZ_B1_collapse (lớp va chạm; tell P = SFX_SHAR… SFX_B1_hz_floor_collapse | sàn sụp | P | đất sụt + đá rơi tại va chạm |
| HazardTrigger (phase windup → impact) HZ_B2_gas / wisp_pocket / wisp_… SFX_B2_hz_gas_pocket | túi khí ma trơi nổ r60 | P | bọt sôi tăng → "phụt" lửa xanh |
| HazardTrigger (phase impact) HZ_B2_bridge / HZ_B2_bamboo_bridge; lớp … SFX_B2_hz_bamboo_collapse | cầu tre sập 1.0 s | P | tre gãy loạt |
| FootstepHero/FootstepEnemyCluster khi chân trong ô HZ_B2_water / HZ_B… SFX_B2_hz_wade | nước nông −15% | — | bước lội (thay bước hero/quái trong vùng) |
| HazardTrigger hazardId=HZ_B3_pour phase=impact (va chạm t=0; lớp thêm… SFX_B3_hz_pour_bronze | rót đồng | P | đồng chảy xèo + hơi |
| HazardTrigger hazardId=HZ_B3_conveyor phase=state (loop khi đoạn băng… SFX_B3_hz_conveyor | băng chuyền 24 px/s | — | loop xích con lăn, ổn định |
| HazardTrigger hazardId=HZ_B3_hook phase=impact (hero bám móc t=0) SFX_B3_hz_crane_hook | móc cẩu (Lướt vào = quét bầy) | — | xích vụt + móc quét |
| HazardTrigger hazardId=HZ_B3_mold phase=impact (va chạm t=0) SFX_B3_hz_mold_drop | khuôn chuông rơi | P | khuôn sắt rơi "rầm" (không ngân) |
| HazardTrigger hazardId=HZ_B4_wind phase=windup t = 0 (1.0 s trước thổ… SFX_B4_hz_wind_gust | gió đẩy 30 px/s, cờ báo 1.0 s | — (báo cờ) | cờ phần phật mạnh lên 1.0 s → gió ào |
| HazardTrigger hazardId=HZ_B4_pendulum phase=impact t = 0 (lớp phụ ≤ −… SFX_B4_hz_pendulum_bell | chuông con lắc quét | P | xích kẽo + chuông lớn 110 Hz vụt qua (không ngân sau va chạm) |
| HazardTrigger hazardId=HZ_B4_signal_bell phase=impact t = 0.3 s sau c… SFX_B4_hz_signal_bell | chuông hiệu → choáng r120 | — (do hero kích) | như B1 village_bell, 196 Hz |
| HazardTrigger hazardId=HZ_B5_ash_rise phase=state: cột mọc (t = 0.30 … SFX_B5_hz_ash_rise | tro rơi ngược (ải B5) | — | lớp bed tăng khi ải dày |
| HazardTrigger hazardId=HZ_B1_bone_field: thay bước chân hero/quái tro… SFX_B1_hz_bone_field | Bãi Xương Bãi Xương HZ_B1_bone_field (chậm) | — | bước trên xương vụn, thay bước hero/quái trong vùng (quái S: 20% bước), −27 |
| HazardTrigger hazardId=HZ_B1_ghost_brazier (lò đổ; vùng N dùng SFX_SH… SFX_B1_hz_ghost_brazier | Lò Lửa Ma Đổ Lò Lửa Ma Đổ HZ_B1_ghost_brazier | N (vùng = zone_n_loop) | lò lửa ma đổ, −20 |
| HazardTrigger hazardId=HZ_B1_toppling_stele (va chạm; tell P chung) SFX_B1_hz_stele_fall | Bia Đổ Bia Đổ HZ_B1_toppling_stele (windup 0.6 s) | P | bia đá cao sập tại va chạm, ≤ −12 dB dưới tell_p_impact ở 0–50 ms |
| HazardTrigger (phase state) HZ_B2_bridge thân_trên_cầu ≥ 4 (loop tới … SFX_ENV_B2_bridge_creak | Cầu Tre Mục Cầu Tre Mục HZ_B2_bridge quá tải (≥ 4 thân trên cầu) | — (báo phụ) | loop kẽo kẹt tới < 4 thân hoặc sập; không swell, −27 |
| HazardTrigger (phase impact) HZ_B2_mud_geyser; lớp trang trí riêng, p… SFX_ENV_B2_mud_geyser | Mạch Bùn Sôi Mạch Bùn Sôi HZ_B2_mud_geyser (0.6 s) | P | bùn sôi phun, lớp trên tell_p_impact, −20 |
| HazardTrigger (phase impact) HZ_B2_drift_wreck: đò vào làn (frame va … SFX_ENV_B2_drift_ram | Đò Mục Trôi Đò Mục Trôi HZ_B2_drift_wreck (0.8 s) | P | đò mục lao dọc kênh, frame va chạm đầu, −18 |
| HazardTrigger (phase state) HZ_B2_mire: hero trong vùng (lớp phụ trên… SFX_ENV_B2_mire_loop | Bùn Lún Tro Bùn Lún Tro HZ_B2_mire | N | kết cấu bước lún trên zone_n_loop, chỉ vùng gần hero nhất, −28 |
| HazardTrigger hazardId=HZ_B3_pour phase=state (vũng đồng nguội sống 3… SFX_ENV_B3_pour_pool_sizzle | vũng đồng nguội sau Rót Đồng (sống 3.0 s) | N | loop xèo nhỏ, tắt fade 0.3 s, ≤ 3 voice gần hero, −28 |
| HazardTrigger hazardId=HZ_B3_mold phase=windup (t=0) SFX_ENV_B3_mold_chain_release | Khuôn Rơi Khuôn Rơi HZ_B3_mold windup t = 0 | P (lớp phụ) | xích tuột, −6 dB dưới tell_p_swell, không cao độ |
| HazardTrigger hazardId=HZ_B3_conveyor phase=windup (đảo chiều −1.0 s) SFX_ENV_B3_conveyor_clunk | Băng Chuyền Băng Chuyền HZ_B3_conveyor đảo chiều −1.0 s | — (báo) | gỗ-sắt đục, −22 |
| HazardTrigger hazardId=HZ_B3_hook phase=windup (hero chạm vùng bắt t=… SFX_ENV_B3_hook_latch | Móc Cẩu Móc Cẩu HZ_B3_hook: hero chạm vùng bắt (trước swing) | — | "cạch" xác nhận bám, decay ≤ 60 ms, −20 |
| HazardTrigger hazardId=HZ_B3_steam phase=impact (van bật t=0, loop 2.… SFX_ENV_B3_steam_hiss | Van Xả Hơi Van Xả Hơi HZ_B3_steam (loop 2.0 s) | N | hơi xả mềm, không phồng to dần, −24 |
| HazardTrigger hazardId=HZ_B3_furnace phase=impact (va chạm t=0, sau t… SFX_ENV_B3_furnace_roar | Phả Hơi Lò Phả Hơi Lò HZ_B3_furnace (0.9 s) | P | phả hơi lò tại va chạm, ngay sau đó spawn_ash (BURST), −17 |
| HazardTrigger hazardId=HZ_B3_slag_cart phase=state (xe chạy; loop, sp… SFX_ENV_B3_cart_rumble | Xe Goòng Xỉ Xe Goòng Xỉ HZ_B3_slag_cart (0.8 s) | Y (tell_y_glint1 + tell_y_tinh) | loop xe lăn, theo vị trí xe, −22 |
| HazardTrigger hazardId=HZ_B4_wind phase=state (thổi 0–4.0 s, fade out… SFX_ENV_B4_hz_wind_blow_loop | Gió Vực Gió Vực HZ_B4_wind đang thổi 0–4.0 s | — | loop gió ổn định (AUD-02), fade ra 0.4 s, −24 |
| HazardTrigger hazardId=HZ_B4_chain_whip phase=impact t = 0 SFX_ENV_B4_hz_chain_whip | Xích Neo Quất Xích Neo Quất HZ_B4_chain_whip (0.75 s) | P | xích quất t = 0, −19 |
| PropBroken biome=B4 propId=counterweight_winch (bị đánh → release) SFX_ENV_B4_hz_winch_release | tời Tời đối trọng: trục gỗ quấn xích + đối trọng sắt treo trên xà phía tr… ENV_B4_counterweight_winch bị đánh → nhả | — (dẫn vào windup P 0.75 s) | tời gỗ-sắt nhả, −21 |
| HazardTrigger hazardId=HZ_B4_counterweight phase=impact t = 0 SFX_ENV_B4_hz_counterweight_drop | Đối Trọng Tời Đối Trọng Tời HZ_B4_counterweight (0.75 s) | P | sắt rơi nghiền, không ngân (AUD-01), −16 |
| HazardTrigger hazardId=HZ_B4_ash_drift phase=state (sống 6.0 s, gần h… SFX_ENV_B4_hz_ash_drift | Đụn Tro Gió Đụn Tro Gió HZ_B4_ash_drift (sống 6.0 s) | N | lớp ambience rất nhỏ, ≤ 1 voice gần hero, bus Ambience −32 |
| HazardTrigger hazardId=HZ_B5_dome_shard phase=windup (lớp phụ của tel… SFX_ENV_B5_shard_fall | Mảnh Vòm Rơi Mảnh Vòm Rơi HZ_B5_dome_shard windup 0.8 s | P (lớp phụ ≤ −12 dB trên tell_p_swell) | đá rạn trên vòm + sỏi lả tả rơi dần, gió rơi nhanh dần 0.3 s cuối; dài = windup |
| HazardTrigger hazardId=HZ_B5_dome_shard phase=impact (tick va chạm) SFX_ENV_B5_shard_hit | Mảnh Vòm Rơi va chạm | P | va chạm, không ngân (đồng B5 câm), −18 |
| HazardTrigger hazardId=HZ_B5_taut_chain phase=windup (lớp phụ tell P … SFX_ENV_B5_chain_taut | Xích Căng Xích Căng HZ_B5_taut_chain windup 1.0 s | P (lớp phụ ≤ −12 dB trên tell_p_swell) | tời gỉ quay lách cách 4 nhịp nhanh dần + xích kéo lê, rên 0.2 s cuối; pan theo trung điểm xích |
| HazardTrigger hazardId=HZ_B5_taut_chain phase=impact (tick va chạm) SFX_ENV_B5_chain_snap | Xích Căng va chạm | P | xích bật, −18 |
| HazardTrigger hazardId=HZ_B5_mute_bell phase=impact: đòn hero trúng c… SFX_ENV_B5_mute_bell_thud | Chuông Làng Câm Chuông Làng Câm HZ_B5_mute_bell (do hero kích) | — | 1 tiếng đục (transient) + sóng 0.3 s sau; không giống "tinh", −17 |
| HazardTrigger hazardId=HZ_B5_censer_spill phase=impact: đòn trúng lư SFX_ENV_B5_censer_swing | Lư Tro Đổ Lư Tro Đổ HZ_B5_censer_spill: đòn trúng lư | — | lư văng, −20 |
| HazardTrigger hazardId=HZ_B5_censer_spill phase=state: dòng tro đổ (t… SFX_ENV_B5_censer_pour | Lư Tro Đổ: dòng tro (t = 0.3 → 0.6) → vũng | N (vùng = zone_n_loop) | tro đổ chạm sàn, −22 |
| HazardTrigger hazardId=HZ_B5_bell_inhale phase=windup: báo 1.0 s + ké… SFX_ENV_B5_inhale | Chuông Hít Hơi Chuông Hít Hơi HZ_B5_bell_inhale: báo 1.0 s + kéo 3.0 s | — | gió kéo về giữa (pan) + hum; không dùng âm tell, −22 |
| HazardTrigger hazardId=HZ_B6_mirror_shallows phase=state: bước chân h… SFX_ENV_B6_hz_wade | Nước Gương Nông Nước Gương Nông HZ_B6_mirror_shallows | — | bước lội bị nước "uống", −12 dB dưới bước thường; quái ≤ 3 voice gần hero, −32 |
| HazardTrigger hazardId=HZ_B6_hush_bloom phase=impact (lớp phụ trên SF… SFX_ENV_B6_hz_bloom_swallow | Hoa Lặng Hoa Lặng HZ_B6_hush_bloom (1.0 s) | P (lớp phụ ≤ −12 dB trên tell_p_impact) | âm bị hút vào rồi cắt bặt, −28 |
| HazardTrigger hazardId=HZ_B6_drowned_bell phase=impact: tiếng đục t =… SFX_ENV_B6_hz_bell_thud | Chuông Chìm Chuông Chìm HZ_B6_drowned_bell (rise 0.3 s) | — | 1 tiếng đục khô 165 Hz (B1 220, B4 196), cắt partial 2.2–3.6 kHz, −16 |
| HazardTrigger hazardId=HZ_B6_under_reflection phase=impact: frame va … SFX_ENV_B6_hz_reflect_strike | Bóng Đáy Gương Bóng Đáy Gương HZ_B6_under_reflection trúng khi KHÔNG bị ĐÁP | Y (tell_y_glint1/tell_y_tinh) | kính nứt + nước xuyên, bus Enemy −22 |
| HazardTrigger hazardId=HZ_B6_under_reflection phase=impact khi bị ĐÁP… SFX_ENV_B6_hz_reflect_shatter | Bóng Đáy Gương bị ĐÁP (sau answer_core) | Y | vỡ thành mảnh gương, sáng hơn reflect_strike, −20 |
- Cột "Âm riêng" của 32 hàng thêm: số cuối =
lufs_mmax(§4.3); spec đủ field ởdata/av/ENV_<Bn>.json. Lớptell_classP/Y ở đây chỉ là lớp phụ ≤ −12 dB (§4.2), tell thật luôn làSFX_SHARED_tell_*trên busEnemyTell. - B2: bed + 3 hazard lõi trong
data/av/ENV_B2.jsondùng đúng id BiomeEnter B2 (mọi phòng B2 trừ cảnh tiện ích có bed riêng nhẹ hơn −3… SFX_B2_amb_bed / FootstepHero/FootstepEnemyCluster khi chân trong ô HZ_B2_water / HZ_B… SFX_B2_hz_wade / HazardTrigger (phase windup → impact) HZ_B2_gas / wisp_pocket / wisp_… SFX_B2_hz_gas_pocket / HazardTrigger (phase impact) HZ_B2_bridge / HZ_B2_bamboo_bridge; lớp … SFX_B2_hz_bamboo_collapse (owner = biome, như B1/B3–B6); hazard thêm của B2 dùngSFX_ENV_B2_*. - Mutator MUT01–MUT12 & Khăn Tang MRN: 0 sự kiện riêng; dùng asset tell + hazard có sẵn (vd MUT03 Mưa Chuông =
tell_p_swell+ HazardTrigger hazardId=HZ_B4_pendulum phase=impact t = 0 (lớp phụ ≤ −… SFX_B4_hz_pendulum_bell lớp va chạm; MRN15 Tro Sống vũng =zone_n_loop, nổ P r30 =tell_p_swell+explode_s). - Trạng thái 6 loop:
SFX_STS_EMBER_looplửa lép bép ·SFX_STS_FROST_loopbăng nứt khẽ ·SFX_STS_SHOCK_looptia lách tách nhiễu ·SFX_STS_ROT_loopbọt sủi ·SFX_STS_BIND_loopxích siết ·SFX_STS_DREAD_loopthở run; đều −30 LUFS, ≤ 3 voice (gần hero nhất).
10.3 Đạo cụ, mục tiêu, phòng & cảnh theo biome (64 sự kiện SFX_ENV_<Bn>_*, thêm 2026-11-07; spec đủ field ở data/av/ENV_<Bn>.json; bus World trừ ghi khác; hook theo §12.2)
| Biome | Đạo cụ (PropBroken / PropCut / prop sống) | Mục tiêu (ObjectiveFeed / ObjectiveState / ObjectiveProgress) | Phòng · cổng · cảnh |
|---|---|---|---|
| B1 (17) | PropBroken biome=B1 propId=gravestone_a|gravestone_c|stone_bench SFX_ENV_B1_prop_stone_break (bia/ghế đá) · _prop_wood_break (quan tài/bàn thờ/bó lúa) · _prop_urn_break (hũ tro) · _candle_snuff (nến sọ tắt) · _charm_tear (PropCut dây bùa giấy) | VIGIL: _obj_brazier_feed (ĐÁP trong r80 quanh OBJ_BRAZIER, +15 HP) · _obj_brazier_low (loop khi HP lò ≤ 33%) · NEST: _obj_nest_crack (67%/34%) · _obj_nest_break · RESCUE: _cocoon_shake (mỗi 100 HP) · _cocoon_open · CHASE: _carrier_giggle (Lướt né 120 px) · _carrier_urn_break | _crypt_door (GateSpawnOpen) · _iron_gate_slam (RoomLock, mở lại = ExitOpened (lối ra/cổng phòng mở) SFX_SHARED_door_open) · _room_ash_veil (RoomStart, màn tro 0.6 s) · _ash_wall_rise (GauntletWall, mỗi 600 px) |
| B2 (12) | PropBroken ENV_B2_reed_clump (gộp: ≤ 1 lần/80 ms toàn cục) SFX_ENV_B2_reed_break (≤ 1 lần/80 ms toàn cục) · _wood_break · _jar_break · _boat_knock (đạn chặn trên thuyền lật/rễ đước/cọc neo) · _lantern_loop (đèn gần hero nhất, ≤ 1 voice, Ambience −32) | _buoy_bell (BELLS, lớp trên ObjectiveBell (mục tiêu BELLS) + nguồn reuse SFX_B1_hz_village_bell (… SFX_SHARED_objective_bell) · _cocoon_shake · _nest_break (OBJ_NEST_B2) · _carrier_loop (OBJ_CARRIER_B2, pan theo bè) | _room_enter · _gate_shroud (khoá/mở cổng MBS/BOS/ELT) · _dock_arrive (nút DOCK giữa Hồi II) |
| B3 (9) | PropBroken biome=B3 propId=quench_trough (bị đòn nặng t=0) SFX_ENV_B3_quench_hiss (máng tôi bị đòn nặng) · _break_clay · _break_slag · _bell_thud (chuông câm bị đánh, decay ≤ 60 ms) · _bell_roll (lăn 0.5 s) | — | _room_enter · _room_clear (Ambience −28, bed lò hạ 3 dB trong 1.0 s, sau RoomCleared (+ stinger nhạc room_clear) SFX_SHARED_room_clear 0.3 s) · _furnace_breath (loop gần cửa lò, ≤ 2 nguồn, Ambience −30) · _ash_wall (GauntletWall Đường Xỉ) |
| B4 (9) | PropBroken biome=B4 propId=crate_ropes SFX_ENV_B4_crate_break · _bell_post_break · _mirror_shatter · _crow_scatter (quạ bay, Ambience) · _bridge_step (bước hero trên ván, thay lớp bước đá, bus Hero −28) | _cage_break (OBJ_NEST_B4) | _room_chainlift (RoomStart) · _ash_door (xong phòng / lối ra GAUNTLET) · _abyss_fall (quái S/M rơi qua lan can gãy, bus EnemyHorde −24) |
| B5 (10) | PropBroken biome=B5 propId=ENV_B5_prop_offering_altar SFX_ENV_B5_bronze_break (bàn lễ) · _urn_burst (hũ tro) · _sluice_open (Kênh Dẫn Hồn, Run sau mở B6 sau BS_FINAL (BS_TRUE). FLAG_SHORE_OPEN) · _ninh_handbell (chuông tay không kêu: im lặng là nội dung) · _candle_loop (nến người sống, r ≤ 96, Ambience −32) | — | Stinger: _segment_shift (Ải Kết: trụ 60 giây trước bầy trộn của 4 Hồi. WS_B5_TRIAL_01 t = 15/30/45 s, lượng tử theo phách 120 BPM) · _trial_ash_out (t = 60 s) · _bell_rim_reveal (Đại Chuông lộ diện → boss_intro của FINALE · B5 Đỉnh Chuông Câm (Kết, act V): ải 60 s trộn quái 4 Hồi (lớp theo I) + BS_FINAL… MUS_finale_crown) · _climb_arrive · _shard_socket_wake (BS_FINAL vào P3, 12 hốc) |
| B6 (7) | PropBroken biome=B6 propId=ENV_B6_silver_reeds (≤ 2 voice, cooldown c… SFX_ENV_B6_reed_snap (sậy bạc, −32, ≤ 2 voice, cooldown chung 150 ms) · _cairn_topple · _wood_snap (mái chèo) | — | _crossing_oar (cảnh đò B5 → B6 15 s; giây 9 send reverb → 0) · _trial_end_hush (SHORE_TRIAL t = 45 s) · _flood_inward (2.0 s) · _first_ripple (BS_TRUE chết + 1.5 s, trước ENDING · END_QUIET_SHORE Bến Bình Yên (hạ BS_TRUE ở B6) · 210 s tuyến tính đi cùng 12 thẻ… MUS_end_quiet_shore; âm có vang duy nhất ở B6) |
Đọc _slug = SFX_ENV_<Bn>_slug cùng hàng. B3: cú trúng đạo cụ chưa vỡ dùng HeroHitBatch hasHeavyTarget=true (Tinh Anh/mini/boss trong cụm) + đòn… SFX_SHARED_hit_heavy. Mọi âm bảng này qua quét AUD-01/AUD-02.
1311. Nguồn, định dạng, nhập Unity
11.1 Thang nguồn SFX (đúng thứ tự, theo skill create-sfx)
| Bậc | Khi | Công cụ | Đầu ra bắt buộc |
|---|---|---|---|
| 1 Dùng lại | asset có sẵn (demo 33 clip đã có credit, SFX_SHARED_*) khớp brief | asset_ref trong audio_sfx.csv | 0 file mới |
| 2 Freesound | MCP bf-sfx kết nối, sfx_status = key accepted | search_sounds (query brief, max_duration, single_event, sort rating_desc, min_num_ratings 5, group_by_pack cho họ biến thể) → find_similar_sounds (biến thể) → get_download_links → make_sfx.py fetch | chỉ CC0 (ưu tiên) hoặc CC BY; sfx-credits.json cạnh file; CC BY → dòng credit vào màn Credits (make_credits) |
| 3 Synth | Freesound trượt 2 vòng hoặc âm trừu tượng (tell, UI, ma, Tro Nhớ) | make_sfx.py make --recipe <r> --element <e> (36 recipe: telegraph_cue → tell, dash_whoosh, hit_slash, hit_impact, explode, stomp_quake, chain_rattle, splash, aura_loop, roar, ui_*…) | .sfx.json (recipe + seed) để làm lại tất định |
| 4 Foley | chất liệu đặc thù không có ở bậc 2–3 (gỗ quan, xẻng đất, lư trầm, dây xu) | thu tại chỗ 48 kHz/24 bit, 2 mic | file gốc lưu Audio_Src/ (ngoài Assets/, Git LFS) |
| 5 Thuê ngoài | ngân sách canon: SFX 4 PM + nhạc 4 PM | hợp đồng chuyển quyền toàn cầu mọi nền tảng | stem/WAV gốc + project file |
- Tell (
tell_y_*,tell_p_*,tell_feint) = synth bậc 3 bắt buộc, recipe khoá trong.sfx.json, seed cố định → không bao giờ đổi âm giữa các bản build (người chơi đã học). - Nhạc: chỉ thuê/soạn (bậc 5) hoặc soạn nội bộ; KHÔNG lấy nhạc từ thư viện mẫu hay Freesound làm cue (được dùng mẫu CC0 đơn lẻ làm chất liệu).
- Cấm: âm thanh/nhạc do AI sinh, API âm thanh trả phí, mẫu có giấy phép NonCommercial/ND/SA, trích âm từ game/phim khác.
- Brief viết trước khi tìm (field
brief); chọn theo khớp nguồn (đúng vật/chất liệu) trước, số đo sau (freesound.md §3 của skill). - Freesound: tuân hạn mức 60 yêu cầu/phút, 2.000/ngày; chỉ tải thứ game dùng.
- Nghe duyệt: agent không nghe được → mọi âm vào hàng
pending; dev nghe theo lô (make_sfx.py pending --audition→verdict ok|redo); tell + ĐÁP + Ult phảiokbởi người trước MS tương ứng.
11.2 Định dạng & mastering
| Loại | Master giao | File runtime | Unity import |
|---|---|---|---|
| SFX one-shot ≤ 1.5 s | WAV 44.1 kHz/24 bit mono (UI/stinger: stereo) | .ogg Vorbis 44.1 kHz | Load Type Decompress On Load, Vorbis quality 70, Force To Mono (trừ stereo), Preload Audio Data on |
| SFX 1.5–5 s (ult, boss) | như trên | .ogg | Compressed In Memory, quality 70 |
| Loop SFX/ambience | WAV stereo, cắt đúng mẫu lặp | .ogg | Compressed In Memory (≤ 20 s) / Streaming (> 20 s), quality 60 |
| Nhạc stem | WAV 44.1 kHz/24 bit stereo, mỗi stem dài đúng loop_samples | .ogg quality 60 (~160 kbps) | Streaming, Preload off, Load In Background on |
- Sample rate file 44.1 kHz; Project Settings › Audio: System Sample Rate = 0 (theo thiết bị), Speaker Mode Stereo.
- Loop mẫu-chính-xác: file loop = đúng
loop_samples, điểm 0 và cuối nối pha (zero-crossing không bắt buộc vì nối liền), không fade; intro tách file__intro. Phát nhạc bằng 2 AudioSource xen kẽ +PlayScheduledtheodspTime(không dùngloop = truecho stem streaming để tránh hở khe Vorbis); one-shot loop ngắn dùngloop = true. - Mastering mỗi file tới
lufs_mmaxbảng §4.3 (BS.1770, cửa sổ 400 ms), đỉnh ≤ −1 dBTP, DC 0, onset ≤ 12 ms, đuôi về −60 dB trước khi hết file (QAcreate-sfx:LOUDNESS CLICK_START CUT_TAIL LATE_ONSET TOO_LONG SILENT LOOP_SEAMphải PASS;PHONE_WEAKđọc là "Deck loa yếu"). - Thư mục:
Assets/_Project/Audio/{Music,SFX,Mixer}/…(khác đường mặc định mobile của skill → luôn truyền--out Assets/_Project/Audio/SFX/<ownerGroup>/<ownerId>). Credit gộp:Assets/_Project/Audio/sfx-credits.json→ màn Credits.
11.3 Bộ nhớ & dung lượng (Steam Deck là trần)
- SFX thường trú/Hồi ≤ 40 MB đã giải nén: hero đang chơi (~3 MB) + quái/Tinh Anh/mini/boss biome (~8 MB) + SHARED + UI (~10 MB) + hazard/ambience spot (~4 MB); dỡ biome trước khi vào Hồi kế (trong DOCK).
- Nhạc streaming: ≤ 12 luồng, bộ đệm ≤ 6 MB.
- Dung lượng cài đặt âm thanh 1.0 ≤ 400 MB (nhạc ~240 MB, SFX ~120 MB, giọng ~20 MB) [ASSUMED].
1412. Nối vào code (hook sự kiện → id)
12.1 Kiến trúc runtime (thay Systems/Sfx.cs demo)
| Class | Việc | Ghi chú |
|---|---|---|
AudioDb | nạp audio_sfx.csv + audio_music.json (qua DataManager, chỉ đọc) → bảng id → SfxDef | không hard-code tên clip trong gameplay |
SfxPlayer | pool 48 AudioSource one-shot + 4 ambience; Play(id, pos, ctx): cooldown/max_voices/steal/biến thể shuffle/pan/gain/pitch clock | 0 cấp phát GC/lần gọi |
HordeAudio | gom hit/kill/spawn mỗi frame (§6) rồi gọi SfxPlayer | chạy sau Combat, trước render |
TellAudio | lịch "tinh"/swell theo PlayScheduled (§5.7), giữ chỗ voice tell | đọc token INV-08 |
MusicDirector | trạng thái nhạc, I, stem, stinger, lượng tử ô, đồng bộ H12 (§3.4–3.5) | 12 AudioSource riêng, dspTime |
AudioSettingsService | slider, snapshot, trợ năng, hiệu chỉnh trễ; lưu ở DataPlayer (module Settings), mặc định trong SetupDefaultData() | không Save() trong Update |
Sự kiện dùng EasyEventManager với hằng EventName (rule third-party); gameplay chỉ bắn sự kiện, KHÔNG gọi thẳng AudioSource.
12.2 Bảng hook (EventName → id; {H} = hero đang chơi, {E} = enemy id, {B} = biome, {BOSS} = id mini/boss)
| EventName | Payload | Phát |
|---|---|---|
HeroAttackCut | heroId, moveIndex, aspect | SFX_{H}_a{n}_swing (bộ biến thể theo Dạng Rèn) |
HeroHitBatch | heroId, n, critCount, hasHeavyTarget, pos | HordeAudio §6.1 → SFX_{H}_hit + hit_multi/hit_mass/hit_crit/hit_heavy |
HeroComboSpecial | heroId, branch | SFX_{H}_combo_special (H08: 9 lớp theo cặp ổ) |
HeroDash / HeroDashRecharge | heroId | dash_base + SFX_{H}_dash / dash_recharge |
HeroAnswerSuccess | heroId, perfect, targetTier | answer_core + SFX_{H}_answer + send Answer |
HeroAnswerWhiff | heroId | answer_whiff |
HeroCounter | heroId | SFX_{H}_counter |
HeroHoldStart / HeroHoldEnd | heroId, cancelled | SFX_{H}_hold_start + hold_loop / dừng loop + hold_end |
HeroPerfectDodge | heroId | perfect_dodge + send Answer |
HeroResource | heroId, kind=gain/full/spend, value | SFX_{H}_res_* (H05 Đà → pitch loop; H12 click khi bật) |
SkillCast | skillId (Hxx_SKnn), rank | SFX_{skillId}_cast (+ __impact khi trúng) |
UltActivate | ultId | ult_core + SFX_{ultId}_<slug> + stinger ult_{H} + send Ult |
UltGaugeFull | — | ult_ready |
HeroDamaged / HeroLowHp / HeroDeath / HeroRevive | amount, hpPct | hero_hurt_impact + SFX_{H}_vo_hurt / hero_low_hp loop / hero_death + SFX_{H}_vo_death + DEATH / revive_ember |
EnemyWindupStart | enemyId, attackId, tellClass, windup, tImpact | Y: tell_y_glint1; P: tell_p_swell (độ dài = windup) + SFX_{E}_atk__{Ann} nếu giữ token |
EnemyTellGlint2 | enemyId, tImpact | tell_y_tinh lịch đúng T−0.12 s (đã lên lịch từ EnemyWindupStart; event này để kiểm) |
EnemyFeint | enemyId | tell_feint |
EnemyImpact | enemyId, tellClass | SFX_{E}_impact; P → tell_p_impact |
EnemyProjectileFire / EnemyProjectileReflected | enemyId, purple | proj_enemy_fire (+ tell_p_proj loop nếu tím) / proj_reflect |
EnemyKilledBatch | k, biome, elites[] | HordeAudio §6.2 |
EnemySpawnMarks | count | spawn_ash (gộp) |
SummonVortex | ownerId | summon_vortex |
EliteSpawn | enemyId, affixId | elite_affix (biến thể EM) + SFX_{E}_vocal + stinger elite_in |
PoiseBroken | enemyId | poise_break (+ SFX_{E}_broken nếu boss) |
ShieldBroken / ShieldBlocked | enemyId | shield_break / shield_block |
AshVariantOn | ownerId, axis | ash_read + stinger ash_read (khựng 0.6 s, ≥ 1.0 s trước hiệu lực) |
AshMesoShift | pct | ash_meso + stinger surge |
BossIntro / BossPhase / BossDefeated | bossId, phase | SFX_{BOSS}_intro + SN_BOSS_INTRO + stinger / SFX_{BOSS}_phase + __stg_phase{n} / SFX_{BOSS}_death + __stg_victory |
HazardTrigger | hazardId | SFX_{B}_hz_* / SFX_ENV_{B}_* hazard §10.2 (+ tell chung nếu Y/P) |
BiomeEnter / AmbienceSpot | biome, roomId | bed SFX_{B}_amb_bed (B1 phòng hầm: RoomStart B1 phòng hầm (crypt_yard, ossuary_ring, twin_crypts, cocoon… SFX_B1_amb_crypt_bed, crossfade 1.5 s) / 1 spot §10.1 mỗi 6–14 s; biome = B6 → fader HeroAttack/HeroSkill −6 dB + send reverb 0 (§5.1, §10.1) |
PropBroken / PropCut | biome, propId | đạo cụ §10.3 theo propId (vd B1 gravestone_a → PropBroken biome=B1 propId=gravestone_a|gravestone_c|stone_bench SFX_ENV_B1_prop_stone_break; paper_charm_line → PropCut biome=B1 propId=paper_charm_line SFX_ENV_B1_charm_tear) |
GateSpawnOpen | biome, propId | GateSpawnOpen biome=B1 propId=crypt_door SFX_ENV_B1_crypt_door (cửa hầm mở khi bầy tràn ra) |
RoomLock | biome | RoomLock biome=B1 (hero vào phòng → 4 cổng sắt sập; mở lại dùng SFX_S… SFX_ENV_B1_iron_gate_slam · B2 RoomLock / ExitOpened phòng MBS/BOS/ELT B2 SFX_ENV_B2_gate_shroud; mở lại = ExitOpened (lối ra/cổng phòng mở) SFX_SHARED_door_open |
GauntletWall | biome | GauntletWall biome=B1 (tường tro dựng sau hero mỗi 600 px) SFX_ENV_B1_ash_wall_rise · B3 GauntletWall biome=B3 (tường tro dựng sau hero t=0) SFX_ENV_B3_ash_wall |
ObjectiveFeed / ObjectiveState / ObjectiveProgress | objective, state, pct | cột "Mục tiêu" §10.3 (vd VIGIL feed → ObjectiveFeed objective=VIGIL (ĐÁP trong r80 quanh OBJ_BRAZIER) SFX_ENV_B1_obj_brazier_feed; VIGIL hp ≤ 33% → loop ObjectiveState objective=VIGIL hp<=33% (loop tới khi > 33% hoặc HP 0) SFX_ENV_B1_obj_brazier_low, dừng khi > 33% hoặc HP 0; NEST vỡ → ObjectiveProgress objective=NEST (tổ vỡ, đẩy r100) SFX_ENV_B1_obj_nest_break) |
StatusApplied / StatusEnded | statusId, targetIsNearHero | status_apply biến thể / dừng SFX_STS_{X}_loop |
PickupCollected | type, chainIndex | xp_pickup (pitch chuỗi) / gold_pickup / heal_orb |
LevelUp / DraftOpen / DraftPick | rarity | level_up / DraftOpen (sau LevelUp; 3 thẻ rút ra lệch 60 ms; snapshot SN_DRAFT) SFX_UI_draft_open + SN_DRAFT / DraftPick rarity=COMMON|RARE|EPIC (biến thể 01 COMMON, 02 RARE, 03 EP… SFX_UI_card_pick (_legend, _cursed) |
ResonanceTriggered / EvolutionTriggered | id | resonance / evolution |
ResonanceCallout | resId, tier | ResonanceCallout tier=I ('CỘNG HƯỞNG: <tên>' 1.2 s) SFX_UI_resonance_1 (bậc I) / ResonanceCallout tier=II ('CỘNG HƯỞNG II: <tên>' 1.2 s) SFX_UI_resonance_2 (bậc II) |
EvolutionFuse | evoId | EvolutionFuse (draft đóng → World ×0 0.8 s EVO1–3 / 1.5 s EVO4; 2 ico… SFX_UI_evo_fuse (01 EVO1–3, 02 EVO4) rồi evolution trên hero |
LinchpinTaken | edgeId (E37–E40) | LinchpinTaken (nhặt Then Chốt H{xx}_E37–E40; callout 'THEN CHỐT: <tên… SFX_UI_linchpin (từ draft: sau card_pick_legend 0.4 s) |
SkillCastDenied | skillId | SkillCastDenied (input kỹ năng khi đang hồi chiêu; HUD nháy ô 0.2 s, … SFX_UI_skill_denied |
RewardPanelOpen / ShopPurchase | kind / itemId, cost | RewardPanelOpen (thưởng phòng: chọn Relic 1/2 hoặc 1/3 ELT_RISK, thẻ … SFX_UI_reward_reveal / ShopPurchase (Sạp Rong SHP/DOCK, mua bằng Vàng Mã; Chợ Đò mở pool dùn… SFX_UI_shop_buy (thiếu Vàng Mã → UiError (hành động không được phép: thiếu tiền, khoá, ô đầy) SFX_UI_nav_error) |
HeroSelected | heroId, kind=hero/loadout | HeroSelected (Lửa Canh: xác nhận hero / ult / Dạng Rèn / 2 kỹ năng kh… SFX_UI_hero_select (biến thể 01/02) |
RoomStart / RoomCleared / ExitOpened | nodeType, objective | MusicDirector COMBAT / room_clear + stinger / door_open |
MapOpen / MapNodeChosen | — | MapOpen (sau phòng xong / nút bản đồ) SFX_UI_map_open / MapNodeChosen (chọn nút CMB/ELT/CHL/EVT/SHP/RST/SEC/RSC/MBS/BOS/DOCK) SFX_UI_map_node |
RunStart / ActChanged / DockEnter | act, biome | MusicDirector cue biome / DOCK · Bến Giữa Hồi (nút DOCK sau boss Hồi I–IV, ≤ 20 s, Sạp Rong + chở đò Calla sang Hồi… MUS_dock_crossing; ActChanged act=VI biome=B6 = hook cảnh đò B5 → B6 (15 s): ActChanged act=VI biome=B6 (cảnh đò B5 → B6): loop suốt 15 s; giây 9 … SFX_ENV_B6_crossing_oar loop suốt cảnh, giây 9 send reverb → 0 (BiomeEnter B6 bắn ở giây 9) |
FootstepHero | heroId, biome, surface (hazardId/propId dưới chân) | thay bước thường theo mặt: B2 Nước Nông HZ_B2_water/Kênh Nông Vành Sân HZ_B2_shallow_water → FootstepHero/FootstepEnemyCluster khi chân trong ô HZ_B2_water / HZ_B… SFX_B2_hz_wade; B4 Ván cầu treo: 4 tấm ván ngang/ô, khe 1 px #25282f lộ vực tối bên dưới… ENV_B4_floor_plank → FootstepHero trên ENV_B4_floor_plank (thay lớp bước đá) SFX_ENV_B4_bridge_step |
FootstepEnemyCluster | biome, surface, count | bước gộp của cụm quái (crowd_bed §6) đổi lớp theo mặt: B2 nước → FootstepHero/FootstepEnemyCluster khi chân trong ô HZ_B2_water / HZ_B… SFX_B2_hz_wade (≤ 3 voice gần hero) |
ProjectileBlocked | biome, propId, pos | đạn (hero/quái) bị đạo cụ chặn: B2 capsized_boat/mangrove_trunk/mooring_post → ProjectileBlocked trên capsized_boat / mangrove_trunk / mooring_post SFX_ENV_B2_boat_knock |
PropAlive | biome, propId, active | đạo cụ sống có loop: B2 lantern_post/ferry_lantern_vigil → PropAlive lantern_post / ferry_lantern_vigil (chỉ đèn gần hero nhất, … SFX_ENV_B2_lantern_loop (chỉ đèn gần hero nhất, ≤ 1 voice); active=false → dừng loop |
EnemyAbyssFall | enemyId, biome, pos | quái S/M rơi qua lan can gãy B4 → EnemyAbyssFall (quái S/M rơi qua lan can gãy) SFX_ENV_B4_abyss_fall |
HubStationInteract | stationId | SFX_HUB_* tương ứng |
HubArrive / ScarCleansed / StationUnlocked / EpitaphCandleLit / StatuePlaced · PaintingHung · MusicBoxPlaced | stationId, itemId | HubArrive t=0 (mảnh lưỡi kéo về lửa) SFX_ENV_HUB_blade_return / _scar_cleanse / _station_unveil / _candle_light / _plinth_place (§7.2) |
BarkShown | speakerId, chars | BarkShown speaker=NPC_* (1 lần khi bark mở) SFX_HUB_npc_murmur (NPC) + BarkShown (mỗi 3 ký tự 1 blip; 8 bộ: 7 NPC + hero; giọng NPC lấy SFX_… SFX_UI_bark_blip |
UiNavigate / UiConfirm / UiBack / UiError | — | SFX_UI_nav_* |
CurrencyChanged | curId, delta | CurrencyChanged delta>0 curId ∈ {CUR_SOUL_ASH 01, CUR_ECHO_SHARD 02, … SFX_UI_currency_gain / _spend |
UnlockGranted / MasteryRankUp / AchievementUnlocked | id | UnlockGranted (hero 01 · Dạng Rèn 02 · ult 03 · mode 04 · trang codex… SFX_UI_unlock / MasteryRankUp (lên MR01–MR20 / xong TT1–TT5) SFX_UI_mastery_rank / AchievementUnlocked (ACH_*; toast góc phải trên) SFX_UI_achievement |
MourningBandChanged | mrnId, total | MourningBandChanged (buộc/cởi MRN01–MRN15: lớp vải; tổng Độ Tang đổi:… SFX_UI_mourning_band |
DeathRecapLine / EpitaphShown | — | DeathRecapLine / dòng 'Tro đã học' (INV-16), 1 lần/dòng, cách ≥ 0.25 s SFX_UI_recap_line / EpitaphShown (bia mộ đóng dấu cuối recap, TMB_Hxx) SFX_UI_epitaph |
EndingStart | endId | MUS_end_* |
Tên hook trong data/av/ENV_*.json chưa đồng nhất; quy về EventName bảng này (2026-11-07): PropBreak / PropHit / PropTrigger → PropBroken · ObjectiveBellRing / ObjectiveCocoonShake / ObjectiveCarrierAlive → ObjectiveState · ObjectiveNestBreak → ObjectiveProgress · RoomEnter / RoomTransition → RoomStart · RoomClear → RoomCleared · GateLock → RoomLock · GateOpen → ExitOpened · BiomeAmbience → BiomeEnter · HazardFire / HazardImpact / HazardState → HazardTrigger (payload thêm phase = windup/impact/state). Luật hook: 1 EventName có thể phát nhiều id, 1 id không bị 2 EventName cùng phát trong 1 frame (khử trùng theo id/frame); payload thiếu → log Debug.LogWarning, không phát.
1513. Ngân sách âm thanh theo mốc (đếm sự kiện SFX theo §4.4; nhạc theo §3.7)
| Mốc | Hero (×28) | Quái+Tinh Anh (×5) | Mini/boss/kết (×8) | Khác (S27 + UI37 + HUB + ENV biome + STS6) | SFX | Cue nhạc |
|---|---|---|---|---|---|---|
| MS02 Next Fest M10 | 3 → 84 | 9 → 45 | 2 → 16 | 27+37+16+30+6 = 116 | 261 | 6: title, hub, b1, boss_b1, miniboss_gate (D), death |
| MS03 EA M13 | 5 → 140 | 18 → 90 | 5 → 40 | 27+37+29+56+6 = 155 | 425 | 9: + dock, b2, boss_b2 (miniboss +E) |
| MS04 U1 M17 | 7 → 196 | 27 → 135 | 8 → 64 | 27+37+29+82+6 = 181 | 576 | 11: + b3, boss_b3 (miniboss +C) |
| MS05 U2 M21 | 9 → 252 | 37 → 185 | 11 → 88 | 27+37+29+105+6 = 204 | 729 | 13: + b4, boss_b4 (miniboss +B) |
| MS06 U3 M26 | 11 → 308 | 37 → 185 | 12 → 96 | 27+37+29+129+6 = 228 | 817 | 15: + finale_crown, end_bell_toll |
| MS07 1.0 M32 | 12 → 336 | 39 → 195 | 13 → 104 | 27+37+29+146+6 = 245 | 880 | 18 + 4 bộ _h12 (+ quiet_shore, end_quiet_shore, end_ash_crown) |
- ENV biome = mọi sự kiện
data/av/ENV_<Bn>.jsoncủa biome đã có (bed + spot §10.1 · hazard §10.2 · đạo cụ/mục tiêu/phòng §10.3): B1 30 · B2 26 · B3 26 · B4 23 · B5 24 · B6 17 = 146; cộng dồn theo biome mở ở mốc. HUB: MS02 16 = 8 lõi (như bản trước) + 8 ambience hub §7.2 [ASSUMED], MS03+ đủ 29. UI 37 đủ từ MS02. - Canon:
_bible.jsonsfx_events~880 (DEC-2026-11-07-17: ~730 → ~880 do data AV thêm 150 sự kiện = UI +8, HUB +16, hazard +32, bed +1, spot 29, ENV khác 64). Data AV là nguồn đơn; bảng MS07 khớp canon. - File: SFX ~2.550
.ogg(880 sự kiện × ~2.9 biến thể TB) [ASSUMED] · nhạc ~281 file (stem + intro + stinger: biome 40,_h1240, boss 50, mini 28, finale 27, quiet_shore 17, hub 19, ult stinger 48, còn lại 12) · giọng không lời ~264 file · ~45 phút nhạc soạn [ASSUMED]. - Người-tháng (canon §10.1): âm thanh 6 PM nội bộ (gồm 0.5 PM/hero trong dòng hero) + thuê ngoài nhạc 4 PM + SFX 4 PM. Thứ tự cắt khi trễ: theo cut-line canon §10.2 (cắt nội dung thì âm của nó cắt theo); không bao giờ cắt tell, ĐÁP, gộp bầy, bộ
_h12.
1614. Kiểm nghiệm (AT = acceptance test; chạy trước mỗi MS)
| Id | Kiểm | Đạt khi |
|---|---|---|
| AT-01 | Nghe mù tell: 10 người, 10 phút B1, màn đen 30% thời gian | ≥ 90% gọi đúng Y/P; 0 âm khác bị gọi là tell |
| AT-02 | Thời điểm "tinh": thu loopback, World 1.0 và 0.25 | đỉnh transient trong ±1 frame (16.7 ms) quanh T−0.12 s |
| AT-03 | Quét phổ audio_lint.py (FFT mọi asset không-tell) | 0 vi phạm AUD-01/AUD-02; chạy trong CI cùng quét từ cấm |
| AT-04 | Tải MS01b trên Deck | §6.5 đạt hết |
| AT-05 | Độ to chương trình | §5.8 đạt hết |
| AT-06 | Lặp nhạc | mọi stem đúng loop_samples; điểm nối < −60 dB click; 30 phút không trôi pha |
| AT-07 | Đồng bộ H12 | lệch máy nhịp ↔ nhạc ≤ 5 ms sau 10 phút; Thương Xót ±0.16 s đúng |
| AT-08 | Credit | mọi file Freesound có mục sfx-credits.json; bước build credits_check (doc 40 §5.7.1): mỗi id SFX nguồn Freesound CC BY trong audio_sfx.csv có đúng 1 dòng credits; thiếu → build FAIL |
| AT-09 | BS_TRUE P2 + P1 rẻ quạt | tell nghe rõ (≥ −20 LUFS ngắn hạn) khi mọi thứ khác bị bóp |
| AT-10 | Mono / loa Deck | tổng mono không làm tell giảm > 3 dB; SN_SMALL_SPEAKER tell vẫn nổi |
| AT-11 | Trễ | input → onset âm p95 ≤ 40 ms (PC, Deck) |
| AT-12 | Nhận ra hero qua âm | ≥ 80% (khớp P6 canon) |
17Quy tắc cho dev/AI
- Đọc
00-Design-Bible.mdINV-02/08/10/11/15/18 trước mọi việc âm thanh; số/id lấy theo_bible.json. - Tell chỉ dùng 6 asset
SFX_SHARED_tell_*; không tạo âm tell riêng cho quái/boss/hazard; không ngẫu nhiên pitch tell; không cho tell vào bus khácEnemyTell. - Mọi âm mới qua quét AUD-01/AUD-02 trước khi merge; vi phạm = sửa âm, không xin ngoại lệ.
- Không gọi
AudioSourcetừ gameplay: bắnEventName(§12.2); thêm id = thêm hàngaudio_sfx.csvtheo mẫu §4.2, đủ field. - Âm lặp ≥ 3 biến thể + cooldown; mọi gộp bầy qua
HordeAudio, không phát âm/quái. - Nhạc: tempo/key/stem đúng §3.2/§3.7; stem dài bằng nhau đúng
loop_samples; đổi lớp chỉ ở vạch ô nhịp; nhạc không theo slow-mo. - Nguồn theo thang §11.1; chỉ CC0/CC BY; ghi credit cùng lượt; bỏ ứng viên Freesound có tên/tag nhắc tên game/thương hiệu (vừa tránh âm bắt chước, vừa giữ repo sạch từ cấm).
- Không AI sinh âm/nhạc/giọng; không lời thoại đọc; không ngôn ngữ bịa.
- Tên id/file ASCII, snake_case slug, không đổi id sau khi ship (đổi file, giữ id + GUID
.meta). - Không viết tên game/studio/thương hiệu có thật vào brief, query lưu repo, tên file, ghi chú; mô tả bằng vật liệu/hành động.
- Báo cáo mỗi lô âm: bậc nguồn, LUFS, QA, và "chưa ai nghe — đang chờ
pending" cho tới khi devverdict ok.
18Quyết định đã chốt
| Q | Quyết định | Lý do |
|---|---|---|
| Middleware âm thanh? | Unity AudioMixer + code riêng (SfxPlayer, MusicDirector) | đủ cho stem lượng tử + duck; không phí bản quyền, port console dễ |
| "Tinh" phát khi nào? | đỉnh transient đúng glint 2 = T−0.12 s; glint 1 có ping nhẹ riêng | khớp INV-02 (SFX "tinh" đi cùng glint 2), cho 0.12 s phản xạ nghe |
| "Ù" dài bao nhiêu? | trải suốt windup tím, cắt cứng ở va chạm | độ to tăng = đồng hồ đếm ngược nghe được |
| Ai độc quyền dải phổ tell? | AUD-01 (ping 2.2–3.6 kHz dài) + AUD-02 (swell < 140 Hz) chỉ cho tell | tương đương sở hữu màu INV-01 cho tai |
| Tell có bị duck/bóp? | không, kể cả BS_TRUE "Nuốt Tiếng" | canon "SFX bóp trừ tell"; công bằng P3/P4 |
| Người nghe ở đâu? | ở hero, pan 2D theo x màn ±0.6, không 3D | góc 3/4 pixel, hero luôn giữa; mono-an toàn cho Deck |
| Bao nhiêu voice? | 64 thật / 256 ảo; 29 chỗ dành cho tell/ĐÁP/Ult/nhạc | 250 quái không được nuốt tell |
| Gộp bầy thế nào? | hit theo n/frame, kill theo k/100 ms, bước chân = crowd_bed | 250 nguồn → 1 khối; CPU thấp |
| Nhạc thích nghi? | 5 stem/cue, I từ mật độ + token + Tinh Anh + HP, lượng tử ô, hysteresis | phản ánh nguy hiểm thật, không nhảy lớp liên tục |
| Boss tempo? | mọi boss Hồi + mini + finale = 120 BPM | khoá pha với máy nhịp H12, không cần bộ boss _h12 |
| 18 cue gồm gì? | §3.7 (6 biome canon + 4 boss + mini + title + hub + dock + chết + 3 kết) | khớp canon 18 + 18 hộp nhạc Nến Canh = 18 cue |
| Stinger tính là cue? | không; asset con <cueId>__stg_<slug> | giữ đúng số canon 18 + 4 |
| Ambience đặt id gì? | SFX_<Bn>_amb_bed (owner = biome) | canon chỉ có tiền tố SFX_/MUS_; không thêm loại id |
| Giọng? | chỉ giọng không lời + text bark | canon §13: không voice có nghĩa ở 1.0; 10 ngôn ngữ không tốn ghi âm |
| Tell làm bằng gì? | synth tất định, seed khoá | âm tell không bao giờ đổi giữa bản build |
| Định dạng? | WAV 44.1/24 master → OGG Vorbis 44.1 kHz; SFX Decompress On Load, nhạc Streaming | độ trễ thấp cho SFX, RAM thấp cho nhạc trên Deck |
| LUFS chương trình? | combat −16 LUFS-I ±1, menu −18, đỉnh −1 dBTP | chuẩn PC/Deck; preset Loa nhỏ −14 |
| Sự kiện môi trường từ data AV? (2026-11-07) | liệt kê đủ id data/av/UI.json + ENV_*.json ở §7.1, §7.2, §10.1–10.3, hook §12.2; tổng 880 (§13) | data là nguồn đơn; doc phải chỉ đúng id để dựng game không cần hỏi |
| B6 nghe khác thế nào? (2026-11-07) | fader HeroAttack/HeroSkill −6 dB + reverb 0, không snapshot mới (§5.1) | "nhỏ hơn một nửa" (Bờ Lặng CDX_b6); tell + ĐÁP giữ mức |
| Credit kiểm thế nào? (2026-11-07) | AT-08 dùng bước build credits_check của doc 40 §5.7.1 (thiếu dòng credits → build FAIL) | một luật kiểm, không lặp tiêu chí giữa doc 32 và doc 40 |
| Mục tiêu CHASE B2 dùng id nào? (2026-11-07) | OBJ_CARRIER_B2 (khớp encounters/B2); OBJ_CARRIER chỉ của B1 | id objective theo biome, data là nguồn đơn |