Поддерживает Minecraft Bedrock Edition и Java Edition и все серверные ядра для обеих редакций, популярные и малоизвестные: Vanilla, Paper, Spigot, Purpur, Folia, Fabric, Forge, NeoForge, Mohist, Sponge, Bedrock Dedicated Server, PocketMine-MP, Nukkit, PowerNukkitX, Cloudburst, Dragonfly, Endstone, LeviLamina и остальные. Полный список.
NBT (Named Binary Tag) — бинарный древовидный формат Minecraft. Тег состоит из однобайтового типа, имени с длиной и данных; вложенные compound-теги завершаются байтом TAG_End. В Java и Bedrock используются 13 типов тегов и пять вариантов кодирования. Ниже описаны все варианты с возможностью проверить их на реальном файле.
13 типов теговBig-endianLittle-endianVarintgzipzlibSNBT
Байт типа элементов, длина int, затем безымянные данные
[1,2]
10
TAG_Compound
Повторяющиеся тип + имя + данные до TAG_End
{a:1}
11
TAG_Int_Array
Длина int, затем 4-байтовые int
[I;1,2]
12
TAG_Long_Array
Длина int, затем 8-байтовые long
[L;1L,2L]
Файл содержит один корневой TAG_Compound: байт типа 0x0A, имя и содержимое compound-тега. Именованные теги встречаются только внутри compound; элементы списка содержат только данные, поэтому список однороден.
Пять вариантов кодирования
Кодирование
Целые числа
Длина строки
Корень
Применение
Java (классический)
Big-endian фиксированной ширины
2-байтовая big-endian
Именованный
Миры Java, структуры и схемы
Сетевой Java (1.20.2+)
Big-endian фиксированной ширины
2-байтовая big-endian
Безымянный
Протокол Java
Bedrock
Little-endian фиксированной ширины
2-байтовая little-endian
Именованный
Миры Bedrock, .mcstructure, значения LevelDB
Bedrock level.dat
Little-endian фиксированной ширины
2-байтовая little-endian
Именованный после 8-байтового заголовка
Метаданные мира Bedrock
Сетевой Bedrock
Zigzag varint для int и long
Беззнаковый varint
Именованный
Протокол Bedrock
В varint-кодировании TAG_Short, TAG_Float и TAG_Double остаются little-endian фиксированной ширины. Только TAG_Int и TAG_Long становятся zigzag varint; длины массивов и списков следуют формату TAG_Int. Длины строк — беззнаковые varint, поэтому ограничение 65535 байт отсутствует.
Строки: модифицированный UTF-8 и UTF-8
Java сериализует строки через DataOutputStream.writeUTF в модифицированный UTF-8: NUL записывается как C0 80, а не 00, а символы вне Basic Multilingual Plane — двумя трёхбайтовыми суррогатными половинами (CESU-8), а не одной четырёхбайтовой последовательностью. Bedrock использует обычный UTF-8. Если инструмент применяет одно кодирование к обоим форматам, при сохранении повреждаются эмодзи и некоторые символы CJK. Здесь кодирование выбирается по формату.
Сжатие
Сам NBT не сжат — это свойство контейнера. Java-файлы обычно используют gzip (сигнатура 1F 8B), чанки внутри регионов — zlib (78 01, 78 9C или 78 DA), а Bedrock хранит level.dat и структуры без сжатия. Формат определяется по сигнатуре. Неверное сжатие — одна из самых частых причин отказа мира после ручной правки.
Минимальный файл по байтам
Канонический hello_world.nbt: корневой compound-тег hello world с одним строковым тегом name и значением Bananrama. В Java big-endian:
0A TAG_Compound
00 0B 68 65 6C 6C 6F 20 77 6F 72 6C 64 name length 11, "hello world"
08 TAG_String
00 04 6E 61 6D 65 name length 4, "name"
00 09 42 61 6E 61 6E 72 61 6D 61 value length 9, "Bananrama"
00 TAG_End
В Bedrock little-endian отличаются только порядки байтов двух полей длины: 0B 00 вместо 00 0B. В Сетевой Bedrock NBT длины становятся однобайтовыми varint 0B и 04 без заполнения. Редактор определит любой из трёх вариантов.
SNBT
SNBT — текстовая запись NBT, которую принимают команды: /data merge entity @s {Invulnerable:1b}. Суффиксы сохраняют типы: b — byte, s — short, L — long, f — float, d — double, без суффикса — int. Типизированные массивы записываются как [B;…], [I;…], [L;…]. Экспорт SNBT позволяет сравнивать версии мира обычным текстовым diff.
Часто задаваемые вопросы
Существует официальная спецификация NBT?
Формальной спецификации Mojang нет. Формат описал Notch в 2010 году, затем документацию поддерживало сообщество. Идентификаторы и структура здесь соответствуют текущей игре.
Почему Bedrock использует little-endian?
Движок Bedrock написан на C++ и работает на little-endian оборудовании, поэтому хранит значения в родном порядке. Сериализация Java использует big-endian по контракту DataOutput.
Что такое zigzag varint?
Способ записывать целые числа минимальным числом байтов, сохраняя короткими отрицательные значения: знак переносится в младший бит, поэтому −1 кодируется как 1, а 1 — как 2. Протокол Bedrock применяет его к int и long.
Может TAG_List содержать разные типы?
Нет. Список объявляет один тип, которому должны соответствовать все элементы. Для смешанных данных нужен список compound-тегов.
Какова максимальная длина строки?
65535 байт в вариантах фиксированной ширины, поскольку поле длины — unsigned short. У сетевого varint-кодирования практического ограничения нет.