PAK (Metroid Prime)

Revision as of 03:40, 26 January 2015 by >Aruki

The .pak format in Metroid Prime and Metroid Prime 2 is a fairly simple packfile format; files are stored with a 32-bit file ID, and can optionally be compressed with zlib (Metroid Prime) or LZO1X-999 (Metroid Prime 2). The assets in a pak are split into two groups: named resources and dependencies. In general, only named resources are accessed directly by the game; the rest are dependencies of the named resources, and are accessed indirectly in the process of parsing those files.

Note that the Metroid Prime 3 E3 prototype uses this pak format as well, but has 64-bit file IDs. This is the only difference; the version number is still the same, so there isn't an easy way to check for this variation of the format.

This file format is almost completely documented
Some minor research is needed to figure out the optimal way to order files to optimize load times.

Format

Header

The pak starts with a short 8-byte header:

Offset Size Description
0x0 4 Version number. Always 0x00030005.
0x4 4 Unused; always 0
0x8 End of header

Named Resources

The named resource table lists files that the game has direct access to. On world paks, this will generally only contain the MLVL file; in other paks, this table is usually quite a bit larger. Note that in non-world paks, the names are hardcoded and are how the game knows where to find the files; if you repack, you need to make sure you keep the names the same.

This section of the file begins with a 32-bit named resource count, followed by a table.

Offset Size Description
0x0 4 File type fourCC.
0x4 4 File ID.
0x8 4 Name length (NL)
0xC NL Name; not zero-terminated
0xC + NL End of entry

Resource Table

This could be considered the main table of contents of the pak. This table begins with a 32-bit resource count, followed by one entry per file; each entry is 0x14 bytes large.

Offset Size Description
0x0 4 Compression flag; this will either be 0 or 1, with 1 denoting a compressed file.
0x4 4 File type fourCC.
0x8 4 File ID
0xC 4 Size (note: always a multiple of 32. The end of the file is padded with 0xFF in order to be 32-byte aligned.)
0x10 4 Offset
0x14 End of entry

Compression

Compressed files begin with their 32-bit decompressed size, followed by the compressed file data. Metroid Prime uses zlib, which is easily recognized from zlib's 0x78DA header at the start of the compressed data. Each file is compressed as a single zlib stream.

Metroid Prime 2 uses LZO1X-999, and gets slightly more complicated. Metroid Prime 2's compressed files are split up into multiple blocks of compressed data, each of which is 0x4000 bytes large when decompressed (except for the last one) and should be compressed and decompressed separately. Each block begins with a 16-bit size value before its actual compressed data begins.

File Order

File order matters significantly and easily makes the difference between a pak loading quickly and optimally, or taking 30+ seconds on every door. While more research is required to figure out exactly how files should be ordered to optimize loading, the game generally clusters together resources that are used together, and a file's dependencies generally appear directly before the file itself. The game also often duplicates assets that are used multiple times within the same pak; there might be 10-11 copies of the same model file in order to allow the game to more easily find and load that file when it needs it.