Skyrim Mod:Archive File Format

The UESPWiki – Your source for The Elder Scrolls since 1995
Jump to: navigation, search

BSA files are the resource archive files used by Skyrim. If you're familiar with the Oblivion BSA file format, Skyrim BSA format is nearly identical to it. If you're familiar with the generic IFF format, you'll find it very easy to understand—BSA, ESM/ESP, and ESS are IFF variants. This archive version v104 (0x68) is also used by Fallout 3 and Fallout: New Vegas, while Oblivion uses v103 (0x67). Note that Bethesda serializes structs directly, including undefined padding bits, which is the reason for the v104/v105 split.

File Structure[edit]

Name Type/Size Info
Header Header See specification of Header below.
folderRecords Folder Record[folderCount] See specification of Folder Record below.
fileRecordBlocks File Record blocks[...] See specification of File Record blocks below.
fileNameBlock File Name block A list of filenames. Each filename ends in \0. See specification of File Name block below.
files data or specification of Compressed File block Raw file data. If the file is compressed the file data will have the specification of Compressed File block.

Header[edit]

Name Type/Size Info
fileId char[4] Constant: "BSA\x00"
version ulong Currently 104 (0x68) for Skyrim or 105 (0x69) for Skyrim Special Edition.
offset ulong Offset of beginning of folder records. All headers are the same size, therefore this value is 36 (0x24).
archiveFlags ulong List of archive flags:
Bit Description
1 (0x1)1 Include Directory Names. (The game may not load a BSA without this bit set.)
2 (0x2)1 Include File Names. (The game may not load a BSA without this bit set.)
3 (0x4) Compressed Archive. This does not mean all files are compressed. It means they are compressed by default.
4 (0x8)2 Retain Directory Names.
5 (0x10)2 Retain File Names.
6 (0x20)2 Retain File Name Offsets.
7 (0x40) Xbox360 archive. Hash values and numbers after the header are encoded big-endian.
8 (0x80)2 Retain Strings During Startup.
9 (0x100) Embed File Names. Indicates the file data blocks begin with a bstring containing the full path of the file. For example, in "Skyrim - Textures.bsa" the first data block is $2B textures\effects\fxfluidstreamdripatlus.dds ($2B indicating the name is 43 bytes). The data block begins immediately after the bstring.
10 (0x200) XMem Codec. This can only be used with Bit 3 (Compress Archive). This is an Xbox 360 only compression algorithm.
1This bit is set in all official BSA files.
2This bit has no effect on the file structure. Probably just instructions for the game.
folderCount ulong Count of all folders in archive.
fileCount ulong Count of all files in archive.
totalFolderNameLength ulong Total length of all folder names, including \0's but not including the prefixed length byte.
totalFileNameLength ulong Total length of all file names, including \0's.
fileFlags ushort List of flags:
Bit Description
1 (0x1) Meshes
2 (0x2) Textures
3 (0x4) Menus
4 (0x8) Sounds
5 (0x10) Voices
6 (0x20) Shaders
7 (0x40) Trees
8 (0x80) Fonts
9 (0x100) Miscellaneous
padding ushort

Folder Record[edit]

Name Type/Size Info
nameHash hash Hash of the folder name (eg: menus\chargen). Must be all lower case, and use backslash as directory delimiter(s).
count ulong Amount of files in this folder.
padding (v105 only) ulong
offset ulong Offset to file records for this folder. (Subtract totalFileNameLength to get the actual offset within the file.)
padding (v105 only) ulong

File Record blocks[edit]

Name Type/Size Info
name bzstring Name of the folder. Only present if Bit 1 of archiveFlags is set.
fileRecords variable (File Record) Many records in the amount of files specified in the associated folder record.

File Record[edit]

Name Type/Size Info
nameHash hash Hash of the file name (eg: race_sex_menu.xml). Must be all lower case.
size ulong Size of the file data.

If the 30th bit (0x40000000) is set in the size:

  • If files are default compressed, this file is not compressed.
  • If files are default not compressed, this file is compressed.

If the file is compressed the file data will have the specification of Compressed File block. In addition, the size of compressed data is considered to be the ulong "original size" plus the compressed data size (4 + compressed size).

offset ulong Offset to raw file data for this folder. Note that an "offset" is offset from file byte zero (start), NOT from this location.

File Name block[edit]

If archive flag 0x2 is not set, this block is omitted. A block of lower case file names, one after another, each ending in a \0. They are ordered in the same order as those generated with the file folder block contents in the BSA archive. These are all the files contained in the archive, such as "cuirass.nif" and "cuirass.dds", etc (no paths, just the root names).

Compressed File block[edit]

Name Type/Size Info
name bstring Full path and name of the file. Only present if Bit 9 of archiveFlags is set.
originalSize ulong Size of uncompressed data.
data ubyte[compressedSize] File data that has been compressed with zlib (v104) or LZ4 (v105).

Uncompressed File block[edit]

Name Type/Size Info
name bstring Full path and name of the file. Only present if Bit 9 of archiveFlags is set.
data ubyte[fileSize] File data.

Files and Dirs order[edit]

Inside a BSA, folders and files in folders must be sorted by hash values. Sort all folders, then all files within the folders, keeping the folders contiguous. The 64 bit unsigned integer of hash value is used for sorting.

Encoding Numbers in the BSA[edit]

If Bit 7 of the archive flags is not set, numbers are encoded in little-endian byte order (low byte to high byte). A ulong of 0xABCDEF01 would have 0x01 in the first file byte, 0xEF in the second file byte, 0xCD in the third file byte, and 0xAB in the fourth and last file byte. This is true of the 64 bit (8 byte) hash value as well. If Bit 7 of the archive flags is set, then all numbers and 8 byte hash values are encoded in reverse order (big-endian).

Unpacking Utilities[edit]

Unpacking can be performed easily with BSAOpt. FOMM's or OBMM's BSA unpacking tools may not unpack some archives correctly. More specifically: If Bit 9 of archive bits is set, some tools may prepend the filename to the data while others will append it. Either scenario produces corrupted data. BSA Command requires that the version field is 0x67, so it won't function at unpacking without the use of a hex editor.

See also[edit]