Doom의 새로운 보금자리는 데이터베이스
Doom이 새로운 보금자리인 데이터베이스를 찾았습니다. CedarDB의 Lukas Vogel이 진행한 프로젝트인 SQLDoom은 단순히 게임의 최고 점수를 데이터베이스에 저장하거나 시각적으로 흉내 낸 것이 아닙니다. 이는 1993년 원작 Doom을 완전히 재구현한 것으로, 핵심 게임 로직과 그래픽 렌더링이 전적으로 SQL 내에서 실행됩니다.
이 아키텍처는 우아하게 분리되어 있습니다. 게임 로직과 렌더링 엔진은 SQL 쿼리로 실행되며, Python은 가벼운 브리지 역할을 합니다. Python의 역할은 키보드 입력을 캡처하고, 게임 루프의 타이밍을 관리하며, 결과로 생성된 프레임 버퍼를 표시하는 것으로 제한됩니다. 여러분이 보는 모든 프레임은 하나의 거대한 SQL 쿼리의 결과물입니다.
이 작업의 규모는 인상적입니다. 320x200 해상도, 총 64,000개의 픽셀은 렌더러에 의해 계산되는데, 이 렌더러는 약 89개의 CTE(Common Table Expressions)에 걸쳐 약 1,300줄의 SQL로 구성되어 있습니다. 게임 로직은 여기에 5,900줄의 SQL을 추가합니다. 이 전체 SQL 코드베이스는 원작 Doom의 약 9,000줄에 달하는 C 게임 로직보다 눈에 띄게 짧습니다.
하나의 쿼리로 64,000개의 픽셀을 그리다
SQLDoom에서 렌더링되는 모든 프레임은 단 하나의 복잡한 데이터베이스 쿼리에서 비롯됩니다. 이 쿼리는 화면의 64,000개 픽셀(320 × 200 해상도) 각각에 대한 색상을 계산하고, 각 픽셀을 하나의 행으로 표현하여 원시 비트맵 데이터로 이미지를 반환합니다. 렌더링 쿼리만 해도 약 89개의 CTE(Common Table Expressions)를 활용하여 약 1,300줄의 SQL에 달합니다.
관계형 연산은 기존의 절차적 코드와 근본적으로 다릅니다. SQLDoom은 게임 객체를 반복하는 명시적 루프 대신 집합 기반 연산(set-based operations)을 활용하여 엔티티를 집단적으로 처리합니다. 예를 들어, 단일 UPDATE 문으로 모든 몬스터의 상태를 동시에 수정할 수 있는데, 이는 원작 C 구현의 수많은 for 또는 while 루프와 극명하게 대비됩니다.
데이터베이스 기반 게임치고는 성능 지표가 인상적입니다. 핵심 게임 로직은 Doom의 원작 초당 35틱(35 tics per second)을 준수하여 원작의 게임 플레이 페이스를 그대로 유지합니다. 하지만 렌더러는 게임 틱 사이의 카메라 위치를 보간함으로써 최신 하드웨어에서 초당 최대 60프레임(FPS)을 달성할 수 있으며, 이는 1993년 원작보다 더 부드러운 시각적 경험을 제공합니다. CedarDB의 Lukas Vogel은 게임 엔진으로서 SQL의 놀라운 잠재력을 효과적으로 입증했습니다.
데이터베이스가 무거운 작업을 처리하다
데이터베이스에서 Doom을 렌더링하는 것은 흥미로운 절충안을 제시합니다. John Carmack이 설계한 1993년 원작 엔진은 BSP(Binary Space Partitioning) 트리를 사용하여 가시성을 결정함으로써 CPU 사이클을 효율적으로 보존했습니다. 반면 SQLDoom은 프레임당 64,000개의 픽셀에 대해 깊이와 가림 계산을 무차별 대입(brute-force) 방식으로 수행합니다. 이로 인해 가시성 계산이 SQL 렌더링 파이프라인에서 가장 느린 부분이 됩니다.
이러한 무차별 대입 방식은 CedarDB의 아키텍처 덕분에 가능합니다. CedarDB의 쿼리 엔진은 SQL 쿼리를 LLVM IR로 직접 컴파일한 후 네이티브 머신 코드로 변환하여, 복잡한 분석 워크로드를 노트북에서도 초당 최대 60프레임의 인상적인 속도로 실행할 수 있게 합니다. 이 컴파일 과정은 프로젝트 블로그 게시물(We Ported the Original Doom to SQL - CedarDB)에 설명된 대로 단일 렌더링 쿼리에 포함된 1,300줄의 SQL을 처리하는 데 필수적입니다.
게임 세계 자체가 구조화된 데이터로 변환됩니다. 맵 지오메트리부터 텍스처까지 모든 것을 정의하는 Doom의 상징적인 WAD 에셋들은 관계형 테이블로서 새로운 보금자리를 찾습니다. 여기에는 다음이 포함됩니다:
- Maps
- Sectors
- Linedefs
- Textures
샷건과 같은 개별 아이템조차 테이블의 행이 되어, 간단한 UPDATE 문으로 샷건이 500개의 탄환을 발사하도록 변경하는 등 게임 메커니즘을 직접 SQL로 조작할 수 있습니다. 이를 통해 전체 게임 세계를 표준 데이터베이스 작업으로 쿼리하고 수정할 수 있습니다.
이 글이 마음에 드셨나요? 매일 아침 이런 글을 메일로 받아보세요.
하루 한 통 · 두 번의 클릭으로 구독 취소 · 제3자 추적 없음
게임 메커니즘이 편집 가능한 행이 될 때
독특한 설계는 놀라운 성과를 가져옵니다. 무기와 플레이어 능력치가 테이블 데이터로 존재하기 때문에, 단 한 번의 SQL 업데이트로 샷건의 탄환 수나 플레이어의 기본 체력을 변경할 수 있습니다. 이는 데이터베이스의 동적 기능을 보여주지만, 실제 게임 중에는 이러한 직접적인 조작이 제한됩니다.
멀티플레이어 기능은 데이터베이스 트랜잭션에서 자연스럽게 구현됩니다. 각 게임 틱은 독립적인 트랜잭션으로 처리되어, 모든 플레이어가 일관되고 동기화된 게임 세계를 조회할 수 있도록 보장합니다. 제한된 함수는 클라이언트가 자신의 체력과 같이 보호된 값을 직접 변경하지 못하도록 하여 게임의 무결성을 유지합니다.
SQLDoom은 단순한 참신함을 넘어, 컴퓨팅 플랫폼으로서 데이터베이스 쿼리 엔진을 엄격하게 테스트하는 시험대 역할을 합니다. 이 프로젝트는 Lukas Vogel의 초기 ASCII 레이캐스팅 프로토타입인 DOOMQL을 기반으로 하며, 관계형 데이터베이스가 달성할 수 있는 한계를 넓히고 있습니다. SQLDoom은 다른 복잡한 게임 메커니즘을 순수 데이터와 쿼리로 표현하고 실행하는 방법에 대해 다시 생각해보게 합니다.
자주 묻는 질문
SQLDoom이란 무엇인가요?
SQLDoom은 CedarDB의 Lukas Vogel이 Doom의 게임 로직과 그래픽 렌더링을 SQL로 재구현한 프로젝트입니다.
SQLDoom은 완전히 SQL에서 실행되나요?
게임 로직과 렌더러는 SQL에서 실행됩니다. Python은 키보드 입력, 타이밍, 그리고 렌더링된 프레임 표시를 처리합니다.
SQLDoom은 프레임당 몇 개의 픽셀을 렌더링하나요?
Doom의 320x200 해상도와 동일한 프레임당 64,000개의 픽셀을 계산합니다.
SQLDoom은 멀티플레이어를 어떻게 처리하나요?
게임 틱은 데이터베이스 트랜잭션으로 실행되어, 플레이어들에게 공유된 게임 상태의 동기화된 뷰를 제공합니다.

