Game of Thrones에서 모바일용 웨스테로스 구축하기: 드래곤파이어

워너 브라더스를 위해. Games Boston은 웨스테로스의 세계를 모바일로 구현하기 위해 단순히 인기 프랜차이즈를 각색하는 것 이상의 노력을 기울였습니다. 드라마 '드래곤의 집'을 기반으로, 왕좌의 게임: 드래곤파이어 대규모 멀티플레이어 전략과 드래곤 전투를 결합하여 최신 모바일 기기에 최적화된 무료 플레이 경험을 제공합니다.
플레이어는 발리리아 후손이 되어 용을 부화시키고, 기르고, 지휘하는 역할을 맡게 되며, 수천 명의 다른 플레이어와 경쟁하여 철왕좌를 차지하기 위해 싸웁니다. 그러한 환상을 구현하기 위해서는 고품질 비주얼, 확장 가능한 성능, 그리고 다양한 기기에서 작동하는 실시간 멀티플레이어 시스템 간의 균형을 맞추는 것이 필요했습니다.
모바일 기기용 드래곤 제작, 대규모 전략 게임플레이 지원, 그리고 Unity 활용하여 웨스테로스 세계를 구현하는 방법에 대해 기술 감독인 아라 예사얀과 고급 기술 아티스트인 타이아 리와 이야기를 나누었습니다.

플레이어의 첫 세션 경험에 대한 주요 목표와 제약 조건은 무엇이었습니까?
Ara Yessayan: 첫 번째 세션 에서는 플레이어의 몰입도를 유지하고 몰입을 방해할 수 있는 공백 시간을 최소화하는 것이 중요합니다. 저희 게임, '하우스 오브 더 드래곤'의 기본 요소와 세계관 속 이야기를 점진적으로 소개하는 것이 중요합니다.
신규 플레이어와 복귀 플레이어 모두의 로딩 시간을 최소화하기 위해 어떤 전략을 사용하셨으며, 이러한 경험은 어떻게 다른가요?
AY: 새로운 설치의 경우, 초기 설정 시 필요한 데이터 양을 최소화하는 데 중점을 둡니다. 저희는 플레이어가 게임 시작 화면에 도달하기 전에 다운로드하거나 메모리에 로드해야 하는 데이터 양을 줄이는 기술과, 화면 전환을 활용하여 이러한 로드 작업을 일부 처리하는 방법을 모색해 왔습니다. 복귀 플레이어의 경우, 플레이어 상태를 구축하고 지도상의 적절한 위치에 배치하기 위해 더 많은 데이터가 필요합니다. 전제는 비슷하지만(데이터 대기 시간 최소화), 기술은 역직렬화 비용과 초기 요구 사항을 줄이는 전략적 방법에 더 중점을 둡니다.

