LYSC STUDIO

LIST
Cover

월드 파티션(World Partition)과 데이터 레이어(Data Layers)를 이용한 심리스 오픈월드 아키텍처 설계

·UE5 Engine

기존의 레벨 스트리밍 방식을 완벽히 대체하는 월드 파티션(World Partition). 방대한 오픈월드를 하나의 레벨로 관리하면서도 협업과 스트리밍을 최적화하는 아키텍처 설계 기법을 다룹니다.

기존 레벨 스트리밍(Level Streaming) 시스템의 한계점

언리얼 엔진 4 시절까지 오픈월드 게임을 만들기 위해서는 맵을 바둑판 모양의 여러 '서브 레벨(Sub-levels)'로 수동 분할해야 했습니다. 레벨 디자이너들은 퍼포먼스를 위해 'Level Streaming Volumes'를 곳곳에 배치하여 플레이어의 이동에 따라 레벨이 로드/언로드 되도록 노가다성 작업을 진행했습니다.

이 방식의 가장 큰 문제는 협업의 병목 현상이었습니다. 맵의 중앙 구역이 담긴 레벨 파일을 한 작업자가 수정하기 위해 체크아웃(Checkout)하면, 다른 모든 팀원들은 해당 지역에 건물 하나 배치할 수 없었습니다. 또한 맵의 크기가 커질수록 서브 레벨 관리 자체가 거대한 기술적 부채가 되었습니다.

월드 파티션(World Partition)의 등장: 원 레벨 룰 뎀 올(One Level to Rule Them All)

언리얼 엔진 5의 월드 파티션은 이 모든 문제를 근본적으로 해결했습니다. 이제 개발자는 맵을 여러 개로 나눌 필요 없이, 엄청나게 거대한 단 하나의 레벨(Single Persistant Level)에서 작업합니다.

월드 파티션 시스템은 엔진 내부적으로 2D 또는 3D 그리드(Grid) 시스템을 생성하여 월드를 자동으로 수많은 그리드 셀로 분할합니다. 에디터 상에서는 모든 액터가 보이거나 미니맵 인터페이스를 통해 필요한 구역만 로드할 수 있지만, 실제 런타임 게임 플레이 시에는 플레이어(Streaming Source)를 중심으로 반경 내에 있는 셀들만 백그라운드에서 동적으로 스트리밍합니다.

OFPA (One File Per Actor) 아키텍처와 팀 협업의 혁신

월드 파티션이 가져온 협업의 혁명은 OFPA (One File Per Actor) 시스템 덕분입니다. 기존에는 레벨 파일(.umap) 안에 모든 액터 데이터가 저장되었지만, OFPA가 활성화되면 맵에 배치된 모든 액터가 각자의 개별 파일로 분리되어 저장됩니다.

이로 인해 환경 아티스트 A가 산을 조형하고 있을 때, 퀘스트 디자이너 B는 그 산 위에 몬스터 스폰 포인트를 배치하고, 사운드 디자이너 C는 배경음 액터를 배치할 수 있습니다. 깃(Git)이나 퍼포스(Perforce) 같은 버전 관리 시스템에서 충돌이 전혀 발생하지 않게 된 것입니다.

계층형 LOD (HLOD, Hierarchical Level of Detail) 자동화

오픈월드 최적화의 핵심은 저 멀리 있는 산맥과 건물을 얼마나 렌더링 비용이 적은 메쉬로 대체하느냐에 있습니다. 월드 파티션은 나나이트와 결합하여 혁신적인 HLOD 생성 파이프라인을 제공합니다.

Commandlet이나 에디터 내 빌드 툴을 실행하면, 엔진이 수만 개의 액터를 병합하고 텍스처를 아틀라스(Atlas)로 구워내어 거대한 프록시 메시를 생성합니다. 플레이어가 특정 그리드 셀에서 멀어지면, 수천 개의 원본 액터들이 메모리에서 언로드되고 단 하나의 HLOD 프록시 액터로 교체됩니다. 이는 나나이트와 완벽히 호환되어 극도의 퍼포먼스를 보장합니다.

데이터 레이어(Data Layers): 논리적 공간의 분할

그리드가 '물리적 공간'의 스트리밍이라면, 데이터 레이어(Data Layers)는 '논리적 조건'에 따른 스트리밍을 담당합니다. 과거의 서브 레벨이 하던 역할을 대체합니다.

예를 들어, 같은 장소라도 퀘스트 수락 전에는 평화로운 마을이지만, 퀘스트 수락 후에는 폐허로 변하고 불타는 이펙트와 몬스터가 스폰되어야 한다고 가정해 봅시다. 이때 '평화로운 마을 레이어'와 '불타는 폐허 레이어'를 만들어두고 블루프린트나 C++에서 런타임에 동적으로 레이어의 상태(Activated, Loaded, Unloaded)를 전환할 수 있습니다. 메모리를 효율적으로 관리하면서 시나리오 연출을 극대화할 수 있는 강력한 기능입니다.

Implementation C++ / UE5
// C++을 이용한 월드 파티션 데이터 레이어 런타임 전환 예시
#include "WorldPartition/DataLayer/DataLayerSubsystem.h"

void AMyGameMode::ChangeVillageStateToRuined()
{
    UDataLayerSubsystem* DataLayerSubsystem = GetWorld()->GetSubsystem();
    if (DataLayerSubsystem)
    {
        // 평화로운 레이어 비활성화
        DataLayerSubsystem->SetDataLayerInstanceRuntimeState(
            PeacefulLayerInstance, EDataLayerRuntimeState::Unloaded);
            
        // 폐허 레이어 활성화
        DataLayerSubsystem->SetDataLayerInstanceRuntimeState(
            RuinedLayerInstance, EDataLayerRuntimeState::Activated);
    }
}
월드 파티션과 OFPA의 결합은 오픈월드 제작의 병목 현상을 해소하고, 대규모 팀의 협업 효율을 극대화합니다. 더 거대하고 밀도 높은 세계를 구축하는 첫걸음을 내딛어 보세요.