Assassins Creed:Forge Files

From TBotR Wiki

Introduction

The forge file is a container file for the various files and resources required by the Assassin's Creed series of games.
PC and XBox360 forge files are read little-endian.

The following game abbreviations are used throughout this page:

AC1 -- Assassin's Creed
AC2 -- Assassin's Creed II
ACB -- Assassin's Creed: Brotherhood
ACRe -- Assassin's Creed: Revelations
AC3 -- Assassin's Creed III
AC3SP -- Assassin's Creed III (Single Player)
AC3MP -- Assassin's Creed III (Multi-Player)
ACL -- Assassin's Creed: Liberation
AC4 -- Assassin's Creed IV: Black Flag
AC4SP -- Assassin's Creed IV: Black Flag (Single Player)
AC4MP -- Assassin's Creed IV: Black Flag (Multi-Player)
ACU -- Assassin's Creed: Unity
ACRo -- Assassin's Creed: Rogue

Structure

Header
File Data Header I
File Data File Data Header II
Index Table
Name Table
Raw Data Table

Header

The Header provides us with the offset to the file data.

AC1, AC2, ACB, ACRe, AC3MP AC4MP AC3SP, ACL, AC4SP, ACU, ACRo
Offset Type Description
0 CHAR[8] "scimitar" All valid forge files start with these 8 characters
8 BYTE Unknown
9 INT32 Possible file version identifier "25"
13 UINT64 Offset to File Data Header
21 INT32 Unknown
25 BYTE Unknown
26 - File Data Header Unused ???
Offset Type Description
0 CHAR[8] "scimitar" All valid forge files start with these 8 characters
8 BYTE Unknown
9 INT32 Possible file version identifier "26"
13 UINT64 Offset to File Data Header
21 INT32 Unknown
25 BYTE Unknown
26 - File Data Header Unused ???
Offset Type Description
0 CHAR[8] "scimitar" All valid forge files start with these 8 characters
8 BYTE Unknown
9 INT32 Possible file version identifier "27"
13 UINT64 Offset to File Data Header
21 INT64 Unknown
29 BYTE Unknown
30 - File Data Header Unused ???

File Data Header I

This File Data Header provides us with total number of files contained in the forge file and the pointer to the first index table.

AC1, AC2, ACB, ACRe, AC3MP AC4MP AC3SP, ACL, AC4SP, ACU, ACRo
Offset Type Description
0 INT32 Total File Count
4 INT32[3] Unknown
16 INT64 Unknown
24 INT32 Maximum number of files for this Index
28 INT32 Unknown
32 INT64 Offset to File Data
Offset Type Description
0 INT32 Total File Count
4 INT32[3] Unknown
16 INT32 Unknown (Total File Count - 1)
20 INT32 Unknown
24 INT32 Maximum number of files for this Index
28 INT32 Unknown
32 INT64 Offset to File Data
Offset Type Description
0 INT32 Total File Count
4 INT32[4] Unknown
20 INT64 Unknown
28 INT32 Maximum number of files for this Index
32 INT32 Unknown
36 INT64 Offset to File Data

File Data

The File Data section may be repeated, depending on the game.

File Data Header II

This is the only section of the forge file that, so far, has remained the same in every game.

This File Data Header provides us with start and end values for the index, and offsets to the Index Table, Name Table, and the next File Data section if one is present.

Offset Type Description
0 INT32 Index Count
4 INT32 Unknown
8 INT64 Offset to Index Table
16 INT64 AC1:Unknown Offset, all others:Offset to next File Data section (-1, no more sections present)
24 INT32 Index Start
28 INT32 Index End
32 INT64 Offset to Name Table
40 INT64 Unknown Offset

Index Table

The Index Table provides us with offsets into the Raw Data Table for each file, along with file size and a file data id.

(Repeat this section equal to Index Count from File Data Header II)

AC1, AC2, ACB, ACRe, AC3MP, AC4MP AC3SP, ACL, AC4SP, ACU, ACRo
Offset Type Description
0 INT64 Offset to Raw Data Table
8 INT32 File Data ID
12 INT32 Raw Data Size
Offset Type Description
0 INT64 Offset to Raw Data Table
8 INT64 File Data ID
16 INT32 Raw Data Size

Name Table

The Name Table provides us with file size, file id, and file name.

(Repeat this section equal to Index Count from File Data Header II)

AC1, AC2, ACB, ACRe, AC3MP, AC4MP AC3SP, ACL, AC4SP, ACU, ACRo
Offset Type Description
0 INT32 Raw Data Size (this should match raw data size from the Index Table respectively for each file)
4 INT64 File ID
12 INT32[4] Unknown
28 INT32 Next File Count
32 INT32 Previous File Count
36 INT32 Unknown
40 INT32 Timestamp
44 BYTE[128] null-terminated File Name string
172 INT32[4] Unknown
Offset Type Description
0 INT32 Raw Data Size (this should match raw data size from the Index Table respectively for each file)
4 INT64 File ID
12 INT32[4] Unknown
28 INT32 Next File Count
32 INT32 Previous File Count
36 INT32 Unknown
40 INT32 Timestamp
44 BYTE[128] null-terminated File Name string
172 INT32[5] Unknown

