RapidNBT
A High-Performance Python Minecraft NBT Library (C++ Binding)
Install / Use
/learn @GlacieTeam/RapidNBTREADME
RapidNBT
Python Bindings for a High-Performance NBT Library
Install 🔧
pip install rapidnbt
Supported NBT format 📖
| NBT Format | Minecraft Edition | Support Status | | --------------------------------- | ---------------------- | ------------------ | | Little Endian | Bedrock Edition | :white_check_mark: | | Little Endian with Header | Bedrock Edition | :white_check_mark: | | Big Endian | Java Edition | :white_check_mark: | | Big Endian with Header | Java Edition | :white_check_mark: | | Bedrock Network (VarInt Encoding) | Bedrock Edition | :white_check_mark: | | Formatted String (SNBT) | Bedrock & Java Edition | :white_check_mark: |
Full SNBT support - Full SNBT format support, include the new SNBT format since Java Edition 1.21.5
Benchmarks 🚀
Comparing with some popular NBT libraries.
Parsing NBT file (870 MB, little-endian binary NBT)
| Library | Link | Time | Performance | Memory Usage | | ---------------- | ------------------------------------------| ------------ | -------------- | ------------ | | RapidNBT | https://github.com/GlacieTeam/RapidNBT | 5.2s | 100% | 4800MB | | nbtlib | https://github.com/vberlier/nbtlib | 33.9s | 15.3% | 6500MB | | PyNBT | https://github.com/TkTech/PyNBT | 33.4s | 15.6% | 8900MB |
Tested on Intel i7 14700-HX with 32GB DDR5-5400 using 720MB little-endian binary NBT
Quick Start 🚀
RapidNBT provides a morden and safe API, and it is easy to use.
- Load NBT from file and modify it
from rapidnbt import nbtio, LongTag
from ctypes import c_int16
def example():
nbt = nbtio.load("./level.dat") # Automatically detect nbt file format and decompress (if compressed)
# nbt = nbtio.load("./level.dat", NbtFileFormat.BIG_ENDIAN) # You can also specify the file format
# Modify NBT
nbt["abc"]["def"] = True # bool will automatically convert to ByteTag(1)
nbt["ghi"]["hjk"] = c_int16(23) # ctypes.c_int16 will automatically convert to ShortTag(23)
nbt["lmn"] = ["test1", "test2"] # Python list will automatically convert to ListTag([StringTag("test1"), StringTag("test2")])
nbt["opq"]["rst"] = { # Python dict will automatically convert to CompoundTag
"key1": False,
"key2": b"2345", # bytes/bytearray will automatically convert to ByteArrayTag
"key3": LongTag(114514), # You can also directly use Tag
}
"""
You need not to create the NBT node first.
Example:
nbt["abc"]["def"] = True
If nbt["abc"]["def"] does not exist, it will be auto created.
"""
- Create a NBT in memory and save it to file
from rapidnbt import nbtio, CompoundTag, ShortTag, LongTag, DoubleTag, IntArrayTag, NbtFileFormat
from ctypes import c_uint8, c_double
# Create a NBT in memory
nbt = CompoundTag(
{
"string": "Test String",
"byte": c_uint8(114),
"short": ShortTag(19132),
"int": 114514,
"int64": LongTag(1145141919810),
"float": 1.4142,
"double": c_double(3.1415926535897),
"byte_array": b"13276273923",
"list": ["string1", "string2"],
"compound": nbt,
"int_array": IntArrayTag([1, 2, 3, 4, 5, 6, 7]),
"long_array": LongArrayTag([1, 2, 3, 4, 5, 6, 7]),
}
)
# Print SNBT
print(nbt.to_snbt())
# Or you can specify SNBT format
print(file.to_snbt(format=SnbtFormat.Classic | SnbtFormat.MarkExtra, indent=4))
# Use | to combime format
# Save NBT to file
nbtio.dump(nbt, "./test.nbt", NbtFileFormat.LITTLE_ENDIAN)
- Use context manager to operate NBT file
from rapidnbt import LongTag, nbtio
# use context manager
with nbtio.open("level.dat") as file:
file["RandomSeed"] = LongTag(1145141919810) # modify NBT
# Auto save file as original format when exit context manager
- Read NBT data
from rapidnbt import nbtio
def example():
nbt = nbtio.load("./test.nbt") # Automatically detect nbt file format and decompress (if compressed)
value1 = nbt["abc"]["def"].value # Use .value method to get any tag value, and returns a Python object (Python int, str, dict, etc...)
value2 = nbt["ghi"]["hjk"].get_short() # Use .get_xxx method to safely get tag value, and will throw TypeError if tag is wrong type
exits = "lmn" in nbt # Check if a tag exist in this NBT
# exits = nbt.contains("lmn") You can also use .contains() method to check
del nbt["opq"]["rst"] # Delete a tag in NBT
# nbt["opq"].remove("rst") You can also use .remove() method to delete
nbt.rename("abc", "ABC") # Rename a key in NBT
More details please see the docstring in
.pyifile
CLI 🔧
You can use CLI commands to opeartor NBT files easily.
Use nbt or python -m rapidnbt to run CLI
options:
-h, --help show this help message and exit
-p, --print print NBT as a formatted string
-i, --indent INDENT NBT format indent
-j, --json format NBT as a json string
-o, --output OUTPUT NBT output file path
--little NBT output should use little endian format
--big NBT output should use big endian format
--network NBT output should use bedrock network format
--snbt NBT output should use a formatted string nbt
--header NBT output should write header
-m, --merge NBT output should merge exist NBT
--merge-list NBT should merge ListTag instead of replace it
-c, --compression {none,gzip,zlib}
NBT output should merge exist NBT
1. Print a NBT file as SNBT
eg. level.dat
nbt level.dat -p
2. Print a NBT file as a json
eg. level.dat, indent = 2
nbt level.dat -pj --indent=2
3. Convert a NBT file to other format
eg. convert level.dat to SNBT and save as level.snbt
python -m rapidnbt level.dat --output=level.snbt --indent=0
4. Merge NBT
eg. use player1.nbt to patch player2.nbt (little-endian, no compression)
nbt player1.dat --output=player2.nbt --merge --little --compression=none
Used Libraries 📖
| Library | License | Link | | ---------------- | ------------ | -------------------------------------------- | | NBT | MPL-2.0 | https://github.com/GlacieTeam/NBT | | pybind11 | BSD-3-Clause | https://github.com/pybind/pybind11 | | magic_enum | MIT | https://github.com/Neargye/magic_enum |
Contributing 🤝
Contributions are welcome! Please follow these steps:
- Fork the repository and create your feature branch
- Add tests for any new functionality
- Submit a pull request with detailed description
License 📄
This project is licensed under the Mozilla Public License 2.0 (MPL-2.0).
Key Requirements:
- Modifications to this project's files must be released under MPL-2.0.
- Using this library in closed-source projects is allowed (no requirement to disclose your own code).
- Patent protection is explicitly granted to all users.
For the full license text, see LICENSE file or visit MPL 2.0 Official Page.
