어떤 리듬의 FPS를 만들지 결정하기
BPM: 불렛 퍼 미닛(Bullets Per Minute)은 박자에 맞춰 총을 쏘고, 재장전하고, 점프하고, 피하는 리듬 액션 FPS 게임입니다.
이 게임을 만들기로 했을 때 디자인 접근 방식에 대한 몇 가지 옵션이 있었습니다.
1. 음높이 차트 (예: 기타 히어로, 락밴드, 프렛 온 파이어)
모든 트랙에는 '공격', '회피', '재장전' 박자를 정의하는 메타데이터가 있습니다. 이 메타데이터는 적들의 행동을 알려줍니다. 음 차트는 AI가 무엇을 해야 할지 알려줍니다.
장점: 훌륭하게 선별된 경험. 고품질 사용자 제작 콘텐츠에 대한 잠재력.
단점: 게임 분당 제작 비용이 비쌈. 다시 플레이할 확률이 낮음.
2. 절차적 음악 (예: 파라파 더 래퍼, Wii 뮤직).
이 음악은 트랙 세그먼트로 구성됩니다. 트랙 세그먼트는 동적이며 알고리즘이 다음으로 재생할 트랙 세그먼트를 선택합니다. 그런 다음 AI가 각 트랙 세그먼트에 대한 특정 마커를 공격합니다.
적들이 16분 음표로 빠르게 공격할 때 드럼롤 세그먼트가 연주되고, 이어서 적들의 스네어 히트에 공격하는 백비트가 연주된다고 생각해보세요.
장점: 역동적임, 다시 플레이할 가능성이 높음.
단점: 음악 품질이 낮을 수 있음. 음악이 노래 구조가 아닌 플레이어에 의해 정의되기 때문에 음악적인 여정이 좋지 않을 수 있습니다.
3. 단지 박자만(예: 크립트 오브 더 네크로댄서).
AI가 음악의 박자에 맞춰 움직이지만 해당 동작이 트랙의 상태에 따라 달라지지 않습니다.
장점: 역동적임, 다시 플레이할 가능성이 높음, 고유한 음악적 여정이 가능함, 더 많은 콘텐츠를 만들기가 더 쉬움, 게임 디자인이 음악적 결과물에 의존하지 않음.
단점: 음악이 경험에 따라 맞춰지지 않습니다.
작은 규모의 팀인 저희는 몇 시간 동안이고 플레이할 수 있는 꽤나 큰 게임을 만들고 싶었기 때문에 '단지 박자만' 방법을 사용하기로 했습니다. 또한 개발 중에도 게임을 즐기고 싶었기 때문에 로그라이크(roguelike) 구조를 선택했습니다. 로그라이크의 랜덤 레벨 생성 덕분에 게임 개발도 재미있었고 게임 플레이도 항상 신선하게 느껴지게 되었죠. 로그라이크는 다시 플레이할 수 있는 가능성이 높아야 하기 때문에 '음높이 차트' 접근 방식으로는 BPM에서 필요한 30시간(최대)의 게임 플레이를 제공할 수 없다는 것을 알았습니다.
저희는 BPM에 몇몇 인스턴스의 절차적 음악을 제작하기로 했습니다. 주로 보스를 처리할 때 스팅어로 사용되죠. 이 음악은 플레이어가 보스를 처리했을 때 플레이어가 컨트롤하는 크레센도로서 재생됩니다.
게임 플레이 조정
BPM의 게임 플레이는 간단히 말해 분당 88 비트인 4분의 4박자로 실행되는 스텝 시퀀서입니다. 적이 몇 박자 후에 '공격'을 요청할 수 있죠. 이를 위해 스텝 시퀀서에 해당 박자에서 공격하는 것이 지나치게 불협 화음인지를 확인하도록 쿼리합니다.
적들은 스텝 시퀀서에게 '두 박자 안에 플레이어를 공격해서 피할 수 밖에 없도록 만들고 싶다'라고 합니다. 스텝 시퀀서는 '네' 혹은 '아니오'로 응답하죠. 스텝 시퀀서의 응답은 해당 비트에서 너무 많은 공격이 발생하는지 혹은 다른 적이 해당 비트에 '독점' 권한을 가지고 있는지의 여부에 따라 결정됩니다. 이렇게 해서 BPM의 전체 게임 플레이는 이 스텝 시퀀서에 의해 결정됩니다.
이 시퀀서는 또한 플레이어의 게임플레이에도 관여합니다. 플레이어의 동작은 매 반 박자마다 수행할 수 있습니다. 예를 들어 플레이어는 매 반 박자마다 무기를 발사하거나, 점프 혹은 마법을 사용할 수 있죠. 하지만 각 박자에서는 재장전, 회피, 발사, 마법 사용 중 단 하나의 동작만 수행할 수 있습니다. (점프는 언제든지 할 수 있습니다. 박자에서만 점프할 수 있게 만들었더니 너무 불편하더군요.)
그래서 기술적인 관점에서 주요 문제는 트랙에서 '박자'가 언제 발생하는지 아는 것이었습니다. 언리얼 엔진 안에서 해결책을 찾으려 해봤지만 그 당시 오디오 시계와 게임 시계를 동기화할 수 있는 방법이 없었습니다. 또한 저희는 트랙 간에 전환할 때 샘플이 누락되어 튀는 소리가 나는 것을 방지하고 싶었습니다.
그래서 저희가 가진 세 가지 문제를 해결해줄 Wwise를 사용하기로 했죠.
1. 트랙이 잘 전환됨
2. 음악이 강렬하게 들리고 효과음이 항상 들릴 수 있게 게임을 믹싱할 수 있음
3. 박자 동기화
전환 및 효과
조쉬 설리반(Josh Sullivan): 저는 BPM의 모든 사운드를 담당했습니다. 제가 사운드를 제작하고 믹싱하는 과정은 꽤 독특합니다. 저는 동영상 제작 분야에서 10년 이상의 경험이 있기 때문에 BPM에 들어갈 사운드를 믹싱하고 결합하는 프로그램으로 동영상 편집 소프트웨어인 Sony Vegas를 사용했습니다. Vegas는 저에게 항상 동영상 미리 보기 창이 있는 Sound Forge(Sony의 오디오 편집 소프트웨어)와 같았죠.
다행히 BPM 사운드트랙은 분당 88 박자입니다. 게임 전체에 걸쳐 일관된 이 템포 덕분에 클릭 트랙에 맞춰야하는 모든 오디오 시퀀스를 쉽게 자를 수 있었죠. 예를 들어 BPM에서 무기의 재장전 단계는 모두 박자에 맞춰져 있습니다 (영화 '베이비 드라이버' 같은 느낌을 주죠). 저는 실제 클릭 트랙을 Vegas 타임라인에 넣고 각 사운드를 이 물리적 클릭 트랙에 맞춰 잘라서 이를 달성했습니다. 각 사운드는 이 단일한 템포에 맞춰져 있죠. 하지만 이 방법은 템포가 하나 이상인 경우 작동하지 못했을 것입니다.
사운드가 준비되면 저는 Wwise로 이를 가져와서 위치 지정 데이터를 입력합니다 (팔요한 경우). 그런 다음 필요한 경우 사운드 인스턴스를 제한합니다. 이 제한이 꼭 필요한 예시인 미니 총은 매 4분 음표마다 발사됩니다. 이 발사 속도 때문에 믹스가 무뎌질 수 있기 때문에 한 번에 하나의 미니 총 발사 소리만 재생되도록 제한하는 것이 좋습니다. 다음으로 저는 General Settings를 조정합니다 (보이스, 피치 등). 마지막으로 사운드를 해당 Output Bus로 설정합니다. 총소리같은 경우 각 총에 대해 적어도 4개의 고유한 사운드가 있습니다. 이 사운드를 모두 Random Container에 넣어서 플레이어가 무의식적으로 반복되는 느낌을 받지 않도록 해줍니다.
이 작업을 완료하고 난 후에는 Wwise에서 해당 오디오에 대한 Event를 생성하기만 하면 됩니다. 저는 Event를 너무 복잡하게 만들지 않았습니다. 이를 사용한 예시 중 하나는 새로운 사운드를 시작하기 전에 이전 사운드를 먼저 중단하는 것이었습니다. 적들이 시끄럽게 떠드는 경우를 생각해보세요 (박자에 맞춰 꾸엑대고 으르렁거리는 소리). 적의 고통 Wwise Event가 트리거되면 '아야' Random Container를 재생할 뿐만 아니라 적의 중얼거리는 소리를 멈춥니다.
음악의 경우 Wwise의 Music Switch Container와 Music Playlist Container를 사용하여 한 음악에서 다른 음악으로 전환하는 것이 비교적 간단해졌습니다. 시간 설정 덕분에 박자에 맞춰 모두 동기화되죠.
게임에서 음악이 박자에 맞지 않아야 하는 경우가 있는데, 그건 바로 보스 피니셔입니다. 보스를 물리치면 박자 없이 보스를 끝낼 수 있습니다. 각 음은 자신의 시간에 맞춰 발사되며 다음 발사까지 각 음이 무한 반복됩니다. 비록 기술적으로는 '음악'이지만 Wwise Event로 구현하기가 더 쉽기 때문에 Wwise에서 '사운드'로 취급했습니다.
리듬 액션 게임 믹싱하기
샘 하우튼(Sam Houghton): BPM을 믹싱할 때의 주요 목표는 플레이어가 지옥의 락 오케스트라를 이끄는 것처럼 느끼게 하는 것이었습니다. 무기는 믹스에서 주도적인 악기가 되며, 게임의 흐름에 들어가 큰 연속 타격을 기록하기 시작할 때 굉장한 만족감을 주는 것이 목표입니다. 반대로, 샷이나 재장전 혹은 능력을 박자에 맞춰 실행하지 못하면 사운드가 재생되지 않아서 빈약하고 실망스럽게 들립니다.
또한 저는 조 콜린슨(Joe Collinson)과 함께 음악을 작곡했기 때문에 이러한 사운드를 위해 음악 편곡에 공간을 남겨두었죠. 결과적으로 OST 자체로도 훌륭하지만 총소리와 섞였을 때 더 멋지게 들린다는 댓글이 꽤나 많았습니다. 플레이어가 이 의도를 알아주니 정말 신이 났죠. 게임 사운드트랙은 결국 게임플레이를 지원하기 위한 것입니다. BPM은 다른 많은 게임 장르보다 이를 더 명확하게 해내죠.
초기에는 플레이어가 '박자에 맞춘 상호작용'을 할 때 음악 채널을 덕킹하는 것을 시도했지만, 약간의 덕킹은 만족감을 높이는 데 아무런 도움이 되지 않았고 오히려 게임의 에너지를 빼앗았습니다. 그래서 Wwise에서는 음악과 관련하여 모든 것이 명확하고 강력하게 들리도록 여기저기서 몇 가지 레벨을 조정하는 일만 합니다. 조쉬 설리반이 게임의 모든 사운드를 훌륭하게 만들어줘서 믹싱 작업이 아주 쉬웠죠.
박자 동기화
데이비드 존스(David Jones): 게임 시계를 박자에 맞추기 위해 저는 보더랜드(Borderlands) 솔루션이 가장 좋다고 생각했습니다. Wwise를 수정하여 MIDI 호출을 가로채고 게임 논리를 중단시키는 것이죠. 매 박자가 끝날 때마다 그 순간의 입력 상태를 요청할 수 있습니다.
완벽한 솔루션은 Wwise에서 박자 Event가 호출될 때마다 컨트롤러 입력이 거의 즉시 폴링되는 것입니다. 거의 샘플 기반 접근 방식이라 할 수 있죠. 입력과 오디오를 매우 밀접하게 연결하여 플레이어의 입력이 '늦었는지' 혹은 '빨랐는지', 그리고 몇 밀리초 차이가 나는지를 판단하여 최대한의 정밀도를 달성합니다. 그런 다음 음악과 너무 맞지 않는 입력은 거부하죠. 하지만 이 솔루션은 저희 팀의 규모로는 실행 불가능했습니다. 이 작업은 Unreal Engine의 전체 입력 시스템에 영향을 미치고 Wwise를 수정해야 하기 때문에 전담 오디오 프로그래머가 필요합니다. 그래서 저희는 다른 방향을 택하기로 했습니다.
간단한 해결 방법
저희 해결책은 아주 간단하고 가볍습니다. 저희 음악 Event에 콜백을 등록하고 EAkCallbackType::MusicSyncBeat를 찾죠. Music Switch Container에서 이러한 Event가 발생할 때마다 게임 시계와 트랙을 통해 이뤄진 암묵적인 진행 상황 간의 차이를 찾습니다. 이 차이가 10밀리초를 초과하면 게임 시계를 재조정하고 모든 관련 액터에게 Event를 호출합니다.
이 간단한 보정 방법을 선택한 이유는 게임플레이가 더 복잡한 것을 필요로 하지 않기 때문입니다. 이는 적들이 리듬 시험 창보다 훨씬 작은 약 10밀리초 이하의 오차로 정확하게 타이밍을 맞추도록 유지해줍니다.
하지만 플레이어의 입력에 대해 고려해야 할 다른 오류가 있습니다. 플레이어 오류 창은 다음과 같습니다.
시계 보정에서 10ms, 프레임타임에서 +[frametime]ms , 지연 렌더러 사용으로 인한 추가 +[frametime]ms , 입력 장치에서 +?ms , 콘솔 처리에서 +?ms , TV/오디오 출력 처리에서 +?ms.
이는 일부 시스템에서 잠재적으로 큰 오류를 일으킬 수 있습니다. 저희는 이 오류가 사용자마다 아주 다양하다는 것을 알고 있었습니다. 하지만 여기에는 훨씬 더 나쁜 문제가 있습니다. 바로 리듬 FPS에 '저주받은 문제'가 있다는 것이죠.
2019 GDC 강연에서 Riot Games의 알렉스 재프(Alex Jaffe)는 이 '저주받은 문제'를 '핵심 플레이어 약속 간의 갈등에 뿌리를 둔, 해결할 수 없는 디자인 문제'라고 정의했습니다. BPM에서 저희가 한 약속은 '박자에 맞춰 발사한다'와 '방아쇠를 당길 때 총알이 발사된다'였습니다. 이 둘은 서로 충돌했죠. 이 문제를 해결할 수 있는 유일한 방법은 '포기함으로써 승리하기'입니다.
기타 히어로(Guitar Hero)같은 박자 맞추기 게임에서는 컨트롤러를 보정하여 설정한 레이턴시 시간만큼 입력이 상쇄됩니다. 음이 인과적 영향을 미치지 않기 때문에 레이턴시 시간을 고려하여 시험할 수 있죠. 게임은 동영상 레이턴시 시간을 고려하여 과거에 리듬 입력을 달성했는지 시험합니다. 게임은 음이 언제 맞아야 했는지, 음이 언제 맞았는지, TV 레이턴시가 무엇인지를 알고 있습니다. 그래서 게임은 현재 시간 - 레이턴시 시간에서 창 안에 있었는지를 확인하기 위해 과거를 들여다봅니다. 이해하기 어려울 수 있어요. 이 때문에 기타 히어로에서 음이 선 아래로 사라지고 선을 지나쳤음에도 불구하고 성공적으로 '스트럼'되는 것을 볼 수 있죠. TV에는 레이턴시가 있으며 여러분이 이 레이턴시를 실시간으로 보고 있는 것이랍니다. 하지만 PS에서는 조준이 매 순간 정의되기 때문에 이를 실행할 수 없습니다.
BPM에서 저희는 사용자에게 80밀리초 미만의 레이턴시가 있다고 가정합니다. 사용에게 이보다 더 많은 레이턴시가 있을 경우 시작 보정 시퀀스 동안 이를 감지하고 자동 리듬을 활성화하죠. 자동 리듬은 플레이어가 입력할 때 다음 비트가 발생할 때까지 이 플레이어 샷을 유지합니다. 80밀리초 미만의 지연 시간이 있는 사용자에게는 조기 샷을 지연시켜 다음 박자에 발생하도록 하고, 늦은 샷은 즉시 발사되도록 합니다.
또한 BPM에는 플레이어의 기분을 좋게 만들기 위해 타이밍이 좋지 않은 특정 행동을 용서해주는 마법이 있습니다. 무엇이 용서할 수 있고 용서할 수 없는 타이밍인지를 정의하는 데 수많은 논리가 있죠. 대부분은 모든 입력 구성을 문제 없이 재생할 수 있도록 하기 위함입니다. 엄격하게 정의된 리듬 게임이 아닌 서사적인 락 오페라 슈팅 경험을 추구했죠.
결국 BPM은 음악과 게임플레이의 탄탄한 통합 덕분에 성공적이었고, Wwise는 저희가 속도와 제어력을 갖춘 BPM을 달성하는 데 도움을 주었습니다.
![]() 데이비드 존스(David Jones) | 프로그래밍 |
![]() 조쉬 설리번(Josh Sullivan) | 사운드 |
![]() 샘 하우튼(Sam Houghton) | 음악 |
댓글