The Sims™ Technical Aspects

SKN/BMF File Format


The following information is not based on any proprietary knowledge or restricted documentation—it was entirely derived from observation, experiment, and public information, thus it may be inaccurate or incomplete.

Analyzed by Greg Noel

(He, to get the cold side outside, put the warm side fur side inside.  That's why he put the fur side inside, why he put the skin side outside, why he turned them inside outside.  . . .)

The BMF format (.bmf) is a binary-encoded form of the SKN format (.skn) ASCII files.  It's possible that BMF stands for Binary Mesh File, but this is not known for certain. 

The format describes the deformable mesh that is used to render an object and contains a reference to the default 2D image (called a texture) used to color it.  In essence, the SKN/BMF format describes the surface (the skin) of the object; the texture is then wrapped around the skin.  (Note that skins are used to render more than just characters.  In fact, there are twice as many skins for heads as there are for bodies, and there are five times as many skins for accessories, ranging from balls and balloons to wine bottles and yoyos, as there are skins for heads and bodies combined.)

The BMF format is almost an exact match, field-for-field, with an equivalent SKN-format file.  Some values in the SKN file have more precision than is possible in the BMF file, suggesting that the .skn file is the master source and .bmf files are normally generated from .skn files. 

In the description below, when discussing the binary BMF format:

In the description below, when discussing the text SKN format:

Some .skn files have floating point values that are around 1e-45 in absolute value.  This is too small to fit in a short float (it's within the range of a long float) so the corresponding value in the .bmf file is the smallest possible, around 1e-38.  This means that it's not always possible to convert between file formats without losing information. 

The blueprint page on the .skn format (local copy here) has some details on using skins.  Hopefully, that information is useful to someone with a 3D-modeling background. 

What follows in this section is speculation on how the mesh elements fit together.  It is done by someone with no background in 3D modeling, so details are liable to be wrong and corrections would be appreciated.  The descriptions of these elements are biased toward this speculation, so if they are wrong, this is one possible reason why. 

The CMX/BCF format describes a skeleton, which defines a list of bones.  It is the bones that are moved when animating a sequence; the mesh simply tracks relative to the bones. 

The SKN/BMF format lists the skeleton bones which it will use.  It then attaches (binds) a set of vertices to each bone, so when the bone is moved, the vertices move, too. 

A vertex can be one of two types: raw or blended. 

Presumably, the sequence of actions is as follows: first, the skeleton is positioned; then the location of each raw vertex is determined from the position of the skeleton and its own offset; and finally, the vertex is adjusted by any blendings that refer to it. 

Once the location of each raw vertex has been determined, the object can be rendered by using the list of faces.  A face consists of three raw vertices, so the triangular area from the associated texture can be painted on the triangular region of the surface, distorting as needed to fit and applying shading. 

BMF File Format
Offset Size Value
0 var Skin name
var var Default texture name
var 4 Count of bones
var var Bone name
var var . . .
var 4 Count of faces
var 12 Face
var 12 . . .
var 4 Count of bone bindings
var 20 Bone binding
var 20 . . .
var 4 Count of texture points
var 8 Texture point
var 8 . . .
var 4 Count of blendings
var 8 Blending info
var 8 . . .
var 4 Count of vertices
var 24 Vertex
var 24 . . .

The BMF format has no leading signature; it immediately starts with two strings, followed by six types of repeating groups.  The equivalent SKN format follows the same structure:

	string-skin-name
	string-texture-name
	count-of-bones
	string-bone-name ...
	count-of-faces
	<face> ...
	count-of-bone-bindings
	<binding> ...
	count-of-texture-points
	<texture-point> ...
	count-of-blending-weights
	<blending-weight> ...
	count-of-verticies
	<vertex> ...

The first string is the name of this skin.  Skin files are invariably named after the contained skin, so if the skin is named foo, it would be found in a file named foo.bmf or foo.skn

The second string is the default texture to apply to the mesh.  This default may be overridden (and often is, particularly for character skins).  If the texture is always overridden, the texture name is sometimes given as "x" or some other nonsensical name. 

A skin is rendered relative to one or more bones in a skeleton.  The list of bones names the bones that this skin will use as its basis; the count of bones gives the number of bones in the list.  Each bone is a string; it matches a bone named in the skeleton.  The order is significant; subsequent entries use an index into this list to refer to the bone.  Note that a skin need not surround the bone(s); it may well identify a volume that is offset from the bone.  Moreover, more than one skin may be applied to a given bone.  This is how a character can carry a chisel or wear a hat; one skin covers the character and the other provides the object. 

A face is a set of three vertices.  It simultaneously represents a triangular region of the surface being rendered and a triangular area in the texture being wrapped.  The count of faces gives the number of faces present. 

A bone binding associates a subset of the vertices with a bone.  The count of bone bindings gives the number of bone bindings present. 

A texture point is a 2D location within the texture image; it matches a corresponding raw vertex.  In other words, the texture point maps a 2D texture location to a 3D vertex; after the vertices are calculated and converted into a screen location, each triangular face of the texture is translated onto the screen.  The count of bone bindings gives the number of bone bindings present. 

A blending info is used when moving a shared vertex (that is, when deforming the mesh).  The count of blendings gives the number of blendings present.  There is one blending info for each blended vertex. 

A vertex entry has the position and normal values (for both raw and blended vertices).  The count of verticies gives the number of verticies present. 

The number of bone bindings is always exactly the same as the number of bones specified, and each bone is specified in a binding exactly once, in the same order.  Moreover, the number of vertices is always equal to the number of texture points plus the number of blendings.  (This is true of all known samples, supporting the speculation about how these elements fit together.) 

This means that the layout is more complex than it need be.  However, if we assume that the memory layout used by the game parallels the file format, then all of the verticies are located together, which allows graphics transformations to be pipelined in a more cache-friendly way. 

The redundancy of the bones and the bindings is a bit puzzling, but if we assume that this layout evolved from an earlier one that only allowed rigid meshes, then these could have been pre-existing elements. 

Most other formats contain very little redundancy, so it's quite possible there are some aspects of this format that are not yet understood.  Keep in mind that the assumptions made here could be wrong. 

BMF Face
Offset Size Value
0 4 Vertex index 1
4 4 Vertex index 2
8 4 Vertex index 3

A face consists of three integers.  Each integer is an index to a raw vertex in the list of vertices.  The SKN format lists these three integers on a single line:

	vertex-ix-1 vertex-ix-2 vertex-ix-3

The face vertices are listed in counter-clockwise order.  This can be used to determine the normal to the face (that is, the direction perpendicular to the face pointing outward), which is needed when rendering. 

BMF Bone binding
Offset Size Value
0 4 Bone index
4 4 Raw vertex index
8 4 Raw vertex count
12 4 Blended vertex index
16 4 Blended vertex count

Bone bindings attach a subset of the vertices to bones.  Each entry consists of five integers.  The SKN format lists these five integers on a single line:

	bone-ix raw-ix raw-cnt blend-ix blend-cnt

The bone index is an index into the list of bones, indicating to which bone the vertex is being bound. 

The raw vertex index is an index into the texture point section (below).  The raw vertex associated with that texture point is the first raw vertex to bind to the bone.  The raw vertex count says how many consecutive vertices are to be bound to the bone.  The vertex count is always positive; it is not known if it is possible to have a binding with only blended vertices. 

The blended vertex index is an index into the blending info section (below).  The blended vertex associated with that blending info is the first blended vertex to bind to the bone.  The blended vertex count says how many consecutive vertices to bind to the bone.  If the blended vertex count is zero, meaning that there are no blended vertices to bind to the bone, the blended vertex index is specified as -1. 

Both the raw index and the blended index start at zero in the first entry and subsequent active entries are incremented by the respective counts.  As such, the index and count values are redundant, and it's puzzling why both would need to be included. 

BMF Texture point
Offset Size Value
0 4 X offset
4 4 Y offset

A texture point is a location in the texture being used to wrap the mesh.  There is one texture point for each raw vertex.  Each entry consists of two 32-bit floating point numbers.  The SKN format lists these two numbers on a single line:

	x-offset y-offset

The X and Y offsets are between zero and one.  They provide the grid location for a point within the associated texture. 

The vertex associated with this texture point is located in the vertex section (below).  The index for the vertex information is the same as the index to the texture point. 

BMF Blending info
Offset Size Value
0 4 Weight
4 4 Vertex index

The blending info identifies the raw index associated with a blended index (that is, the raw index that the blended index will deform) and provides the blending weight.  The SKN format has the same values on a single line, but note that the values are reversed:

	vertex-index weight

The weight is an integer that is used during blending.  Exactly how it works is unknown; hopefully, some expert on 3D graphics will elucidate it someday. 

The vertex index is an index to a raw vertex in the vertex section (below).  Although it would be possible for more than one blended vertex to refer to the same raw vertex, there are no cases where this occurs.  The mathematics of blending multiple verticies suggest that it is unlikely, since the required transformations are not associative, so the results would differ depending on the order in which blends were applied.  The limitation to at most one blending for a raw vertex is probably a restriction of the format. 

The vertex associated with this blending info is located in the vertex section (below).  Assuming that there are N raw vertices, the index for the vertex information is N plus the index to the blending info. 

BMF Vertex
Offset Size Value
0 4 x offset
4 4 y offset
8 4 z offset
12 4 normal x
16 4 normal y
20 4 normal z

This component consists of six 32-bit floating-point values.  The SKN format lists the values on one line:

	z-off y-off x-off z-norm y-norm x-norm

A vertex reflects an offset in 3D space and then normal orientation for the point (that is, which direction is "outside").  A mesh must have at least one face, so it follows that there must be at least three vertices. 

Three floating point numbers give the (x, y, z) value of the offset. 

Three more floating point numbers give the (x, y, z) value for the normal direction (that is, pointing most directly away from the inside). 

Vertices are divided into two segments.  The first segment corresponds one-for-one with the texture points.  The second segment corresponds one-for-one with the blendings. 

Each vertex is bound to exactly one bone, although the format allows a vertex to be bound to multiple bones (or not to be bound at all).  This is probably a restriction of the format. 


Reminder: This information is not based on any proprietary knowledge or restricted documentation—it was entirely derived from observation, experiment, and public information, thus it may be inaccurate or incomplete.

Valid XHTML 1.1! Valid CSS!
Copyright © 2001-2008 Dave Baum and Greg Noel. All rights reserved.
The Sims™ is a trademark of Maxis and Electronic Arts.
This page was last modified Wednesday, 03-Mar-2004 18:31:19 UTC.
Made on a Mac
SourceForge