모든 형식 페이지 ↓
그래픽·미디어

WAV — 효과음과 사운드 뱅크 연결

출처: coreprime/kbot @ 0ab97bf · GitHub에서 편집

Total Annihilation의 효과음(유닛 음성 샘플, 무기 피격음, UI 클릭음)은 평범한 8비트 / 16비트 PCM WAV 파일입니다 — 컨테이너에는 TA만의 특별한 점이 없습니다. 흥미로운 부분은 연결 구조입니다: 유닛 FBI, 무기 TDF, 전역 UI가 세 단계의 간접 참조를 거쳐 파일 이름을 사운드 버스로 보내는 방식입니다.

Tip

직접 해 보세요.

# Play one directly
ls $(kbot ctx path)/sounds/ | head
afplay $(kbot ctx path)/sounds/cmdsel1.wav   # macOS
aplay  $(kbot ctx path)/sounds/cmdsel1.wav   # Linux

# The web UI also previews WAV/MP3 inline
kbot mount $(kbot ctx path) --server

디스크상으로는 그냥 WAV입니다

WAV 파일은 sounds/에 있습니다. 표준 RIFF WAVE 형식을 따르므로 WAV를 재생할 수 있는 것이라면 무엇으로든 재생됩니다. kbot은 이를 별도 형식으로 파싱하지 않으며, 탐색기는 브라우저의 <audio> 요소에 그대로 넘깁니다.

Cavedog이 배포한 파일의 일반적인 인코딩:

속성 값
샘플링 레이트 22050 Hz(대부분), 11025 Hz(일부 UI 클릭음)
비트 깊이 8비트 부호 없는 PCM
채널 모노
길이 0.1–3초
파일 크기 5 KB – 200 KB

모드는 가끔 16비트 스테레오 샘플을 배포하는데, 엔진은 이를 받아들이지만 메모리를 더 씁니다.


연결의 3계층

"Arm Commander를 선택하면 무엇이 재생되는가"를 찾아가면 다음 연결을 따르게 됩니다.

   FBI                gamedata/sound.tdf            sounds/
┌─────────────┐     ┌───────────────────────┐    ┌──────────────┐
│ units/      │     │ [ARM_COM]             │    │ cmdsel1.wav  │
│ armcom.fbi  │     │   {                   │    │              │
│             │ ──▶ │     select1=cmdsel1;  │ ──▶│              │
│ Sound       │     │     ok1=cmdok1;       │    │              │
│ Category=   │     │     ...               │    │              │
│   ARM_COM;  │     │   }                   │    │              │
└─────────────┘     └───────────────────────┘    └──────────────┘
   1. FBI picks       2. sound.tdf maps             3. WAV file
      a category         event → filename              on disk

계층 1 — FBI의 SoundCategory

유닛의 FBI가 분류 하나를 지정합니다.

[UNITINFO]
{
    UnitName=ARMCOM;
    SoundCategory=ARM_COM;     // ← points at [ARM_COM] in sound.tdf
    ...
}

분류는 여러 유닛이 함께 씁니다 — 모든 Arm Commander 변형이나 모든 Arm K-bot이 같은 분류를 가리키므로, 한 진영 안에서 선택 음성이 일관되게 유지됩니다.

계층 2 — gamedata/sound.tdf

이 TDF는 분류 안에서 엔진 이벤트를 WAV 파일 이름에 연결합니다.

[ARM_COM]
{
    select1=cmdsel1;       // Selecting the unit
    ok1=cmdok1;            // Movement order acknowledged
    arrived1=cmdarvd1;     // Reached destination
    cant1=cantdo4;         // Order rejected ("I can't do that")
    underattack=warning1;  // Took damage
    count5=count1;         // Commander self-destruct countdown (5)
    count0=count6;         // …countdown (now)
    canceldestruct=cancel2;
}

대부분의 이벤트 이름에 붙은 1 접미사에 주목하세요. 모든 이벤트는 여러 선택지를 가질 수 있습니다: 접미사 없는 키(select)와 번호가 붙은 키 select1, select2, select3 등이며, 엔진은 변화를 주려고 그중 하나를 무작위로 고릅니다. select1만 정의되어 있으면 매번 같은 대사가 재생됩니다.

TA 3.1c는 이벤트마다 접미사 없는 키가 있으면 그것을, 그다음 KEY1, KEY2, …를 처음으로 빠진 번호 직전까지 읽습니다: select1=kbarmsel; select3=kbarmse2;이면 select2가 빠져서 목록이 끝나므로 kbarmsel만 재생됩니다. (접미사 없는 키가 빠진 것은 번호 붙은 키를 막지 않습니다.) 빈 값은 소리 없는 선택지입니다. 아래 이벤트에 해당하지 않는 키는 절대 재생되지 않습니다.

계층 3 — sounds/<name>.wav

TDF 값은 어간(.wav 확장자 없음)입니다. 엔진은 가상 파일 시스템에서 sounds/<stem>.wav를 찾습니다.

Important

.wav 접미사는 생략된 것으로 간주합니다. TDF에 select1=cmdsel1.wav라고 쓰면 엔진은 sounds/cmdsel1.wav.wav를 찾으려다 조용히 아무것도 재생하지 않습니다.


표준 이벤트 키

TA 3.1c는 유닛의 사운드 분류에서 23개의 이벤트를 읽으며, 각 이벤트는 위에서 설명한 대로 접미사 없는 키와 번호 붙은 키 묶음(ok, ok1, ok2, …)으로 이루어집니다.

