안동민 개발노트

본문 시작

핫픽스와 업데이트 전략

긴급 핫픽스와 정기 업데이트를 구분하고 전체·증분 패치 생성과 CDN 배포 전략을 설계합니다.

이전 절에서는 게임 디버깅과 로그 관리를 다뤘습니다.

배포 이후에는 피드백, 버그 보고, 콘텐츠 추가에 대응하기 위해 업데이트 절차와 배포 방식을 운영 기준으로 관리해야 합니다.

이번 절에서는 언리얼 엔진 게임의 핫픽스(Hotfix)와 업데이트(Update)의 개념을 이해하고, 다양한 업데이트 전략 및 언리얼 엔진이 제공하는 관련 시스템에 대해 자세히 살펴보겠습니다.


핫픽스 vs 업데이트: 개념 이해

  • 핫픽스 (Hotfix)
    • 목적: 게임 플레이에 심각한 영향을 미치는 긴급 버그(예: 크래시, 진행 불가 버그, 익스플로잇)를 최대한 빠르게 수정하여 배포하는 것을 목표로 합니다.
    • 특징: 긴급도와 좁은 변경 범위로 구분합니다. 코드 수정도 핫픽스일 수 있으며 작은 다운로드나 무재시작 적용이 자동으로 보장되지는 않습니다.
    • 적용 방식: 준비된 데이터 갱신 경로 또는 플랫폼의 패치·재시작 절차를 사용합니다. 변경 종류와 로드 상태에 따라 적용 시점이 달라집니다.
  • 업데이트 (Update) / 패치 (Patch)
    • 목적: 버그 수정 외에도 새로운 콘텐츠(맵, 캐릭터, 아이템), 기능 추가, 성능 개선, 밸런스 조정 등 광범위한 변경 사항을 포함합니다.
    • 특징: 핫픽스보다 패치 크기가 크고, 적용하는 데 더 많은 시간과 대역폭이 소요될 수 있습니다. 일반적으로 클라이언트 전체 또는 변경된 부분의 재다운로드를 요구합니다.
    • 적용 방식: 게임 런처나 플랫폼 스토어를 통해 다운로드하여 설치됩니다.

언리얼 엔진의 업데이트 관련 시스템

언리얼 엔진은 패치 및 업데이트를 지원하기 위한 여러 도구와 개념을 제공합니다.

패치 파일 생성

콘텐츠 컨테이너는 프로젝트 설정에 따라 Pak 또는 IoStore(.utoc/.ucas) 등을 사용합니다. 아래 명령은 공식 Pak 기반 패치 흐름의 예시이며 IoStore 배포 절차에 그대로 적용한다고 가정하지 않습니다.

  • 기준 릴리스 보관: 기본 BuildCookRun 인자에 -build -cook -stage -pak -createreleaseversion=1.0을 더해 기준 릴리스를 만들고 Releases/1.0의 메타데이터를 보존합니다.
  • Pak 패치 생성: 같은 프로젝트·플랫폼의 기본 인자에 -build -cook -stage -pak -generatepatch -basedonreleaseversion=1.0을 사용합니다. basedonreleaseversion만 넣거나 cookonthefly를 켜는 것으로 패치 생성이 완성되지는 않습니다.
  • 차이 단위: 변경된 에셋 패키지가 패치에 포함됩니다. 임의의 파일 바이트 차분만 전송하는 방식과 구별합니다.
  • UnrealPak.exe: 명령줄 도구로, .pak 파일을 생성, 압축, 해제하는 데 사용됩니다. 패치 파일을 수동으로 조합할 때 유용합니다.

다운로드 및 적용

언리얼 엔진은 런타임에 .pak 파일을 마운트(Mount)하여 게임 콘텐츠로 인식할 수 있는 기능을 제공합니다.

  • 다운로드한 Pak의 버전·무결성을 확인한 뒤 지원되는 마운트 경로에 연결합니다. Pak 마운트는 파일 접근 경로를 추가하는 단계이며, 이미 로드된 UObject를 자동으로 교체하거나 코드를 갱신하지는 않습니다.
  • 이는 일반적으로 커스텀 패치 시스템이나 런처를 통해 구현됩니다.

버전 관리와 핫리로드

  • 개발 중 변경과 배포 패치: 에디터의 에셋 편집·Live Coding 동작은 배포된 게임의 갱신 계약이 아닙니다. 실행 코드와 구조 변경은 해당 플랫폼의 새 바이너리 배포 및 재시작 정책으로 다룹니다.
  • Asset Registry: 에셋을 찾기 위한 메타데이터를 관리합니다. 새 콘텐츠의 레지스트리 반영·검색 경로와 기존 객체의 재로드는 별도 책임이며 최신 패키지를 마운트한 것만으로 완료되지 않습니다.

