Skip to content

Reversing a .NAV File Format

Jack Mioriday edited this page Aug 1, 2020 · 1 revision

As a start, grab a Linux server binary to disassemble. Use VTable Dumper and check for any subclasses of CNavArea or CNavMesh, and checking if the subclass overrides the following functions:

class CNavMesh
{
  virtual NavErrorType Load( void );
  virtual void LoadCustomData( CUtlBuffer &fileBuffer, unsigned int subVersion ) { }
  virtual void LoadCustomDataPreArea( CUtlBuffer &fileBuffer, unsigned int subVersion ) { }
}

class CNavArea
{
  virtual NavErrorType Load( CUtlBuffer &fileBuffer, unsigned int version, unsigned int subVersion );
}

If there aren't any subclasses, then you might not have to do anything and there's a chance that the plugin will work as is. If it still doesn't work correctly, it might either be because of your .NAV file or the game modified the base code of CNavMesh::Load() or CNavArea::Load(). Left 4 Dead 2 is an example of this, on top of overriding those functions.

If you stumble upon custom data being loaded in those functions, take note of all calls to CUtlBuffer::CheckGet() and CUtlBuffer::Scanf(). Identifying a pair of these functions is a call to CUtlBuffer::Get<Type>() as the function is inlined. Here's a table that lists out each pair and what type it denotes.

Type CUtlBuffer::CheckGet(size) CUtlBuffer::Scanf()
char 1 %c
float 4 %f
int 4 %d
short 2 %d
uchar 1 %u
uint 4 %u
ushort 2 %u

Once you know the layout, make use of the NavMeshLoadCustomDataPreArea, NavMeshLoadCustomData, and NavMeshLoadAreaCustomData functions as much as possible, then after you've tested and confirmed it works, feel free to send a pull request to this repository.

Clone this wiki locally