Статус: ready — СГЕНЕРИРОВАН scripts/audio/gen_audio_reference.py из карты звука. Руками не править: правка уедет при следующем прогоне. Источник правды — scripts/audio/audio_map.py, оттуда же собираются FMOD-события и каталог.


Что в игре звучит, чем именно, откуда взят материал и кто его дёргает. Одна страница, чтобы вопрос «а этот звук у нас вообще есть и где он играет» не требовал раскопок по трём слоям — карте, FMOD-проекту и коду.

Как это устроено и почему — Planning - SFX Round 2.

Сводка

FMOD-событий109
из них per-action дефолтов14
исходных сэмплов211
банкиSFX.bank, Music.bank (+ Master/strings) в Assets/StreamingAssets
целевая громкость-23.0 dB RMS активной части, true peak ≤ -1.0 dBFS

Шины

Слайдеры настроек пишут в bus:/, bus:/Music, bus:/SFX — поэтому под-шины обязаны висеть именно под ними, иначе громкость никуда не доедет.

ШинаУровеньЧто в ней
bus:/SFX+0 dB— (родительская)
bus:/Music-6 dBmusic
bus:/SFX/Combat+0 dBcast, death, impact, tonal, whoosh
bus:/SFX/UI-5 dBui, ui_soft
bus:/SFX/Ambient-9 dBambient
bus:/SFX/Stingers+1 dBstinger

Категории: микс и анти-каша

Категория задаёт всё поведение звука в бою: громкость, разброс, сколько копий может звучать разом и кого душить при переполнении.

КатегорияШинаOffsetПитчГромк.ГолосовКулдаунStealingПриоритет
impactSFX/Combat+0 dB±2.5 st−3.0 dB450 мсQuietestLow
whooshSFX/Combat-2 dB±1.5 st−3.0 dB460 мсQuietestLow
tonalSFX/Combat-3 dB±0.5 st−2.0 dB360 мсVirtualizeMedium
castSFX/Combat-1 dB±1.0 st−2.0 dB250 мсVirtualizeMedium
deathSFX/Combat+0 dB±2.0 st−3.0 dB380 мсOldestHigh
stingerSFX/Stingers+0 dB±0.0 st−0.0 dB1250 мсNoneHighest
uiSFX/UI-2 dB±1.0 st−2.0 dB230 мсOldestHigh
ui_softSFX/UI-9 dB±1.0 st−2.0 dB240 мсOldestMedium
musicMusic+0 dB±0.0 st−0.0 dB10 мсNoneHighest
ambientSFX/Ambient-6 dB±0.0 st−0.0 dB10 мсNoneMedium

Слоумо: глобальный параметр TimeScale (0.05…3.0) крутит питч bus:/SFX/Combat по кривой из 8 точек. Пишет его только TimeScaleService.

Дефолты действий

Играют, когда точной записи под контент нет. Без них новый юнит или эффект был бы немым.

ДействиеСобытиеКатегорияСэмплов
Attackevent:/SFX/Combat/attackwhoosh4
Fireevent:/SFX/Combat/firewhoosh3
Hitevent:/SFX/Combat/hitimpact7
Evadeevent:/SFX/Combat/evadewhoosh3
Shieldevent:/SFX/Combat/shieldimpact6
Healevent:/SFX/Combat/healtonal1
Castevent:/SFX/Combat/castcast1
Deathevent:/SFX/Combat/deathdeath6
Applyevent:/SFX/Combat/applytonal2
Expireevent:/SFX/Combat/expiretonal1
Tickevent:/SFX/Combat/ticktonal1
Uievent:/SFX/UI/uiui5
Stingerevent:/Stingers/stingerstinger1
Loopevent:/SFX/Ambient/loopambient1

Точечные ключи

Бой (combat.*)

Кто дёргает: боевая симуляция → AudioPresenter.

