6 minute read

유지보수 비용이 낮은 간단한 기술을 사용해서 훌륭한 결과물을 만들어냈다. 로컬에서 변경한 걸 같이 테스트하고 싶다면 클릭 몇 번으로 판이 깔린다. 빠른 플레이테스트 환경을 만든 기술이 Guild Wars 2의 Streaming Client처럼 서비스로 이어질 수 있다. 게임 실행에 필요한 최소한의 파일을 다운로드 받은 다음 플레이하는 동안 백그라운드로 에셋을 다운로드해서 대용량 게임 설치 부담을 줄일 수 있게 된다. 믿고 보는 블리자드 발표다.

요약 by human

  • 과장을 한 숟갈 넣으면 플레이테스트 같은 문화는 기술이 만든다
  • 플레이테스트(playtest)
    • 게임 개발자가 새로 만든 게임 피처를 테스트
  • 다운로드 용량이 문제
    • 하루에 빌드 50개, 2주 보관, 게임 데이터 용량이 50GB
      • 정규 빌드, 브랜치 빌드, 로컬 변경 사항 빌드 포함
  • 에셋을 CAS(Content-addressable storage)로 저장
    • 중복 데이터 검출에 편리
  • Manifest file(매니페스트 파일)에 게임에 필요한 에셋을 관리
    • 에셋을 다운로드 할 때, 로컬에 없는 hash값을 가진 에셋만 다운로드
  • 바이너리는 모듈러 빌드(modular builds), 빌드 피처(build feature)로 효율화
    • 단일 실행 파일과 다수의 빌드 피처로 구성됨
  • 플레이테스트 툴인 ToolsTray를 실행해서 클릭 몇 번이면 플레이테스트를 위한 판이 깔림
    • 바이너리 실행 파일을 하나 다운로드 받아서 실행하고 에셋과 빌드 피처를 다운로드
    • 에셋, 바이너리 다운로드 효율화로 몇 분 내에 시작

플레이테스트(Playtest) 뜻

A playtest is the process by which a game designer tests a new game for bugs and design flaws before releasing it to market. Playtests can be run “open”, “closed”, “beta”.

Playtesting is a part of usability test in the process of game development.

플레이테스트는 게임 디자이너가 새 게임을 시장에 출시하기 전에 버그와 디자인 결함이 없는지 테스트하는 프로세스입니다. 플레이테스트는 “공개”, “비공개”, “베타”로 실행할 수 있습니다.

플레이테스트는 게임 개발 과정에서 사용성 테스트의 일부입니다.

Playtest - en.wikipedia.org

새 게임을 출시하기 전에 테스트하는 프로세스로 OBT(open beta test), CBT(closed beta test), FGT(focus group test)와 같이 테스트하는 범위를 정한 테스트도 포함하는 개념이다. 게임 개발자가 새로 만든 게임 피처를 테스트하는 것도 플레이테스트라고 부른다. Dogfooding(개밥 먹기)를 게임 개발 프로세스에 한정해 사용하는 단어라고 생각하면 된다.

플레이테스트 문화를 지탱하는 건 기술

  • a culture of playtesting
    • our playtest system is the most important feature in our toolchain
    • drive team culture through better tooling
    • iterate as a team

자주 팀테스트를 하자. 플레이테스트가 더 좋은 게임을 만든다. 게임 개발자는 경험 많은 게임 플레이어이기도 하기 때문이다. 오버워치 (Overwatch, Blizzard, 2016)처럼 멀티플레이어 대전 게임에서는 특히 더 중요하다. 사람을 상대로 테스트를 더 많이 해야 하기 때문이다.

최신을 받고 서버와 클라이언트를 실행하는 데 시간을 쓴다. 같이 테스트하려고 개발자 A의 서버에 연결한다. 버전이 달라서 클라이언트가 서버에 접속하지 못한다. 다시 버전을 맞춘다. 말해준 버전을 못 찾겠다. 브랜치를 따서 작업한 거라고 한다. main 브랜치만 정기적으로 빌드해서 배포한다. 해당 브랜치를 체크아웃(checkout)하고 로컬에서 빌드한다.

