Quake – Details about Bot Navigation Data & File Format

Quake – Details about Bot Navigation Data & File Format 1 - steamlists.com
Quake – Details about Bot Navigation Data & File Format 1 - steamlists.com

Describes the file format of the bot navigation files .nav used by the Quake 2021 Re-Release version.
 
 

Introduction

This guide will describe and explain the .nav files. These are the files that save all the bot navigation data (eg: waypoints). This guide is intended for programmers.
 
 
It’s a binary format but it’s relatively simple. I’ve written the format into Kaitai – [kaitai.io] . Download the KSY file here – [pastebin.com]  and you can try it at their online IDE – [kaitai.io] . From there you’re able to upload .nav files and see the contents or generate file readers for multiple programming languages.
 
 

Some important info

 
All offsets are relative to the beginning of the structure or sub-structure, not the file. The file is variable length so it’s not possible to do that anyway.
 
 
Here’s the types and their length in case there’s any confusion:
 
 

Type Size (bytes) Comment
int 4
short 2
float 4
vector3 12 XYZ coordinates, 3 floats

 
 
 

Diagram

This is a diagram generated from the Kaitai struct file. It doesn’t correspond 1:1 to what is in this guide but all the fields are there.
 
 
Quake - Details about Bot Navigation Data & File Format - Diagram - 66FE47E
 
 
 

File Structure

The file is divided into 6 structures.
 
 

Rel. Off. Name Type Description
0 Header Header Header of the file. Contains some important info.
20 Nodes Node[] Info about the nodes
Node origins NodeOrigin[] 3D coordinates where nodes are placed
Links Link[] Info about the links between nodes
Traversals Traversal[] Info that helps bots on how to traverse big gaps between nodes
Edicts Edicts Info about connection of links to edicts

 
 
 

Header

The header of the file contains mostly counters that tell you how much data to expect.
 
 

Rel. Off. Name Type Description
0 Magic Number char[4] Always ‘NAV2’
4 Unknown int Always 14. Probably version indicator.
8 Node count int How many nodes exist in the file
12 Link count int How many links exist in the file
16 Traversal count int How many traversals exist in the file

 
After the header comes the Node structure.
 
 
 

Nodes

The node structure contains info related to each node, but surprisingly not the position as that is contained inside a separate structure.
 
 
There are as many sequential nodes here as specified in the header.
 
 

Rel. Off. Name Type Description
0 Flags short The type of node. See table below
2 Connection count short How many outgoing connections this node has.
4 Connection start index short In which index in the connection array the connections for this node begin.
6 Radius short Radius of the node

 
After this array, the file continues with Node origins structure.
 
 

Node flags

 
This is a bit flag enum.
 
 

Bit flag Description
1 Teleporter
2 Pusher
4 Elevator Top
8 Elevator Bottom
16 Underwater
32 Hazard

 
 
 

Nodes origins

The nodes origin coordinates are stored in a separate array. There is as many as there are Nodes and they correspond by index. So for example, Node[53] will be NodeOrigin[53].
 
 

Rel. Off. Name Type Description
0 Origin vector3 XYZ coordinates

 
After this, comes the Links structure.
 
 
 

Links

The links connect all nodes together and provide pathing for the bots, however this array is quite bare.
 
 
As with Nodes, there are as many Links as defined in the Header.
 
 

Rel. Off. Name Type Description
0 Destination short Target Node index where this link leads to
2 Type short What type of link this is. See table below.
4 Traversal index short Index of the traversal info to use for this link. 0xFFFF if not used.

 
The file continues with the Traversals structure.
 
 

Link types

 
A link can only be 1 type.
 
 

Value Name
0 Walk
1 Long Jump
2 Teleport
3 Walk Off Ledge
4 Pusher
5 Barrier Jump
6 Elevator
7 Train
8 Manual Jump
9 Unknown (literally)

 
 
 

Traversals

This is probably the most surprising thing from the file, as it contains pre-computed helping coordinates to tell the bot how to traverse gaps like long jumps.
 
 
There as many Traversals as specified in the Header.
 
 
For simplicity sake I’ll condense XYZ float coordinates into a ‘vector3’ type.
 
 

Rel. Off. Name Type Description
0 Node exit vector3 Where the bot should leave the node. Coordinate is at the radius edge.
12 Jump start vector3 Where the bot should start jumping.
36 Jump end vector3 Where the jump ends / lands.

 
The file continues with the Edicts structure.
 
 
 

Edicts

The final structure of the file is the Edicts. It appears to be kind of independent of the other structures as it links Nodes to Edicts.
 
 

Header

 
The structure begins with a small header that indicates how many ‘Edict’ entries come after.
 
 

Rel. Off. Name Type Description
0 Edict count int How many edicts are contained in the file.

 

Edict

 
There are as many Edict as specified in the Edict header.
 
 

Rel. Off. Name Type Description
0 Link id short Which link this belongs to, connected via it’s index
4 Mins vector3 The world coordinates for the target edict ‘mins’
16 Maxs vector3 The world coordinates for the target edict ‘maxs’
28 targetname int Engine string index for the targetname of the target edict.
32 classname int Engine string index for the classname of the target edict.

 
 

A little explanation

 
So the way this structure works is a bit weird but at the same time it also makes it pretty reliable in some ways.
 
 
You’ll notice that there’s no entity index here, and you might think that it links to the entity via the targetname. But if that’s the case how can it work with buttons which have no targetname?
 
 
The answer is via the mins and maxs. Even if you remove the targetname and classname from the file, it will automatically find the entity contained within that box and fill up the information. I suspect if you remove the mins and maxs it might use targetname and classname to find it as well, but this hasn’t been tested.
 
 
However… You can’t really use the targetname and classname yourself. As they’re not strings but instead engine strings. Engine strings are assigned an index and they’re allocated at the beginning of the map and are different for each map. But in sum, if you’re pointing to the same entity, it’ll be the same id.
 
 

Written by JPiolho

 
 
I hope you enjoy the Guide we share about Quake – Details about Bot Navigation Data & File Format; if you think we forget to add or we should add more information, please let us know via commenting below! See you soon!
 
 


Be the first to comment

Leave a Reply

Your email address will not be published.


*