NDC 참관기: 게임 애셋 스트리밍 패치

이승재 (http://ricanet.com) 군의 발표. 여기서 들은 내용을 간략히 정리해 보았다.

프론티어 팀에서 데스크탑 히어로즈(이하 DH)를 개발하면서 얻은 경험을 공유했다. 여기서 애셋은 그래픽 리소스, 사운드 등등의 게임 내 리소스를 말한다.

왜 스트리밍 패치를 했는가?

설치 용량 10 MiB 이하인 게임을 원해서 애셋 스트리밍 패치를 구현. 그 결과,

  • 작동을 위한 ‘최소한의 파일’ 만 받게 함 (다만 이 리소스를 사람이 수동으로 고르지는 않게)
  • 게임 패쳐를 내장해야 한다

어떻게 했는가?

  1. DH는 스테이지 단위로 쪼개져 있다. 스테이지에서 필요한 걸 로딩 시점에 다운로드 받게

개별 애셋은 이름 / 크기 / CRC / svn revison 로 구분하도록 했다.

전체 애셋은 수 십 MiB -> 이들의 목록은 수 십 KiB -> 이에 대한 버전은 수 십 bytes 버전 파일을 비교하고, 필요하면 목록을 얻어와서 필요한 파일만 받도록 구현.

  1. 지금 (스테이지) 필요한 파일만 ‘미리’ 로딩 화면에서 받는다 (플레이 중 멈추는 건 대략 좋지 않음)
  • 항상 필요한 파일 (bin, script, ui …, seed.lua?)
  • 현재 스테이지에서 필요로 하는 파일
  • 이들이 의존하는 파일

로 구분해서 이 파일들을 다운 받는다.

이를 위해 ‘애셋 의존성 분석’ 코드를 리소스 종류별로 만들었다.  이 의존성은 게임 요소에  따라 다르고, 리소스 종류가 추가되면 추가해야 함. 3. 다운로더

  • 메인 스레드가 ‘큐에 요청을 넣음’
  • 다운로드 스레드 (1~10) 가 이 큐에서 요청을 꺼내고, 해당 리소스와, 해당 리소스가 의존하는 리소스를 다운 받게 구현

기타 이슈

  • 개발용 버젼은 스트리밍 패치를 (당연히) 끄게 했다. 근데 이렇게 했더니 개발 중에는 잘되는데 릴리즈에서 죽는 경우가 생김 (리소스 종류가 추가되거나, 꼭 필요한 파일인데 seed.lua에 추가 안하거나) + 개발 버젼에서도 처음 보는 종류의 리소스 같은 걸 검사하게 수정
  • 제일 복잡한 서브 시스템이 되어버림
    • 임의 파일 추가 / 삭제 처리

    • MT read/write를 보장해야

    • 견고 해야 한다. 오류에 충분히 저항해야 함. 임의 시점에 클라가 죽을 수도 있다

      그래서,

      • 파일 메타 데이터처리를 저널링으로 구현
      • 힙처럼 관리해서 지울 때 참조하는 애가 없어야 실제로 free-block으로 마크
      • 오버랩드 I/O로 처리 등등 의 수 많은 예외 파일이 없어서 죽거나 기타 등등 수많은 예외가 생겼고, 이에 대한 크래시 리포트 분석 및 예외 처리 작업 (현재 진행 형)
  • 아바타: 누가 내 ‘방’에 들어올지 모르니 항상 필요한 리소스로 처리.. 다만 이걸 더미 리소스로 보여주고, 백그라운드 로딩해서 바꿔치기 하는 등으로 할 수 있음
  • 보너스: 의존성 검사가 있기 때문에, ‘필요 없어진’ 리소스를 쉽게 파악하게 되었음

여기서 부터 내 촌평.

스트리밍 패치는 어느 정도 게임 의존적이긴 하겠지만, 많은 경우 쓸만한 곳을 찾을 수 있겠더라. (일단 내가 작업 중인 쪽만 해도…)

리소스 의존성을 ‘잘 기술하면’ 재사용될 부분도 많고, 전체 개발 프로세스에 + 요인이 될 듯함. (특히 비대해지기 쉬운 파일 묶음을 어떻게든 줄일 수 있으면…)

실질적으로 서버 비용이 줄어드는 것도 있고, VFS 같은 걸 만드는 건 꽤나 재밌기 때문에 (어이).

전체적으로, 발표 전반에서 ‘어째서, 어떻게, 왜’가 잘 드러나 있는 점이 만족스러웠다 (메이플 스토리 개발 스토리랑 비슷한 느낌; 예전 같은 팀이라?). 다만 해당 강연장이 강단을 빼고 어둡게 처리되어있는데, 카메라 플래시가 계속 터져서 집중하기 어려운 건 좀 그랬다; 이건 내년에 좀 해결되었으면 한다.