개발 과정에서 가장 큰 로딩 시간 병목 현상을 어떻게 파악하셨나요?
AY: 로딩 시간을 개선하기 위해 몇 가지 접근 방식을 사용했습니다. 병목 현상이 어디에 있는지 전반적으로 파악하기 위해 로딩 프로세스의 각 단계에 대한 사용자 지정 프로파일링 이벤트를 설정하고 이를 CSV 파일에 기록했습니다. 우리는 여러 세션에 걸쳐 값을 종합하여 어떤 단계가 주요 관심사인지 파악했습니다. 또한 이러한 데이터를 Chrome 추적 이벤트 및 OpenTelemetry 추적 데이터로 변환하여 각 단계가 병렬로 로드되는 방식을 더 잘 시각화할 수 있도록 했습니다.
그 후, 우리는 특정 단계에 집중했습니다. Unity Profiler 의 CPU 모듈 덕분에 비효율적인 코드에 대해 더 깊이 이해하고 이를 개선할 수 있었습니다. 경우에 따라 여러 프로파일을 기록하고 Unity 프로파일 분석기를 사용하면 일부 로딩 값을 조정했을 때 로딩 시간이 어떻게 개선(또는 악화)되는지 평가하는 데 도움이 되었습니다.
CPU 프로파일러는 프레임 끊김 현상이 심한 프레임을 분석할 때, 프레임률 저하의 원인을 파악하고 더 나은 기술을 찾는 데 유용하게 사용되었습니다.
로딩 외에도 렌더링 모듈은 게임 내에서 렌더링의 비효율성을 파악하는 데 도움이 되었고, RenderDoc은 런타임 문제를 심층적으로 분석해야 할 때 활용한 또 다른 도구였습니다.
마지막으로, 세션을 계속 진행하기 위해서는 메모리 사용량을 통제해야 했습니다. 메모리 프로파일러 스냅샷을 통해 특히 맵과 행군 지역에서 불필요한 에셋 및 객체 로드를 식별했으며, 이를 통해 게임 접속에 필요한 로딩 시간을 줄였습니다.
유니티의 메모리 프로파일러를 사용하여 에셋 번들의 메모리 사용량을 분석하고, 중복 에셋을 감지하고 에셋 언로딩을 확인하는 방법을 설명해 주시겠습니까? 구체적인 예를 들어주시겠습니까?
타이아 리: 일반적으로 메모리 프로파일러를 사용하여 게임 내에서 예상치 못한 시점에 에셋이 로드되어 메모리에 남아 있는 경우를 식별합니다. 예를 들어, 텍스처가 여러 곳에서 사용되지만 단일 번들에 포함되어 있는 경우, 해당 텍스처 하나만 필요할 때 전체 번들이 로드되는 문제가 발생할 수 있습니다.
이것이 바로 우리가 이러한 문제를 방지하기 위해 특정 공유 번들을 만들고자 하는 또 다른 이유입니다. 이 도구는 특히 우리가 인지하지 못했거나 예상보다 규모가 큰 기억 오류의 주요 원인을 찾아내는 데에도 유용합니다.

특히 콘텐츠 제공 및 게임 플레이 성능과 관련하여 초기에 겪었던 가장 예상치 못한 성능 문제는 무엇이었습니까?
AY: 놀라웠던 점은 지도 레이아웃을 나타내는 지도 파일 데이터를 불러오는 데 생각보다 많은 메모리가 필요했다는 것입니다. ~ 안에 왕좌의 게임: 드래곤파이어 플레이어는 자신의 군대와 용을 이용하여 지도상의 영토(타일)를 점령합니다. 이러한 요소들은 플레이어가 자원을 모으는 데 도움을 주고, 플레이어 자신이나 같은 진영의 다른 구성원이 인접한 타일을 소유해야 한다는 조건을 기반으로 군대를 보낼 수 있는 지역을 제한합니다.
콘텐츠를 불러오려면 지도 데이터를 여러 부분으로 나눠야 한다는 것을 알고 있었습니다. 게임이 각 좌표에 무엇이 있는지 이해하려면 해당 데이터가 필수적이었으며, 특히 여러 타일에 걸쳐 있는 노드의 경우 추가 데이터를 저장해야 했기 때문에 더욱 중요했습니다. 2000×4000 크기의 맵과 관련된 모든 구조체를 로드하는 데 너무 많은 메모리가 사용되어 일부 기기가 다운되었습니다.
전체 맵 대신 필요한 부분만 로드하도록 개선 및 최적화 작업을 진행하면서, 기존 플레이어들의 로딩 시간이 크게 단축되었습니다.
지도 최적화를 위해 사용한 또 다른 기술은 지도상의 지형을 나타내는 게임 오브젝트를 메시를 직접 렌더링하는 방식으로 대체하는 것이었습니다. 이를 통해 해당 게임 오브젝트를 인스턴스화하는 데 드는 메모리 비용을 피할 수 있었습니다. 이와 더불어 주변 지역에 필요한 메시와 모델만 전략적으로 로드함으로써 지도 진입 및 스크롤 성능이 모두 향상되었습니다.

