콘텐츠로 바로가기

Game Engine Architecture

수만 개의 물리 객체를 실시간으로 동기화하고 업데이트하는 거대 순환 루프 구조와, 성능 한계를 돌파하는 데이터 중심 아키텍처(ECS)를 다룹니다.

Article
M

Me

hyunyoun's Blog

human-computer-interaction-graphicshuman-computer-interactiongraphicsgame-engine-architecturehcigame-enginesphysics-simulationlearning9 min read

1. Overview

게임 엔진 아키텍처(Game Engine Architecture, GEA)는 수만 개의 3D 개체, 물리 연산, 사운드, 네트워크 패킷이 1초에 60번(16.6ms)이라는 가혹한 시간 제약 속에서 단 한 번의 프레임 드랍 없이 동기화되어 돌아가게 만드는 '실시간 거대 분산 시스템의 심장'입니다.

게임 엔진은 단순한 렌더러가 아닙니다. 학습자는 시간의 흐름을 통제하는 **게임 루프(Game Loop)**의 타이밍 역학과, 거대한 월드에서 그려야 할 것만 골라내는 씬 그래프(Scene Graph) 공간 분할 알고리즘을 배웁니다. 특히, 전통적인 객체 지향 프로그래밍(OOP)의 상속이 가져오는 메모리 낭비를 부수고 CPU 캐시 히트율을 극대화하는 **데이터 중심 설계(ECS: Entity Component System)**의 물리적 혁신을 다루며, 극한의 하드웨어 성능을 쥐어짜는 소프트웨어 아키텍트의 시야를 확보합니다.

2. Scope & Boundaries

In-Scope

  • 엔진 코어 시스템 (Engine Core): 서브시스템 초기화 순서, 커스텀 메모리 할당자(Memory Allocators), 싱글톤과 전역 상태.
  • 게임 루프와 타이밍 (Game Loop): 프레임 레이트(FPS), 가변 델타 타임(Variable dt) vs 고정 델타 타임(Fixed dt), 렌더 루프 동기화.
  • 공간 분할과 씬 그래프 (Spatial Data): 바운딩 볼륨 트리(BVH), 쿼드트리(Quadtree)/옥트리(Octree), 절두체 컬링(Frustum Culling).
  • 아키텍처 패턴 (Architecture Patterns): 개체 컴포넌트 시스템(ECS), 옵저버 패턴(Event System), 상태 기계(FSM/Behavior Trees).

Out-of-Scope

  • 상용 엔진(Unreal/Unity)의 UI 에디터 사용법: 마우스로 버튼을 클릭하여 게임을 조립하는 개발자 편의 툴 학습.
  • 서버 클라이언트 간 패킷 암호화: 멀티플레이어 게임의 깊은 네트워크 보안 \rightarrow 08-01. Network Protocols 영역으로 위임.

Boundaries

  • GEA vs. RRG (12-05): RRG(12-05)가 "그래픽 카드를 쥐어짜서 그림을 예쁘게 그리는 법"이라면, GEA는 "언제 그림을 그리고, 언제 총알의 물리 충돌을 계산하고, 언제 소리를 재생할지 순서를 통제하는 오케스트라 지휘자"의 역할입니다.

3. Counterexample

  • 가변 델타 타임의 물리적 재앙 (Variable dt Fallacy): 게임 루프 안에서 물체의 이동 거리를 속도 * 이번 프레임에 걸린 시간(dt)으로 계산하고, 총알의 물리 충돌 판정(Collision)까지 여기에 맞춰버리는 실수. 컴퓨터에 렉이 걸려 프레임이 길어지면(예: dt = 0.5초), 총알이 벽을 한 번에 통과해 버리는 터널링(Tunneling) 버그가 터집니다. 렌더링은 가변 시간으로 부드럽게 그리더라도, 물리 연산은 무조건 **고정 델타 타임(Fixed Step)**으로 쪼개서 일정한 간격으로 실행해야 월드가 붕괴되지 않습니다.
  • 상속 기반 객체 지향의 함정 (OOP Monster Fallacy): GameObject 상속받아 Monster 만들고 그 아래에 FlyingMonster를 만드는 전통적인 OOP 방식. 몬스터 1만 마리가 필드에 깔리면, CPU는 메모리 여기저기 흩어진 객체의 가상 함수(Virtual Function) 포인터를 찾으러 다니느라 캐시 미스(Cache Miss) 폭탄을 맞고 게임이 뻗습니다. 수만 개의 객체 처리는 상속이 아니라, 데이터를 배열로 모아놓고 일괄 처리하는 ECS 아키텍처로 전환해야 메모리 대역폭의 한계를 돌파할 수 있습니다.

