Minecraft Blogs / Tutorial

Function Data Packs for Dummies #10 Part 1 | NBT: The hidden layer behind all of Minecraft

  • 5,716 views, 9 today
  • 23
  • 9
  • 4
Bertiecrafter's Avatar Bertiecrafter
Retired Moderator
Level 71 : Legendary Engineer
This series of tutorials will teach you how to create your very own data packs, assuming you know absolutely nothing about commands. Although data packs could just contain files that replace built-in assets like resource packs, these posts will focus on adding new features and mechanics to the game. In every part I assume you've read the previous parts.

Introduction to NBT

Most, if not all, data in Minecraft is saved using the NBT format. NBT stands for Named Binary Tag. The format is invented by Notch himself and has been around since Indev. The specification (not the usage) of NBT has barely changed since Beta 1.3 and therefore has proven that it's a robust and powerful definition language. Unlike JSON, the NBT format is binary data that cannot be read by humans. However, a Stringified NBT (SNBT) format was created for usage in commands, which looks a lot like JSON. By learning the ins and outs of the SNBT format, we can interact with this hidden layer behind all of Minecraft and unlock the real power of data packs.

Although "SNBT format" is the official term for the syntax used in commands, most people including myself will be referring to it as just "NBT".

This blog post is going to be quite complex and extensive. There will be a step by step usage example to get you going at the end, so don't worry if all of this seems a bit much at first.

Comparison between NBT and JSON

NBT is based on JSON. It distinguishes between more types than JSON does and has different notations for strings and compounds.

IconRangeNBT NameNBT ExamplesJSON NameJSON Examples
Function Data Packs for Dummies #10 Part 1 | NBT: The hidden layer behind all of Minecraft
Function Data Packs for Dummies #10 Part 1 | NBT: The hidden layer behind all of Minecraft
"It\'s cool"
'Single quotes allowed'
"It\'s cool"
Function Data Packs for Dummies #10 Part 1 | NBT: The hidden layer behind all of Minecraft-128 to 127
Whole numbers
± 3.2E4
Whole numbers
± 2.1E9
Whole numbers
There is no suffix on this one
± 9.2E18
Whole numbers
± 3.4E38
Allows decimals
Allows decimals
Item types are often of same type.List
(Any type)
[true, true, false]
[A, B, C]
[23, 534, -3434]
[23b, -28b]
[0.0f, 0.25f, -0.25f]
Array[true, true, false]
["A", "B", "C"]
[23, 533, -234]
[64.53, 64.96, -23.46]

Items must be of same type and require array prefixByte Array
Integer Array
Long Array
[B; 52b, -123b]
[I; 24, -11532]
[L; 254l, -344l]

-Compound{Health:20.0f, IsBaby:0b}Object
{"text":"hi", "color":"red"}

Note 1: 4E2 stands for "multiply 4 by 10, 2 times". For example, 1,000,000 = 1E6 and 7,512,000,000 = 7.512E9.
Note 2: View the up to date list of data types here.

This might seem like a lot to take in and yes, it is. You'll learn to work with NBT soon, so don't stress too much about reminding it all right this second.

Special value representations