이벤트 발생 시점
select 유닛이 선택됨.
underattack 유닛이 피해를 입음.
activate / deactivate 켜기/끄기 전환(레이더, 교란기, 방어 시설).
ok 명령이 받아들여짐.
arrived 유닛이 이동을 마침.
cant 명령이 거부됨(지형, 건설 대기열 등).
unitcomplete 유닛 건설이 끝남.
build 건설 유닛이 건설을 시작함.
repair 건설 유닛이 수리를 시작함.
working 건설 유닛이 회수/부활 중.
load / unload 수송 유닛이 유닛을 태움 / 내려놓음.
cloak / uncloak 유닛이 은폐함 / 은폐를 풂(커맨더).
capture 커맨더나 포획 가능한 유닛이 포획을 시작함.
count5 … count0 자폭 카운트다운의 각 틱.
canceldestruct 자폭이 취소됨.

각 키에는 그 대사의 자막을 담은 KEYtext 항목(select1text)이 짝으로 있을 수 있습니다. 분류 안의 다른 키는 무시됩니다.

KBot Studio의 유닛 뷰어와 샌드박스도 같은 규칙을 따릅니다: 유닛 메타(/api/studio/unit/{name})에는 게임이 이 이벤트들에 재생하는 키만 정확히 들어 있으며, 각 이벤트는 자기 키 중 하나를 무작위로 재생합니다.


UI 사운드 — allsound.tdf

UI 이벤트(버튼 클릭, 메뉴 전환, 게임 종료 효과음)도 같은 방식으로 키를 쓰지만, gamedata/allsound.tdf의 [GLOBAL_*] 방식 섹션에 들어 있습니다.

[BIGBUTTON]   { sound=butmain1; }
[SMLBUTTON]   { sound=button1;  }
[SKIRMISH]    { sound=butnskir; }
[BGM]         { sound=drone2;   }   // Background music ID

이 섹션들은 메뉴 .gui 파일에서 이름으로 참조합니다. "Skirmish" 버튼의 클릭음을 바꾸려면 이 TDF만 고치면 됩니다 — .gui는 고칠 필요가 없습니다.


무기 사운드

무기 TDF(TDF)는 간접 참조 계층 없이 자체 사운드 키를 직접 담습니다.

[LIGHTLASER] {
    ...
    soundstart=lasrmas1;     // On fire
    soundhit=lasrhit1;       // On impact
    soundwater=splshbig;     // On water hit (overrides soundhit)
    soundtrigger=1;          // Play soundstart on each burst pulse, not just first
}

같은 sounds/<stem>.wav 조회 방식이 적용됩니다. 무기 사운드는 발사마다 맞춰 조정되어 있으므로, 유닛의 무기를 바꾸면 무기 TDF의 소리 크기도 다시 조정해야 합니다.


실제 예제 — 새 선택 음성 추가하기

  1. sounds/에 새 WAV를 넣으세요(모노, 22050 Hz, 8비트 권장).

    mymod/sounds/cmdsel_grunt.wav
  2. gamedata/sound.tdf에 새 이벤트를 추가하세요.

    [ARM_COM]
    {
        select1=cmdsel1;       // Existing
        select2=cmdsel_grunt;  // Your new line, randomly selected
    }
  3. FBI는 고칠 필요가 없습니다 — 기존 SoundCategory=ARM_COM 참조로 충분합니다.

  4. 패킹하고 테스트하세요.

    kbot hpi pack ./mymod --target mymod.ufo

이제 커맨더를 선택하면 엔진이 cmdsel1.wav와 cmdsel_grunt.wav를 번갈아 재생합니다.


일반적인 크기

에셋 Cavedog 에셋에서 관찰된 범위
유닛 음성 대사 5–60 KB
무기 피격음 5–30 KB
폭발음 30–120 KB
음악 루프 100 KB – 1 MB
gamedata/sound.tdf 약 20 KB(분류 300개 이상)
gamedata/allsound.tdf 약 6 KB

주의할 점

Warning

WAV가 없으면 오류가 아니라 무음입니다. select1=cmsdel1처럼 철자를 틀리면(글자 순서가 바뀜) 엔진은 선택할 때 그냥 아무것도 재생하지 않습니다 — 로그 메시지도, 대체 소리도 없습니다. 바꾼 사운드는 항상 게임 안에서 테스트하세요.

  • .wav 확장자는 생략된 것으로 간주합니다 — TDF 값에 절대 쓰지 마세요.
  • 샘플링 레이트가 중요합니다. 8 kHz / 11.025 kHz / 22.05 kHz / 44.1 kHz가 아닌 레이트로 재생되는 소리는, 일부 정식판 엔진이 여전히 쓰는 Windows 9x 시절의 하드웨어 경로에서 끊길 수 있습니다. 22050 Hz 모노가 안전한 기본값입니다.
  • 스테레오 WAV는 엔진이 모노로 섞습니다. 특별한 공간적 이유가 없다면 스테레오로 배포하지 마세요.
  • sounds/의 MP3 — 엔진은 여기 있는 MP3를 무시합니다. 음악 플레이어는 music/*.mp3를 위한 별도의 코드 경로를 씁니다.
  • Cavedog은 16비트 PCM에 이상한 샘플링 레이트(예: 7000 Hz)를 쓰는 WAV도 일부 배포합니다 — 여전히 동작하지만, 22050/8/모노를 가정하는 도구를 만든다면 여기서 걸려 넘어집니다.

함께 보기

  • TDF — sound.tdf, allsound.tdf, 무기 사운드 필드가 쓰는 형식.
  • TA: Kingdoms GUI — .gui 위젯은 UI 사운드 이벤트를 참조합니다.
  • 용어집 — sound category.