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:

All offsets are relative to themselves and may be negative.

OffsetSizeDescription
0x04Magic number (FRES)
0x44Version number
0x82BOM (Always 0xFEFF)
0xA2Header size (always 0x10)
0xC4Filesize

Metadata

The metadata comes right after the header.

OffsetSizeDescription
0x104Alignment
0x144Offset to archive name
0x184Size of string table
0x1C4Offset to string table
0x204Offset to model dictionary
0x244Offset to texture dictionary
0x284Offset to skeletal animation dictionary
0x2C4Offset to shader param animation dictionary
0x304Offset to color animation dictionary
0x344Offset to texture SRT animation dictionary
0x384Offset to shader param animation dictionary
0x3C4Offset to bone visibility animation dictionary
0x404Offset to material visibility animation dictionary
0x444Offset to shape animation dictionary
0x484Offset to scene animation dictionary
0x4C4Offset to file dictionary
0x502Number of model objects
0x522Number of texture objects
0x542Number of skeletal animation objects
0x562Number of shader param animation objects
0x582Number of color animation objects
0x5A2Number of texture SRT animation objects
0x5C2Number of shader param animation objects
0x5E2Number of bone visibility animation objects
0x602Number of material visibility animation objects
0x622Number of shape animation objects
0x642Number of scene animation objects
0x662Number of files
0x684Padding

File Info

This section contains information for additional files that may be stored in a BFRES archive:

OffsetSizeDescription
0x04Offset to file
0x44Size 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:

OffsetSizeDescription
0x04Size of dictionary
0x44Number of objects
0x8Dictionary nodes

Every dictionary node is stored as follows:

OffsetSizeDescription
0x04Inspected bit position
0x42Left index (followed when bit is 0)
0x62Right index (followed when bit is 1)
0x84Offset to name
0xC4Offset 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.

OffsetSizeDescription
0x04Offset to user data name
0x42Number of values (N)
0x61Value type
0x71Padding
0x84 * NValues

User Data Type

IDType
0Integer
1Float
2String
3Wide string
4Raw data

Model

OffsetSizeDescription
0x04Magic number (FMDL)
0x44Offset to model name
0x84Offset to model path
0xC4Offset to skeleton
0x104Offset to vertex buffer array
0x144Offset to shape dictionary
0x184Offset to material dictionary
0x1C4Offset to user data dictionary
0x202Number of vertex buffers
0x222Number of shapes
0x242Number of materials
0x262Number of user data entries
0x284Number of vertices
0x2C4Reserved (always 0)

Texture

OffsetSizeDescription
0x04Magic number (FTEX)
0x4156Texture
0xA04Reserved (always 0)
0xA44Unknown
0xA84Offset to texture name
0xAC4Offset to texture path
0xB04Offset to image data
0xB44Offset to mipmap data
0xB84Offset to user data dictionary
0xBC2Number of user data entries
0xBE2Padding

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.