NAV (file format): Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
m (Remove unused category.)
(Elaborated on NAV file data. (Info primarily gotten from TF2 NAVs, still incomplete.))
Line 8: Line 8:


== File format ==
== File format ==
 
{{todo|Add approach spot data.}}
{{note|This is reverse engineered data. Reverse engineered format code can also be found [https://github.com/mrazza/gonav/blob/master/parser.go here].}}
{{note|This is reverse engineered data. Reverse engineered format code can also be found [https://github.com/mrazza/gonav/blob/master/parser.go here].}}
{{ExpandBox|<source lang="cpp">
{{ExpandBox|<source lang="cpp">
Line 39: Line 39:
}
}
}
}
{
// Load custom data pre area
// This is by default is completely unused, it is left for mods to store custom data
}
unsigned int count; // number of CNavAreas


{
{
Line 52: Line 45:
// Assuming that the data is per nav area
// Assuming that the data is per nav area
//for( int i = 0; i < count; ++i ) {
//for( int i = 0; i < count; ++i ) {
//}
//}
}
}


for( i = 0; i < count; ++i ) {
unsigned int areaCount; // number of CNavAreas
// Per CNavArea data
unsigned int id; // ID of the CNavArea
 
// Attribute flags
if ( version <= 8 ) {
unsigned char attributeFlags;
} else if ( version < 13 ) {
unsigned short attributeFlags;
} else {
int attributeFlags;
}


Vector m_nwCorner; // size is 3 * float(x,y,z), North-West corner of the area
area_t area[areaCount];
Vector m_seCorner; // size is 3 * float(x,y,z), South-East corner of the area
// More data...
}


if ( version >= 6 ) {
if ( version >= 6 ) {
Line 86: Line 65:
// Again, by default this is unused
// Again, by default this is unused
}
}
</source>}}
===Area===
{{todo|Add visibility data.}}
<source lang="cpp">
struct area_t {
unsigned int ID;
union Attributes {
unsigned char; // In NAV versions ≤ 8
unsigned short; // In NAV versions < 13
unsigned int;
};
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 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 ladderData_t {
unsigned int ladderCount; // Amount of ladder Ids.
unsigned int ladderIDs[ladderCount]; // Ladder IDs
} ladderData[2];
float EarliestOccupyTimes[2]; // Earliest occupy times for teams.
float LightIntensity[4]; // Light Intensities for each corner.
// Insert visibility data.
unsigned int InheritVisibilityFromAreaID; // Inherit visibility from area.
void* customData; // Game-specific data.
}
</source>
===Connection===
<source lang="cpp">
struct connectionData_t {
unsigned int count; // Amount of connections.
unsigned int AreaIDs[count]; // List of area IDs that each connection points to.
};
</source>
===Hiding Spot===
<source lang="cpp">
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;
float position[3]; // Position of the hiding spot.
Attribute Attributes; // Attributes
};
</source>
</source>
}}
 
===Encounter Path===
<source lang="cpp">
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.
};
</source>
===Encounter Spot===
<source lang="cpp">
struct encounterSpot_t {
unsigned int OrderID; // Unknown.
unsigned char ParametricDistance; // Parametric distance in bytes.
};
</source>
 
==See also==
==See also==
* [[Nav Mesh Editing]]
* [[Nav Mesh Editing]]

Revision as of 23:25, 6 October 2021

English (en)Translate (Translate)
Nav Mesh
Not to be confused with AIN.

A NAV file is a map specific Navigation Mesh file that defines the walkable space in a level for bots in Source games. They usually reside in <game folder>/maps and can be integrated into BSPs in some Source games.[Clarify]

In Template:Game name and Template:Game name, the file is generated automatically when bots are played for the first time on a specific map.

Tip.pngTip:NAV creation is an open-source task available in the SDK.

File format

Todo: Add approach spot data.
Note.pngNote:This is reverse engineered data. Reverse engineered format code can also be found here.

unsigned int magicNumber; // Magic number to check if the file is a .nav file
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 ) {
	// 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];

if ( version >= 6 ) {
	unsigned int count; // number of CNavAreas

	for( i = 0; i < count; ++i ) {
		// Ladder data
	}
}

{
	// Load Custom Data
	// Again, by default this is unused
}

Area

Todo: Add visibility data.
struct area_t {
	unsigned int ID;
	union Attributes {
		unsigned char; // In NAV versions ≤ 8
		unsigned short; // In NAV versions < 13
		unsigned int;
	};
	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 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 ladderData_t {
		unsigned int ladderCount; // Amount of ladder Ids.
		unsigned int ladderIDs[ladderCount]; // Ladder IDs
	} ladderData[2];
	float EarliestOccupyTimes[2]; // Earliest occupy times for teams.
	float LightIntensity[4]; // Light Intensities for each corner.

	// Insert visibility data.

	unsigned int InheritVisibilityFromAreaID; // Inherit visibility from area.

	void* customData; // Game-specific data.
}

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

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;
	float position[3]; // Position of the hiding spot.
	Attribute Attributes; // Attributes
};

Encounter Path

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

struct encounterSpot_t {
	unsigned int OrderID; // Unknown.
	unsigned char ParametricDistance; // Parametric distance in bytes.
};

See also