4. Prerequisites

  • 시스템 아키텍처와 메모리 (Basic): 포인터, 가상 메모리, CPU L1/L2 캐시의 라인 크기를 알아야 왜 ECS가 빠른지 이해할 수 있습니다. (03. CSA)
  • 자료 구조와 알고리즘 (Recommended): 트리(Tree) 구조를 모르면 공간 분할(Quadtree/Octree) 알고리즘을 짤 수 없습니다. (04. CDS)

5. Learning Map

Sequence Core Cluster Objective & Description Evidence (BoK)
1 Engine Core & Memory 게임이 켜질 때 물리, 사운드, 렌더 모듈을 순서대로 부팅하고, 자체 메모리 풀을 짜서 가비지 컬렉터의 간섭을 막습니다. Industry Dog
2 Game Loop Physics "입력 \rightarrow 물리 업데이트 \rightarrow 렌더링"을 초당 60번 무한 반복하는 거대 심장 박동(Loop)을 조율합니다. P1
3 Spatial Partitioning 1만 명의 적 중 누가 내 시야에 있는지 일일이 비교하면 폭발하므로, 공간을 큐브 형태로 분할해 탐색 속도를 높입니다. P4
4 ECS Architecture 모든 객체의 피통(HP)만 따로 배열에 모으고, 위치 좌표만 따로 모아 CPU 캐시 히트율을 극한으로 끌어올리는 혁신을 배웁니다. Industry

6. Learning Topics

Basic

Core Topic 01: 엔진 코어와 서브시스템 부팅 (Engine Core)

  • Why to Learn: 게임 엔진은 수십 개의 독립적인 라이브러리 뭉치이므로, 이들이 꼬이지 않고 메모리를 효율적으로 나눠 쓰며 부팅되게 통제하기 위해서입니다.
  • What to Learn:
    • Concepts: 서브시스템 아키텍처, 싱글톤(Singleton) 패턴의 한계.
    • Skills: 시작(Startup) 및 종료(Shutdown) 순서 관리, 커스텀 메모리 할당자(Custom Allocators: Pool, Stack).
    • Tools: C++ (엔진 코어 언어).
    • Trade-offs: OS가 주는 malloc이나 new를 그대로 쓰는 편리함 vs 파편화된 메모리 쓰레기를 치우기 위해 가비지 컬렉터가 돌 때마다 게임 화면이 0.1초씩 멈추는(Spike) 프레임 드랍의 참사.
  • How to Learn:
    • 1단계: 렌더링 엔진을 켜기 전에 무조건 메모리 매니저를 켜야 하고, 로깅 시스템은 제일 먼저 켜져야 하는 서브시스템 간의 철저한 의존성(Dependency) 트리를 그려봅니다.
    • 2단계: 총알 1,000발을 매번 new로 생성/삭제하지 않고, 미리 1,000칸짜리 배열(Object Pool)을 만들어 둔 뒤 활성화(Active) 플래그만 껐다 켰다 하는 물리적 재활용 기법을 스케치합니다.
  • Implement: 5개의 가상 서브시스템(Memory, File, Physics, Audio, Render)의 부팅 순서와 종료 순서(역순)를 제어하고, 에러 시 즉각 롤백하는 Manager 시스템의 C++ 뼈대 코드 작성.

Core Topic 02: 게임 루프와 시간 동기화 (The Game Loop)

  • Why to Learn: 세상에서 가장 바쁜 while (true) 루프 안에서 입력, 업데이트, 렌더링이 서로 발목을 잡지 않고 16.6ms(60fps) 안에 끝나도록 조율하기 위함입니다.
  • What to Learn:
    • Concepts: 프레임 레이트(Frame Rate), 델타 타임(dtdt).
    • Skills: 가변/고정 델타 타임(Variable/Fixed Time Step), 보간(Interpolation) 렌더링.
    • Tools: CPU 고정밀 타이머(High-Resolution Timer).
    • Trade-offs: 모니터 주사율에 맞춰 물리 엔진 업데이트 속도까지 묶어버리는 과거의 단순한 V-Sync 방식 vs 그래픽 프레임이 30에서 144를 널뛰어도 물리 엔진은 정확히 1초에 50번만 돌게 만드는 분리형 타이머 설계의 복잡도.
  • How to Learn:
    • 1단계: 자동차가 앞으로 가는 코드를 position.x += 10;이라고 짜면 컴퓨터가 빠른 집에선 자동차가 로켓이 되는 버그를 인지하고, position.x += speed * dt;로 치환하여 시간(Time) 차원을 주입하는 원리를 깨닫습니다.
    • 2단계: 물리 업데이트 주기가 렌더링보다 느릴 때, 두 물리 상태(과거와 현재) 사이를 렌더링 시점에 블렌딩(보간)하여 눈에 보일 때는 부드럽게 넘어가도록 속이는 수리적 보간법을 뜯어봅니다.
  • Implement: while(!quit) 루프 구조 내에 UpdatePhysics(fixed_dt)Render(variable_dt)를 분리하여 동작시키는 'Free the Physics' 게임 루프 알고리즘 프로토타입 작성.

