The .def file format

Field types, nested structures, references, arrays and TERA packet definition versions.

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.