Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?

NWN2 TRN.ASWM packet structure

Thibaut CHARLES - CromFr@gmail.com

Packet

TRN.ASWM packets are used to store the walkmesh information in TRN and TRX files.

The packet itself is stored as is:

Type Name Description
char[4] data_type Always COMP for compressed walkmesh
uint32_t compressed_data_size Size of compressed_data
uint32_t uncomp_length Uncompressed walkmesh size
void[compressed_data_size] compressed_data zlib-compressed walkmesh data

Uncompressed walkmesh data can be retrieved using zlib.deflate. The following structure information are for the uncompressed walkmesh data.

TRN/TRX

TRN.ASWM is slightly different weather it is stored in a TRX or TRN file. Generally, the TRX version is smaller as it has to be downloaded/loaded by the client, and contains the baked version of the walkmesh (with placeable walkmesh/walkmesh cutter alterations).

  • TRN version:
    • The whole map is stored, but no information on placeable walkmeshes nor walkmesh cutters
  • TRX version:
    • Baked counterpart of the TRN version
    • Border megatiles are not stored. Only the map center is stored.
    • Triangles cut by a "walkmesh cutter" are not stored (creates holes in the mesh)
    • Placeable walkmeshes modifications appears

Data blocks

Offsets are for a newly created exterior area of size 4x4

Offset Data type Name Description
0x000000 Header header Header
0x000035 Vertex[header.vertices_count] vertices Vertex list
0x02AE81 Junction[header.junctions_count] junctions Junction list
0x0D4981 Triangle[header.triangles_count] triangles Triangle list
0x296981 ??? unknown1_block No idea what it is ?
0x2BB038 END of file

Header struct (53 bytes)

Values are for a newly created exterior area of size 4x4

Type Value Name Description
uint32_t version
char[32] name
uint8_t owns_data
uint32_t 14641 vertices_count
uint32_t 43440 junction_count
uint32_t 28800 triangles_count
uint32_t 0 triangles_offset Seems to be always 0
Notes
  • unknownA seems to be always the same for exterior areas, ie: 0x6C_00_00_00_4B_28_92_00_B0_FC_12_00_66_2C_92_7C_FF_FF_FF_FF_18_EE_90_7C_00_8E_91_7C_B8_02_15_00_FA_8D_91_7C_01

Work in progress, still unknown...

Any ext area:                         6C 00 00 00 4B 28 92 00 B0 FC 12 00 66 2C 92 7C FF FF FF FF 18 EE 90 7C 00 8E 91 7C B8 02 15 00 FA 8D 91 7C 01
marais-enclave_illithid.trn (int):    6C 00 00 00 CD CC CC 3D 51 BB 2A C3 00 00 48 43 CD CC CC 3D C2 F9 20 C3 3C CA 8A 10 01 CC CC 3D C2 F9 20 C3 01
eauprofonde-palais.TRN (int):         6C 00 00 00 00 F0 8A 04 21 00 00 00 18 96 0B 11 4C 00 01 10 98 F0 8A 04 50 57 BF 10 6E 50 61 72 74 00 BF 10 01
ravinyard-mine.trn (int):             6C 00 00 00 0A D7 23 34 D9 05 00 00 98 54 92 14 78 BD 85 15 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 01
icyngard-bazaar.trn (int):            6C 00 00 00 35 00 8B 01 19 00 00 00 C0 0F 8B 10 44 00 02 10 38 20 8B 01 A0 D9 5E 10 50 00 00 00 1A 00 00 00 01
aaaaaa.trn (1x1 int):                 6C 00 00 00 4B 28 92 00 B0 FC 12 00 66 2C 92 7C FF FF FF FF 18 EE 90 7C 00 8E 91 7C B8 02 15 00 FA 8D 91 7C 01
aaabbb.trn (same re-created):         6C 00 00 00 4B 28 92 00 B0 FC 12 00 66 2C 92 7C FF FF FF FF 18 EE 90 7C 00 8E 91 7C B8 02 15 00 FA 8D 91 7C 01
aaabbb.trn (same with 1 tile placed): 6C 00 00 00 4B 28 92 00 B0 FC 12 00 66 2C 92 7C FF FF FF FF 18 EE 90 7C 00 8E 91 7C B8 02 15 00 FA 8D 91 7C 01

Vertex struct (12 bytes)

Type Description
float[3] x/y/z coordinates of the vertex

