NAV (file format): Difference between revisions
m (Replaced deprecated {{Game name}} template with {{Software}} counterpart. Action performed by bot)  | 
				CHILLMODEA (talk | contribs)  m (fix merge notice)  | 
				||
| (11 intermediate revisions by 3 users not shown) | |||
| Line 1: | Line 1: | ||
{{back|Nav Mesh}}  | {{back|Nav Mesh}}  | ||
{{distinguish|AIN}}  | {{distinguish|AIN}}  | ||
A '''NAV''' file is a map specific [[Nav Mesh|'''<u>Nav</u>'''igation Mesh]] file that defines the walkable space in a level for [[bot]]s in   | {{merge|[[Nav Mesh]]}}  | ||
A '''NAV''' file is a map specific [[Nav Mesh|'''<u>Nav</u>'''igation Mesh]] file that defines the walkable space in a level for [[bot]]s in {{gldsrc|1}} ({{cscz|1|nt=1}}) and {{src|1}} games. They usually reside in <code><game folder>/maps</code> and can be integrated into [[BSP|BSPs]] in some [[Source]] games.{{clarify}}  | |||
{{Todo|Document GoldSrc version. Format is identical - {{cscz|1}} uses version 5.}}  | |||
== Games ==  | == Games ==  | ||
In {{css|4}} and {{csgo|4}}, the file is generated automatically when bots are played or being added into a map for the first time on a specific map that doesn't have one.  | In {{css|4}} and {{csgo|4}}, the file is generated automatically when bots are played or being added into a map for the first time on a specific map that doesn't have one.  | ||
Nav Mesh file write is open source in Source SDK 2013: https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/mp/src/game/server/nav_file.cpp#L1071  | |||
Nav Mesh generation is also open source in Source SDK 2013: https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/sp/src/game/server/nav_generate.cpp#L3399  | |||
{{l4d|4}} games have extra data per nav-area, as well as in after the nav place directory (null term string + short?), both of which have unknown format.  | |||
== File format ==  | == File format ==  | ||
| Line 13: | Line 21: | ||
{{note|This is reverse engineered data.}}  | {{note|This is reverse engineered data.}}  | ||
{{ExpandBox|<source lang="cpp">  | {{ExpandBox|<source lang="cpp">  | ||
unsigned int magicNumber; // Magic number to check if the file is a .nav file  | unsigned int magicNumber; // Magic number to check if the file is a .nav file (little endian 0xFEEDFACE)  | ||
unsigned int version; // Version of the .nav file, for example GMod and TF2 has 16  | unsigned int version; // Version of the .nav file, for example GMod and TF2 has 16  | ||
| Line 55: | Line 63: | ||
if ( version >= 6 ) {  | if ( version >= 6 ) {  | ||
	unsigned int   | 	unsigned int ladderCount; // number of CNavLadders  | ||
	ladder_t ladders[ladderCount]; // Ladder Data  | |||
}  | }  | ||
| Line 154: | Line 159: | ||
	unsigned int ID; // Identifier of hide spot. Added in NAV version 2.  | 	unsigned int ID; // Identifier of hide spot. Added in NAV version 2.  | ||
	float position[3]; // Position of the hiding spot. Added in NAV version 1.  | 	float position[3]; // Position of the hiding spot. Added in NAV version 1.  | ||
	unsigned char Attributes; // Attribute field. Added in NAV version 2. Defaults to IN_COVER for version 1  | |||
};  | };  | ||
</source>  | </source>  | ||
| Line 167: | Line 172: | ||
| {{csgo|4}} || Determines where bots can take cover and shoot at.  | | {{csgo|4}} || Determines where bots can take cover and shoot at.  | ||
|}  | |}  | ||
===Encounter Path===  | ===Encounter Path===  | ||
Encounter paths are structures used to determine routes to take to get to certain areas.  | Encounter paths are structures used to determine routes to take to get to certain areas.  | ||
| Line 190: | Line 196: | ||
</source>  | </source>  | ||
{{warning|Encounter spots are only used in {{css|4}} and {{csgo|4}}.}}  | {{warning|Encounter spots are only used in {{css|4}} and {{csgo|4}}.}}  | ||
===Ladder===  | |||
A navigation mesh ladder.  | |||
<source lang="cpp">  | |||
struct nav_ladder_t {  | |||
	unsigned int ID; // Identifier of the navigation ladder.  | |||
	float width; // extent of ladder  | |||
	float top[3]; // top endpoint of ladder  | |||
	float bottom[3]; // bottom endpoint of ladder  | |||
	float length; // ladder length  | |||
	unsigned int direction; // Direction of the ladder (NavDirType)  | |||
	unsigned char bDangling; // if version 6, dangling status  | |||
	unsigned int topForwardArea; // area ID  | |||
	unsigned int topLeftArea; // area ID  | |||
	unsigned int topRightArea; // area ID  | |||
	unsigned int topBehindArea; // area ID  | |||
	unsigned int bottomArea; // area ID  | |||
}  | |||
</source>  | |||
===Custom Data===  | ===Custom Data===  | ||
Some games store custom data in areas.  | Some games store custom data in areas.  | ||
| Line 197: | Line 227: | ||
|-  | |-  | ||
| 2 || unsigned int || {{tf2|4}} specific attributes.  | | 2 || unsigned int || {{tf2|4}} specific attributes.  | ||
|-  | |||
| 1 || char[14] || {{csgo|4}} unknown data.  | |||
|}  | |}  | ||
| Line 209: | Line 241: | ||
| 16  | | 16  | ||
| 2  | | 2  | ||
|-  | |||
| {{gmod|4}}  | |||
| 16  | |||
| 0  | |||
|-  | |||
| {{l4d2|4}}  | |||
| 16  | |||
| 14  | |||
|-  | |||
| {{l4d|4}}  | |||
| 15  | |||
| 13  | |||
|-  | |||
| {{css|4}}  | |||
| 9  | |||
| n/a  | |||
|-  | |||
| {{cscz|4}}  | |||
| 5  | |||
| n/a  | |||
|}  | |}  | ||
| Line 219: | Line 271: | ||
* [https://github.com/WhyIsEvery4thYearAlwaysBad/kaitai_struct_formats/blob/master/game/source_engine_nav.ksy Base NAV file format in Kaitai Struct.]  | * [https://github.com/WhyIsEvery4thYearAlwaysBad/kaitai_struct_formats/blob/master/game/source_engine_nav.ksy Base NAV file format in Kaitai Struct.]  | ||
* [https://github.com/mrazza/gonav Nav file parser in Go.] (Outdated)  | * [https://github.com/mrazza/gonav Nav file parser in Go.] (Outdated)  | ||
[[Category:Level Design]]  | [[Category:Level Design]]  | ||
Latest revision as of 17:41, 8 June 2025
A NAV file is a map specific Navigation Mesh file that defines the walkable space in a level for bots in GoldSrc (CS:CZ) and Source games. They usually reside in <game folder>/maps and can be integrated into BSPs in some Source games.[Clarify]
Games
In 
 Counter-Strike: Source and 
 Counter-Strike: Global Offensive, the file is generated automatically when bots are played or being added into a map for the first time on a specific map that doesn't have one.
Nav Mesh file write is open source in Source SDK 2013: https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/mp/src/game/server/nav_file.cpp#L1071
Nav Mesh generation is also open source in Source SDK 2013: https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/sp/src/game/server/nav_generate.cpp#L3399
 Left 4 Dead games have extra data per nav-area, as well as in after the nav place directory (null term string + short?), both of which have unknown format.
File format
unsigned int magicNumber; // Magic number to check if the file is a .nav file (little endian 0xFEEDFACE)
unsigned int version; // Version of the .nav file, for example GMod and TF2 has 16
if ( version >= 10 ) {
	unsigned int subVersion; // Sub version of the .nav file, for example GMod has 0, TF2 has 2. This is usedt
}
if ( version >= 4 ) {
	unsigned int saveBspSize; // Size of source bsp file to verify that the bsp hasn't changed
}
if ( version >= 14 ) {
	unsigned char isAnalyzed;
}
if ( version >= 5 ) {
	// Callouts. Places data. This is the "Mid", "Banana", etc stuff that is used in this nav mesh
	unsigned short count;
	for( int i = 0; i < count; ++i ) {
		unsigned short len; // length of the name
		char name[len]; // The name. Maximum len is 256
	}
	if ( version > 11 ) {
		unsigned char m_hasUnnamedAreas;
	}
}
{
	// PreLoadAreas( count )
	// This is by default is completely unused, it is left for mods to store custom data
	// Assuming that the data is per nav area
	//for( int i = 0; i < count; ++i ) {
	//}
}
unsigned int areaCount; // number of CNavAreas
area_t area[areaCount]; // Area Data
if ( version >= 6 ) {
	unsigned int ladderCount; // number of CNavLadders
	ladder_t ladders[ladderCount]; // Ladder Data
}
{
	// Load Custom Data
	// Again, by default this is unused
}
Area
A navigation area is a bounding square in which bots can move.
struct nav_area_t {
	unsigned int ID; // Identifier of the navigation area.
	union AttributeBitField {
		unsigned char; // In NAV versions ≤ 8
		unsigned short; // In NAV versions ≤ 12
		unsigned int; // In NAV Versions ≥ 13
	};
	float nwCorner[3]; // North-West corner vector.
	float seCorner[3]; // South-East corner vector.
	float NorthEastZ; // Z coordinate of North-East corner.
	float SouthWestZ; // Z coordinate of South-West corner.
	connectionData_t connectionData[4]; // Connection data in NESW (North, East, South, West) order.
	unsigned char hidingSpotCount; // Amount of hiding spots.
	hidingSpot_t hidingSpots[hidingSpotCount]; // Hiding spot data.
	/* Approach spots were removed in NAV version 15.
	unsigned char approachSpotCount; // Amount of approach spots
	approachSpot_t approachSpotData[approachSpotCount]; // Approach spot data.
	*/
	unsigned int encounterPathCount; // Amount of encounter paths.
	encounterPath_t encounterPaths[encounterPathCount]; // Encounter path data.
	unsigned short PlaceID; // ID of place.
	// Ladder data stored in order of vertical direction (up then down).
	struct ladderIDSequence_t {
		unsigned int ladderCount; // Amount of ladder Ids.
		unsigned int ladderIDs[ladderCount]; // Ladder IDs
	} ladderIDSequence[2];
	float EarliestOccupyTimes[2]; // Earliest occupy times for teams.
	float LightIntensity[4]; // Light Intensities for each corner.
	unsigned int areaBindCount; // Amount of area-binds stored.
	nav_area_bind_t areaBindSequence[areaBindCount]; // Sequence of area-binds stored.
	unsigned int InheritVisibilityFromAreaID; // Inherit visibility from area.
	void* customData; // Game-specific data.
}
Approach Spot
struct approachSpot_t {
	uint approachHereId; 
	uint approachPrevId;
	byte approachType;
	uint approachNextId;
	byte approachHow;
}
Area-bind
Area-binds are a structure type used in nav areas to determine the visibility between the parent area and another navigation area, based on area ID.
struct nav_area_bind_t {
  unsigned int target_area_id; // Area ID of area.
  unsigned char AttributeBitField; // Attribute flag field that determines the visibility type.
};
Area-binds were added in NAV version 16.
Connection
struct connectionData_t {
	unsigned int count; // Amount of connections.
	unsigned int AreaIDs[count]; // List of area IDs that each connection points to.
};
Hiding Spot
Hiding spots are data structures used to determine points in a nav mesh that bots can hide at.
enum Attribute : unsigned char // Hiding Spot attribute values.
{
	IN_COVER = 0x01, // In a corner with good hard cover nearby
	GOOD_SNIPER_SPOT = 0x02, // Had at least one decent sniping corridor
	IDEAL_SNIPER_SPOT = 0x04, // Can see either very far, or a large area, or both
	EXPOSED	= 0x08 // Spot in the open, usually on a ledge or cliff
};
struct hidingSpot_t {
	unsigned int ID; // Identifier of hide spot. Added in NAV version 2.
	float position[3]; // Position of the hiding spot. Added in NAV version 1.
	unsigned char Attributes; // Attribute field. Added in NAV version 2. Defaults to IN_COVER for version 1
};
| Game | Used For | 
|---|---|
| Determines where Spy bots can lurk for targets. | |
| Determines where bots can take cover and shoot at. | |
| Determines where bots can take cover and shoot at. | 
Encounter Path
Encounter paths are structures used to determine routes to take to get to certain areas.
struct encounterPath_t {
	unsigned int EntryAreaID; // ID of the Area entered from.
	unsigned byte EntryDirection; // Direction of entry.
	unsigned int DestAreaID; // ID of the Area destination.
	unsigned byte DestDirection; // Direction towards the destination area.
	unsigned char encounterSpotCount; // Amount of encounter spots.
	encounterSpot_t encounterSpots[encounterSpotCount]; // Encounter spots.
};
Encounter Spot
Encounter Spots (better termed waypoints) are data structures used in encounter paths to determine the order of area IDs in a route.
struct encounterSpot_t {
	unsigned int AreaID; // The Area ID to go to.
	unsigned char ParametricDistance; // Parametric distance in bytes.
};
Ladder
A navigation mesh ladder.
struct nav_ladder_t {
	unsigned int ID; // Identifier of the navigation ladder.
	float width; // extent of ladder
	float top[3]; // top endpoint of ladder
	float bottom[3]; // bottom endpoint of ladder
	float length; // ladder length
	unsigned int direction; // Direction of the ladder (NavDirType)
	unsigned char bDangling; // if version 6, dangling status
	unsigned int topForwardArea; // area ID
	unsigned int topLeftArea; // area ID
	unsigned int topRightArea; // area ID
	unsigned int topBehindArea; // area ID
	unsigned int bottomArea; // area ID
}
Custom Data
Some games store custom data in areas.
| Subversion | Data | Label | 
|---|---|---|
| 2 | unsigned int | |
| 1 | char[14] | 
Versions Used By Games
| Game | Version | Subversion | 
|---|---|---|
| 16 | 2 | |
| 16 | 0 | |
| 16 | 14 | |
| 15 | 13 | |
| 9 | n/a | |
| 5 | n/a | 
See also
NAV processors
- Nav file parser in C++.
 - libSourceNav — a NAV parser in Common Lisp.
 - Base NAV file format in Kaitai Struct.
 - Nav file parser in Go. (Outdated)