출시 시점에 반드시 제공해야 하는 콘텐츠와 나중에 스트리밍하거나 로드할 수 있는 콘텐츠를 어떻게 결정하시나요?
AY: 첫 번째 단계는 플레이어가 게임의 멀티플레이어 단계에 진입하기 전에 최초 사용자 경험(FTUE)에 필요한 것이 무엇인지 파악하는 것입니다. 이를 통해 플레이어들이 정식 게임에 접속할 때 사용하는 모든 데이터를 다운로드할 수 있는 기회를 얻게 됩니다.
실시간 운영이나 후기 단계 기능과 관련된 다른 유형의 콘텐츠도 나중에 다운로드할 수 있습니다. 저희는 플레이어들이 시스템을 접하는 즉시 게임을 즐길 수 있도록 하고 싶습니다.
향후 로딩 시에는 로딩 시간을 늘릴 수 있는 요소를 미리 로드하는 것과 화면이나 영역에 진입하기 전에 로딩 스피너를 활성화할 수 있는 비동기적으로 로드하는 것 사이에서 신중한 균형을 유지해야 합니다. 저희는 최상의 사용자 경험을 찾기 위해 이 분야에서 지속적으로 개선 작업을 진행하고 있습니다.
다운로드 크기, 메모리 사용량 및 런타임 유연성 간의 균형을 맞추기 위해 자산 번들 파이프라인을 어떻게 구성하고 자동화했습니까?
TL: 일반적으로 자산 번들의 크기는 8MB 미만으로 유지하는 것을 목표로 하지만, 사용 사례 및 번들에 필요한 자산에 따라 예외가 있을 수 있습니다. 이러한 이유로 우리는 런타임에 함께 자주 사용되는 자산들이 동시에 사용 가능하도록 번들을 구성하게 되었습니다.
반대로, 자산의 일부만 사용되는 지나치게 큰 묶음 상품은 피합니다. 저희는 게임 영역, 기능 또는 공유 자산 유형별로 번들을 정리해 놓았습니다. 예를 들어, 저희 지도에는 다양한 생태계가 있으며, 각 생태계에는 해당 위치에 맞는 별도의 에셋이 있습니다.
우리는 북쪽의 설산과 남쪽의 사막 산맥을 같은 묶음으로 볼 필요가 없습니다. 하지만 일부 메시와 텍스처는 여러 바이옴에서 공유되므로 이러한 에셋은 공유 번들에 포함됩니다.
이는 게임 성능을 최적화하기 위해 게임 전반에서 자산이 어디에 사용되는지 이해해야 하는 균형 문제입니다. 다른 모든 라이브 게임과 마찬가지로, 이는 새로운 기능이 추가됨에 따라 지속적으로 검토하고 재구성해야 하는 과정입니다.
AY: Addressables가 출시되기 전에, Addressables가 현재 해결하는 많은 문제들을 해결하는 데 도움이 되는 일련의 도구를 자체적으로 개발했습니다. 이러한 내부 도구 중 일부는 번들 구성을 이해하고 패치를 다운로드하여 업데이트하는 고급 기술(이를 "바이너리 패칭"이라고 함)을 사용할 수 있도록 지원합니다.

자산 묶음 작업을 하면서 어떤 절충점이나 어려움을 겪으셨고, 어떻게 해결하셨나요?
TL: 우리가 직면한 가장 큰 어려움은 누군가가 기존 프리팹을 수정하거나 많은 새 에셋을 추가할 때 에셋 번들 크기 및 구성에 미치는 잠재적 영향을 인지하지 못한 채 에셋 번들 크기가 급격히 증가할 수 있다는 점입니다.
사람들이 모르는 사이에 번들 크기가 한 번에 5MB 이상 증가하는 경우가 있었고, 최악의 경우 이로 인해 .aab 파일이 스토어 제출 시 허용되는 크기 제한을 초과하는 상황이 발생했습니다. 이후 빌드 파이프라인에 이러한 경우를 감지하는 알림 기능을 추가하여 개발자들이 변경 사항으로 인해 번들 크기가 예기치 않게 증가할 수 있는 시점을 더 잘 이해할 수 있도록 지원했습니다.
자산 종속성을 어떻게 처리해야 중복 다운로드와 불필요한 메모리 사용을 방지할 수 있을까요?
TL: 내부 자산 번들 관리 도구에서 번들 간에 중복된 자산을 확인할 수 있습니다. 일반적으로 중복되는 에셋, 특히 용량이 큰 에셋은 원하지 않으므로, 여러 번들에서 종속성으로 가져오도록 허용하는 대신 해당 에셋을 번들에 직접 추가합니다. 해당 파일이 여러 곳에서 사용할 수 있는 번들에 추가되도록 해야 하지만, 일반적으로는 별도의 공유 번들을 생성합니다.

