PAK Files - Galaxy1036/AL-Assets-RE GitHub Wiki
.pak files are common files used in many games as files archives a bit like .zip files. However Arcane Legends use a completely custom .pak format. The main .pak of the game (android000.png
, spacetimes devs though they could bait us by changing the extension from .pak to .png lol) can be found in the APK files. Others .pak are downloaded from the spacetimes patch servers by the game at the first launch. You can easily grab them out of the application cache if you own a rooted device.
Format
PAK magic bytes (4 bytes)
Can be either 36 30 30 30 ("0006" as ascii char) or 35 30 30 30 ("0005"). It's used to determine what type of compression is used by the .pak. In the actual game version (2.7.9) all .pak use the "0006" version
Archive files content information
Following numeric values are using little endian encoding.
Amount of files (UINT32)
A simple count that tell us how many files can be found in the .pak archive
File description blocks
You can find a desciption block for each files.
Data type | Purpose |
---|---|
UINT32 | Filename crc32c checksum |
UINT32 | Filename beginning offset in the decompressed filenames table |
UINT32 | File beginning offset in the decompressed block of data |
UINT32 | File size |
Filenames table
The following table is just a block of data containing null char terminated strings that are the files output path, they are ordered according to the file id.
Data type | Purpose |
---|---|
UINT32 | Table compressed size |
UINT32 | Table uncompressed size |
If the table uncompressed size is bigger than the compressed size the table use the following format:
Data type | Length | Purpose |
---|---|---|
Raw bytes (list of null char terminated strings) | Table compressed size | Files path compressed using Brotli algorithm if the .pak is using "0006" version, if the .pak is using "0005" version the game use another unknown compression algorithm |
Else it means the table isn't compressed at all and use the following format:
Data type | Length | Purpose |
---|---|---|
Raw bytes (list of null char terminated strings) | Table uncompressed size | Files path list |
Archive data block informations
The goal of the following data is to extract a big block of raw data that can be splitted in different files using previous archive files content informations. The big block of raw data is actually splitted in different compressed or not blocks of raw data.
Data type | Purpose |
---|---|
UINT32 | uncompressed raw data blocks size, usually 65536 (0xFFFF) |
UINT32 | total uncompressed data size |
The amount of raw data blocks is calulated using the following formula:
blocks_amount = ((total_uncompressed_data_size + uncompressed_block_size - 1) // uncompressed_block_size) + 1
Raw blocks offsets
Data type | Purpose |
---|---|
UINT32 | raw block beginning offset |
For each raw block you can find a block beginning offset, with thoses you can easily get each raw block size.
Raw block data
As the filenames table, raw blocks data can be compressed or not depending on their size.
If the uncompressed raw data blocks size is bigger than the raw block size (calculated using previous offsets) then it use the following format:
Data type | Length | Purpose |
---|---|---|
Raw bytes | calculated raw block size | A block of raw data compressed using Brotli algorithm if the .pak is using "0006" version, if the .pak is using "0005" version the game use another unknown compression algorithm |
Else it means the raw block is not compressed and use the following format:
Data type | Length | Purpose |
---|---|---|
Raw bytes | calculated raw block size | A block of already uncompressed raw data |
Once extracted you can merge all thoses raw block of data together to get the final big block of data containing all files content
File end block
The final end block is used for integrity check and use the following format
Data type | Purpose |
---|---|
FourCC (4 char) | CRC0 tag used to check following info are what we are looking for |
UINT32 | CRC32C checksum of the whole .pak file without the end block |
UINT32 | Size of the whole .pak file without the end block |