플레이테스트 문화가 일장 연설이나 계몽으로 이뤄지는 게 아니다. 기술이 문화를 지탱한다. 클릭 한 번으로 몇 분 내에 개발 중인 피처를 같이 테스트할 수 있게 Toolchain을 구축했다. 플레이테스트하기 쉬운 환경을 만들어서 문화가 자리 잡게 견인한다. 문화를 만드는데 프로그래머가 어떤 역할을 할 수 있는지 새삼 깨닫게 된다.

도전 과제

  • challenges
    • many branches, many builds
    • server stacks for modern games are complicated
    • large amounts of content
    • share your local changes
  • workflow goals
    • 바르게 만들고 공유
    • 빠르게 참가할 수 있어야 함

도전 과제를 한마디로 요약하자면 용량이다. 하루에 한 개의 정규 빌드만 만든다치고 2주 정도 빌드를 유지한다면 10개의 정규 빌드를 유지해야 한다. 정규 빌드를 만드는 개발 브랜치와 다른 출시 브랜치를 합친다면 더 많아진다. 게다가 다른 개발 중인 브랜치도 지원해야 한다. 기하급수적으로 관리해야 할 빌드 개수가 늘어나고 용량도 늘어난다.

기존 PC 사용자와 PC를 사용하는 감시 기지 팩 보유자의 경우, 10월 1일 오전 5시 30분경(한국 시각 기준)부터 오버워치 2를 미리 다운로드해 둘 수 있습니다. 다운로드 용량은 최대 50GB입니다. Battle.net에서 자동 업데이트를 활성화해 두었다면 다운로드가 백그라운드에서 자동으로 진행됩니다. 그러지 않을 경우 게임 시작 버튼 오른쪽의 톱니바퀴 아이콘을 클릭한 후 “업데이트 확인”을 선택해서 수동으로 다운로드를 시작할 수 있습니다.

오버워치 2 전투 준비: 출시에 미리 대비하세요! (10월 4일 오전 1시부터 서버 점검 예정) - 새소식 - 오버워치 - overwatc…

빌드 관리도 문제지만 플레이테스트를 하려고 다운로드 받는 용량도 문제가 된다. 플레이테스트를 할 때마다 50G를 받아야 한다면?

50GB를 10Gbps로 다운로드에 걸리는 시간 = 42초

1Gbps로 연결되어 있다면 이상적으로 약 7분이 걸린다. 동시 사용자 수, 파일을 서빙하는 서버 성능 등을 고려하면 10분 이상을 예상해야 한다.

플레이테스트를 위해 내려받는 양을 어떻게 줄일 것인가? 이게 도전 과제다.

에셋 데이터를 저장하고 다운로드 받는 방법

게임을 실행하는 데 필요한 데이터가 50GB라고 하면 48GB가 에셋(asset)이 대부분을 차지한다. 게임에서 화면에 보여주기 위한 텍스처, 사운드, 3D 모델, 애니메이션 등의 데이터가 대부분을 차지한다. 이런 에셋을 효율적으로 저장하고 다운로드 받을 수 있게 해야 한다. 각 빌드마다 50GB 용량이 필요하다고 해서 50GB를 차지하는 데이터가 모두 다른 건 아니기 때문이다.

발표에 따르면 Overwatch 개발팀에서는 하루에 빌드가 50개 이상 나온다고 한다. 정규 빌드, 브랜치 빌드, 플레이테스트를 위한 로컬에서 변경한 빌드를 포함한 갯수다. 빌드를 2주 이상 사용한다고 하면 최소한 700개 빌드를 유지해야 한다. 게임 크기가 50GB라고 하면 바이너리는 2GB 정도로 잡을 수 있고 대부분이 에셋이다. 따라서 35TB 정도를 계속 유지할 수 있는 컨텐츠 배급 저장소가 필요하다. 이 정도야 돈으로 해결할 수 있다. 하지만 작업자 컴퓨터 저장공간 관리 때문에 예전에 다운로드 받은 데이터를 다시 다운로드해야 하는 스노우볼링이 시작된다.

