.nbt 구조물 파일은 블록 이름이 아니라 팔레트 인덱스를 저장한다 — 그래서 파일이 이렇게 작다
세 개의 키가 건축물 전체를 담는다: size, palette, blocks. 각 블록은 팔레트를 가리키는 정수 하나이므로, 32³ 크기의 돌 부피는 문자열 하나와 32,768개의 작은 항목 — 각각 위치와 인덱스 — 만으로 표현된다. 이름은 결코 들어가지 않는다.
.nbt 구조물 파일 — 구조물 블록이 저장하고 데이터팩이 배포하는 그것 — 은 겉에서 보이는 것보다 훨씬 단순한 형식이다. 건축물에 필요한 모든 것은 최상위 키 몇 개에 담겨 있고, 파일이 이렇게 작은 이유는 설계상의 결정 하나로 설명된다.
건축물을 담는 세 개의 키
size [x, y, z] — a list of exactly three integers
palette [ { Name, Properties } … ] — every DISTINCT block state, once
blocks [ { pos, state, nbt } … ] — one entry per placed block
palette는 각기 다른 블록 상태를 정확히 한 번씩만 담는다. 각 항목은 Name — minecraft:oak_stairs 같은 블록 id — 에 블록 상태를 담는 선택적 Properties 컴파운드가 붙은 형태로, 예를 들어 facing: north 와 half: bottom 같은 것이다.
blocks는 이름을 절대 반복하지 않는다. 각 항목은 정수 세 개로 이루어진 pos 와 state 를 담고 있으며, state 는 블록 id가 아니라 팔레트를 가리키는 인덱스다. 북쪽을 향한 참나무 계단은 문자열 데이터로 한 번만 등장하고, 그 뒤에 나오는 모든 참나무 계단은 작은 정수 하나일 뿐이다.
이것이 전부다. 32 × 32 × 32 크기의 평범한 돌 부피는 팔레트 항목 하나와 위치 + 인덱스로 이루어진 32,768개의 블록 항목 — minecraft:stone 라는 단어의 복사본 32,768개가 아니다. 팔레트는 얼마나 다양한 것들로 지었는지에 따라 커지고, 블록 목록은 얼마나 크게 지었는지에 따라 커진다. 이 둘은 매우 다른 숫자이며, 보통 그중 하나만 큰 값을 가진다.
설계할 때 염두에 둘 두 가지 결과
블록 상태는 블록 목록이 아니라 팔레트를 늘린다. 참나무 계단은 팔레트 항목 하나가 아니다 — 실제로 사용한 방향마다 하나씩이다. 네 방향, 위쪽과 아래쪽 절반, 직선과 안쪽·바깥쪽 모서리: 같은 블록이 팔레트 슬롯 십여 개를 차지할 수 있다. 그래서 디테일이 많은 건축물은 크기와 무관하게 팔레트가 크고, 단순한 건축물은 그렇지 않다.
저장된 위치만 항목을 가진다. 블록 목록은 조밀한 3D 배열이 아니라 리스트이며, 없는 항목은 그냥 없는 것이다 — 이 페이지의 뷰어는 격자를 -1 로 채우고 좌표가 비어 있으면 아무것도 놓이지 않은 것으로 취급한다. 하지만 구조물 블록은 다른 블록과 마찬가지로 공기도 저장한다. 구조물 공허 공간만 제외된다. 속이 빈 건축물을 저장할 때 더 저렴하게 만들려면 저장 전에 내부를 구조물 공허 공간으로 채워야 한다.
nbt 는 블록별이며 선택 사항이다
blocks 의 각 항목은 자체적인 nbt 컴파운드를 가질 수 있으며, 대부분은 가지지 않는다. 상자의 내용물, 표지판의 글자, 생성기의 몹, 현수막의 무늬가 바로 여기에 들어간다 — 팔레트가 아니라 개별 블록에 붙는다.
이 구분은 중요하다: 팔레트 데이터는 공유되고 블록 데이터는 그렇지 않다. 상자 두 개는 팔레트 항목 하나인데, 같은 블록 상태이기 때문이다 — 하지만 각자는 자신의 nbt 에 자신의 인벤토리를 따로 보관한다. 블록 상태를 바꾸면 팔레트를 건드리는 것이고, 그 안의 내용물을 바꾸면 블록 목록의 항목 하나를 건드리는 것이다.
한 번에 한 층씩 읽기
여기 있는 뷰어는 의도적으로 2D다. y 층을 그리려면 블록 목록을 순회하면서 pos[1] 가 y 인 항목만 남기고, 각 항목의 state 를 팔레트에서 찾는다. 이것이 알고리즘의 전부이며, 여러분이 직접 이런 파일을 들여다볼 때도 같은 방식이라는 점에서 알아둘 가치가 있다: 만들 공간 인덱스도 없고, gzip 래퍼 외에 풀어야 할 압축도 없다. 이 형식은 걸러내는 평평한 목록이다.
이는 또한 구조물 파일이 그 자체로는 월드 어디에 속하는지에 대해 아무것도 알려주지 않는다는 뜻이기도 하다. size 는 경계 상자이고 pos 값은 그 모서리를 기준으로 한 상대 좌표다. 배치는 구조물 블록이 할 일이지, 파일이 할 일이 아니다.