Skip to content
Colin Basnett edited this page Oct 22, 2018 · 35 revisions

This page describes the format for the ABC models found in No One Lives Forever.

All binary numeric values are in little-endian byte-order.

Sections

The file lists various sections consecutively. Each section begins with it's type, followed by an absolute offset to the next section. The data that follows in the section is dependent on the section's type (see Section Data).

Section

Name Type Notes
Type String
NextSectionOffset uint32 Offset is relative to the beginning of the file (absolute offset).
Data Variable (see below)

Section Data

Header

Name Type Notes
Version uint32
KeyframeCount uint32
AnimationCount uint32
NodeCount uint32
PieceCount uint32
ChildModelCount uint32
FaceCount uint32
VertexCount uint32
WeightCount uint32
LODCount uint32
SocketCount uint32
WeightSetCount uint32
StringCount uint32 See below.
StringLengthTotal uint32 See below.
CommandString String
InternalRadius float32
LODDistanceCount uint32
Padding uint8[60] This is a bit-field of zeroes for every file in the game.
LODDistances float32[LODDistanceCount]

StringCount is the total number of unique, non-empty strings in:

  • Command string (counts as 1, unless empty)
  • Node names
  • Child model names
  • Animation names
  • Keyframe strings

StringLengthTotal is the summed length of all of the strings.

The purpose of these two variables is unknown, but one can speculate that it's likely used for some sort of memory mapping scheme within the engine.

Pieces

Name Type Notes
WeightCount uint32
PieceCount uint32
Pieces Piece[PieceCount]

Nodes

The nodes block is a flat list of the nodes in depth-first traversal order.

Name Type Notes
Nodes Node[NodeCount]

ChildModels

The term "Child Models" actually seems like a bit of a misnomer, since this is used to inherit the animations of other models. A more appropriate name might be "Base Models". It's interesting to note that the number of base models appears to be one more than it actually is. The first entry appears to be a ChildModel with an empty name.

Name Type Notes
Count UINT16
ChildModels ChildModel[ChildModelCount]

Animation

Name Type Notes
Count uint32
Animations Animation[Count]

Sockets

Name Type Notes
Count uint32
Sockets Socket[Count]

AnimBindings

This section appears to be redundantly listing the Extents of each Animation in the file.

Name Type Notes
Count uint32
AnimBindings AnimBinding[Count]

Data Types

String

Strings are length-prefixed.

Name Type Notes
Length uint16
Bytes uint8[Length] ASCII-encoded bytes.

Vector

Name Type Notes
X float32
Y float32
Z float32

TexCoord

Name Type Notes
U float32
V float32

Quaternion

Name Type Notes
X float32
Y float32
Z float32
W float32

Piece

Name Type Notes
Material Index uint16
Specular Power float32 (0..100)
Specular Scale float32 (-10..10)
LOD Weight float32
Unknown uint16 Always 0.
Name String
LODs LOD[LODCount]

LOD

Name Type Notes
FaceCount uint32
Faces Face[FaceCount]
VertexCount uint32
Vertices Vertex[VertexCount]

Face

Name Type Notes
Vertices FaceVertex[3]

FaceVertex

Name Type Notes
Texcoord TexCoord
VertexIndex uint16

Vertex

Name Type Notes
WeightCount uint32
Weights Weight[WeightCount]
Location Vector
Normal Vector

Weight

Name Type Notes
NodeIndex uint32
Location Vector
Bias float32

Node

Name Type Notes
Name String
Index uint16
Flags uint8 See flags below.
Matrix float32[16]
ChildCount uint32

Node Flags

Name Type Notes
Removable 0x01 The word "removable" was gleaned from ModelEdit, where nodes with this flag are marked as (removable). It's not yet know what this means, exactly, but it appears that the root node of every model has this flag set.
RelativePlacement 0x02 Checking a node's checkbox in ModelEdit turns this flag on. According to official Lithtech documentation: "If a node name has a check in its check box, the node will be placed relative to its parent, only the rotation will be used from the animation data. Not checking these where needed will cause bone lengths to be transferred from a child model to the parent, causing potentially strange looking scaling of a character".

Animation

Name Type Notes
Extents Vector
Name String
Unknown int32 Value is -1 the vast majority of the time, though there are some exceptions (see PLAYERBASE.ABC and DOG_ACTION.ABC).
Interpolation Time uint32 The time, in milliseconds, it takes to interpolate playing this this animation.
KeyframeCount uint32
Keyframes Keyframe[KeyframeCount]
Keyframe Transforms KeyframeTransform[NodeCount][KeyframeCount]

Keyframe

Name Type Notes
Time uint32 The time, in milliseconds, that this key-frame appears at in the animation.
String String This string provides animation-based cues to the game code.

KeyframeTransform

Name Type Notes
Location Vector
Rotation Quaternion

AnimBinding

Name Type Notes
Name String
Extents Vector
Origin Vector

Socket

Name Type Notes
Node Index uint32
Name String
Rotation Quaternion
Location Vector