앱 시작 시 에셋 역직렬화로 인해 발생하는 CPU 사용량 급증이나 지연을 줄이기 위해 어떤 기술을 사용하셨습니까?
AY: 저희가 설계 데이터를 저장하는 데 사용하는 기술 중 하나는 일반적인 JSON 형식 대신 프로토콜 버퍼(Protobuf) 형식을 사용하는 것입니다. gRPC에서 사용하는 바이너리 형식인 Protobuf는 더 작은 저장 공간과 더 빠른 역직렬화 속도를 제공합니다.
연관된 구조화된 스키마 파일을 사용하면 JSON 문자열의 내용을 구문 분석하고 구조를 토큰화하지 않고도 데이터를 메모리에 훨씬 빠르게 로드할 수 있습니다. 데이터를 보다 효율적으로 저장하고 역직렬화하기 위해 BSON 및 Odin Serializer와 같은 다른 옵션도 검토했지만, gRPC를 사용하여 서버와 더욱 효율적으로 통신할 수 있다는 점이 우리에게 적합한 선택이었습니다.
효과적인 스레드 관리 또한 매우 중요합니다. Unity 메인 스레드에서 분리할 수 있는 작업을 파악하여, 에셋과 씬을 로드하는 작업에만 집중할 수 있도록 하세요.
패치 및 콘텐츠 업데이트 속도를 높이기 위해 빌드 크기와 배포 파이프라인을 최적화하는 방법은 무엇입니까?
AY: 저희가 사용하는 몇 가지 기술이 있습니다. 무엇보다도, 우리는 게임 바이너리에 포함된 필수 에셋과 나중에 다운로드할 수 있는 에셋 사이의 적절한 균형을 맞추는 데 집중합니다. 저희 게임에는 몇 분 정도 소요되는 튜토리얼이 있는데, 이 시간을 활용하여 플레이어들이 처음 로그인할 때 방해받지 않고 필요에 따라 추가 리소스를 다운로드할 수 있습니다.
안드로이드의 플레이 에셋 배송 기능을 활용함으로써 초기 단계에서 더 많은 리소스를 확보할 수 있었습니다. 우리는 일부 동적 데이터 테이블이 오래된 데이터가 될 수 있다는 것을 예상하고 게임 클라이언트에 해당 테이블들을 포함시키기 시작했습니다. 변경된 테이블만 다운로드함으로써 로딩 시간을 단축했습니다.
그 후, 우리는 바이너리 패칭 기술을 도입하여 더 작은 바이너리 차이점을 다운로드하고 새 버전을 통째로 다운로드하는 대신 수정된 파일을 패치할 수 있게 되었습니다. 이 기능을 에셋 번들에도 활용하여 새로운 라이브 이벤트에 맞춰 게임 콘텐츠를 필요에 따라 패치할 수 있습니다.

돌이켜보면, 플레이어들의 로딩 시간을 개선하기 위해 가장 큰 영향을 미친 변화는 무엇이었습니까?
AY: 간단히 말해서, 플레이어가 필요한 것만 로드하도록 하는 것입니다. 소프트 론칭에 앞서, 우리는 지도가 로딩 시간을 지연시키는 가장 큰 병목 현상 중 하나임을 파악했습니다. 당시 게임은 최적화를 시작하기 전에 모든 지도 리소스를 미리 불러와 플레이어의 본거지 주변 지역만 표시하도록 했습니다.
필요한 데이터를 파악하고 나머지 데이터를 나중에 비동기적으로 로드하는 기술을 구현함으로써 고사양 기기에서도 로딩 시간을 수 초씩 단축할 수 있었습니다. 우리 팀은 플레이어들의 로딩 시간을 개선하고 더 나은 사용자 경험을 제공하는 임무를 완수했으며, 그들의 노고에 진심으로 감사드립니다.
Unity 로 제작된 프로젝트에 대한 자세한 내용을 보려면 리소스 페이지를 방문하세요.