주요 업데이트 전략

게임의 특성, 플랫폼, 개발팀의 리소스에 따라 다양한 업데이트 전략을 선택할 수 있습니다.

Full Client Download

  • 방법: 업데이트가 있을 때마다 플레이어가 게임 클라이언트 전체를 다시 다운로드하도록 하는 가장 단순한 방법입니다.
  • 장점: 구현이 매우 간단하고, 파일 손상이나 패치 관련 문제를 최소화할 수 있습니다.
  • 단점: 플레이어에게 가장 큰 불편함을 주며, 대용량 게임의 경우 막대한 대역폭과 다운로드 시간을 요구합니다. 배포 플랫폼의 차분 다운로드 정책에 따라 실제 전송량은 달라질 수 있습니다.
  • 적합한 경우: 게임의 규모가 매우 작거나, 업데이트 빈도가 극히 낮을 때.

Incremental Patching (증분 패치)

  • 방법: 이전에 배포된 버전을 기준으로 변경되거나 새로 추가된 파일만 다운로드하도록 하는 방식입니다. 언리얼의 Pak 패치는 보관한 기준 릴리스와 generatepatch·basedonreleaseversion 옵션을 함께 사용합니다.
  • 장점: 다운로드 크기를 크게 줄여 플레이어의 대역폭 부담과 다운로드 시간을 줄입니다.
  • 단점: 패치 시스템의 구현이 복잡해집니다. 어떤 파일이 변경되었는지 정확히 추적하고, 파일 무결성을 검증하며, 패치 적용 중 발생할 수 있는 오류를 처리해야 합니다.
  • 적합한 경우: 대부분의 PC 온라인 게임, 정기적인 업데이트가 필요한 게임.

Live Patching / Hotfix System

  • 방법: 게임이 실행 중인 상태에서 또는 재시작 시점에 매우 작은 데이터 변경 사항(설정값, 밸런스 수치, 텍스트 등)을 네트워크를 통해 다운로드하고 적용하는 방식입니다. 코드를 직접 수정하는 것은 대부분 불가능하며, 주로 데이터 테이블, JSON 파일, 또는 특정 코드 경로를 통해 동적으로 로드되는 에셋에 한정됩니다.
  • 장점: 플레이어가 게임을 완전히 다시 시작하지 않고도 수정 사항을 즉시 경험할 수 있어 사용자 경험에 매우 긍정적입니다. 긴급 버그 수정에 매우 효과적입니다.
  • 단점: 구현이 가장 복잡하며, 어떤 데이터를 핫픽스 가능한 형태로 만들지 설계 단계부터 고려해야 합니다. 보안 취약점(데이터 변조)에 노출될 수 있으므로 무결성 검증이 중요합니다.
  • 적합한 경우: 라이브 서비스 중인 온라인 게임, 긴급 밸런스 조정, 이벤트 활성화/비활성화.
  • 언리얼 엔진에서의 구현
    • Data Table / UDataAsset: 데이터 정의를 코드와 분리할 수 있습니다. 다운로드·컨테이너 마운트·기존 객체 교체·소비자의 재조회는 프로젝트에서 구현해야 하며, FDataTableRowHandle을 쓴다는 이유만으로 즉시 갱신되지는 않습니다.
    • Config Files (.ini): 파일 변경 후 해당 설정을 다시 읽고 적용하는 경로가 필요합니다. 모든 속성이 실행 중 재적용을 지원하는 것은 아닙니다.
    • Asset Management (Asset Manager): FStreamableManager를 사용하여 특정 에셋을 비동기적으로 로드하고 언로드하는 방식으로 핫픽스 데이터를 관리할 수 있습니다.
    • 커스텀 서버-클라이언트 통신: 게임 서버에서 최신 핫픽스 데이터를 클라이언트에게 푸시(Push)하거나, 클라이언트가 시작 시 서버에 업데이트 요청을 보내는 커스텀 로직을 구현해야 합니다.

핫픽스 안정성을 높이려면 C++ 측 데이터 로드/검증 코드를 함께 설계해야 합니다.

구체적인 구현 예시는 7장 3절의 Data Asset / Data Table 섹션을 참고하세요.

CDN (Content Delivery Network)

  • 방법: 패치 파일이나 전체 클라이언트 빌드를 CDN에 호스팅하여 전 세계 플레이어에게 빠르고 안정적인 다운로드 서비스를 제공합니다.
  • 장점: 높은 대역폭, 낮은 지연 시간, 높은 가용성을 제공하여 플레이어의 다운로드 경험을 향상시킵니다.
  • 단점: CDN 서비스 비용이 발생합니다.
  • 적합한 경우: 모든 규모의 온라인 게임.