Raw Data Table

The Raw Data Table provides us with file name, file id, file size, file data id, and the raw data for each file.

(Repeat this section equal to Index Count from File Data Header II)

AC1, AC2, ACB, ACRe, AC3MP, AC4MP AC3SP, ACL, AC4SP, ACU, ACRo
Offset Type Description
0 CHAR[8] "FILEDATA"
8 BYTE[128] Null-terminated file name string
136 BYTE[255] Unknown
391 INT32 File ID
395 INT32 Raw Data Size
399 INT64 File Data ID
407 INT32[6] Unknown
431 INT32 Timestamp
435 BYTE[5] Unknown
440 CHUNK Raw Data Chunk equal to Raw Data Size
Offset Type Description
0 CHUNK Raw Data Chunk equal to Raw Data Size

Raw Data Chunk

The Raw Data Chunk is sometimes uncompressed, but the majority are compressed. The compression used varies with the game.

This is where things get a little tricky. I haven't yet found a way before this point to determine whether or not a file is compressed. We'll start with the compressed version first:

Structure

Header I
Block Index
Compressed Data Chunks
Header II
Block Index
Compressed Data Chunks

Raw Chunk Header I

AC1 AC2, ACB, ACRe, AC3MP, AC4MP AC3SP, ACL, AC4SP, ACRo ACU
Offset Type Description
0 INT64 0x1004FA9957FBAA33 or 1,154,322,941,026,740,787 Signifies a compressed chunk
8 INT16 Unknown
10 BYTE Compression Type
Value Type
0 lzo1x
1 lzo1x
2 lzo2a
5 lzo1c
11 INT16 Min Size
13 INT16 Max Size
15 INT16 Compressed block count
Offset Type Description
0 INT32 Unknown
4 INT64 0x1004FA9957FBAA33 or 1,154,322,941,026,740,787 Signifies a compressed chunk
12 INT16 Unknown
14 BYTE Compression Type
Value Type
0 lzo1x
1 lzo1x
2 lzo2a
5 lzo1c
15 INT16 Min Size
17 INT16 Max Size
19 INT16 Compressed block count
Offset Type Description
0 INT64 Unknown
8 INT64 0x1004FA9957FBAA33 or 1,154,322,941,026,740,787 Signifies a compressed chunk
16 INT16 Unknown
18 BYTE Compression Type
Value Type
0 lzo1x
1 lzo1x
2 lzo2a
5 lzo1c
19 INT16 Min Size
21 INT16 Max Size
23 INT16 Compressed block count
Offset Type Description
0 INT64 0x1004FA9957FBAA33 or 1,154,322,941,026,740,787 Signifies a compressed chunk
8 INT16 Unknown
10 BYTE Compression Type
Value Type
0 lzo1x
1 lzo1x
2 lzo2a
5 lzo1c
11 INT16 Min Size
13 INT16 Max Size
15 INT32 Compressed block count

Raw Chunk Header II

AC1, AC2, ACB, ACRe, AC3, ACL, AC4, ACRo ACU
Offset Type Description
0 INT64 0x1004FA9957FBAA33 or 1,154,322,941,026,740,787 Signifies a compressed chunk
8 INT16 Unknown
10 BYTE Compression Type
Value Type
0 lzo1x
1 lzo1x
2 lzo2a
5 lzo1c
11 INT16 Min Size
13 INT16 Max Size
15 INT16 Compressed block count
Offset Type Description
0 INT64 0x1004FA9957FBAA33 or 1,154,322,941,026,740,787 Signifies a compressed chunk
8 INT16 Unknown
10 BYTE Compression Type
Value Type
0 lzo1x
1 lzo1x
2 lzo2a
5 lzo1c
11 INT16 Min Size
13 INT16 Max Size
15 INT32 Compressed block count

Block Index

Repeat a number of times equal to Compressed block count

Offset Type Description
0 UINT16 Uncompressed Size
2 UINT16 Compressed Size

If Uncompressed Size = Compressed Size, that block of data is not compressed.

Compressed Data Chunks

Repeat a number of times equal to Compressed block count

Offset Type Description
0 INT32 Checksum ???
4 BYTE[n] Compressed data n = Compressed Size

If you do not find the compressed chunk signature, you should start over from the beginning of the raw data chunk and read it as uncompressed data.

Once everything has been decompressed (or simply extracted in the case of an uncompressed raw data chunk), you have created a Datafile.

Personal tools