이걸 CAS(Content-addressable storage) 블리자드 구현체인 CASC(content addressable storage container)를 사용해서 에셋을 저장해서 해결한다. CAS는 Git을 떠올리면 된다. 파일 path로 구분하는 게 아니라 내용으로 hash 값을 만들어서 저장하는 방식이다. 파일 내용으로 hash 값을 계산하기 때문에 중복 제거가 자연스럽게 된다.

빌드 과정에서 각 빌드가 사용하는 에셋의 hash 값 리스트가 있는 Manifest file(매니페스트 파일)을 만든다. 여기에는 각 에셋의 hash 값과 다운로드 받을 수 있는 경로가 담겨져 있다. 클라이언트는 해당하는 빌드의 매니페스트 파일을 먼저 다운로드 받고 로컬에 없는 에셋 파일을 다운로드 받는 식으로 중복된 에셋을 다운로드 받는 시간 낭비를 줄인다.

바이너리를 효율적으로 다운로드 하기 - 모듈러 빌드(modular builds), 빌드 피처(build features)

앞서 살펴봤듯이 게임 데이터에서 에셋이 차지하는 비율이 압도적으로 높다. 게임 용량이 50GB라고 하면 48GB 정도가 에셋이다. 그래서 매니페스트 파일을 만들고 필요한 에셋만 받는 기능보다 우선순위가 떨어진다.

하나의 바이너리 파일로 만들지 않고 Windows라면 DLL(dynamic link library)로 모듈을 쪼갠다. 기능 단위로 쪼개서 필요한 기능만 다운로드하게 구성했다. 예를 들면 로봇에게 사격과 기술 연습을 하는 스테이지에 들어가면 해당 모듈을 다운로드 받는 식이다. 발표에서는 빌드 피처(build feature)라고 부른다.

바이너리 diff 패치 시스템도 고려해볼 수 있겠지만 모듈러 빌드가 가능하다면 다운로드 용량을 줄이겠다고 시스템 복잡성을 높일 필요는 없다고 생각한다.

바이너리는 단일 실행 파일과 다수의 빌드 피처로 구성된다.

플레이테스트 워크플로(workflow)

nil

  1. 플레이테스트 생성
    1. 서버를 세팅하는 과정
    2. 로컬에서 서버 스택을 모두 실행된다
  2. 플레이테스트 탐색
    1. 서버는 UDP 멀티캐스트(multicast)를 사용해 참가하는데 필요한 정보를 브로드캐스팅
    2. 플레이테스트를 위해 만든 인하우스(in-house) 툴인 ToolsTray에서 플레이테스트 서버를 표시
  3. 플레이테스트 참가
    1. 단일 실행 파일을 다운로드 후 실행
    2. 이후 서버가 브로드캐스팅한 정보에 담겨있는 주소에서 매니페스트 파일을 다운로드
    3. 에셋과 빌드 피처 다운로드

플레이테스트 툴 - ToolsTray

nil

ToolsTray에 script를 적극적으로 사용했다. 대부분의 기능을 script로 구현하고 script 호출에 필요한 인자를 편하게 입력할 수 있는 창구 역할을 ToolTray 바이너리가 하는 것 같다. 자동 업데이트 기능을 넣어두고 최신 버전으로 구현해도 괜찮지 않을까? 변경 사항이 생기면 예전 버전을 마일스톤 2개 정도는 지원하게 유지했다가 지우는 식으로 관리할 수 있을 것 같다.

disk cleaner 기능이 있는 것 보고 참 세심하단 생각을 했다. 플레이테스트가 많이 하다 보면 효율적으로 관리한다고 해도 저장 공간이 부족해지기 마련이다.

마치며

과장을 보태서 몇몇 문화는 기술이 만든다고 생각한다. “이거 봐라. 내가 우리 게임 플레이테스트를 하자고 귀에 못이 박히도록 얘기했는데, 해보지를 않았나 봐.” 잊을만하면 Slack 공지 채널에 올라오는 열심히 플레이테스트하자는 말로는 문화가 만들어지지 않는다. 클릭 몇 번으로 빠르게 플레이테스트를 할 수 있는 기술이 문화를 만든다.

links