КлючСобытие FMODКатегорияСэмплов
combat.attack_interrupted.evadeevent:/SFX/Combat/attack_interruptedui_soft2
combat.unit_spawn.uievent:/SFX/Combat/unit_spawnui_soft2

Исход и старт боя (battle.*)

Кто дёргает: фаза боя → RunAudioPresenter / CombatFeelDirector.

КлючСобытие FMODКатегорияСэмплов
battle.defeat.stingerevent:/Stingers/defeatstinger1
battle.start.stingerevent:/Stingers/battle_startstinger1
battle.victory.stingerevent:/Stingers/victorystinger1

Feel-слой (feel.*)

Кто дёргает: CombatFeelDirector и UnitView (killstinger, тяжёлый удар, финишер, разлёт).

КлючСобытие FMODКатегорияСэмплов
feel.death_shatter.deathevent:/SFX/Feel/death_shatterimpact5
feel.finisher.stingerevent:/SFX/Feel/finisherstinger2
feel.heavy_hit.hitevent:/SFX/Feel/heavy_hitimpact5
feel.kill.stingerevent:/SFX/Feel/killstinger5

Мементо (герои) (relic.*)

Кто дёргает: по contentId юнита из боевых событий.

КлючСобытие FMODКатегорияСэмплов
relic.assassin.castevent:/SFX/Relics/assassin/castwhoosh1
relic.cryomancer.attackevent:/SFX/Relics/cryomancer/attacktonal1
relic.cryomancer.castevent:/SFX/Relics/cryomancer/castcast2
relic.defender.shieldevent:/SFX/Relics/defender/shieldimpact3
relic.druid.castevent:/SFX/Relics/druid/casttonal1
relic.flame_swordsman.attackevent:/SFX/Relics/flame_swordsman/attackwhoosh2
relic.iron_spearman.attackevent:/SFX/Relics/iron_spearman/attackwhoosh2
relic.light_shepherd.castevent:/SFX/Relics/light_shepherd/casttonal1
relic.light_shepherd.fireevent:/SFX/Relics/light_shepherd/firetonal1
relic.ranger.fireevent:/SFX/Relics/ranger/firewhoosh2
relic.treant.attackevent:/SFX/Relics/treant/attackimpact2
relic.whirl_monk.castevent:/SFX/Relics/whirl_monk/castwhoosh1

Эффекты и статусы (effect.*)

Кто дёргает: EffectSystem.OnEffectApplied / OnEffectEnded.

КлючСобытие FMODКатегорияСэмплов
effect.bulwark_shield.applyevent:/SFX/Effects/bulwark_shield/applyimpact2
effect.burn.applyevent:/SFX/Effects/burn/applytonal1
effect.burn.tickevent:/SFX/Effects/burn/tickui_soft1
effect.dodge.applyevent:/SFX/Effects/dodge/applyui_soft1
effect.frozen.applyevent:/SFX/Effects/frozen/applytonal1
effect.frozen.expireevent:/SFX/Effects/frozen/expireimpact5
effect.hunters_mark.applyevent:/SFX/Effects/hunters_mark/applyui_soft2
effect.ice_chains_stun.applyevent:/SFX/Effects/ice_chains_stun/applyimpact2
effect.ignition.applyevent:/SFX/Effects/ignition/applycast1
effect.light_mend.tickevent:/SFX/Effects/light_mend/tickui_soft1
effect.overgrowth.applyevent:/SFX/Effects/overgrowth/applytonal1
effect.resolute_strike_stun.applyevent:/SFX/Effects/resolute_strike_stun/applyimpact2
effect.spore_cloud.applyevent:/SFX/Effects/spore_cloud/applytonal1
effect.stealth.applyevent:/SFX/Effects/stealth/applywhoosh2
effect.stealth_buff.applyevent:/SFX/Effects/stealth_buff/applywhoosh1
effect.vortex_entry.applyevent:/SFX/Effects/vortex_entry/applywhoosh1

Враги (enemy.*)

Кто дёргает: по contentId врага.

