Skip to content

Latest commit

 

History

History
295 lines (244 loc) · 12.5 KB

format.md

File metadata and controls

295 lines (244 loc) · 12.5 KB

NBTDoc Format

The NBTDoc format is a format for documenting NBT structures. It has many similarities to Rust's type definitions.

Syntax Syntax

Symbol Meaning
str literal
A* A zero or more times
A+ A one or more times
A? A zero or one times
A | B Either A or B
[ A B C ] One of the literals A, B, or C
[ A-Z ] Any literal from A to Z
( A ) General grouping
NAME A referenced token rule
Name A referenced parser rule
\n A line ending

File Structure

An NBTDoc file is made up of a list of compound definitions, enum definitions, module declarations, use clauses, and describes clauses.

The Following Section describes syntax in two forms. the syntax preceded with SYNTAX (TOKEN) cannot have any whitespace or tokens in between the indiviual "rules". The syntax preceded with SYNTAX can have whitespace and standard comments (starting with //, but not ///, and going until the end of the line). The full file has this syntax:

SYNTAX
File:
    (
      CompoundDef
    | EnumDef
    | ModDecl
    | UseClause
    | DescribeClause
    | InjectClause
    )*

Common Syntax

Identifier

SYNTAX (TOKEN)
IDENT:
    [ A-Z a-z _ ] [ A-Z a-z 0-9 _ ]*

An identifier is the main form of names in the NBTDoc format.

Identifier Path

SYNTAX (TOKEN)
IDENT_PATH:
    ( :: )? ( IDENT | super ) ( :: ( IDENT | super ) )*

An identifier path is the way to reference items from another module. If it starts with ::, the resultant path will start at the global root, not the "crate" root. When one of the parts of the path is super, it will reference the parent module.

Minecraft Identifier

SYNTAX (TOKEN)
MINECRAFT_IDENT:
    [ a - z _ - ]* : [ a-z _ - ]* ( / [ a-z _ - ]* )*

Minecraft identifiers are just namespaced paths, just like the namespaced resource path in minecraft

Integer

SYNTAX (TOKEN)
INTEGER:
    0 | -? [ 1-9 ] [ 0-9 ]*

A signed integer

Float

SYNTAX (TOKEN)
FLOAT:
    -? [ 0-9 ]+ FLOAT_EXPONENT?
  | -? [ 0-9 ]* . [ 0-9 ]+ FLOAT_EXPONENT?

FLOAT_EXPONENT:
    [ e E ] [ - + ]? [ 0-9 ]+

A signed floating point number

String

SYNTAX (TOKEN)
STRING:
    " ( ~[ " \ UNICODE_CC ] | \ [ b n f r t \ " ] )* "

A string literal. Cannot contain any control characters (UNICODE_CC). Can be escaped with a \, and the valid escape characters are \b, \n, \f, \r, t, \\, \".

Doc Comment

SYNTAX
DocComments:
    DOC_COMMENT*

SYNTAX (TOKEN)
DOC_COMMENT:
    /// ~[ \n ]* ( \n | EOF )

Doc comments are the way to attatch descriptions to parts of the format. Each doc comment takes up the whole line, and multiple will get concatenated together to make the description. Doc comments should use Markdown for syntax, but don't have to

Compound Definition

SYNTAX
CompoundDef:
    DocComments compound IDENT ExtendClause? { CompoundFields? }

ExtendClause:
    extends ( IDENT_PATH | REGISTRY_INDEX )

CompoundField:
    DocComments KEY ?? : FieldType

CompoundFields:
    CompoundField ( , CompoundField )*

SYNTAX (TOKEN)
KEY:
    IDENT | STRING

Compound Definitions are the way to describe patterns of compound tags. The compound itself can have doc comments, and each field can have doc comments. The extends clause is used to create inheritance, and it can be another named compound or a registry index. Each key can be an identifer, or a string in the case that the NBT key cannot be expressed as an identifier.

Field Type

SYNTAX
FieldType:
   byte IntRange [ ] UnsignedRange     // Byte Array
  | int IntRange [ ] UnsignedRange     // Int Array
  | long IntRange [ ] UnsignedRange     // Long Array
  | boolean     // Byte (0b or 1b)
  | byte IntRange     // Byte
  | short IntRange     // Short
  | int IntRange     // Int
  | long IntRange     // Long
  | float FloatRange     // Float
  | double FloatRange     // Double
  | string     // String
  | [ FieldType ] UnsignedRange     // List
  | RegistryIndex     // Compound (dynamically indexed)
  | id ( MINECRAFT_IDENT )     // String (with id validation)
  | IDENT_PATH     // Compound or Enum
  | ( ( FieldType ( | FieldType )* )? )     // Union type

IntRange:
    @ ( INTEGER .. INTEGER?
  | ..? INTEGER )

UnsignedRange:
    @ ( ( 0 | [ 1-9 ] [ 0-9 ] * ) .. ( 0 | ( [ 1-9 ] [ 0-9 ] * ) )?
  | ..? ( 0 | [ 1-9 ][ 0-9 ] )* )

FloatRange:
    @ ( FLOAT .. FLOAT?
  | ..? Float )

Field Types

The field types describes all of the available NBT types.
All of the array types have an integer range and a natural range. The integer is range is the range which all of the items have to be within, and the natural range is the range of the length of the list.
The byte, short, int, long, float, and double all have their respective ranges that the value must be within.
The list type contains another field type, which is the lists item, and a natural range which the length of the list must be within.
The dynamically indexed compound accesses the registry specified by the Minecraft identifier with the ID at the path described in the square brackets.
The string with id validation must be a valid minecraft identifier and must be in the registry described by the Minecraft identifier in the parenthesis.
The compound or enum is just the name of a compound or enum. It can be defined in the current file or in another file, with it being accessed by the indentifier path. If the item that the name points to is a compound, the value should be a compound, otherwise if the item is an enum, the type of the value should be the type of the enum. The union type allows for a field that can have different types. These types must be distinguishable. If the union type has no field types inside of it, it signifies that the field does not exist.

Ranges

The ranges are almost identical to minecraft's range syntax. They are preceded with an @, and they can be in one of the four forms:

  • VALUE_1 .. VALUE_2 - VALUE_1 <= x <= VALUE_2
  • VALUE .. - VALUE <= x
  • .. VALUE - x <= Value
  • VALUE - x = Value

Note that these ranges are always inclusive.
There are 3 types of ranges

  • Integer ranges, where the values may be signed integers.
  • Unsigned integer ranges, where the values may be unsigned integers.
  • Float ranges, where the values may be signed floating point numbers.
Registry Index

SYNTAX
RegistryIndex:
    MINECRAFT_IDENT [ FIELD_PATH ]

SYNTAX (TOKEN)
FIELD_PATH:
    FIELD_PATH_KEY ( . FIELD_PATH_KEY )*

FIELD_PATH_KEY:
    super | IDENT | STRING

Registry indexes are the way to get dynamic data. They can be used as a field value or in a compound's extends clause. When the field path key is super the current tag's parent will be accessed.

Enum Definition

SYNTAX
EnumDef:
    DocComments enum ( ENUM_TYPE ) IDENT { EnumField ( , EnumField )* }

EnumField:
    DocComments IDENT = INTEGER | FLOAT | STRING

SYNTAX (TOKEN)
ENUM_TYPE:
    byte | short | int | long | string | float | double

Enums are the primary way to associate limited data with understandable names. Each enum has a number of fields that the value must be one of. The data of the enum must match the type of the enum.

  • byte - integer
  • short - integer
  • int - integer
  • long - integer
  • string - string
  • float - float
  • double - float

If a value has an invalid type it will not parse

Module Declaration

SYNTAX
ModDecl:
    mod IDENT ;

Module declarations describe what children modules this module has. If this current file is a mod.nbtdoc file, then the children will be accessed as siblings (in ./). If this file has another name (ex.nbtdoc), then all of the children modules will be checked for in ./ex/.
The name of the file is the identifier in the delcaration. For a mod IDENT;, if IDENT.nbtdoc cannot be found, then the file IDENT/mod.nbtdoc will be read from.

Use Clause

SYNTAX
UseClause:
    export? use IDENT_PATH ;

The use clause is the recommended way to import external names. The target must be a compound or an enum. If the export keyword is in front, then the imported name will be re-exported along with the rest of the names in this file. This is primarily useful for utility modules.

Describe Clause

SYNTAX
DecribeClause:
    IDENT_PATH describes MINECRAFT_IDENT ( [ MINECRAFT_IDENT ( , MINECRAFT_IDENT )* ] )? ;

The describe clause is the way to interface between the compound definitions and registrys. The ident path is the name of the target item,which will be the one associated with the objects inside the registry specified by the Minecraft identifier outside the sqaure brackets. The Minecraft identifiers inside the square brackets will be mapped to the specified compound. If the square brackets and idenitifers inside of them are not present, the specified compound will be used as the default for the registry.

Inject Clause

SYNTAX
InjectClause:
    inject ( CompoundInject | EnumInject )

CompoundInject:
    compound IDENT_PATH { CompoundFields? }

EnumInject:
    enum ( ENUM_TYPE ) IDENT_PATH { EnumField ( , EnumField )* }

The inject clause gives support for injecting data into other items. The specified fields will be inserted to the targeted item. The item targeted does not have to be loaded in yet, and injects will be loaded retroactively. If two injects target the same item, the order they will be applied is not defined, and modules should avoid injecting to the same place twice. The injected field will always overwrite the source field however.