Not all kinds of values perfectly fit in the listed NBT value types. Here are some value representations that you might not have expected:
  • NBT is used almost everywhere, from blocks to items and entities. An exception to this is text representation, which happens in JSON. The minecraft JSON text component appears on signs, in books, as display name of scoreboard objectives, in /tellraw, in /title, in names of items, blocks and entities and maybe in a couple other places I forgot about. Because JSON is different from NBT, you must write your JSON in a string. Since JSON already contains quotes, the surrounding character is an apostrophy.
    /setblock ~ ~ ~ minecraft:oak_sign{Text1:'{"text":"This is BOLD","bold":true}'}
  • Color is another interesting value representation. For the default color of a sign and the color component of JSON text, the color is represented by a string (see wiki page). The JSON text component also supports a hex value (use color picker).
    /setblock ~ ~ ~ minecraft:oak_sign{Text1:'{"text":"This is built-in RED","color":"dark_red"}'}
    /setblock ~ ~ ~ minecraft:oak_sign{Text1:'{"text":"This is custom bright RED","color":"#ff0000"}'}
    For the wolf collar or sheep colors, it's a byte number (0-15) with the order matching the order of any colored block in the inventory.
    /summon wolf ~ ~ ~ {CollarColor:3b,OwnerUUID:"00000000-0000-0000-0000-000000000000"}For leather armor, potion, map marker and banner pattern colors, the color is represented by a single integer value. Obtain the value by picking a color and converting its hex value (the code behind the hashtag) to decimal.
    # Hex value: #00ffcc
    # Convert: 00ffcc -> 65484
    /give @s minecraft:leather_chestplate{display:{color:65484}}
    # Fireworks use an integer array to specify one or more color(s)
    /give @s minecraft:firework_rocket{Fireworks:{Explosions:[{Flicker:1b,Trail:0b,Type:1b,Colors:[I;65484,6724095]}]}}
    Most appearances of color are simply in the block or item id:
    /give @s minecraft:red_wool
    /give @s minecraft:yellow_wool
  • UUID stands for "Universally Unique Identifier" and is created by just generating a bunch of random bytes. It's not really unique, but the chance of generating the same number twice is almost zero. They are represented by numbers or strings and are used as "short and easy" values to reference big complex data structures, not only in MC, but also in programming. For example, a wolf has data to indicate its owner, so it uses a UUID instead of repeating all of the player data. It looks like this: # There are about 3 different kinds of UUID representations

    # Wolf owner (string):
    OwnerUUID: "7105a944-75c3-4202-81e8-5b2d29e83683"
    # Pigman hurt by player (string):
    HurtBy: "7105a944-75c3-4202-81e8-5b2d29e83683"
    # Arrow owner to determine who can pick it up (long):
    # "most" and "least" are just 2 halves of the UUID
    OwnerUUIDMost:1583815768071029214L, OwnerUUIDLeast:-7722708526158156803L
    # Common 1.16 format (Integer Array):
    # The other representations are being changed to this one
    OwnerUUID: [I;1662566817,-1492500203,-1840623774,-15879993]
    It's important to know whether you're dealing with a reference to an existing UUID or a reference point requiring a newly generated UUID. When you (un)equip armor, Minecraft uses UUIDs in the attributes data to know how which set of armor points to add or remove. The difference is that this UUID is being referenced, while the wolf owner UUID is the reference (to a player). In a case like the attributes one, you want to generate a new UUID, equal values will result in attributes being ignored. In a case like the wolf owner one, you want to use the UUID of the player you're trying to reference. Non-existant values will result in the wolf not recognizing any players. The explanations of data tags on the wiki pages give a lot of context on what the UUID means and how it's used.

Sources on the Minecraft Wiki

Being able to find the information you need is just as important as being able to read and use that information. Although every wiki page on any block, item or entity will tell you which NBT tags are available, there are a couple pages with full overviews of the available NBT:
  • Chunk Format: This page lists the NBT format for block entities.
  • Entity Format: This page lists the NBT format for all mobs, projectiles, vehicles, falling blocks and a couple of other things.
  • Player.dat Format: This page describes the NBT format for the "player" entity and all items. This includes information on potions, fireworks, books, player heads, maps, spawn eggs, enchantments, named items and even suspicious stews.

Simple Commands that use NBT

  • /setblock: Add curly braces to the block ID to define it's NBT. (From Chunk Format)
    /setblock ~ ~ ~ spawner{SpawnData:{id:"minecraft:creeper"}}
  • /summon: The last argument can contain NBT within curly braces. (From Chunk Format)
    /summon minecraft:slime ~ ~ ~ {Size:10b}
  • /give or /replaceitem: Add curly braces to the item ID to define it's NBT. (From Player.dat Format)
    Note that the specified NBT will be placed in the "tag" tag of an item, meaning that you can't set an id, slot or amount using this method.
    /give @s minecraft:diamond_sword{display:{Name:'{"text":"Dragon Slayer","color":"red","bold":true}'}}

Block States

While NBT is often used for dynamic data that has a large range of values, block states are used for simple block properties that have a small and finite number of values. Block states appear on the middle right in the F3 overlay and can also be auto-completed in commands.
# Placing a chest facing north (default)
/setblock ~ ~ ~ chest
# Placing a chest facing west
/setblock ~ ~ ~ chest[facing=west]
# Placing a chest facing north that can only be opened by an item with name: "Unlock"
/setblock ~ ~ ~ chest{Lock:"Unlock"}
# Placing a chest facing west that can only be opened by an item with name: "Unlock"
/setblock ~ ~ ~ chest[facing=west]{Lock:"Unlock"}

The wiki pages for a certain block will also mention the available block states.

