What a .def describes
A definition maps packet bytes to named JavaScript object fields. The protocol map associates a packet name with a numeric opcode; .def specifies its layout. These are separate inputs: a correct opcode does not guarantee a correct layout version.
Filenames follow S_EXAMPLE.1.def: message name, definition number, extension. A layout change gets a new version while needed older versions remain available. Definition versions are not game patch numbers. The original format specification lives in the tera-data repository.
Syntax
A line contains a type and field name. # starts a comment. Each leading hyphen adds one nesting level. Spaces align text but do not create nesting themselves.
uint32 sequence
object position
- vec3 loc
- angle w
array entries
- uint32 id
- string label
This teaching example produces event.sequence, event.position.loc, event.position.w and an event.entries array of { id, label } objects. object groups JavaScript properties without adding a binary header. Do not use this as a real packet definition without checking its bytes.
Field types
| Type | Representation |
|---|---|
bool |
Boolean, one byte |
byte |
Unsigned 8-bit integer |
int16, int32 |
Signed integer Number |
uint16, uint32 |
Unsigned integer Number |
int64, uint64 |
64-bit integer BigInt |
float, double |
32/64-bit floating-point Number |
angle |
16-bit wire angle, radians in JavaScript |
vec3 |
Three floating-point coordinates; a Vec3 object |
vec3fa |
Three angle-format components converted to radians |
skillid, skillid32 |
Packed skill identifier with decoded properties |
customize |
Packed appearance properties |
string |
Null-terminated UTF-16LE text |
bytes |
Variable-length byte buffer |
array |
Array of objects with nested fields |
array<type> |
Array of values of the specified primitive type |
object |
Logical grouping of nested fields |
skillid occupies 64 bits in newer layouts; skillid32 occupies 32 bits in older ones. Choose according to the packet layout. A skill object exposes id, type, npc, huntingZoneId, reserved, plus equals, clone and toString. Do not replace it with a whole number without accounting for packing. For 64-bit IDs, use literals such as 0n rather than 0 where a BigInt operation is required.
Header and byte order
An ordinary packet begins with a uint16 total length including the header and a uint16 opcode. Do not list these four bytes in the definition. Numeric fields are little-endian. Transport and integrity details are handled by the networking layer; .def describes the layout exposed to the parser.
References to variable data
Strings, arrays and byte blocks require metadata. By default, the parser inserts references before ordinary fields at the corresponding level:
| Field | Metadata |
|---|---|
array |
uint16 element count, then uint16 offset |
bytes |
uint16 offset, then uint16 length |
string |
uint16 offset |
Offsets are measured from the start of the packet, including its header. The serializer calculates offsets and counts; you do not add them manually to event.
Explicit ref
If a real packet places reference metadata elsewhere, insert ref fieldName at that position. Explicit references disable the automatic mode for the definition: provide references for every string, array and bytes field. A reference into a nested object can use a dotted path such as position.name.
uint32 sequence
ref entries
array entries
- uint32 id
Here the array count and offset follow sequence. Without ref, they would precede it. Do not accidentally mix explicit and implicit references. Historical count/offset syntax is recognized for compatibility; use ref for new definitions.
Array layout
Each ordinary array element begins with two implicit uint16 values: its own offset (here) and the next element's offset (next). The final next is zero. Element fields follow them. Nested arrays and strings have their own references. A protocol array is therefore a chain of elements, not necessarily a contiguous sequence of fixed-size records.
# Logical definition
uint32 sequence
array entries
- uint16 value
# Layout: header, entries count/offset, sequence,
# then array nodes: here, next, value
Validating a definition
Check packet length, field order, hyphen nesting and reference placement. Compare parsing and serialization against known packets from the target server. A wrong type or version shifts subsequent fields and produces incorrect values. Some malformed lines only generate parser warnings: the absence of an exception does not establish a correct layout.
Checked against node_modules/tera-data-parser/lib/parsers/def.js, lib/protocol/compiler.js and parser types, with the format cross-checked against the tera-data README. This article targets the current Toolbox parser.