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