Quake New Version – Bot Navigation .nav File Format Explained!

Quake New Version – Bot Navigation .nav File Format Explained! 1 - steamsplay.com
Quake New Version – Bot Navigation .nav File Format Explained! 1 - steamsplay.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:
 
 

TypeSize (bytes)Comment
int4
short2
float4
vector312XYZ 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 New Version - Bot Navigation .nav File Format Explained! - Diagram - 66FE47E
 
 
 

File Structure

The file is divided into 6 structures.
 
 

Rel. Off.NameTypeDescription
0HeaderHeaderHeader of the file. Contains some important info.
20NodesNode[]Info about the nodes
Node originsNodeOrigin[]3D coordinates where nodes are placed
LinksLink[]Info about the links between nodes
TraversalsTraversal[]Info that helps bots on how to traverse big gaps between nodes
EdictsEdictsInfo 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.NameTypeDescription
0Magic Numberchar[4]Always ‘NAV2’
4UnknownintAlways 14. Probably version indicator.
8Node countintHow many nodes exist in the file
12Link countintHow many links exist in the file
16Traversal countintHow 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.NameTypeDescription
0FlagsshortThe type of node. See table below
2Connection countshortHow many outgoing connections this node has.
4Connection start indexshortIn which index in the connection array the connections for this node begin.
6RadiusshortRadius of the node

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

Node flags

 
This is a bit flag enum.
 
 

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

 
 
 

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.NameTypeDescription
0Originvector3XYZ 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.NameTypeDescription
0DestinationshortTarget Node index where this link leads to
2TypeshortWhat type of link this is. See table below.
4Traversal indexshortIndex 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.
 
 

ValueName
0Walk
1Long Jump
2Teleport
3Walk Off Ledge
4Pusher
5Barrier Jump
6Elevator
7Train
8Manual Jump
9Unknown (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.NameTypeDescription
0Node exitvector3Where the bot should leave the node. Coordinate is at the radius edge.
12Jump startvector3Where the bot should start jumping.
36Jump endvector3Where 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.NameTypeDescription
0Edict countintHow many edicts are contained in the file.

 

Edict

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

Rel. Off.NameTypeDescription
0Link idshortWhich link this belongs to, connected via it’s index
4Minsvector3The world coordinates for the target edict ‘mins’
16Maxsvector3The world coordinates for the target edict ‘maxs’
28targetnameintEngine string index for the targetname of the target edict.
32classnameintEngine 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.
 
 

By JPiolho

 
 
Hope you enjoy the post for Quake New Version – Bot Navigation .nav File Format Explained!, If you think we should update the post or something is wrong please let us know via comment and we will fix it how fast as possible! Thank you and have a great day!
 


Be the first to comment

Leave a Reply

Your email address will not be published.


*