Practical

Core Topic 03: 씬 그래프와 공간 분할 거버넌스 (Spatial Partitioning)

  • Why to Learn: 100만 평짜리 맵에 나무가 10만 그루 있을 때, 카메라에 보이지 않는 등 뒤의 나무들을 화면에 그리지 말라고 1초 만에 걸러내기 위해서입니다.
  • What to Learn:
    • Concepts: 씬 그래프(Scene Graph), 절두체 컬링(Frustum Culling).
    • Skills: 쿼드트리(Quadtree), 옥트리(Octree), 바운딩 박스(AABB).
    • Tools: 공간 분할 디버깅 뷰.
    • Trade-offs: 월드의 모든 물체를 평면 배열에 넣고 매 프레임마다 카메라 안에 있는지 O(N)O(N)으로 무식하게 검사하는 것 vs 월드를 8등분 트리(Octree)로 나누어 O(logN)O(\log N)으로 탐색 속도를 올리는 대신 물체가 움직일 때마다 트리를 갱신해야 하는 관리 비용.
  • How to Learn:
    • 1단계: 사람의 팔을 움직이면 손목과 손가락이 자동으로 따라오는 구조를 만들기 위해, 부모 노드의 이동/회전 변환 행렬(Matrix)이 자식 노드에 곱해지는 계층적 씬 그래프(Hierarchy) 물리를 분해합니다.
    • 2단계: 카메라가 바라보는 시야 모양의 피라미드(Frustum) 바깥에 위치한 옥트리(Octree) 노드를 통째로 잘라내어(Culling), 렌더러에 넘기는 물체 수를 10,000개에서 200개로 압축하는 공간 제압술을 시뮬레이션합니다.
  • Implement: 2D 공간에 1,000개의 점(물체)을 무작위로 뿌리고, 쿼드트리(Quadtree) 자료구조를 짜서 특정 사각형 영역 내에 존재하는 점들을 순회 검색 연산보다 10배 빠르게 찾아내는 검색 함수 구현.

Advanced

Core Topic 04: 데이터 중심 설계와 ECS 아키텍처 (ECS)

  • Why to Learn: 클래스(Class)와 상속(Inheritance)이라는 인간 중심의 프로그래밍을 버리고, CPU가 메모리를 일렬로 읽어 들이기 가장 좋아하는 '기계 중심'의 하이엔드 최적화를 하기 위해서입니다.
  • What to Learn:
    • Concepts: ECS (Entity - Component - System), 데이터 지향 설계(Data-Oriented Design).
    • Skills: 메모리 연속성(Contiguous Memory), 배열의 구조체(AoA/SoA: Structure of Arrays vs Array of Structures), 캐시 히트/미스(Cache Hit/Miss).
    • Tools: Unity DOTS, EnTT (C++ 라이브러리).
    • Trade-offs: Player.TakeDamage()처럼 함수 안에 모든 데이터를 캡슐화하는 아름다운 객체 지향 코드 vs 객체라는 개념을 찢어버리고 피통 배열, 공격력 배열을 따로 만들어 System 함수가 배열 전체를 쓸고 지나가게 만드는 극강의 메모리 친화적 추악함(성능 압살).
  • How to Learn:
    • 1단계: CPU는 데이터를 달라고 할 때 메모리에서 바이트 하나만 가져오지 않고 캐시 라인(64 Byte) 뭉치를 한꺼번에 퍼옵니다. 이때 안 쓰는 쓰레기 데이터까지 섞여 있으면 캐시가 버려지고 다시 퍼와야 하는 병목 현상을 하드웨어 레벨에서 해부합니다.
    • 2단계: '엔티티(ID 번호표)'에 '이동 컴포넌트(속도 데이터)'와 '렌더 컴포넌트(메시 데이터)'를 스티커처럼 붙이고, '이동 시스템(System)'이 이동 컴포넌트를 가진 녀석들만 배열에서 일렬로 주르륵 읽어내어 수학 계산만 때리고 끝내는 파이프라인을 짭니다.
  • Implement: 전통적인 OOP 클래스(상속)로 만든 10,000개의 개체 이동 코드와, ECS(데이터 배열 중심)로 만든 이동 코드의 실행 시간을 프로파일링하여 CPU 캐시 친화성이 렌더링 성능(FPS)에 미치는 영향을 증명하는 리포트.