업데이트 과정의 고려 사항

  • 하위 호환성 (Backward Compatibility): 새로운 업데이트가 이전 버전의 세이브 파일이나 게임 데이터와 호환되는지 확인해야 합니다. 호환되지 않는다면 데이터 마이그레이션 또는 초기화 로직이 필요합니다.
  • 버전 관리: 클라이언트와 서버의 버전 충돌을 방지하기 위해 엄격한 버전 관리 시스템을 유지해야 합니다. 서버는 구 버전 클라이언트의 접속을 거부하거나 강제 업데이트를 유도할 수 있습니다.
  • 패치 노트(Patch Notes): 업데이트 내용을 상세하게 설명하는 패치 노트를 제공하여 플레이어가 변경 사항을 이해하도록 돕습니다.
  • 롤백(Rollback) 계획: 업데이트 배포 후 심각한 문제가 발생할 경우를 대비하여 이전 버전으로 롤백할 수 있는 비상 계획을 마련해야 합니다.
  • A/B 테스트 및 단계별 배포: 새로운 기능이나 큰 변경 사항은 모든 플레이어에게 동시에 배포하기보다, 일부 사용자에게 먼저 A/B 테스트를 진행하거나, 점진적으로 배포하여 위험을 최소화할 수 있습니다.
  • 다운로드 중 플레이: 일부 게임은 다운로드 중에도 게임 플레이를 허용하여 플레이어가 기다리는 시간을 줄입니다. (예: 필수 콘텐츠만 먼저 다운로드 후 플레이 가능)

지속적인 통합 및 배포 (CI/CD) 와의 연계

자동화된 CI/CD 파이프라인은 핫픽스 및 업데이트 전략의 효율성을 크게 높일 수 있습니다.

  • 코드 변경 -> 자동 빌드 -> 자동 테스트 -> 패치 파일 생성 -> CDN 업로드 -> 런처 업데이트 알림 -> 플레이어 다운로드.
  • 이러한 자동화는 업데이트 주기를 단축하고, 수동 오류를 줄이며, 개발팀의 부담을 경감시킵니다.
패치 산출물과 게임에 반영되는 시점

파일 교체와 이미 실행 중인 상태 변경은 같은 작업이 아닙니다.

패치 산출물과 게임에 반영되는 시점
변경 대상필요한 적용 경로자동으로 되지 않는 것
실행 코드플랫폼에 맞는 새 바이너리 배포·재시작 정책Pak 마운트만으로 실행 코드나 UCLASS 구조가 교체되지 않습니다.
쿠킹 콘텐츠기준 릴리스·컨테이너·레지스트리·로드 정책을 함께 맞춥니다.마운트한 파일이 기존 UObject와 참조를 즉시 교체하지 않습니다.
설정·밸런스 값검증 후 다시 읽고 소비자에게 적용하는 경로ini·JSON·DataTable을 바꾼 것만으로 모든 시스템이 재조회하지 않습니다.
저장 데이터·프로토콜읽을 수 있는 버전과 접속 허용 정책을 정합니다.실행 파일만 이전 버전으로 돌려도 이미 변경된 영속 데이터가 되돌아가지는 않습니다.
실행 코드
필요한 적용 경로: 플랫폼에 맞는 새 바이너리 배포·재시작 정책
자동으로 되지 않는 것: Pak 마운트만으로 실행 코드나 UCLASS 구조가 교체되지 않습니다.
쿠킹 콘텐츠
필요한 적용 경로: 기준 릴리스·컨테이너·레지스트리·로드 정책을 함께 맞춥니다.
자동으로 되지 않는 것: 마운트한 파일이 기존 UObject와 참조를 즉시 교체하지 않습니다.
설정·밸런스 값
필요한 적용 경로: 검증 후 다시 읽고 소비자에게 적용하는 경로
자동으로 되지 않는 것: ini·JSON·DataTable을 바꾼 것만으로 모든 시스템이 재조회하지 않습니다.
저장 데이터·프로토콜
필요한 적용 경로: 읽을 수 있는 버전과 접속 허용 정책을 정합니다.
자동으로 되지 않는 것: 실행 파일만 이전 버전으로 돌려도 이미 변경된 영속 데이터가 되돌아가지는 않습니다.

긴급한 핫픽스라는 이름이 적용 방식을 결정하지 않습니다. 변경 대상과 현재 로드 상태를 기준으로 정합니다.

새 설치와 기존 설치의 업데이트, 다운로드 중단 후 재시도, 이전 세이브와 서버 버전 조합을 확인합니다. 이 절은 배포 설계와 명령 형태를 설명하며 패치 생성·설치 성공을 실행 확인한 결과는 아닙니다.