Skip to content

Game tables file formats

rebaserHEAD edited this page Oct 14, 2026 · 1 revision

reference, committed verified 2026-10-14 stable a4e75b18

The three file formats the server reads at start-up, as its own readers read them: game tables (.tbl), text tables (.bin), and the map files NexusForever.MapGenerator writes (.nfmap). All integers are little-endian. How the server uses the tables is on Game tables.

Game tables

Header

96 bytes. Every offset after it counts from the end of the header.

Offset Field Type Read as
0 Signature u32 Must be 0x4454424C, DTBL
4 Version u32 Not checked
8 NameLength u64 Unused
16 Unknown1 u64 Unused
24 RecordSize u64 Bytes per row
32 FieldCount u64 Number of column descriptors
40 FieldOffset u64 Where the column descriptors start
48 RecordCount u64 Number of rows
56 TotalRecordSize u64 Rows plus the string table, in bytes
64 RecordOffset u64 Where the first row starts
72 MaxId u64 Size of the id lookup the reader builds
80 LookupOffset u64 Unused; the reader builds its own lookup
88 Unknown2 u64 Unused

Column descriptors

24 bytes each, FieldCount of them.

Offset Field Type Read as
0 NameLength u64 Unused
8 NameOffset u64 Unused: the reader never reads column names
16 Type u16 The column's data type, below
18 Unknown2 u16 Unused
20 Unknown3 u32 Unused

Data types

Value Name Bytes in the row Row model field
3 UInt 4 uint, or any enum
4 Single 4 float
11 Boolean 4 bool, true when non-zero
20 ULong 8 ulong
130 String 8 string, see below

Rows and strings

  • Row i starts at RecordOffset + i * RecordSize, and each row is read from its own start, so a bad row can't shift the next one.
  • The first column is the row's id.
  • The string table starts right after the last row. A string column holds two u32 offsets; the string is at the larger one, less the size of all the rows, read as null-terminated UTF-16.
  • After a string column whose first offset is 0, the reader skips 4 more bytes unless the next field is also a string.

When a model doesn't match

Condition Result
File shorter than the header, or a wrong signature InvalidDataException
Debug: field count differs from column count GameTableException, "GameTable model has an invalid field count"
Debug: a field's type differs from its column's GameTableException, "Invalid GameTable model field type"
Release: either of the above No check. Values are read into the wrong fields
An id of MaxId or more IndexOutOfRangeException

Text tables

Header

96 bytes.

Offset Field Type Read as
0 Signature u32 Must be 0x4C544558, LTEX
4 Version u32 Not checked
8 Language i32 1 English, 2 German, 3 French, 5 Chinese
12 Unknown1 u32 Unused
16 TagNameLength, TagNameOffset u64, u64 Unused
32 ShortNameLength, ShortNameOffset u64, u64 Unused
48 LongNameLength, LongNameOffset u64, u64 Unused
64 RecordCount u64 Number of strings
72 RecordOffset u64 Where the records start
80 StringTableLength u64 Length of the string table, in UTF-16 characters
88 StringTableOffset u64 Where the string table starts

Records

Each record is a u32 id and a u32 offset into the string table, counted in UTF-16 characters. The reader sizes its lookup from the last record's id, so it expects records in id order.

File Language Required
en-US.bin English Yes
de-DE.bin German No; a warning when missing
fr-FR.bin French No; a warning when missing

Map files

Layout

One .nfmap per world, named after the world's asset folder.

Part Fields
Header u32 magic 0x504D464E, NFMP; u32 version, which must be 4; u32 client build, which must be 16042
Asset The world's asset path, as a length-prefixed string
Grids u32 count, then each grid
Grid u32 X, u32 Y, u32 cell count, then each cell
Cell u32 X, u32 Y, u32 flags, then a block for each flag set, in bit order

The file must end exactly after the last grid.

Cell blocks

Flag Name Block
0x01 Zone 4 u32 world zone ids
0x02 Height 17 × 17 half-precision heights
0x10 ZoneBound 64 × 64 bytes of zone and aura flags

0x04 (Aura) and 0x08 (Liquid) are declared but have no block, and the reader throws on either.

World geometry

Constant Value
Grids per axis 128, with grid 64 at world position 0
Grid size 512 world units
Cell size 32 world units, so 16 cells per grid axis

Where the code lives

Piece Path
Table header and descriptors Source/NexusForever.GameTable/GameTableHeader.cs, GameTableField.cs
Data types Source/NexusForever.GameTable/DataType.cs
Table reader and layout check Source/NexusForever.GameTable/GameTable.cs
Text table reader Source/NexusForever.GameTable/TextTable.cs, TextTableHeader.cs
Map file reader Source/NexusForever.IO/Map/MapFile.cs, MapFileGrid.cs, MapFileCell.cs
Map constants Source/NexusForever.IO/Map/MapDefines.cs
Map file writer Source/NexusForever.MapGenerator/

Clone this wiki locally