Junction struct (16 bytes)

Type Description
uint32_t[2] Vertex indices
uint32_t[2] Attached triangle indices. -1 if a triangle does not exist.
Notes
  • The struct defines a junction between two triangles, with the shared edge.
  • Every triangle seems to be referenced in 3 of these structs, so basically every triangle side has its Junction struct.
  • Exact use is unknown, but:
    • Might be used to set non-walkable lines on the walkmesh, but no case were found.
    • Might also be used for pathfinding.

Triangle struct (64 bytes)

Type Name Description
uint32_t[3] vertices Vertex indices composing the triangle
uint32_t[3] linked_junctions Junction indices corresponding to this triangle edges
uint32_t[3] linked_triangles Triangle indices that have an edge in common with this triangle. -1 is there is no triangle on one.
float[2] center Triangle center x/y coordinates
float[3] normal Normal vector
float unknownA ???
uint16_t microtileId -1 if the triangle is non walkable (only map borders in TRN files), else it is a microtile ID (1 microtile = 6*6 quads/72 triangles, 4 microtiles makes a tile, 16 microtiles makes a megatile)
uint16_t flags Walkmesh flags
Walkmesh flags
  • 0b0000_0000_0000_0001: walkable flag (1 if walkable)
  • 0b0000_0000_0000_0010: Unknown (no use case found)
  • 0b0000_0000_0000_0100: if the triangle is drawn clockwise (0 if counter clockwise)
  • 0b0000_0000_0000_1000: Dirt flag
  • 0b0000_0000_0001_0000: Grass flag
  • 0b0000_0000_0010_0000: Stone flag
  • 0b0000_0000_0100_0000: Wood flag
  • Other bits are unused
microtileId & walkable flag
  • In TRN files:
    • Map border megatiles triangles have microtileId=-1 and walkable flag set to 0
    • Bakeable triangles (map center) have a valid microtileId (ie: != -1), and the walkable flag set to 1/0 if the triangle is meant to be walkable/non walkable.
  • In TRX files:
    • Map borders are not stored
    • Non walkable triangles have microtileId=-1 and walkable flag set to 0
    • Triangles cut by a "walkmesh cutter" are not stored
Notes
  • For the raw map:
    • unknownA is always 0 (or -0)
  • For the icy peak map
    • -498.294 ==> 475.229

unknown1_block

Work in progress, still unknown...

Block size: 149176=0x246B8


Maybe a bitmap or similar? (not a DDS)

Maybe 13 byte header + (1+72)*337 + (0,1,2..47 for each uint8_t) + (0,1,2..47 for each uint32_t)
...
~ 0x0000 ~ (0,1,2..47 uint8_t) ~ (0,1,2..47 uint32_t) ~ 72+(0xFF ~ 72*uint8_t)
Offset raw Type raw ilesaison aaabbb illith Description
0x296981 uint32_t 63 63 15 15
      | `float`       | 10.0     | 10.0       | 9.0      | 9.0      |
      | `uint32_t`    | 20       | 32         | 1        | 20       | Area height in microtiles (number of megatiles x4) (or tile for interior areas?!)
      | `uint32_t`    | 20       | 36         | 1        | 20       | Area width in microtiles
      | `uint32_t`    | 0        | 0          | 44       | 0        |
      | `ubyte[29]`   | 0        | 0          | strange  | 0        |

0x2969B2| uint32_t | 14641 | value | 52 | 36 ?! | Vertex count? | uint32_t | 43440 | value | 133 | 85 ?! | Junction count? | uint32_t | 72 | 72 | 82 | 50 | ? | float? | 10.0 | 10.0 | 9.0 | 9.0 | | float? | 10.0 | 10.0 | 9.0 | 9.0 | | uint32_t? | 0 | 72 | 0 | 0 | | uint32_t? | 0 | 0 | 0 | 0 | | uint32_t? | 0 | 72 | 0 | 0 | | uint32_t? | 72 | 0 | 0 | 0 | | ubyte[114] | | | | | ?

  • raw.trn

    • ~ 171 (or less) patterns with 31 39 00 00 B0 A9 00 00 (14641, 43440) or 31 39 00 00 B0 A9 00 00 48 00 00 00 00 00 20 41 00 00 20 41
    • 146 byte pattern
  • ilesaison.trn

    • 297 patterns
    • 146 byte pattern
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment