Skip to content
This repository has been archived by the owner on Aug 29, 2021. It is now read-only.

Commit

Permalink
feat(binary-nbt): prepare for publishing
Browse files Browse the repository at this point in the history
  • Loading branch information
Levertion committed Apr 6, 2019
1 parent 4737043 commit f1c8553
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 9 deletions.
122 changes: 119 additions & 3 deletions binary-nbt/README.md
@@ -1,7 +1,123 @@
# Binary NBT

A parser for the Minecraft nbt format
A serializer and deserializer for Minecraft's [NBT](https://wiki.vg/NBT)
archives with support for ergonomic roundtripping.

<!-- TODO: More docs -->
Roundtripping here means that a value can be deserialized from NBT and then
serialized back into exactly the same NBT value. Ergonomic means that the
deserialized value can be treated as a plain JavaScript object. E.g.
`level.Data.allowCommands` works as expected for a `level.dat` file. Other
libraries such as [`nbt`](https://www.npmjs.com/package/nbt) use custom objects,
e.g. `{value: <...>, type: TAG_COMPOUND}`.This is possible through the use of
ES6
[`Symbol`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol)s -
every deserialized object has `NBTTypeSymbol` applied to it, which is used in
serialisation (with sensible defaults for when this is not provided). This
approach
[also works for primitives](https://stackoverflow.com/questions/42560540/what-happens-when-i-object-assign-to-a-primitive-type-in-javascript).
The primary disadvantage of this approach is that the produced value cannot be
safely serialised into any form other than NBT without losing the data required
to reconstruct the NBT. However, if such serialisation is required, NBT can be
used as the format!

https://stackoverflow.com/questions/42560540/what-happens-when-i-object-assign-to-a-primitive-type-in-javascript
`TAG_LONG`s are deserialized as `Long`s from the
[`long`](https://www.npmjs.com/package/long) package.

This library currently only supports NodeJS 8 and 10. Other javascript
environments may be supported, should the need arise. Open an issue if you are
interested. We also only support big endian NBT, so the pocket edition nbt is
not yet supported

This package is part of the
[`mcfunction-langserver`](https://github.com/Levertion/mcfunction) project.

## Usage

Example:

```js
const { deserializeNBTUncompressed } = require("binary-nbt");
const fs = require("fs");

const contents = fs.readFileSync("some_nbt.nbt");
console.log(deserializeNBTUncompressed(contents));
```

Or in Typescript:

```ts
const { deserializeNBTUncompressed } = require("binary-nbt");
const fs = require("fs");

const contents = fs.readFileSync("level.dat");
const level: Level = deserializeNBTUncompressed(contents);
```

## Api

The full api is documented in the included typescript declaration files.

## Comparison with alternatives

This library is yet another NBT library amongst the wide selection of existing
JavaScript NBT libraries. A comparison with a selection of the others is below.
The primary advantages of this library are the use of `Promise`s, vanilla
JavaScript classes (e.g. `Number`, `String`) which can be treated as primitives
in most cases, and Typescript type definitions.

A brief rundown of the differences of other packages are below, in the order
they appear in when searching for
[`nbt` on npm](https://www.npmjs.com/search?q=nbt). For example, if they don't
support little endian nbt, no attention is brought to that fact as it is not a
difference from this package.

### [`nbt`](https://www.npmjs.com/package/nbt):

- Has a very desirable name on `npm`;
- Data can be safely serialised and deserialized into formats other than NBT;
- Supports the browser
- Has good [API documentation](http://sjmulder.github.io/nbt-js/), although
the following two points aren't well signposted;
- Every value is wrapped in an unwieldy
`{value: <actual value>, type: <type>}` object;
- `TAG_LONGS`s are encoded as an `[upper, upper]` number array, without any
convenience APIs;
- Doesn't have `Typescript` type definitions available;
- Doesn't use `Promise`s (this can be circumvented using `util.promisify`);

### [`prismarine-nbt`](https://www.npmjs.com/package/prismarine-nbt)

- Supports little endian NBT;
- Uses same format as `nbt` for longs and other values;
- Has weak API documentation and no `Typescript` type definitions;
- Doesn't use `Promise`s

### [`nbt-ts`](https://www.npmjs.com/package/nbt-ts)

- Uses `BigInt`s for longs, so only supports Node 10
- Custom classes must be used for numbers, so the value must be accessed using
the `value` property

### Excluded packages

Some packages are not up-to-date with the latest version of NBT or are not NBT
packages and so are excluded. These are:

- [`node-nbt`](https://www.npmjs.com/package/node-nbt),
[`mcnbt`](https://www.npmjs.com/package/mcnbt),
[`nbt-js`](https://www.npmjs.com/package/nbt-js),
[minecraft-nbt](https://www.npmjs.com/package/minecraft-nbt): No support for
`TAG_LONG_ARRAY`
- [`mc-schematic`](https://www.npmjs.com/package/mc-schematic),
[`minecraft-schematic`](https://www.npmjs.com/package/minecraft-schematic):
Not packages for arbritrary NBT data - provide a APIs for schematics.
- [`nibbit`](https://www.npmjs.com/package/nibbit),
[`nibbit-nolong`](https://www.npmjs.com/package/nibbit-nolong): No support
for longs or long arrays.
- [`nbtviewer`](https://www.npmjs.com/package/nbtviewer): An NBT cli, not a
package
- [`mcpe-anvil`](https://www.npmjs.com/package/mcpe-anvil): Just uses
`prismarine-nbt` internally.
- [`@nbxx/nb-table`](https://www.npmjs.com/package/@nbxx/nb-table),
[`nbtemplates`](https://www.npmjs.com/package/nbtemplates) and
[`nbtc`](https://www.npmjs.com/package/nbtc): Unrelated to Minecraft NBT
12 changes: 6 additions & 6 deletions binary-nbt/package.json
@@ -1,7 +1,7 @@
{
"name": "binary-nbt",
"version": "0.0.0",
"description": "A serialiser/deserialiser for the Minecraft NBT format",
"description": "A serializer and deserializer for Minecraft's NBT archives with support for ergonomic roundtripping.",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"scripts": {
Expand All @@ -27,17 +27,17 @@
"url": "https://github.com/Levertion/mcfunction/issues"
},
"devDependencies": {
"@types/node": "10.0.3",
"@types/long": "4.0.0",
"@types/mocha": "5.2.0",
"typescript": "3.4.1",
"@types/node": "10.0.3",
"mocha": "6.0.2",
"ts-mocha": "6.0.0",
"tslint": "5.14.0"
"tslint": "5.14.0",
"typescript": "3.4.1"
},
"dependencies": {
"tslib": "1.9.3",
"long": "4.0.0"
"long": "4.0.0",
"tslib": "1.9.3"
},
"homepage": "https://github.com/Levertion/mcfunction#readme",
"files": [
Expand Down
Binary file added binary-nbt/test/data/hello_world.nbt
Binary file not shown.

0 comments on commit f1c8553

Please sign in to comment.