КлючСобытие FMODКатегорияСэмплов
enemy.training_dummy.hitevent:/SFX/Enemies/training_dummy/hitimpact4

Интерфейс (ui.*)

Кто дёргает: UiSoundSystem (корень панели), BattleInputController, DeploymentController.

КлючСобытие FMODКатегорияСэмплов
ui.back.uievent:/SFX/UI/backui3
ui.click.uievent:/SFX/UI/clickui5
ui.deploy_grab.uievent:/SFX/UI/deploy_grabui2
ui.deploy_place.uievent:/SFX/UI/deploy_placeui2
ui.deploy_reject.uievent:/SFX/UI/deploy_rejectui1
ui.disabled.uievent:/SFX/UI/disabledui3
ui.drag_drop.uievent:/SFX/UI/drag_dropui3
ui.drag_grab.uievent:/SFX/UI/drag_grabui2
ui.drag_reject.uievent:/SFX/UI/drag_rejectui2
ui.hover.uievent:/SFX/UI/hoverui_soft5
ui.modal_open.uievent:/SFX/UI/modal_openui2
ui.pause.uievent:/SFX/UI/pauseui1
ui.relic_equip.uievent:/SFX/UI/relic_equipui2
ui.relic_select.uievent:/SFX/UI/relic_selectui3
ui.relic_unequip.uievent:/SFX/UI/relic_unequipui1
ui.resume.uievent:/SFX/UI/resumeui1
ui.screen_close.uievent:/SFX/UI/screen_closeui1
ui.screen_open.uievent:/SFX/UI/screen_openui1
ui.scroll.uievent:/SFX/UI/scrollui_soft3
ui.slider.uievent:/SFX/UI/sliderui_soft3
ui.speed.uievent:/SFX/UI/speedui_soft1
ui.tab.uievent:/SFX/UI/tabui3
ui.toggle.uievent:/SFX/UI/toggleui3
ui.tooltip_detail.uievent:/SFX/UI/tooltip_detailui_soft1
ui.tooltip_show.uievent:/SFX/UI/tooltip_showui_soft2

Карта акта (map.*)

Кто дёргает: WorldMapView.

КлючСобытие FMODКатегорияСэмплов
map.close.uievent:/SFX/Map/closeui2
map.node_hover.uievent:/SFX/Map/node_hoverui_soft1
map.node_locked.uievent:/SFX/Map/node_lockedui2
map.node_select.uievent:/SFX/Map/node_selectui3
map.open.uievent:/SFX/Map/openui2
map.travel_arrive.uievent:/SFX/Map/travel_arriveui1
map.travel_start.uievent:/SFX/Map/travel_startui_soft1

Переходы (flow.*)

Кто дёргает: RunAudioPresenter (шторка перехода).

КлючСобытие FMODКатегорияСэмплов
flow.fade_in.uievent:/SFX/Flow/fade_inui_soft1
flow.fade_out.uievent:/SFX/Flow/fade_outui_soft1

Награда (reward.*)

Кто дёргает: MenuRouter + RunAudioPresenter.

КлючСобытие FMODКатегорияСэмплов
reward.card_select.uievent:/SFX/Flow/reward_card_selectui2
reward.open.stingerevent:/Stingers/reward_openstinger1
reward.skip.uievent:/SFX/Flow/reward_skipui1
reward.take.stingerevent:/Stingers/reward_takestinger1

Лавка (shop.*)

Кто дёргает: ShopController.

КлючСобытие FMODКатегорияСэмплов
shop.buy.uievent:/SFX/Flow/shop_buyui1
shop.denied.uievent:/SFX/Flow/shop_deniedui1
shop.reroll.uievent:/SFX/Flow/shop_rerollui2
shop.sell.uievent:/SFX/Flow/shop_sellui1

Привал (camp.*)

Кто дёргает: CampScreenView через MenuRouter.

