{"id":24894949,"url":"https://github.com/synt4xerr0r4/syntaxnbt","last_synced_at":"2025-08-27T01:49:53.314Z","repository":{"id":167750180,"uuid":"469901639","full_name":"Synt4xErr0r4/syntaxnbt","owner":"Synt4xErr0r4","description":"A NBT and SNBT library for Java","archived":false,"fork":false,"pushed_at":"2023-05-21T00:52:00.000Z","size":59,"stargazers_count":6,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-22T07:04:58.670Z","etag":null,"topics":["java","mcr","minecraft","nbt","snbt"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Synt4xErr0r4.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-03-14T20:54:58.000Z","updated_at":"2025-05-16T09:25:14.000Z","dependencies_parsed_at":null,"dependency_job_id":"ada1d5db-c573-4011-b7d5-d9e658a2ab29","html_url":"https://github.com/Synt4xErr0r4/syntaxnbt","commit_stats":null,"previous_names":["synt4xerr0r4/syntaxnbt"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/Synt4xErr0r4/syntaxnbt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Synt4xErr0r4%2Fsyntaxnbt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Synt4xErr0r4%2Fsyntaxnbt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Synt4xErr0r4%2Fsyntaxnbt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Synt4xErr0r4%2Fsyntaxnbt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Synt4xErr0r4","download_url":"https://codeload.github.com/Synt4xErr0r4/syntaxnbt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Synt4xErr0r4%2Fsyntaxnbt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272277843,"owners_count":24905571,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-26T02:00:07.904Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","mcr","minecraft","nbt","snbt"],"created_at":"2025-02-01T19:15:10.742Z","updated_at":"2025-08-27T01:49:53.306Z","avatar_url":"https://github.com/Synt4xErr0r4.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SyntaxNBT [![javadoc](https://img.shields.io/endpoint?label=javadoc\u0026url=https%3A%2F%2Fjavadoc.syntaxerror.at%2Fsyntaxnbt%2F%3Fbadge%3Dtrue%26version%3Dlatest)](https://javadoc.syntaxerror.at/syntaxnbt/latest) ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/Synt4xErr0r4/syntaxnbt/maven.yml)\n\nA NBT and SNBT library for Java (17)\n\n## Overview\n\nThis is an implementation for serializing, deserializing, parsing, and stringifying NBTs (Named Binary Tags) by [Mojang Studios](https://mojang.com), according to this [specification](https://wiki.vg/NBT).\n\n## Getting started\n\nIn order to use the code, you can either [download the jar](https://github.com/Synt4xErr0r4/syntaxnbt/releases/download/1.0.0/syntaxnbt-1.0.0.jar), or use the Maven dependency:\n\n```xml\n\u003c!-- Repository --\u003e\n\n\u003crepository\u003e\n  \u003cid\u003esyntaxerror.at\u003c/id\u003e\n  \u003curl\u003ehttps://maven.syntaxerror.at\u003c/url\u003e\n\u003c/repository\u003e\n\n\u003c!-- Dependency --\u003e\n\n\u003cdependency\u003e\n  \u003cgroupId\u003eat.syntaxerror\u003c/groupId\u003e\n  \u003cartifactId\u003esyntaxnbt\u003c/artifactId\u003e\n  \u003cversion\u003e1.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nThe library itself is located in the module `syntaxnbt`.\n\n## Usage\n\nIn order to parse a binary NBT file or an SNBT string, you can use the [NBTUtil](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/NBTUtil.html) class:\n\n```java\nimport java.io.InputStream;\nimport at.syntaxerror.syntaxnbt.tag.TagCompound;\nimport at.syntaxerror.syntaxnbt.NBTUtil;\n\n// read NBT tag from a stream\ntry(InputStream stream = ...) {\n    TagCompound tag = NBTUtil.deserialize(stream);\n}\n\n// parse SNBT tag from a string\nTagCompound tag = NBTUtil.parse(\"...\");\n```\n\nThe other way around works analogously:\n\n```java\nimport java.io.OutputStream;\nimport at.syntaxerror.syntaxnbt.NBTUtil;\n\n// write NBT tag to a stream\ntry(OutputStream stream = ...) {\n    NBTUtil.serialize(null, stream, tag);\n}\n\n// convert SNBT tag to a string\nString snbt = NBTUtil.stringify(tag);\n\n// or alternatively:\nString snbt = tag.toString();\n```\n\nYou can also create tags by yourself:\n\n```java\nimport at.syntaxerror.syntaxnbt.tag.TagCompound;\n\nTagCompound tag = new TagCompound();\nTagList\u003cTagString\u003e list = new TagList\u003c\u003e(TagString.class);\nTagInt num = new TagInt(1337);\nTagByteArray array = new TagByteArray(new byte[] { 1, 2, 3 });\n```\n\n### Compounds\n\nCompound Tags are lists of named tags (basically a [`Map\u003cString, Tag\u003c?\u003e\u003e`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Map.html)).\nThey are implemented in the [`TagCompound`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagCompound.html) class,\nexposing the following methods:\n\n- `putX(String key, X value)` - associates the specified value with the specified key in this compound tag. An existing mapping will be overridden\n- `getX(String key)` - returns the value to which the specified key is mapped. Throws an exception if this map contains no mapping for the key\n- `remove(String key)` - removes the entry associated with the key from the map, if present.\n- `has(String key)` - returns true if this map contains a mapping for the specified key\n- `size()` - returns the number of key-value mappings in this compound tag\n- `clear()` - removes all of the mappings from this map\n\n`X` stands for any of the supported types (listed below). You can specify either tags (e.g. `putByteTag`)\nor values (e.g. `putByte`), which will automatically be wrapped around their respective tags.\n\nWhen `X` is unspecified, the untyped tags are used instead (e.g. `put(String key, Tag\u003c?\u003e value)`).\n\n### Lists\n\nList Tags are lists of unnamed tags ([`List\u003cTag\u003c?\u003e\u003e`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html)),\nonly capable of holding tags of the same type (specified by the generic type). This type can also be queried by using the\n[`getComponentType()`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagList.html#getComponentType()) method.\n\nIf the list is created via [`TagList.emptyList()`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagList.html#emptyList()),\nthe type of the list is determined by the first operation on the list involving types (e.g. `addByte`).\n\nLists are implemented in the [`TagList\u003c?\u003e`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagCompound.html) class,\nexposing the following methods:\n\n- `addX(X value)` - adds an element to the list\n- `addX(int index, X value)` - inserts an element at the specified position in the list\n- `setX(int index, X value)` - replaces an element at the specified position in the list\n- `getX(int index)` - returns the element at the specified position in this list\n- `remove(int index)` - removes the value at the specified position in the list\n- `size()` - returns the number of entries in the list\n- `clear()` - removes all entries from the list\n\nWhen `X` is unspecified, the generic type is used instead (e.g. `add(ByteTag value)` for `List\u003cByteTag\u003e`).\n\nWhen trying to add a tag that is not compatible with the other tags in the list, an exception is thrown.  \n  \nIn case you are dealing with a list of currently unknown type (`TagList\u003c?\u003e` or `TagList\u003cTag?\u003e\u003e`), you can\neasily cast the list to the desired type by using the `asXList()` methods. This does not create a new list\nand will throw an exception if the desired type is incompatible with the [`component type`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagList.html#getComponentType()).\n\n### Array\n\nArray Tags are arrays of values of the same type (`byte[]`, `int[]`, or `long[]`).\n\nThey are implemented in the\n[`TagByteArray`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagByteArray.html),\n[`TagIntArray`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagIntArray.html), and\n[`TagLongArray`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagLongArray.html)\nclasses, which are all sub-classes of [`TagArray`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagArray.html),\nexposing the following methods:\n\n- `add(Number value)`, `addTag(T value)` - adds an element to the array\n- `add(int index, Number value)`, `addTag(int index, T value)` - inserts an element at the specified position in the array\n- `set(int index, Number value)`, `setTag(int index, T value)` - replaces an element at the specified position in the array\n- `get(int index)` - returns the element at the specified position in this array\n- `remove(int index)` - removes the value at the specified position in the list\n- `size()` - returns the number of entries in the array\n- `clear()` - removes all entries from the array\n\n`T` stands for the tag-equivalent of elements in the array (e.g. for `TagByteArray`, `T` would be `TagByte`).\nHowever, not the tag itself is added to the array, only the value stored in this tag.\n\n## Tags\n\nThe NBT specification specifies the following tags:\n\nID | Name             | Java type | Implementation | Payload size (bytes) | Description\n-- | ---------------- | --------- | -------------- | -------------------- | ----------\n0  | `TAG_End`        | `void`    | [`TagEnd`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagEnd.html) | 0 | Signifies the end of a TAG_Compound. It is only ever used inside a TAG_Compound, and is not named despite being in a TAG_Compound\n1  | `TAG_Byte`       | `byte`    | [`TagByte`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagByte.html) | 1 | A single signed byte\n2  | `TAG_Short`      | `short`   | [`TagShort`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagShort.html) | 2 | A single signed, big endian 16 bit integer\n3  | `TAG_Int`        | `int`     | [`TagInt`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagInt.html) | 4 | A single signed, big endian 32 bit integer\n4  | `TAG_Long`       | `long`    | [`TagLong`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagLong.html) | 8 | A single signed, big endian 64 bit integer\n5  | `TAG_Float`      | `float`   | [`TagFloat`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagFloat.html) | 4 | A single, big endian [IEEE-754](http://en.wikipedia.org/wiki/IEEE_754-2008) single-precision floating point number ([NaN](http://en.wikipedia.org/wiki/NaN) possible)\n6  | `TAG_Double`     | `double`  | [`TagDouble`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagDouble.html) | 8 | A single, big endian [IEEE-754](http://en.wikipedia.org/wiki/IEEE_754-2008) double-precision floating point number ([NaN](http://en.wikipedia.org/wiki/NaN) possible)\n7  | `TAG_Byte_Array` | `byte[]`  | [`TagByteArray`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagByteArray.html) | 4+n | A length-prefixed array of **signed** bytes. The prefix is a **signed** integer (thus 4 bytes)\n8  | `TAG_String`     | `String`  | [`TagString`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagString.html) | 2+n | A length-prefixed [modified UTF-8 string](https://docs.oracle.com/javase/8/docs/api/java/io/DataInput.html#modified-utf-8). The prefix is an **unsigned** short (thus 2 bytes) signifying the length of the string in bytes\n9  | `TAG_List`       | `List\u003cTag\u003e` | [`TagList`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagList.html) | 5+x | A list of **nameless** tags, all of the same type. The list is prefixed with the Type ID of the items it contains (thus 1 byte), and the length of the list as a **signed** integer (a further 4 bytes). If the length of the list is 0 or negative, the type may be 0 (TAG_End) but otherwise it must be any other type. (The notchian implementation uses TAG_End in that situation, but another reference implementation by Mojang uses 1 instead; parsers should accept any type if the length is \u003c= 0).\n10 | `TAG_Compound`   | `Map\u003cString, Tag\u003e` | [`TagCompound`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagCompound.html) | 1+x | Effectively a list of a **named** tags. Order is not guaranteed.\n11 | `TAG_Int_Array`  | `int[]`   | [`TagIntArray`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagIntArray.html) | 4+4*n | A length-prefixed array of **signed** integers. The prefix is a **signed** integer (thus 4 bytes) and indicates the number of 4 byte integers.\n12 | `TAG_Long_Array` | `long[]`  | [`TagLongArray`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/tag/TagLongArray.html) | 4+8*n | A length-prefixed array of **signed** longs. The prefix is a **signed** integer (thus 4 bytes) and indicates the number of 8 byte longs.\n\n## NBT Paths\n\nAn NBT Path is used to specify a particular element from an NBT tree. A path consists of multiple nodes, each of\nwhich can be one of seven types (see [here](https://minecraft.fandom.com/wiki/NBT_path_format) for more information).\n\nPaths are parsed via `NBTUtil.parsePath(String path)`, which returns a [`PathNode`](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/path/pathNode.html). Inside this class, there is the `traverse(Tag\u003c?\u003e tag)` method, which returns a List of Tags. When this method is called,\nthe NBT tree is traversed and all elements matching the path pattern are returned.\n\n```java\nimport java.util.List;\nimport at.syntaxerror.syntaxnbt.tag.TagCompound;\nimport at.syntaxerror.syntaxnbt.tag.Tag;\nimport at.syntaxerror.syntaxnbt.path.PathNode;\nimport at.syntaxerror.syntaxnbt.NBTUtil;\n\n// ...\n\nString nbtString = \"{ foo: { bar: baz } }\";\nString pathString = \"foo{bar: baz}.bar\";\n\nTagCompound tag = NBTUtils.parse(nbtString);\nPathNode path = NBTUtils.parsePath(pathString);\n\n// contains a TAG_String with a value of \"baz\"\nList\u003cTag\u003c?\u003e\u003e result = path.traverse(tag);\n```\n\n## Region files\n\nYou can also read and write Minecraft's region files (typically named `r.X.Z.mcr`, where `X` and `Z` are the region coordinates).\nEach region file contains 32x32 chunks, which further each consist of 16x384x16 blocks. The chunks itself are stored as (compressed)\nNBT Tags, therefore the region files are basically similar to an array of NBT Tags, expect that they contain a 'last-modified' flag for each chunk.\n\nRegion file format:\n\nRange           | Type              | Size   | Purpose\n--------------- | ----------------- | ------ | -----------------------------------------------------------------------------\n`0x0000-0x0FFF` | `location[1024]`  | 4KiB   | Offset and size of each chunk in the file\n`0x1000-0x1FFF` | `timestamp[1024]` | 4KiB   | Array containing the time each chunk was last modified\n`0x1FFF-?`      | `chunk[1024]`     | varies | The actual chunk, stored as a chunk header followed by the (compressed) NBT tag\n\nChunk header format:\n\nRange       | Type             | Size     | Purpose\n----------- | ---------------- | -------- | -------\n`0x00-0x03` | `int`            | 4 bytes  | Length of the chunk data\n`0x04`      | `byte`           | 1 byte   | Compression scheme; `1` = gzip, `2` = zlib (default), `3` = uncompressed\n`0x05-X`    | `TagCompound`    | varies   | The chunk data itself\n`X-4096*n`  | `byte[4096*n-X]` | 4096*n-X | Padding, so that the next chunk lies on a 4KiB-page boundary\n\nThe [Region](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/region/Region.html) class implements regions,\nthe [Chunk](https://javadoc.syntaxerror.at/syntaxnbt/latest/syntaxnbt/at/syntaxerror/syntaxnbt/region/Chunk.html) class implements chunks.\n\nThey can either be created via their respective constructors or deserialized from a file; you can also serialize them:\n\n```java\nimport java.io.InputStream;\nimport at.syntaxerror.syntaxnbt.region.Region;\nimport at.syntaxerror.syntaxnbt.NBTUtil;\n\n// read Region from a stream\ntry(InputStream stream = ...) {\n    Region region = NBTUtil.deserializeRegion(stream);\n}\n\n// write Region to a stream\ntry(OutputStream stream = ...) {\n    NBTUtil.serializeRegion(stream, region);\n}\n```\n\nChunks can then be acquired by using the `getChunk(int x, int z)` method, where `x` and `z` are the relative\nchunk coordinates ranging from `0` to `31` (inclusive).\n\nIf you want to replace a chunk in a region, you can use the `setChunk(int x, int z, Chunk chunk)` method.\n\nThe compression scheme is defined by the Region object, but can be overridden for each Chunk individually (via `setCompression(NBTCompression scheme)`).\n\n## Limits\n\nBy default, only the first 512 layers of the `Tag\u003c?\u003e` structure are serialized/stringified.\nThis is added as a countermeasure to circular references, which would create an infinite\nloop and eventually cause a StackOverflowError, writing to a stream indefinitely or similar.  \nThis threshold, however, is configurable by modifying the `MAX_DEPTH` field in the `NBTUtil` class.\n\n## Documentation\n\nThe JavaDoc for the latest version can be found [here](https://javadoc.syntaxerror.at/syntaxnbt/latest).\n\n## License\n\nThis project is licensed under the [MIT License](https://github.com/Synt4xErr0r4/syntaxnbt/blob/main/LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynt4xerr0r4%2Fsyntaxnbt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsynt4xerr0r4%2Fsyntaxnbt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynt4xerr0r4%2Fsyntaxnbt/lists"}