7. Terminology

Term (EN / ko, abbr) 1문장 정의 단계(기본/권장/실무/심화) 역할/맥락 관련 개념 유사/대비/함께 사용 오해 포인트 Evidence(Primary/Secondary/Industry) Flags(core)
Entity-Component-System (ECS) 게임 객체(Entity)를 데이터(Component)와 로직(System)으로 철저히 분리하여 메모리 캐시 효율과 병렬 처리 성능을 극대화하는 아키텍처입니다. 실무 아키텍처 Data-Oriented Design vs. OOP (상속) 객체 지향 프로그래밍(OOP)이 게임에서도 무조건 최고라는 맹신 Industry DOTS core
Game Loop 사용자 입력을 받고, 물리 상태를 업데이트하며, 화면을 렌더링하는 과정을 초당 수십 회 무한 반복하는 엔진의 심장부입니다. 기본 실행 흐름 Delta Time vs. Event-driven 게임도 웹브라우저처럼 이벤트가 올 때만 갱신된다는 착각 Primary core
Collision Physics 두 객체의 경계 상자(AABB)나 콜라이더가 겹치는지를 충돌 검출(Detection)하고 튕겨나가는 반응(Response)을 수리적으로 계산하는 모듈입니다. 권장 물리 역학 Rigid Body, Raycast vs. Visual Rendering 화면에 닿아보이면 물리 엔진도 자동으로 충돌을 안다는 오해 Primary/Graphics core
Scene Graph 월드에 존재하는 모든 객체의 부모-자식 관계와 상대적 공간 변환(Transform) 행렬을 트리 구조로 관리하는 데이터 체계입니다. 실무 공간 관리 Transform Matrix vs. Flat Array 객체들이 화면 안에서 독립적으로만 존재한다는 착각 Industry, Unity core

8. References

Primary References

  • [CS2023: Systems Architecture] — 게임 엔진 코어 구조, 메모리 매니지먼트 및 리소스 로딩 파이프라인.
  • [SWEBOK v3: Software Construction] — 고성능 컴퓨팅에서의 데이터 지향 설계(Data-Oriented Design) 원칙.

Secondary References

  • [Game Engine Architecture (Jason Gregory)] — 메인 게임 루프, 물리 엔진 연동, 멀티스레딩 및 하드웨어 통제.
  • [GDC (Game Developers Conference) Vault] — 프로덕션 레벨의 충돌 처리, 메모리 할당 최적화 사례.

Industry References

  • [Unity DOTS Documentation] — 엔티티 컴포넌트 시스템(ECS)과 C# 잡 시스템(Job System) 기반 멀티코어 병렬화.
  • [Unreal Engine Source Code] — 가비지 컬렉션 억제, UObject 생명주기 및 물리 기반 블루프린트 연산.

9. Final Checklist

Primary Checklist

  • 엔진의 메인 루프(Game Loop)가 디스플레이 주사율에 종속되지 않고, 독립적인 시간 변수(Delta Time)를 기준으로 물리 상태를 업데이트하는가?
  • 객체 지향의 깊은 상속 구조(Deep Inheritance)로 인한 메모리 파편화를 피하고, ECS 기반의 데이터 지향 설계로 CPU 캐시 적중률을 높였는가?

Secondary Checklist

  • 복잡한 폴리곤 메시끼리의 충돌을 매 프레임 계산하는 대신, 단순화된 기본 도형(AABB, Sphere Collider)을 통해 1차 충돌 검출(Broad Phase)을 필터링하는가?
  • 씬(Scene)이 로딩될 때 수천 개의 객체를 동적으로 생성/삭제(Instantiate/Destroy)하지 않고, 오브젝트 풀(Object Pool) 패턴으로 메모리 틱을 방어했는가?

Industry Checklist

  • 거대한 월드를 다룰 때 메모리 오버플로우를 막기 위해, 시야각(Frustum) 밖이나 너무 먼 객체의 렌더링/물리 연산을 컬링(Culling) 또는 LOD 처리하는가?
  • 메인 스레드가 렌더링과 물리 연산을 모두 떠안아 프레임이 튀지 않도록, 잡 시스템(Job System)이나 멀티스레딩 아키텍처로 작업을 분산시켰는가?

HCI :: Game Engines & Physics Simulation

10 / 11