Step By Step: A Reward Chest

Imagine you're creating an adventure map and want to provide the players with a chest filled with goodies as a reward. I'll be illustrating the thought process in detail, please follow along with your browser and minecraft client. Of course the first thing you want to do is spawn a chest.
/setblock ~ ~ ~ minecraft:chestNow how do you get items in it? You remember that you can find block NBT on the Chunk Format page, so you take a look there. Two thirds down the page you find the chest NBT. It says there is an "Items" tag, with an icon indicating it's a list type. The page also shows an icon for an item, representing the compound type. You intend to give the player a nice diamond sword, enchanted golden apples and a turtle helmet for some mysterious reason.
/setblock ~ ~ ~ minecraft:chest{Items:[{},{},{}]}This still doesn't tell Minecraft what items to put in the chest. After unfolding the NBT data for an item on the wiki page, you see that an item has id, Slot, Count and tag tags. The description of the id tag conveniently links another page with all block and item ids, where you find the ids of the desired items. The page also says that the slots are from 0 to 26. After literally using your finger to tap each slot in an empty chest on the screen while counting, you realise you need the slots 11, 13 and 15. Although normally all NBT data has defaults, you discover by trial and error that all tags except the "tag" tag is required. The icon for id indicates it's a string, while the icons for Count and Slot indicate it's a byte. You also remember that Byte values need a "b" on the end of the value.
/setblock ~ ~ ~ minecraft:chest{Items:[{id:"minecraft:enchanted_golden_apple",Count:8b,Slot:11b}]}After testing with 1 item, you decide to add the others.
/setblock ~ ~ ~ minecraft:chest{Items:[{id:"minecraft:enchanted_golden_apple",Count:8b,Slot:11b},{id:"minecraft:diamond_sword",Count:1b,Slot:13b},{id:"minecraft:turtle_helmet",Count:1b,Slot:15b}]}Awesome! You have now created a chest that's pre-filled with 3 items. You want to add a name to the diamond sword, so you open up the Player.dat format page which lists all NBT for items. Under "Display Properties" you see the "tag" tag which is the same as the "tag" tag that was listed on the Chunk Format page. The icon indicates it's a compound. The tag contains another compound tag, named "display". This last tag contains a "Name" tag. The icon indicates it's a string. Let's focus on the NBT for just the diamond sword.
{id:"minecraft:diamond_sword",Count:1b,Slot:13b,tag:{display:{Name:''}}}The wiki page says that the Name tag contains a JSON text component. You navigate to the wiki page that contains the definition of JSON text. You start with a root compound and see that there is a "text" tag having an icon indicating it's a string. You also remember that JSON is not NBT and need to enclose JSON with apostrophes.
{id:"minecraft:diamond_sword",Count:1b,Slot:13b,tag:{display:{Name:'{"text":"Blade of Doom"}'}}}Well that looks kinda silly.... You read up on the color and bold tags to create something that looks a lot cooler.
{id:"minecraft:diamond_sword",Count:1b,Slot:13b,tag:{display:{Name:'{"text":"Blade of Doom","color":"dark_red","bold":true}'}}}To finish things off, you want to add enchantments. You go back to the Player.dat Format page and under "Enchantments", you find the "Enchantments" tag which is a list of compounds. The types are again indicated by the icons in front. The id tag is a string and the level is a integer starting at 1. For some dumb reason, the enchantments page does not contain the enchantment ids at the time of writing this. You intend to add Sharpness 5 and by using the auto-complete on /enchant, you figure out that the id is "minecraft:sharpness".
{id:"minecraft:diamond_sword",Count:1b,Slot:13b,tag:{Enchantments:[{id:"minecraft:sharpness",lvl:5}]}}After combining the snippets for a cool name and the sharpness enchantment, you're left with a fully functional command that spawns a chest full of goodies.
/setblock ~ ~1 ~ minecraft:chest{Items:[{id:"minecraft:enchanted_golden_apple",Count:8b,Slot:11b},{id:"minecraft:diamond_sword",Count:1b,Slot:13b,tag:{display:{Name:'{"text":"Blade of Doom","color":"dark_red","bold":true}'},Enchantments:[{id:"minecraft:sharpness",lvl:5}]}},{id:"minecraft:turtle_helmet",Count:1b,Slot:15b}]}The command is too big for chat now, you need a function file or command block to spawn the chest. I changed the y coordinate to ~1 to spawn the chest above the command block. I do not recommend creating separate parts of NBT and combining them later, I only did this in the example to make additions more obvious. You should just write NBT in one piece, but add closing brackets as soon as you write an opening one. Example progression of a command:
/give @s item
/give @s item{}
/give @s item{display:{}}
/give @s item{display:{Name:'{}'}}
/give @s item{display:{Name:'{"text":"Awesome ","color":"yellow","extra":[{}]}'}}
/give @s item{display:{Name:'{"text":"Awesome ","color":"yellow","extra":[{"text":" Item","color":"gold"}]}'}}