КлючСобытие FMODКатегорияСэмплов
camp.action.uievent:/SFX/Flow/camp_actionui1
camp.denied.uievent:/SFX/Flow/camp_deniedui1

Сундук (chest.*)

Кто дёргает: MenuRouter.

КлючСобытие FMODКатегорияСэмплов
chest.open.stingerevent:/Stingers/chest_openstinger1

Текстовые события (event.*)

Кто дёргает: MenuRouter.

КлючСобытие FMODКатегорияСэмплов
event.choice.uievent:/SFX/Flow/event_choiceui2

Забег (run.*)

Кто дёргает: RunAudioPresenter, RunStateService.

КлючСобытие FMODКатегорияСэмплов
run.gold_gain.uievent:/SFX/Flow/gold_gainui2
run.outcome_defeat.stingerevent:/Stingers/run_defeatstinger1
run.outcome_victory.stingerevent:/Stingers/run_victorystinger1
run.start.stingerevent:/Stingers/run_startstinger1

Меню (menu.*)

Кто дёргает: RunAudioPresenter.

КлючСобытие FMODКатегорияСэмплов
menu.hide.uievent:/SFX/Flow/menu_hideui1
menu.show.uievent:/SFX/Flow/menu_showui1
menu.title_card.stingerevent:/Stingers/title_cardstinger1

Музыка (music.*)

Кто дёргает: RunAudioPresenter (одна дорожка за раз).

КлючСобытие FMODКатегорияСэмплов
music.battle.loopevent:/Music/battlemusic1
music.map.loopevent:/Music/mapmusic1
music.menu.loopevent:/Music/menumusic1

Амбиент (ambient.*)

Кто дёргает: RunAudioPresenter (пока мир на первом плане).

КлючСобытие FMODКатегорияСэмплов
ambient.arena.loopevent:/SFX/Ambient/arenaambient1

Музыка и амбиент

Лупы играются хранимым EventInstance (FmodAudioService), одна дорожка за раз; приоритет — меню важнее фазы боя, бой важнее карты.

КлючТрекЛицензияИсточник
music.menu.loopFantasy Orchestral ThemeCC0OpenGameArt
music.map.loopTown Theme (cynicmusic)CC0OpenGameArt
music.battle.loopBattle Theme A (cynicmusic)CC0OpenGameArt
ambient.arena.loopLoopable Dungeon AmbienceCC0OpenGameArt

Громкость: музыка нормализована к -18.0 LUFS, амбиент — к -24.0 LUFS (интегральный EBU R128, в отличие от one-shot).

Откуда взяты сэмплы

ПакЛицензияОбязательстваФайлов задействовано
Kenney — Interface SoundsCC0без атрибуции63
Kenney — UI AudioCC0без атрибуции10
Kenney — RPG AudioCC0без атрибуции34
Kenney — Impact SoundsCC0без атрибуции51
Kenney — Music JinglesCC0без атрибуции8
RPG Essentials Free (Leohpaz)бесплатно для коммерческихкредит опционален40

Sonniss GDC-бандл в игре не используется: его файлы длинные и дизайнерские, их надо резать на слух, а CC0-паки закрыли все дыры. Лежит как резерв.

Пайплайн

scripts/audio/audio_map.py            ключ → категория → сэмплы (ЕДИНСТВЕННЫЙ источник правды)
  → build_source_audio.py             нормализация → FMOD Project/SourceAudio + manifest.json
  → build_populate.py                 → FMOD Project/Tooling/populate.js
  → fmodstudiocl -script populate.js  шины, события, микс, параметр TimeScale
  → fmodstudiocl -build -export-guids банки → Assets/StreamingAssets
  → меню Alebardium/Audio/Populate Catalog from Manifest   → AudioCatalog.asset
  → gen_audio_reference.py            → этот документ

Проверки: audit_samples.py (технический брак), clap_pick.py --verify (соответствие сэмпла его смыслу), EditMode-тесты AudioCoverageTests (код ↔ каталог ↔ манифест).

Связи