Working with items
Read NBT data
ItemStack item = player.getInventory().getItemInMainHand();
// Read-only access
String value = NBT.get(item, nbt -> {
return nbt.getString("CustomKey");
});
// Check if key exists
boolean hasKey = NBT.get(item, nbt -> nbt.hasTag("CustomKey"));
Modify NBT data
ItemStack item = new ItemStack(Material.DIAMOND_SWORD);
NBT.modify(item, nbt -> {
nbt.setString("Owner", player.getName());
nbt.setInteger("Level", 5);
nbt.setBoolean("Legendary", true);
});
player.getInventory().addItem(item);
Compound tags
NBT.modify(item, nbt -> {
NBTCompound stats = nbt.getCompound("Stats");
if (stats == null)
stats = nbt.addCompound("Stats");
stats.setInteger("Kills", 10);
stats.setDouble("Damage", 25.5);
stats.setString("Type", "SWORD");
});
Lists
- String list
- Compound list
- Integer list
NBT.modify(item, nbt -> {
NBTList<String> lore = nbt.getStringList("Lore");
lore.add("Line 1");
lore.add("Line 2");
lore.add("Line 3");
});
NBT.modify(item, nbt -> {
NBTCompoundList enchants = nbt.getCompoundList("Enchantments");
NBTListCompound ench1 = enchants.addCompound();
ench1.setString("id", "minecraft:sharpness");
ench1.setInteger("lvl", 5);
NBTListCompound ench2 = enchants.addCompound();
ench2.setString("id", "minecraft:fire_aspect");
ench2.setInteger("lvl", 2);
});
NBTList<Integer> numbers = nbt.getIntegerList("Numbers");
numbers.add(1);
numbers.add(2);
numbers.add(3);
Working with entities
Read entity NBT
Entity entity = ...; // Your entity
String customName = NBT.get(entity, nbt -> {
return nbt.getString("CustomName");
});
boolean isAngry = NBT.get(entity, nbt -> {
return nbt.getBoolean("Angry");
});
Modify entity NBT
NBT.modify(entity, nbt -> {
nbt.setBoolean("NoAI", true);
nbt.setBoolean("Silent", true);
nbt.setInteger("Age", -24000); // Baby
});
Persistent data container
For custom plugin data (1.14+):NBT.modifyPersistentData(entity, nbt -> {
nbt.setString("PluginData", "value");
nbt.setInteger("Level", 5);
});
int level = NBT.getPersistentData(entity, nbt -> {
return nbt.getInteger("Level");
});
Working with blocks
Tile entities
Block block = player.getTargetBlock(null, 5);
BlockState state = block.getState();
NBT.modify(state, nbt -> {
nbt.setString("CustomName", "My Chest");
// For containers
NBTCompoundList items = nbt.getCompoundList("Items");
// Modify items...
});
state.update();
Available data types
nbt.setString("key", "value");
String value = nbt.getString("key");
Key operations
Check if key exists
boolean has = NBT.get(item, nbt -> nbt.hasTag("CustomKey"));
Get all keys
Set<String> keys = NBT.get(item, nbt -> nbt.getKeys());
for (String key : keys) {
System.out.println(key);
}
Remove key
NBT.modify(item, nbt -> {
nbt.removeKey("OldKey");
});
Get tag type
NBTType type = NBT.get(item, nbt -> nbt.getType("key"));
if (type == NBTType.NBTTagString) {
// It's a string
}
Advanced usage
Merging compounds
NBT.modify(item, nbt -> {
NBTContainer source = new NBTContainer();
source.setString("Key1", "Value1");
source.setInteger("Key2", 42);
nbt.mergeCompound(source);
});
Item meta access
NBT.modify(item, nbt -> {
nbt.modifyMeta((readableNBT, meta) -> {
if (meta instanceof SkullMeta) {
SkullMeta skull = (SkullMeta) meta;
skull.setOwningPlayer(player);
}
});
});
Cloning NBT
ItemStack source = ...
ItemStack target = new ItemStack(Material.DIAMOND);
NBT.get(source, sourceNbt -> {
NBT.modify(target, targetNbt -> {
targetNbt.mergeCompound(sourceNbt);
});
});
Working with files
Read from file
File file = new File("data.nbt");
NBTFile nbtFile = new NBTFile(file);
String value = nbtFile.getString("key");
int number = nbtFile.getInteger("number");
nbtFile.save();
Write to file
NBTFile nbtFile = new NBTFile(new File("data.nbt"));
nbtFile.setString("playerName", player.getName());
nbtFile.setInteger("level", 10);
nbtFile.setUUID("uuid", player.getUniqueId());
nbtFile.save();
Containers
Create standalone NBT containers:NBTContainer container = new NBTContainer();
container.setString("Name", "Example");
container.setInteger("Value", 42);
// Convert to JSON
String json = container.toString();
// Load from JSON
NBTContainer loaded = new NBTContainer(json);
Practical examples
Custom item with data
public ItemStack createCustomSword(Player player, int level) {
ItemStack sword = new ItemStack(Material.DIAMOND_SWORD);
NBT.modify(sword, nbt -> {
// Store owner
nbt.setUUID("Owner", player.getUniqueId());
// Store level
nbt.setInteger("Level", level);
// Store creation time
nbt.setLong("Created", System.currentTimeMillis());
// Store custom stats
NBTCompound stats = nbt.addCompound("Stats");
stats.setDouble("Damage", 10.0 + (level * 2.5));
stats.setDouble("Speed", 1.6);
stats.setInteger("Durability", 1561 + (level * 100));
// Store custom abilities
NBTList<String> abilities = nbt.getStringList("Abilities");
abilities.add("FIRE_ASPECT");
abilities.add("SWEEPING_EDGE");
});
return sword;
}
Reading custom item
public void checkCustomSword(ItemStack item) {
if (item == null || item.getType() != Material.DIAMOND_SWORD)
return;
NBT.get(item, nbt -> {
if (!nbt.hasTag("Owner"))
return; // Not a custom sword
UUID owner = nbt.getUUID("Owner");
int level = nbt.getInteger("Level");
long created = nbt.getLong("Created");
NBTCompound stats = nbt.getCompound("Stats");
double damage = stats.getDouble("Damage");
System.out.println("Level " + level + " sword");
System.out.println("Damage: " + damage);
});
}
Persistent entity data
public void markEntity(Entity entity, String faction) {
NBT.modifyPersistentData(entity, nbt -> {
nbt.setString("Faction", faction);
nbt.setLong("SpawnTime", System.currentTimeMillis());
nbt.setInteger("Level", 5);
});
}
public String getEntityFaction(Entity entity) {
return NBT.getPersistentData(entity, nbt -> {
return nbt.getString("Faction");
});
}
NBT operations on items create a copy of the item. Always use the returned item from
NBT.modify().Modifying NBT can make items incompatible with vanilla clients or cause unexpected behavior. Always test thoroughly!