Synopsis

file.norbert

Description

Important This document describes an experimental file format that is subject to change.

Norbert is a text file format used by the norbert(1) tool to represent NBT data. The goal of the format is to be easily parsed by text-based command line tools. Each line in a norbert-formatted file represents a single leaf tag, and has the form

fullname = (type) value

fullname is constructed from the leaf tag’s name and the names of its ancestors. type is the tag type of the leaf tag. value is the leaf tag’s payload. fullname, (type), value, and the equals sign (=) may be padded with any amount of whitespace without changing how the tag is interpreted. There must not be any whitespace between the parentheses and type, however. Thus, fullname = ( type ) value is an invalid norbert tag.

Norbert is not suitable for representing tags with special characters in their names or payloads. In particular, implementations of this spec may have trouble parsing tags with whitespace or characters from the string ,#= in fullname or value.

The format of fullname, type, and value is explained in the Names, Types, and Values sections below. For examples, see the Examples section.

Names

To construct fullname, start with the name of the root tag and traverse the NBT tree towards the leaf tag. For each child of a TAG_Compound traversed, the child’s name is prepended with a comma and appended to fullname. For each child of a TAG_List traversed, the child’s index in the list is prepended with a hash symbol (#) and appended to fullname. Construction of fullname is complete when the child tag is reached.

Thus, if fullname is foo,bar#0,baz, it represents a leaf tag named "baz" which is the 0th item in a TAG_List named "bar" which is a member of a TAG_Compound named "foo". Or, put another way, TAG_Compound foo is the parent of TAG_List bar, which is the parent of its 0th tag baz. If baz is a TAG_Short with a payload of 42, this structure could be represented as

TAG_Compound("foo"): 1 entries
{
   TAG_List("bar"): 1 entries of type TAG_Compound
   {
      TAG_Compound: 1 entries
      {
         TAG_Short("baz"): 42
      }
   }
}

Types

type is the type of the leaf tag, and must be one of TAG_Byte, TAG_Short, TAG_Int, TAG_Long, TAG_Float, TAG_Double, TAG_Byte_Array, TAG_String, TAG_List, TAG_Compound, or TAG_Int_Array.

Additionally, type must always be surrounded with parentheses. No whitespace or other text is permitted between type and the parentheses.

Values

value is the tag’s payload, and depends on type. Valid values are described below for each tag type.

TAG_Byte

An integer ranging from -128 to 127.

TAG_Short

An integer ranging from -32768 to 32767.

TAG_Int

An integer ranging from -2147483648 to 2147483647.

TAG_Long

An integer ranging from -9223372036854775808 to 9223372036854775807.

TAG_Float

An IEEE 754-2008 single-precision floating point number.

TAG_Double

An IEEE 754-2008 double-precision floating point number.

TAG_Byte_Array

A comma-delimited list of integers ranging from -128 to 127.

TAG_String

A UTF-8 string. The string must not be wrapped in quotes, but may have escape sequences for special characters such as tabs, newlines, and unicode characters.

TAG_List

The type of tags contained in the list. Valid values are the same as the valid values for type. See the Types section above.

TAG_Compound

For TAG_Compounds, value is ignored. This is because leaf TAG_Compounds are always empty.

TAG_Int_Array

A comma-delimited list of integers ranging from -2147483648 to 2147483647.

Examples

The test.nbt example file in Markus Persson’s NBT spec has the following contents:

TAG_Compound('hello world'): 1 entry
{
        TAG_String('name'): 'Bananrama'
}

In norbert format, this would be expressed as

hello world,name = (TAG_String) Bananrama

The bigtest.nbt example file from the spec

TAG_Compound("Level"): 11 entries
{
   TAG_Short("shortTest"): 32767
   TAG_Long("longTest"): 9223372036854775807
   TAG_Float("floatTest"): 0.49823147058486938
   TAG_String("stringTest"): HELLO WORLD THIS IS A TEST STRING ÅÄÖ!
   TAG_Int("intTest"): 2147483647
   TAG_Compound("nested compound test"): 2 entries
   {
      TAG_Compound("ham"): 2 entries
      {
         TAG_String("name"): Hampus
         TAG_Float("value"): 0.75
      }
      TAG_Compound("egg"): 2 entries
      {
         TAG_String("name"): Eggbert
         TAG_Float("value"): 0.5
      }
   }
   TAG_List("listTest (long)"): 5 entries of type TAG_Long
   {
      TAG_Long: 11
      TAG_Long: 12
      TAG_Long: 13
      TAG_Long: 14
      TAG_Long: 15
   }
   TAG_Byte("byteTest"): 127
   TAG_List("listTest (compound)"): 2 entries of type TAG_Compound
   {
      TAG_Compound: 2 entries
      {
         TAG_String("name"): Compound tag #0
         TAG_Long("created-on"): 1264099775885
      }
      TAG_Compound: 2 entries
      {
         TAG_String("name"): Compound tag #1
         TAG_Long("created-on"): 1264099775885
      }
   }
   TAG_Byte_Array("byteArrayTest (the first 1000 values of (n*n*255+n*7)%100, starting with n=0 (0, 62, 34, 16, 8, ...))"): [1000 bytes]
   TAG_Double("doubleTest"): 0.4931287132182315
}

would be expressed as

Level,shortTest = (TAG_Short) 32767
Level,longTest = (TAG_Long) 9223372036854775807
Level,floatTest = (TAG_Float) 0.4982314705848694
Level,stringTest = (TAG_String) HELLO WORLD THIS IS A TEST STRING ÅÄÖ!
Level,intTest = (TAG_Int) 2147483647
Level,nested compound test,ham,name = (TAG_String) Hampus
Level,nested compound test,ham,value = (TAG_Float) 0.75
Level,nested compound test,egg,name = (TAG_String) Eggbert
Level,nested compound test,egg,value = (TAG_Float) 0.5
Level,listTest (long)#0 = (TAG_Long) 11
Level,listTest (long)#1 = (TAG_Long) 12
Level,listTest (long)#2 = (TAG_Long) 13
Level,listTest (long)#3 = (TAG_Long) 14
Level,listTest (long)#4 = (TAG_Long) 15
Level,byteTest = (TAG_Byte) 127
Level,listTest (compound)#0,name = (TAG_String) Compound tag #0
Level,listTest (compound)#0,created-on = (TAG_Long) 1264099775885
Level,listTest (compound)#1,name = (TAG_String) Compound tag #1
Level,listTest (compound)#1,created-on = (TAG_Long) 1264099775885
Level,byteArrayTest (the first 1000 values of (n*n*255+n*7)%100, starting with n=0 (0, 62, 34, 16, 8, ...)) = (TAG_Byte_Array) 0,62,34,16,8,10,22,44,76,18,70,32,4,86,78,80,92,14,46,88,40,2,74,56,48,50,62,84,16,58,10,72,44,26,18,20,32,54,86,28,80,42,14,96,88,90,2,24,56,98,50,12,84,66,58,60,72,94,26,68,20,82,54,36,28,30,42,64,96,38,90,52,24,6,98,0,12,34,66,8,60,22,94,76,68,70,82,4,36,78,30,92,64,46,38,40,52,74,6,48,0,62,34,16,8,10,22,44,76,18,70,32,4,86,78,80,92,14,46,88,40,2,74,56,48,50,62,84,16,58,10,72,44,26,18,20,32,54,86,28,80,42,14,96,88,90,2,24,56,98,50,12,84,66,58,60,72,94,26,68,20,82,54,36,28,30,42,64,96,38,90,52,24,6,98,0,12,34,66,8,60,22,94,76,68,70,82,4,36,78,30,92,64,46,38,40,52,74,6,48,0,62,34,16,8,10,22,44,76,18,70,32,4,86,78,80,92,14,46,88,40,2,74,56,48,50,62,84,16,58,10,72,44,26,18,20,32,54,86,28,80,42,14,96,88,90,2,24,56,98,50,12,84,66,58,60,72,94,26,68,20,82,54,36,28,30,42,64,96,38,90,52,24,6,98,0,12,34,66,8,60,22,94,76,68,70,82,4,36,78,30,92,64,46,38,40,52,74,6,48,0,62,34,16,8,10,22,44,76,18,70,32,4,86,78,80,92,14,46,88,40,2,74,56,48,50,62,84,16,58,10,72,44,26,18,20,32,54,86,28,80,42,14,96,88,90,2,24,56,98,50,12,84,66,58,60,72,94,26,68,20,82,54,36,28,30,42,64,96,38,90,52,24,6,98,0,12,34,66,8,60,22,94,76,68,70,82,4,36,78,30,92,64,46,38,40,52,74,6,48,0,62,34,16,8,10,22,44,76,18,70,32,4,86,78,80,92,14,46,88,40,2,74,56,48,50,62,84,16,58,10,72,44,26,18,20,32,54,86,28,80,42,14,96,88,90,2,24,56,98,50,12,84,66,58,60,72,94,26,68,20,82,54,36,28,30,42,64,96,38,90,52,24,6,98,0,12,34,66,8,60,22,94,76,68,70,82,4,36,78,30,92,64,46,38,40,52,74,6,48,0,62,34,16,8,10,22,44,76,18,70,32,4,86,78,80,92,14,46,88,40,2,74,56,48,50,62,84,16,58,10,72,44,26,18,20,32,54,86,28,80,42,14,96,88,90,2,24,56,98,50,12,84,66,58,60,72,94,26,68,20,82,54,36,28,30,42,64,96,38,90,52,24,6,98,0,12,34,66,8,60,22,94,76,68,70,82,4,36,78,30,92,64,46,38,40,52,74,6,48,0,62,34,16,8,10,22,44,76,18,70,32,4,86,78,80,92,14,46,88,40,2,74,56,48,50,62,84,16,58,10,72,44,26,18,20,32,54,86,28,80,42,14,96,88,90,2,24,56,98,50,12,84,66,58,60,72,94,26,68,20,82,54,36,28,30,42,64,96,38,90,52,24,6,98,0,12,34,66,8,60,22,94,76,68,70,82,4,36,78,30,92,64,46,38,40,52,74,6,48,0,62,34,16,8,10,22,44,76,18,70,32,4,86,78,80,92,14,46,88,40,2,74,56,48,50,62,84,16,58,10,72,44,26,18,20,32,54,86,28,80,42,14,96,88,90,2,24,56,98,50,12,84,66,58,60,72,94,26,68,20,82,54,36,28,30,42,64,96,38,90,52,24,6,98,0,12,34,66,8,60,22,94,76,68,70,82,4,36,78,30,92,64,46,38,40,52,74,6,48,0,62,34,16,8,10,22,44,76,18,70,32,4,86,78,80,92,14,46,88,40,2,74,56,48,50,62,84,16,58,10,72,44,26,18,20,32,54,86,28,80,42,14,96,88,90,2,24,56,98,50,12,84,66,58,60,72,94,26,68,20,82,54,36,28,30,42,64,96,38,90,52,24,6,98,0,12,34,66,8,60,22,94,76,68,70,82,4,36,78,30,92,64,46,38,40,52,74,6,48,0,62,34,16,8,10,22,44,76,18,70,32,4,86,78,80,92,14,46,88,40,2,74,56,48,50,62,84,16,58,10,72,44,26,18,20,32,54,86,28,80,42,14,96,88,90,2,24,56,98,50,12,84,66,58,60,72,94,26,68,20,82,54,36,28,30,42,64,96,38,90,52,24,6,98,0,12,34,66,8,60,22,94,76,68,70,82,4,36,78,30,92,64,46,38,40,52,74,6,48
Level,doubleTest = (TAG_Double) 0.4931287132182315
Warning Due to the commas and equals sign in Level,byteArrayTest, this is not a valid norbert file. Using it with tools that implement the norbert format may yield unexpected results.
Note The Level,byteArrayTest tag might be split onto multiple lines depending on the format you are reading this documentation in. In a properly formatted norbert file, it should be on a single line.

See Also

The norbert project page is located at http://dmbuce.github.com/norbert/.

Authors

To see a full list of contributors, use git shortlog -s in the norbert git repository.