NW > Model Archive (FRES)
A BFRES archive contains various resources for 3D objects, such as models, textures and animations. This page describes version 3.0.0.1
of the file format.
The general file structure is as follows:
- Header
- Metadata
- File info
- Dictionaries
- Resources
- String table
- Texture data
- File data
All offsets are relative to themselves and may be negative.
Header
Offset | Size | Description |
---|---|---|
0x0 | 4 | Magic number (FRES ) |
0x4 | 4 | Version number |
0x8 | 2 | BOM (Always 0xFEFF) |
0xA | 2 | Header size (always 0x10) |
0xC | 4 | Filesize |
Metadata
The metadata comes right after the header.
Offset | Size | Description |
---|---|---|
0x10 | 4 | Alignment |
0x14 | 4 | Offset to archive name |
0x18 | 4 | Size of string table |
0x1C | 4 | Offset to string table |
0x20 | 4 | Offset to model dictionary |
0x24 | 4 | Offset to texture dictionary |
0x28 | 4 | Offset to skeletal animation dictionary |
0x2C | 4 | Offset to shader param animation dictionary |
0x30 | 4 | Offset to color animation dictionary |
0x34 | 4 | Offset to texture SRT animation dictionary |
0x38 | 4 | Offset to shader param animation dictionary |
0x3C | 4 | Offset to bone visibility animation dictionary |
0x40 | 4 | Offset to material visibility animation dictionary |
0x44 | 4 | Offset to shape animation dictionary |
0x48 | 4 | Offset to scene animation dictionary |
0x4C | 4 | Offset to file dictionary |
0x50 | 2 | Number of model objects |
0x52 | 2 | Number of texture objects |
0x54 | 2 | Number of skeletal animation objects |
0x56 | 2 | Number of shader param animation objects |
0x58 | 2 | Number of color animation objects |
0x5A | 2 | Number of texture SRT animation objects |
0x5C | 2 | Number of shader param animation objects |
0x5E | 2 | Number of bone visibility animation objects |
0x60 | 2 | Number of material visibility animation objects |
0x62 | 2 | Number of shape animation objects |
0x64 | 2 | Number of scene animation objects |
0x66 | 2 | Number of files |
0x68 | 4 | Padding |
File Info
This section contains information for additional files that may be stored in a BFRES archive:
Offset | Size | Description |
---|---|---|
0x0 | 4 | Offset to file |
0x4 | 4 | Size of file |
These entries are referenced by the file dictionary (see metadata).
Dictionary
A dictionary contains a patricia trie that makes it possible to find an object in the BFRES archive by name. It is stored as follows:
Offset | Size | Description |
---|---|---|
0x0 | 4 | Size of dictionary |
0x4 | 4 | Number of objects |
0x8 | Dictionary nodes |
Every dictionary node is stored as follows:
Offset | Size | Description |
---|---|---|
0x0 | 4 | Inspected bit position |
0x4 | 2 | Left index (followed when bit is 0) |
0x6 | 2 | Right index (followed when bit is 1) |
0x8 | 4 | Offset to name |
0xC | 4 | Offset to data |
The search always starts at the first node. In the first node, the bit position is always -1 and the left index is always followed. Then, whether the left or right index is followed depends on the inspected bit in the object name.
The search ends when a node is reached that has a higher bit position than the previous position. For this reason, the dictionary must always be arranged so that the bits are inspected from right to left (high to low).
Given a byte string, the correct bit can be extracted as follows:
def get_bit(name, index):
return (name[index // 8] >> (index % 8)) & 1
If the bit index is longer than the given name, then 0 is used.
User Data
Various objects in a BFRES archive support user data. This can be used to store additional data in the object for any purpose.
Offset | Size | Description |
---|---|---|
0x0 | 4 | Offset to user data name |
0x4 | 2 | Number of values (N) |
0x6 | 1 | Value type |
0x7 | 1 | Padding |
0x8 | 4 * N | Values |
User Data Type
ID | Type |
---|---|
0 | Integer |
1 | Float |
2 | String |
3 | Wide string |
4 | Raw data |
Model
Offset | Size | Description |
---|---|---|
0x0 | 4 | Magic number (FMDL ) |
0x4 | 4 | Offset to model name |
0x8 | 4 | Offset to model path |
0xC | 4 | Offset to skeleton |
0x10 | 4 | Offset to vertex buffer array |
0x14 | 4 | Offset to shape dictionary |
0x18 | 4 | Offset to material dictionary |
0x1C | 4 | Offset to user data dictionary |
0x20 | 2 | Number of vertex buffers |
0x22 | 2 | Number of shapes |
0x24 | 2 | Number of materials |
0x26 | 2 | Number of user data entries |
0x28 | 4 | Number of vertices |
0x2C | 4 | Reserved (always 0) |
Texture
Offset | Size | Description |
---|---|---|
0x0 | 4 | Magic number (FTEX ) |
0x4 | 156 | Texture |
0xA0 | 4 | Reserved (always 0) |
0xA4 | 4 | Unknown |
0xA8 | 4 | Offset to texture name |
0xAC | 4 | Offset to texture path |
0xB0 | 4 | Offset to image data |
0xB4 | 4 | Offset to mipmap data |
0xB8 | 4 | Offset to user data dictionary |
0xBC | 2 | Number of user data entries |
0xBE | 2 | Padding |
String Table
Most text strings, such as object names, are stored in the string table. Every string is null-terminated and padded so that its size is a multiple of 4 bytes. Every string is also prefixed by a 4-byte integer that specifies its size without the null terminator and padding.
When an offset refers to a string, it always points to the string itself, not the length prefix.
In official files, the string table seems to be sorted. The last string is always an empty string.