Named Binary Tags (NBT)
Read and write the tag data Bedrock stores on items.
NBT (Named Binary Tag) is the key/value format Bedrock uses to store structured data - on items, blocks, and entities. Endstone exposes it through endstone.nbt as Python-friendly tag objects, so you read and edit it without touching the binary format.
Tag types
Every value is a typed tag. Scalars hold a single .value; the container tags nest other tags:
| Tag | Holds |
|---|---|
ByteTag, ShortTag, IntTag, LongTag | an integer |
FloatTag, DoubleTag | a float |
StringTag | a string |
ByteArrayTag, IntArrayTag | an array of integers |
ListTag | a sequence of tags (all the same type) - list-like |
CompoundTag | a map of named tags - dict-like |
Read an item's NBT
ItemStack.nbt returns a CompoundTag, which behaves like a dict - index it, check membership, iterate items():
# `player` is an endstone.Player
item = player.inventory.item_in_main_hand
if item is None:
return
tag = item.nbt # a CompoundTag
for key, value in tag.items():
player.send_message(f"{key} = {value}")Reading a scalar back out means going through .value:
if "my_plugin:level" in tag:
level = tag["my_plugin:level"].value # an intWrite NBT
Reading nbt gives you a tag to edit; assign it back to nbt to apply the change. Wrap raw values in the matching tag type:
from endstone.nbt import IntTag, StringTag
tag = item.nbt
tag["my_plugin:level"] = IntTag(5)
tag["my_plugin:owner"] = StringTag("Steve")
item.nbt = tagNamespace your keys (my_plugin:level, not level) so they can't collide with the vanilla data Bedrock keeps on the same item.
Build nested structures
CompoundTag and ListTag nest, so you can build whatever shape you need. Both also construct from plain Python - a dict or an iterable of tags:
from endstone.nbt import CompoundTag, ListTag, IntTag, StringTag
stats = CompoundTag()
stats["kills"] = IntTag(10)
lore = ListTag()
lore.append(StringTag("Forged in fire"))
stats["lore"] = loreCompoundTag.to_dict() and ListTag.to_list() go the other way, unwrapping a tag tree into plain Python values.
Serialize and load
To persist NBT or move it between systems, dump() writes the binary form and load() reads it back. Bedrock uses little-endian byte order, which is the default:
from endstone.nbt import load
data = tag.dump() # bytes, little-endian
restored, root_name = load(data)Pass byte_order="big" for Java-style NBT, or network=True for Bedrock's network varint encoding.