Documentation
¶
Overview ¶
Package nbt implements encoding and decoding of Minecraft's Named Binary Tag (NBT) format, as used by Java Edition for level data, player data and structure (.nbt) files.
The API is modeled on encoding/json. Go values are converted to and from NBT with Marshal and Unmarshal, or streamed with Encoder and Decoder. Struct fields are mapped with `nbt:"name,opts"` tags.
When the shape of the data is not known ahead of time, decode into a Tag (or an empty interface) to get a tree of Compound, List, Int, ... values, much like decoding JSON into map[string]any.
Type mapping ¶
Go values are encoded as follows:
bool Byte (0 or 1) int8, uint8 Byte int16, uint16 Short int32, uint32 Int int, uint Int (an error if the value does not fit) int64, uint64 Long float32 Float float64 Double string String []byte, []int8 ByteArray []int32, []uint32 IntArray []int64, []uint64 LongArray other slices and arrays List (elements must all encode to the same type) map[string]T Compound struct Compound pointer, interface the value pointed to; nil is omitted
The "list" tag option forces a byte, int or long slice to be encoded as a List instead of an array, which some Minecraft formats require (for example the "pos" field in structure files is a List of Int):
Pos [3]int32 `nbt:"pos,list"`
NBT has no null value, so nil pointers, interfaces and maps-of-nothing are left out of the enclosing compound rather than written as an empty value.
Decoding is lenient in the same way encoding/json is: any integer tag can be decoded into any Go integer (or bool) as long as the value fits, any numeric tag into a float, arrays and lists into slices, and unknown compound keys are ignored unless Decoder.DisallowUnknownFields is set.
Compression ¶
Unmarshal and Decoder detect gzip and zlib compressed input automatically. Encoder.SetCompression selects compression when writing; Java Edition structure files are gzip compressed.
SNBT ¶
Every Tag formats itself as stringified NBT (the syntax used by commands such as /data and /give) via its String method, and ParseSNBT, MarshalSNBT and UnmarshalSNBT convert in the other direction.
Example ¶
package main
import (
"fmt"
"log"
"github.com/MinecraftMetascript/nbt-go"
)
type Item struct {
Slot int8 `nbt:"Slot"`
ID string `nbt:"id"`
Count int32 `nbt:"count"`
}
type Chest struct {
CustomName string `nbt:"CustomName,omitempty"`
Items []Item `nbt:"Items"`
}
func main() {
chest := Chest{Items: []Item{{Slot: 0, ID: "minecraft:diamond", Count: 3}}}
data, err := nbt.Marshal(chest)
if err != nil {
log.Fatal(err)
}
var decoded Chest
if err := nbt.Unmarshal(data, &decoded); err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", decoded)
}
Output: {CustomName: Items:[{Slot:0 ID:minecraft:diamond Count:3}]}
Index ¶
- Constants
- func Equal(a, b Tag) bool
- func FromTag(t Tag, v any) error
- func Marshal(v any) ([]byte, error)
- func MarshalSNBT(v any) (string, error)
- func Matches(pattern, t Tag) bool
- func Quote(s string) string
- func Unmarshal(data []byte, v any) error
- func UnmarshalSNBT(s string, v any) error
- type Byte
- type ByteArray
- type Compound
- type Compression
- type Decoder
- type Double
- type Encoder
- type Float
- type Int
- type IntArray
- type InvalidUnmarshalError
- type List
- type Long
- type LongArray
- type Marshaler
- type MarshalerError
- type Path
- type PathError
- type SNBTSyntaxError
- type Short
- type String
- type SyntaxError
- type Tag
- type TagType
- type UnknownFieldError
- type UnmarshalTypeError
- type Unmarshaler
- type UnsupportedTypeError
Examples ¶
Constants ¶
const MaxDepth = 512
MaxDepth is the maximum nesting depth of lists and compounds accepted when reading, matching Minecraft's own limit.
Variables ¶
This section is empty.
Functions ¶
func Equal ¶
Equal reports whether two tags have the same type and value. An empty list or array equals a nil one of the same type, and compound entries holding nil are ignored, as they are when encoding.
func FromTag ¶
FromTag stores t in the value pointed to by v, using the same rules as Unmarshal. It is the inverse of ToTag.
func Marshal ¶
Marshal returns the uncompressed binary NBT encoding of v, written as a root tag with an empty name (as Java Edition does for structure and level files). Use an Encoder to set the root name or compress the output.
v is normally a struct or map, giving a TAG_Compound root. See the package documentation for how Go values map to NBT.
func MarshalSNBT ¶
MarshalSNBT returns the stringified NBT (SNBT) form of v, the syntax used by Minecraft commands such as /data and /give. Compound keys are sorted so the output is deterministic.
func Matches ¶
Matches reports whether t matches pattern the way a path's {k:v} does: a compound matches when it has every key of the pattern with a matching value, a list when every element of the pattern matches some element of it (an empty pattern list only matches an empty list), and other tags when they are equal. A nil pattern matches anything.
func Quote ¶
Quote returns s as a quoted SNBT string, the way Minecraft writes one. The quote is '"' unless a quote character appears in s, in which case it is the other kind from the first one found, so `say "hi"` becomes 'say "hi"'. Backslashes, the chosen quote and control characters are escaped (\n, \t, \x01, ...), so the result is always one line.
func Unmarshal ¶
Unmarshal parses binary NBT data and stores the result in the value pointed to by v. Gzip and zlib compressed data is detected and decompressed automatically. The root tag's name is ignored; use a Decoder to read it.
v may be a pointer to a struct or map (for a compound root), to a Tag or empty interface (to get the raw tree), or to any other type compatible with the root tag. See the package documentation for the conversion rules.
Example (Tree) ¶
package main
import (
"fmt"
"log"
"github.com/MinecraftMetascript/nbt-go"
)
func main() {
data, _ := nbt.Marshal(map[string]any{
"pos": []float64{1.5, 64, -3},
"name": "Steve",
})
// Decode into a Tag (or any) when the shape isn't known up front.
var tree nbt.Tag
if err := nbt.Unmarshal(data, &tree); err != nil {
log.Fatal(err)
}
c := tree.(nbt.Compound)
fmt.Println(c["name"], c["pos"].Type())
fmt.Println(tree)
}
Output: "Steve" TAG_List {name:"Steve",pos:[1.5d,64d,-3d]}
Types ¶
type Byte ¶
type Byte int8
Byte is a TAG_Byte, a signed 8-bit integer. Minecraft also uses it for booleans.
type Compound ¶
Compound is a TAG_Compound: a set of uniquely named tags. Key order is not significant in NBT; SNBT output sorts keys.
type Compression ¶
type Compression int
Compression selects how an Encoder compresses its output.
const ( // None writes uncompressed NBT. This is the default. None Compression = iota // Gzip writes gzip-compressed NBT, the format of Java Edition .nbt // structure files, level.dat and player data. Gzip // Zlib writes zlib-compressed NBT, as used for chunks in region files. Zlib )
func (Compression) String ¶
func (c Compression) String() string
type Decoder ¶
type Decoder struct {
// contains filtered or unexported fields
}
A Decoder reads NBT values from an input stream.
func NewDecoder ¶
NewDecoder returns a new decoder that reads from r. Gzip or zlib compression is detected from the first bytes of the stream.
The decoder may read data from r beyond the NBT values requested.
func (*Decoder) Compression ¶
func (d *Decoder) Compression() Compression
Compression reports the compression detected on the stream. It is only meaningful after the first call to Decode or DecodeTag.
func (*Decoder) Decode ¶
Decode reads the next root tag from the stream and stores it in the value pointed to by v. See Unmarshal for details of the conversion. It returns io.EOF when the stream has no more values.
func (*Decoder) DecodeTag ¶
DecodeTag reads the next root tag from the stream and returns it as a tree. It returns io.EOF when the stream has no more values.
func (*Decoder) DisallowUnknownFields ¶
func (d *Decoder) DisallowUnknownFields()
DisallowUnknownFields causes Decode to return an UnknownFieldError when a compound contains a key that does not match any field of the destination struct.
type Encoder ¶
type Encoder struct {
// contains filtered or unexported fields
}
An Encoder writes NBT values to an output stream.
Example (Gzip) ¶
package main
import (
"bytes"
"fmt"
"log"
"github.com/MinecraftMetascript/nbt-go"
)
func main() {
var buf bytes.Buffer
enc := nbt.NewEncoder(&buf)
enc.SetCompression(nbt.Gzip)
if err := enc.Encode(map[string]int32{"DataVersion": 3955}); err != nil {
log.Fatal(err)
}
// Decoders detect compression on their own.
dec := nbt.NewDecoder(&buf)
var v struct{ DataVersion int32 }
if err := dec.Decode(&v); err != nil {
log.Fatal(err)
}
fmt.Println(v.DataVersion, dec.Compression())
}
Output: 3955 gzip
func NewEncoder ¶
NewEncoder returns a new encoder that writes to w.
func (*Encoder) Encode ¶
Encode writes the NBT encoding of v to the stream as a named root tag. See Marshal for details of the conversion.
func (*Encoder) SetCompression ¶
func (e *Encoder) SetCompression(c Compression)
SetCompression sets the compression applied to each value written. With Gzip or Zlib, every call to Encode writes one complete compressed stream.
func (*Encoder) SetRootName ¶
SetRootName sets the name written for the root tag. It defaults to the empty string, which is what Java Edition uses.
type InvalidUnmarshalError ¶
An InvalidUnmarshalError describes an invalid argument passed to Unmarshal. The argument must be a non-nil pointer.
func (*InvalidUnmarshalError) Error ¶
func (e *InvalidUnmarshalError) Error() string
type List ¶
type List []Tag
List is a TAG_List. All elements must have the same type. An empty List is written with element type TAG_End, as Minecraft does.
type MarshalerError ¶
A MarshalerError wraps an error returned by a MarshalNBT method.
func (*MarshalerError) Error ¶
func (e *MarshalerError) Error() string
func (*MarshalerError) Unwrap ¶
func (e *MarshalerError) Unwrap() error
type Path ¶
type Path struct {
// contains filtered or unexported fields
}
A Path is an NBT path, the syntax commands such as /data and /execute use to point into NBT: foo.bar[0]."a key"[{id:"x"}]. Parse one with ParsePath.
A path is a list of nodes, each of which selects tags inside the ones the previous node selected:
{k:v} the root, if it matches the compound (only first)
name the compound child name; quote it ("a b") if it has
spaces, quotes, dots or brackets
name{k:v} the child name, if it is a compound that matches
[n] the list or array element n; negative n counts from the end
[] every element of a list or array
[{k:v}] every element of a list that is a compound that matches
A compound matches a pattern when it has every key of the pattern, each with a matching value: compounds match recursively, a list matches if every element of the pattern matches some element of it (an empty pattern list only matches an empty list), and anything else must be equal. This is how Minecraft compares them.
Example ¶
package main
import (
"fmt"
"log"
"github.com/MinecraftMetascript/nbt-go"
)
func main() {
root := nbt.Compound{}
p := nbt.MustParsePath(`Items[{Slot:0b}].count`)
n, err := p.Set(root, nbt.Int(5))
if err != nil {
log.Fatal(err)
}
fmt.Println(n, root)
fmt.Println(p.Get(root))
nbt.MustParsePath("Items[0]").Remove(root)
fmt.Println(root)
}
Output: 1 {Items:[{Slot:0b,count:5}]} [5] {Items:[]}
func MustParsePath ¶
MustParsePath is like ParsePath but panics if the path is invalid.
func ParsePath ¶
ParsePath parses an NBT path such as Inventory[0].components."minecraft:custom_data".
func (Path) Get ¶
Get returns the tags the path selects in root, in order. It returns none, not an error, when nothing matches.
func (Path) Modify ¶
Modify calls f with each tag the path selects in root, creating them the way Path.Set does with create if they are missing (create is then called for the new tag, and may be nil to create nothing). The tag f returns replaces the old one. Modify returns how many tags f was called for.
It is how /data modify ... append and merge work: Modify with create returning an empty List, appending in f.
func (Path) Remove ¶
Remove deletes every tag the path selects in root and returns how many it removed. A path that selects the root itself removes nothing.
func (Path) Set ¶
Set replaces every tag the path selects in root with a copy of v, and returns how many it changed: a tag already equal to v does not count, so a 0 is how /data modify ... set fails with "Nothing changed".
Compounds and lists missing on the way are created, as the game does: name creates a compound (or a list if the next node indexes one), name{k:v} creates a copy of its pattern, [{k:v}] adds one to an empty or unmatched list, and [] adds an element to an empty list. An index past the end of a list creates nothing.
root is changed in place, so it must be a Compound (or a path that starts below its root); Set returns an error if a list or array would end up holding mixed types.
type PathError ¶
type PathError struct {
Path string
Offset int // byte offset in Path, for a syntax error; -1 otherwise
// contains filtered or unexported fields
}
A PathError reports a path that cannot be parsed, or an operation a path cannot do.
type SNBTSyntaxError ¶
type SNBTSyntaxError struct {
Offset int // byte offset in the input
// contains filtered or unexported fields
}
An SNBTSyntaxError describes malformed SNBT.
func (*SNBTSyntaxError) Error ¶
func (e *SNBTSyntaxError) Error() string
type SyntaxError ¶
type SyntaxError struct {
Offset int64 // bytes read before the error occurred
// contains filtered or unexported fields
}
A SyntaxError describes malformed binary NBT.
func (*SyntaxError) Error ¶
func (e *SyntaxError) Error() string
type Tag ¶
type Tag interface {
// Type reports the wire type of the tag.
Type() TagType
String() string
// contains filtered or unexported methods
}
Tag is an NBT value. The concrete types are Byte, Short, Int, Long, Float, Double, ByteArray, String, List, Compound, IntArray and LongArray. The set is closed: other packages cannot implement Tag.
The String method of every Tag returns its SNBT representation.
func ParseSNBT ¶
ParseSNBT parses a single SNBT value, such as
{Items:[{Slot:0b,id:"minecraft:diamond",count:3}],CustomName:'"Loot"'}
Unquoted values are typed the way Minecraft types them: 1b is a Byte, 1s a Short, 1 an Int, 1L a Long, 1.5f a Float, 1.5 or 1.5d a Double, true and false are Bytes, and anything else is a String.
Example ¶
package main
import (
"fmt"
"log"
"github.com/MinecraftMetascript/nbt-go"
)
type Item struct {
Slot int8 `nbt:"Slot"`
ID string `nbt:"id"`
Count int32 `nbt:"count"`
}
type Chest struct {
CustomName string `nbt:"CustomName,omitempty"`
Items []Item `nbt:"Items"`
}
func main() {
tag, err := nbt.ParseSNBT(`{Items:[{Slot:0b,id:"minecraft:diamond",count:3}]}`)
if err != nil {
log.Fatal(err)
}
var chest Chest
if err := nbt.FromTag(tag, &chest); err != nil {
log.Fatal(err)
}
fmt.Println(chest.Items[0].ID, chest.Items[0].Count)
}
Output: minecraft:diamond 3
type TagType ¶
type TagType byte
TagType identifies the type of an NBT tag as it appears on the wire.
const ( TagEnd TagType = 0 TagByte TagType = 1 TagShort TagType = 2 TagInt TagType = 3 TagLong TagType = 4 TagFloat TagType = 5 TagDouble TagType = 6 TagByteArray TagType = 7 TagString TagType = 8 TagList TagType = 9 TagCompound TagType = 10 TagIntArray TagType = 11 TagLongArray TagType = 12 )
The NBT tag types, with their on-the-wire IDs.
type UnknownFieldError ¶
An UnknownFieldError is returned when Decoder.DisallowUnknownFields is set and a compound has a key with no matching struct field.
func (*UnknownFieldError) Error ¶
func (e *UnknownFieldError) Error() string
type UnmarshalTypeError ¶
type UnmarshalTypeError struct {
Tag TagType // the NBT type that was found
Type reflect.Type // the Go type it could not be assigned to
Path string // dotted path of the offending value, e.g. "blocks[3].pos"
Value string // optional detail, e.g. the overflowing number
}
An UnmarshalTypeError describes an NBT tag that could not be stored in a Go value of a particular type.
func (*UnmarshalTypeError) Error ¶
func (e *UnmarshalTypeError) Error() string
type Unmarshaler ¶
Unmarshaler is implemented by types that can set themselves from a Tag.
type UnsupportedTypeError ¶
An UnsupportedTypeError is returned by Marshal when asked to encode a value of a type that has no NBT representation, such as a channel or func.
func (*UnsupportedTypeError) Error ¶
func (e *UnsupportedTypeError) Error() string
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
nbt-mcp
module
|
|
|
Package structure reads, writes and builds Minecraft Java Edition structure files: the gzip-compressed .nbt files saved by structure blocks and loaded by /place template or data packs.
|
Package structure reads, writes and builds Minecraft Java Edition structure files: the gzip-compressed .nbt files saved by structure blocks and loaded by /place template or data packs. |