FEZ Content Specification

FEZ is a game built on Microsoft XNA Game Studio, which distributes all its content as a binary data stored in a proprietary XNB format. This format is then packed into a simple containers with .pak extension. This specification defines the format of these containers and XNB files with attention to details specific to FEZ.

Tip

Keep in mind that underlying knowledge of these formats is not required for modding purposes, as our current modding environment takes advantage of content conversion to more user-friendly formats. For more information, visit Content Conversion page.

Note

Both XNB and PAK binary files are compatible with C#’s BinaryReader and BinaryWriter, meaning all of the fields are little-endian, and string fields are prefixed with 7-bit encoded integer. Additionally, the following documentation will use C#’s data types for describing fields.

PAK packages

FEZ stores its assets in four package files that are buffered into a memory on game launch. Three packages, Essentials.pak, Updates.pak and Other.pak (loaded in this order), contain all game assets except music, each in a binary XNB content format. Fourth package, Music.pak, is loaded separately and contains all music in an OGG format.

PAK package format

The file starts with a small header, containing an integer indicating a number of files in this archive, followed by an array of files.

Field Type Description
uint File count defining the size of following array.
File Array Array of variable-sized files, placed one after another.

Every file in the array is represented as follows:

Field Type Description
string Path and name of the file without its extension.
uint Size of the file data in bytes.
byte[] File data.

Types of files stored in the archive can vary. Because file extensions are not included in their paths, the only indication of a file type is its own header and path/name. FEZ packages contain three types of files:

  • XNB - Microsoft XNA Game Studio 4.0 compiled content containers. Stores textures, sound effects, triles, levels, scripts and other miscellaneous data.
  • OGG - digital multimedia container. Stores music.
  • FXC - files that can be located in the effects directory. They're compiled XNA effect files.

Path of the file can be mixed case. However, FEZ expects them to be lowercase when loading assets.

It is possible for package to contain multiple files with the same path - for instance, in effects directory of Updates.pak there are multiple effect files which are stored as both FXC files and XNB Effect assets. The game seem to ignore duplicates within single package and across multiple ones, leaving only the first one cached in memory.

XNB files

Most of assets in the package files are stored in compressed XNB content format, produced by XNA Game Studio.

XNB file format

Note

This is a rough description of the format, with attention to FEZ-specific details. For full format specification, consult the XNB Content Format documentation

Header of each XNB file has following structure:

Field Type Description
char[3] Format identifier. Should be equal to ['X', 'N', 'B'].
char Target platform. Possible values are w, m and x for MS Windows, Windows Phone 7 and Xbox 360 respectively.
byte XNB format version. FEZ uses 5 - XNA Game Studio 4.0.
byte Flag bits. See below for details.
uint Compressed file size, including header.

Flag bits can contain following flags:

  • 0x01 - content is for HiDef profile (used for FEZ assets),
  • 0x40 - data is compressed (LZ4, unused for FEZ),
  • 0x80 - data is compressed (LZX, used for all original FEZ assets).

If compression flag is set, the rest of the file is compressed and prefixed with uint representing the size of this data after decompression. In case of FEZ, slightly modified LZX algorithm is used for compression. For details, visit XNB reader code from open source implementation of MonoGame.

Uncompressed data (or non-compressed file content after header) should look like this:

Field Type Description
7BitEncodedInt Type reader count, defining the number of elements in following array.
Type Reader Info Array An array of type reader information blocks.
7BitEncodedInt Shared resource count, defining the number of additional resources in array later on. Always 0 in FEZ.
Object The primary resource of the XNB file.
Object Array Shared resources array. In FEZ, none of the original XNB files contain additional resources.

Each Type Reader Info Array entry stores information about the ContentTypeReader<T> subclass that was used to read the informations within this file:

Field Type Description
string Type reader name - .NET assembly qualified name of a subclass.
int Version number, usually zero.

In original XNB files, type reader name includes assembly name specification (which contains assembly identifier, version, culture and public key token). In most cases, they're not required by the game to read the asset file. However, sometimes it is necessary to include it, especially for readers and types in FezEngine namespace. For instance, the way it's done in FEZ Repacker is by including simplified assembly name specification to every data structure that can be stored in XNB files.

Each Object is a reference to a type reader, followed by a raw data, like so:

Field Type Description
7BitEncodedInt Object type. If non-zero, then (type - 1)th entry of Type Reader Info Array is used.
byte[] Raw object data. Empty if object type is zero.

XNB reader uses the object type to determine what reader should be used to read the raw object data. Readers can use other readers to read underlying properties of the object, in which the same rule of reading object applies (a 7-bit encoded object identifier and a raw data is expected, then read by a corresponding content type reader). For primitive types like int, float, bool, etc., the data is written directly into a binary format.

Even though the structures of these objects are static, the correct type identifiers are still required by the game, and error will be thrown if mismatch of types is detected.

Additionally, binary data of an object may not ideally reflect its structure, and it's up to the corresponding content type reader to interpret it correctly.

Content types

Based on primary reader type of every XNB file contained within FEZ's packages, we can distinguish 13 unique data types.

XNB content type name Main purpose
Texture2D Sprites and textures
AnimatedTexture Animated textures
ArtObject 3D models of art objects
TrileSet Texture and models of level blocks (triles)
Dictionary[String,Dictionary[String,String]] Language texts
SpriteFont Bitmap font
Level Level data
MapTree World map data
NpcMetadata NPC behaviour information
Sky Skybox structure
TrackedSong Song information
Effect Binary XNA effect file container
SoundEffect WAV sound effect container

For now, for the exact method of storing each of these data types, refer to the implementation of ContentTypeReader for each type in FEZ decompilation.