Challenge Yourself

After every tutorial, I'll include a section where you are challenged to apply what you've learned. I recommend you playing with what you've learned, it helps you getting familiar with new concepts and be able to find solutions to problems. You don't have to do exactly what's written below, you can always challenge yourself in a different way.

Create a couple of the following items, blocks or entities using the wiki pages:
  • A creeper with max explosion radius.
  • A lit tnt entity with an 8 second fuse.
  • A floating moving block by spawning a minecart with custom block data on underground tracks with an offset big enough to make the block visible above ground.
  • A falling diamond block
  • An armor stand with custom pose
  • An invisible creeper
  • 3 slimes stacked on top of each other, using the "Passengers" tag. Each slime must be smaller than the one below.
  • An item with custom Name and Lore. Make sure to make both non-italic and color the Lore gray or blue to make it look more official.
  • A lucky potion with a couple awesome status effects
  • Pretty Fireworks
  • Leather armor in your favourite, but not survival obtainable colour.
  • A placed sign with styled text (color, bold, italic)
  • A book with a contents page, filled with clickable links that navigate to a different page.
Of course these are just examples, you can also scroll through the Chunk Format and Player.dat Format pages yourself and see if you get curious about anything.

What's next?

In this tutorial we've only seen ways of creating things with NBT already applied to them. In the next tutorial we'll have a look at more ways our data packs can interact with NBT. This includes reading, modifying and checking for NBT, but also combining the powers of both the scoreboard and NBT.

Subscribe if you want to get notified of new posts.


1 Update Logs

Updated data type icons : by Bertiecrafter 10/24/2020 7:20:38 amOct 24th, 2020

The wiki used new icons, so I made this blog display the up to date versions.

Create an account or sign in to comment.

04/07/2020 1:24 pm
Level 71 : Legendary Engineer
Bertiecrafter's Avatar
Thank you Luracasmus, PMC, wms98, pettyGamingHD, Luki2811, Masta969, Rune_Bloodstone, Redfuzzyturtle, PixieMax, end-user, TofuChild36, Vellaris, SanctuaryThief, Davgaming, SUPERIONtheKnight, eliaspaukune, Zamanbre and Weigurde for the diamonds!
07/09/2021 5:00 pm
Level 1 : New System
Photon_Phox's Avatar
Oh Forgot To Tell You I'm On 1.16.5 Thats the Version Of Minecraft I Need Of The Command
07/09/2021 4:56 pm
Level 1 : New System
Photon_Phox's Avatar
Hey If You Come Back To This And Read My Reply Which Obviously Your Are Can You Tell Me How To Get Multiple Tags On A Item For Example Like A Leather Chest Plate With Red Color And A Name And A Enchantment Please Tell Me Cause I'm Working On A Datapack And I Need To Know To Continue It Please Tell Me
07/10/2021 4:03 am
Level 71 : Legendary Engineer
Bertiecrafter's Avatar
Start by opening the player.dat wiki page. Under the header "Display Properties" you can see that there are display -> color tags. Use the two links above to pick a color (e.g. #FF0000) and convert it to an integer (which would be 16711680). This results in the first part of the command:
/give @s leather_chestplate{display:{color:16711680}}Then, you also can see under the same header that the Name is also in the display tag and uses the JSON raw text format (see first item in Special value representations above). You can just add multiple tags to the same compound (= data between curly braces) by using commas. Order does not matter. The next part of the command would then be:
/give @s leather_chestplate{display:{color:16711680,Name:'{"text":"hi"}'}}And lastly, you can scroll up to Enchantments and read how you define enchantments. See if you can relate the next command to what you see on the wiki page:

/give @s leather_chestplate{display:{color:16711680,Name:'{"text":"hi"}'},Enchantments:[{id:"protection",lvl:3s}]}
I hope this answered your question :P