MC Toolkit

Руководства / Команды и данные

Файл структуры .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: id блока, например minecraft:oak_stairs, плюс необязательный составной тег Properties с его blockstate, вроде facing: north и half: bottom.

blocks никогда не повторяет имя. Каждая запись несёт pos из трёх целых чисел и state, причём state — это индекс в палитре, а не id блока. Дубовые ступеньки, повёрнутые на север, — это строковые данные один раз, а все последующие — просто небольшое целое число.

Вот и весь фокус. Объём 32 × 32 × 32 из обычного камня — это одна запись палитры и 32 768 записей блоков из позиции и индекса, а не 32 768 копий слова minecraft:stone. Палитра растёт вместе с тем, сколько разных вещей вы построили, а список блоков растёт вместе с тем, насколько большую постройку вы сделали. Это очень разные числа, и обычно большое только одно из них.

Два следствия, которые стоит учесть при проектировании

Blockstates умножают вашу палитру, а не список блоков. Дубовые ступеньки — это не одна запись палитры, а по одной на каждую реально использованную ориентацию. Четыре направления, верхняя и нижняя половина, прямая и оба угла — внутренний и внешний: один и тот же блок может занять дюжину слотов палитры. Поэтому постройка, богатая деталями, имеет большую палитру, а простая — нет, независимо от размера.

Запись получают только сохранённые позиции. Список блоков — это список, а не плотный трёхмерный массив, и записи, которой нет, просто нет — просмотрщик на этой странице заполняет свою сетку -1 и считает отсутствующую координату ничем не размещённым. Но блок-конструктор сохраняет воздух как любой другой блок; опускается только пустой блок. Пустая внутри постройка дешевле в хранении только если вы заполните её внутренность пустыми блоками перед сохранением.

nbt задаётся для каждого блока и необязателен

Каждая запись в blocks может нести свой собственный составной тег nbt, и у большинства его нет. Именно здесь живут содержимое сундука, текст таблички, моб спавнера и узоры флага — привязанные к отдельному блоку, а не к палитре.

Различие важно: данные палитры общие, а данные блока — нет. Два сундука — это одна запись палитры, потому что у них одинаковое состояние блока, но каждый хранит свой инвентарь в своём nbt. Измените состояние блока — и вы трогаете палитру; измените то, что внутри, — и вы трогаете одну запись в списке блоков.

Чтение по одному слою за раз

Просмотрщик здесь намеренно двумерный. Чтобы нарисовать слой y, он перебирает список блоков, оставляет записи, у которых pos[1] равен y, и ищет state каждой из них в палитре. Это весь алгоритм, и его стоит знать, потому что именно так вы сами исследовали бы один из этих файлов: здесь нет пространственного индекса, который нужно строить, и нет распаковки сверх обёртки gzip. Формат — это плоский список, который вы фильтруете.

А значит, файл структуры ничего не говорит о том, где она должна находиться в мире. size — это ограничивающая рамка, а значения pos отсчитываются от её угла. Размещение — забота блок-конструктора, а не файла.

Инструменты структур и компонентов NBT →

Другие руководства

Смотреть все →