-
Notifications
You must be signed in to change notification settings - Fork 98
Description
Summary
Deliver full sound modability to KeeperFX, enabling modders and mapmakers to add custom sounds for creatures, spells, effects, music, and all audio-producing game elements — matching the extensibility of sprites, lenses, and creatures.
Goals
- Parity with other moddable systems — sounds should be as configurable as sprites/creatures
- Clean architecture — modern SoundManager API wrapping legacy globals
- Named references — configs use
SoundPlayed = FIREBALLnotSoundPlayed = 58 - Campaign/level hierarchy — sounds load from
campgns/<name>/sounds/ - Full scripting support — Lua, DKScript, and config-based customization
- Modder documentation — clear guides for all use cases
Architecture
graph TB
subgraph "Modder Layer"
CFG[Config Files<br/>creatures/*.cfg<br/>magic.cfg<br/>sounds.cfg]
LUA[Lua Scripts<br/>level.lua<br/>campaign.lua]
DKS[DKScript<br/>map00001.txt]
end
subgraph "API Layer"
SM[SoundManager<br/>C++ Singleton]
REG[Sound Registry<br/>name → ID mapping]
CAPI[C API Bridge<br/>sound_manager_* functions]
end
subgraph "Bank Layer"
B0[Bank 0: sound.dat<br/>Built-in sounds]
B1[Bank 1: speech.dat<br/>Mentor speech]
B2[Bank 2: Custom<br/>Runtime WAV/OGG]
B3[Bank 3: Campaign<br/>Per-campaign sounds]
end
subgraph "Playback Layer"
OAL[OpenAL<br/>3D positioned audio]
SDL[SDL2_Mixer<br/>Music streaming]
EMT[Sound Emitters<br/>Per-Thing audio sources]
end
CFG --> REG
LUA --> CAPI
DKS --> CAPI
REG --> SM
CAPI --> SM
SM --> B0
SM --> B1
SM --> B2
SM --> B3
B0 --> OAL
B1 --> OAL
B2 --> OAL
B3 --> OAL
SM --> SDL
OAL --> EMT
Sound Flow
sequenceDiagram
participant Modder as Modder Config
participant Registry as Sound Registry
participant Manager as SoundManager
participant Bank as Sound Banks
participant OpenAL as OpenAL
Note over Modder: sounds.cfg defines<br/>FIREBALL = 58
Modder->>Registry: Load sound definitions
Registry->>Registry: Build name→ID map
Note over Modder: magic.cfg uses<br/>SoundPlayed = FIREBALL
Modder->>Registry: get_sound_id("FIREBALL")
Registry-->>Manager: Returns 58
Note over Manager: Runtime playback
Manager->>Bank: Get sample from bank
Bank-->>OpenAL: Audio buffer
OpenAL->>OpenAL: 3D positioned playback
Modder Use Cases
- Custom creatures with sounds.
- Override of current creatures with new sounds
- Levels with new sounds
- Spells & Traps with new sounds.
- Full campaign pack with custom audio at each teir above
Current State
Implemented
- SoundManager singleton class
- Custom WAV loading (
loadCustomSound()) - Creature cfg
CustomSoundfield parsing - Third sound bank (
g_custom_bank)
Sound Categories Audit
Configurable (Already Works)
| Category | Config Location | Notes |
|---|---|---|
| Creature voices (12 types) | creatrs/*.cfg [sounds] |
Foot, Hit, Happy, Sad, Hurt, Die, Hang, Drop, Torture, Slap, Fight, Piss |
| Power/spell selection | magic.cfg SoundPlayed |
Faux-latin announcement |
| Spell self-cast | magic.cfg SelfCasted |
|
| Shot firing/flight/impact | magic.cfg |
FiringSound, ShotSound, Hit*Sound |
| Trap placement/trigger | trapdoor.cfg |
PlaceSound, TriggerSound |
| Room ambient | terrain.cfg |
AMBIENTSNDSAMPLE |
| Object ambience | objects.cfg |
AmbienceSound, EffectSound |
| Effects | effects.cfg |
Per-effect sounds |
| Atmospheric | keeperfx.cfg |
ATMOS_* |
| Music | Script/Lua | OGG or CD audio |
| Mentor speech | Speech banks | output_message() |
Hardcoded (Needs Work)
| Category | Sample ID | Location | Priority |
|---|---|---|---|
| Refusal | 119 | ~15 places | High |
| GUI tab clicks | 62 | frontmenu_ingame_tabs.c | Medium |
| Gold pickup | 32-34 | power_hand.c | Medium |
| Room claim | 116 | room_data.c | Medium |
| Heart beat | 150-151 | thing_objects.c | Low |
| Door open/close | 91, 92 | thing_doors.c | Medium |
| Digging impact | 72-74 | thing_shots.c | Low |
| Zoom | 177 | player_instances.c | Low |
Reactions are currently unavailable