JsonNBT - DaFuqs/Spectrum GitHub Wiki
For anyone who's dealt with loot tables and predicates for long enough, you know the pain of writing SNBT. Single-line, frequent escaping, the nightmare of unmatching brackets... well, no more! Introducing:
JsonNBT
This is a custom format that Spectrum is using to simplify writing NBT in Json files. However, it does have a few constraints, which are noted below. Spectrum also accepts standard SNBT to maintain compatability.
Format
NBTByte
Bytes (8-bit signed values) are represented as Json strings, with the format "[0-9]+[bB]"
. Additionally, the boolean values true
and false
map to 1b
and 0b
, respectively. For example:
{
"NBTBytes": [
"127b",
"-128B",
true,
false
]
}
NBTShort
Shorts (16-bit signed values) are represented as Json strings, with the format "[0-9]+[sS]"
. For example:
{
"NBTShorts": [
"32767s",
"-32768S"
]
}
NBTInt
Integers (32-bit signed values) are represented as Json numbers, with the format [0-9]+
. As mentioned in Limitations, decimal points are also valid as long as the number is whole. Additionally, to help with specificity, JsonNBT interprets "[0-9]+[iI]"
as integers as well. For example:
{
"NBTInts": [
"2147483647i",
"-2147483648I",
12,
-3.00
]
}
NBTLong
Longs (64-bit signed values) are represented as Json strings, with the format "[0-9]+[lL]"
. For example:
{
"NBTLongs": [
"9223372036854775807l",
"-9223372036854775808L"
]
}
NBTFloat
Floats (32-bit floating-point values) are represented as Json strings, with the suffix f
or F
. For example:
{
"NBTFloats": [
"3.40282346639e+38f",
"-3.40282346639E+38F"
]
}
NBTDouble
Doubles (64-bit floating-point values) are represented as Json strings, with the suffix d
or D
. Additionally, Json numbers that have a fractional component or are larger than an integer will be parsed as a double. For example:
{
"NBTDoubles": [
"1.7976931348623157e+308d",
"-1.7976931348623157E+308D",
0.5,
1000000000000
]
}
NBTString
Strings are represented as Json strings, when none of the other formats apply. For example:
{
"NBTStrings": [
"Hello, world!",
"This is a string"
]
}
NBTList
Lists are represented as Json arrays. Note that each element in the array must be parsed to the same NBT type. For example:
{
"NBTList": [
"1b",
"2b",
true
]
}
NBTCompound
Compounds are represented as Json objects. The only difference from SNBT is that the keys are quoted. For example:
{
"NBTCompound": {
"key1": "value1",
"key2": "value2"
}
}
NBTByteArray
Byte arrays are the same as a list of bytes, but with the first element being "B;". For example:
{
"NBTByteArray": [
"B;",
"1b",
"2b",
true
]
}
NBTIntArray
Int arrays are the same as a list of integers, but with the first element being "I;". For example:
{
"NBTIntArray": [
"I;",
30,
171,
-10
]
}
NBTLongArray
Long arrays are the same as a list of longs, but with the first element being "L;". For example:
{
"NBTLongArray": [
"L;",
"12135L",
"-43L"
]
}
Limitations
Unfortunately, since Json is less specific than SNBT, this format is not without its limitations. Specifically, since strings are being used to add type information, it's possible that a string may be interpreted as a number even when you don't want it to. Of course, it's unlikely that you'll be using strings such as "B;"
and "13d"
, and we still support standard SNBT in that case.
Another limitation is that some NBT contains Json within itself (e.g. CustomName
), which currently must be expressed in a string. We may revisit this in the future, but for now, the complexity isn't worth it.
Also, since Json doesn't differentiate between integers and floating-point numbers, there isn't a good way to handle plain numbers. We currently just check if it can fit into an integer, so both 123
and 1.0
are integers, but 0.5
and 1000000000000
are doubles. If your number is ambiguous, you can specify its type explicitly via a string with the i/I
and d/D
suffixes.
Suggestions
If you have any suggestions, please feel free to mention them! This format is meant to simplify things in Minecraft's increasingly data-driven model, so any feedback is appreciated.