> For the complete documentation index, see [llms.txt](https://docs.bestway.com.ua/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.bestway.com.ua/foundational-knowledge/gem-rts-binary-file-formats/anm-format-.anm.md).

# ANM format (.anm)

## Overview

Format `.anm` is used to store animations of skeletal models in engines of the GEM family.\
GEM RTS supports all previous versions of the animation format.\
Each file may contain:

* frame range parameters;
* bone map;
* animation keys;
* visibility data;
* mesh animation;
* optional comments.

**File structure**

```
EANM
version
FRMS
    frame_max + 1
CMNT
    size
    comment[size]
BMAP
    bone_count
    bones [bone_count]
        bone_name
frame cycle
    FRMN | FRM2 | FRM3
```

## Chunks

### File Header

Content verifier. Confirms that the file contains animation.

<table><thead><tr><th width="117.13671875">Name</th><th width="93.76171875">Type</th><th width="78.03515625">Size</th><th>Description</th></tr></thead><tbody><tr><td>FourCC</td><td>uint8[4]</td><td>4</td><td><code>EANM</code></td></tr><tr><td>version</td><td>int16[2]</td><td>4</td><td>Format version. The first 2 bytes contain <code>major</code>, the second 2 bytes contain <code>minor</code>:<br><code>0x00040000</code> version 4.0 (GEM1, Soldiers Heroes of World War II)<br><code>0x00060000</code> version 6.0 (GEM2, Men of War)<br><code>0x00060001</code> version 6.1 (GEM2.5, Majesty2; GEM RTS, Men of War II)<br>GEM RTS supports all versions</td></tr></tbody></table>

### Chunk `FRMS`

Specifies the maximum frame number in the animation.

**Data structure**

```
FRMS
    frame_max + 1
```

<table><thead><tr><th width="145.92578125">Name</th><th width="102.61328125">Type</th><th width="82.23046875">Size</th><th>Description</th></tr></thead><tbody><tr><td><code>FourCC</code></td><td>uint8[4]</td><td>4</td><td><code>FRMS</code></td></tr><tr><td><code>frame_max + 1</code></td><td>int32</td><td>4</td><td>The value is 1 greater than the maximum frame number.</td></tr></tbody></table>

### Chunk `CMNT`

An optional comment chunk. Also used as a GEM3 format flag.

**Data structure**

```
CMNT
    size
    comment[size]
```

<table><thead><tr><th width="112.7578125">Name</th><th width="108.5">Type</th><th width="79.3515625">Size</th><th>Description</th></tr></thead><tbody><tr><td>FourCC</td><td>uint8[4]</td><td>4</td><td><code>CMNT</code></td></tr><tr><td>size</td><td>uint16</td><td>2</td><td>Comment size in bytes</td></tr><tr><td>comment</td><td>char[size]</td><td>1+</td><td>Comment text</td></tr></tbody></table>

### Chunk `BMAP`

Animation bones map. Supports LOD via suffix `._lod<lod_number>` in the name of a bone.

**Data structure**

```
BMAP
    bone_count
    bones[bone_count]
         bone_name
```

<table><thead><tr><th width="122.77734375">Name</th><th width="168.609375">Type</th><th width="80.10546875">Size</th><th>Description</th></tr></thead><tbody><tr><td>FourCC</td><td>uint8[4]</td><td>4</td><td><code>BMAP</code></td></tr><tr><td>bone_count</td><td>int32</td><td>4</td><td>The number of bones in the map. Regardless of type <code>int32</code>, version 6.1 supports no more than 255 bones</td></tr><tr><td>bones</td><td>struct[bone_count]</td><td></td><td>Bone data array</td></tr></tbody></table>

**Description of the bone array**

<table><thead><tr><th width="124.0703125">Name</th><th width="132.71875">Type</th><th width="77.1796875">Size</th><th>Description</th></tr></thead><tbody><tr><td>bone_name</td><td>string8/24 or string32</td><td>1+</td><td>Name of the bone. If the GEM3 format is used, the following applies <code>string8/24</code>. For older formats, use <code>string32</code></td></tr></tbody></table>

## Frame cycles

After the bone map, a sequence of animation frames begins.

**Data structure**

```
frame cycle
    FRMN | FRM2 | FRM3
```

The chunk type depends on the animation format version.

<table><thead><tr><th width="170.27734375">Frame format identifier</th><th width="100.73828125">Version</th><th>Comment</th></tr></thead><tbody><tr><td>FRMN</td><td>V1</td><td>Supported since GEM1</td></tr><tr><td>FRM2</td><td>V2</td><td>Supported since GEM2</td></tr><tr><td>FRM3</td><td>V3</td><td>Supported since GEM2.5 / GEM RTS</td></tr></tbody></table>

\*) GEM RTS supports all format versions.

### Frame format V1 (`FRMN`)

Used in GEM1.

**Data structure**

```
FRMN
frame_no
cycle
     BONE
     index
     cycle
          MATR
               matrix
          VISI
               visibility
          MESH
               size
               mesh_data[size]
```

#### **Frame Verifier V1**

<table><thead><tr><th width="117.1484375">Name</th><th width="101.46484375">Type</th><th width="79.80078125">Size</th><th>Description</th></tr></thead><tbody><tr><td>FourCC</td><td>uint8[4]</td><td>4</td><td><code>FRMN</code></td></tr><tr><td>frame_no</td><td>int32</td><td>4</td><td>Frame number</td></tr></tbody></table>

#### **Chunk `BONE`**

Contains animation of a single bone.

<table><thead><tr><th width="92.73828125">Name</th><th width="102.953125">Type</th><th width="83.484375">Size</th><th>Description</th></tr></thead><tbody><tr><td>FourCC</td><td>uint8[4]</td><td>4</td><td><code>BONE</code></td></tr><tr><td>index</td><td>int32</td><td>4</td><td>Bone index from the <code>BMAP</code> table</td></tr></tbody></table>

#### **Chunk `MATR`**

Bone transformation matrix.

<table><thead><tr><th width="99.89453125">Name</th><th width="115.23828125">Type</th><th width="79.578125">Size</th><th>Description</th></tr></thead><tbody><tr><td>FourCC</td><td>uint8[4]</td><td>4</td><td><code>MATR</code></td></tr><tr><td>matrix</td><td>float[3][4]</td><td>48</td><td>3x4 matrix. Contains: position, orientation, scale</td></tr></tbody></table>

#### **Chunk `VISI`**

Visibility of a bone.

<table><thead><tr><th width="99.48828125">Name</th><th width="93.73046875">Type</th><th width="88.2109375">Size</th><th>Description</th></tr></thead><tbody><tr><td>FourCC</td><td>uint8[4]</td><td>4</td><td><code>VISI</code></td></tr><tr><td>visibility</td><td>int32</td><td>4</td><td>Visibility flag. Values: <code>0</code> - invisible <code>1</code> - visible</td></tr></tbody></table>

#### **Chunk `MESH`**

Mesh animation.

<table><thead><tr><th width="109.58984375">Name</th><th width="110.62890625">Type</th><th width="79.3125">Size</th><th>Description</th></tr></thead><tbody><tr><td>FourCC</td><td>uint8[4]</td><td>4</td><td><code>MESH</code></td></tr><tr><td>size</td><td>int32</td><td>4</td><td>Mesh animation data size</td></tr><tr><td>mesh_data</td><td>uint8[size]</td><td></td><td>Mesh animation data</td></tr></tbody></table>

### Frame Format V2 (`FRM2`)

Used in GEM2.

**Data structure**

```
FRM2
frame_no
key_count

keys[key_count]
bone_map_index
key_flags

[if key_flags & 0x0001]
            position

[if key_flags & 0x0002]
            orientation

[if key_flags & 0x0040]
            scale

[if key_flags & 0x0020]
            mesh
                size
                data[size]
```

#### **Frame Verifier V2**

<table><thead><tr><th width="113.47265625">Name</th><th width="179.22265625">Type</th><th width="80.35546875">Size</th><th>Description</th></tr></thead><tbody><tr><td>FourCC</td><td>uint8[4]</td><td>4</td><td><code>FRM2</code></td></tr><tr><td>frame_no</td><td>uint16</td><td>2</td><td>Frame number</td></tr><tr><td>key_count</td><td>uint8</td><td>1</td><td>Number of animated keys per frame</td></tr><tr><td>keys</td><td>struct[key_count]</td><td></td><td>Key description structure</td></tr></tbody></table>

#### **Key structure (`struct[key_count]`)**

<table><thead><tr><th width="155.45703125">Name</th><th width="83.9453125">Type</th><th width="85.8203125">Size</th><th>Description</th></tr></thead><tbody><tr><td>bone_map_index</td><td>uint8</td><td>1</td><td>Bone index from the <code>BMAP</code> table</td></tr><tr><td>key_flags</td><td>uint16</td><td>2</td><td>Bitmask of animated parameters</td></tr></tbody></table>

#### **Bit mask for `key_flags`**

<table><thead><tr><th width="124.5">Bit</th><th>Description</th></tr></thead><tbody><tr><td><code>0x0001</code></td><td>Position</td></tr><tr><td><code>0x0002</code></td><td>Orientation</td></tr><tr><td><code>0x0004</code></td><td>Sign of a mirrored matrix</td></tr><tr><td><code>0x0008</code></td><td>Turning on visibility</td></tr><tr><td><code>0x0010</code></td><td>Turning off visibility</td></tr><tr><td><code>0x0020</code></td><td>Mesh animation</td></tr><tr><td><code>0x0040</code></td><td>Scale</td></tr></tbody></table>

#### **Key data**

Fields are present only if the corresponding bit is set in `key_flags`.

<table><thead><tr><th width="136.82421875">Name</th><th width="115.67578125">Type</th><th width="80.20703125">Size</th><th>Description</th></tr></thead><tbody><tr><td>position</td><td>float[3]</td><td>12</td><td>Position</td></tr><tr><td>orientation</td><td>float[3]</td><td>12</td><td>Normalized form of a quaternion</td></tr><tr><td>scale</td><td>float[3]</td><td>12</td><td>XYZ scale</td></tr><tr><td>mesh</td><td>struct</td><td></td><td>Mesh animation</td></tr><tr><td>mesh.size</td><td>int32</td><td>4</td><td>Data size</td></tr><tr><td>mesh.data</td><td>uint8[size]</td><td></td><td>Binary data of mesh animation</td></tr></tbody></table>

### Frame format V3 (`FRM3`)

Used in GEM2.5 and GEM RTS.

**Data structure**

```
FRM3
    frame_no

    keys[key_count]
        bone_map_index
        key_flags

[if key_flags & 0x0001]
            position

[if key_flags & 0x0002]
            orientation

[if key_flags & 0x0040]
            scale

[if key_flags & 0x0020]
            mesh
                size
                mesh_data[size]
```

#### **Frame Verifier V3**

<table><thead><tr><th width="113.6796875">Name</th><th width="170.09375">Type</th><th width="78.12890625">Size</th><th>Description</th></tr></thead><tbody><tr><td>FourCC</td><td>uint8[4]</td><td>4</td><td><code>FRM3</code></td></tr><tr><td>frame_no</td><td>uint8 <br>uint16 <br>uint32</td><td>1<br>2 <br>4</td><td><p>The field size depends on <code>frame_max</code>. <br>Used by: </p><ul><li><code>uint8</code>, if <code>frame_max &#x3C;= 255</code> </li><li><code>uint16</code>, if <code>frame_max &#x3C;= 65535</code> </li><li><code>uint32</code>, if <code>frame_max >= 65536</code></li></ul></td></tr><tr><td>key_count</td><td>uint8</td><td>1</td><td>Number of animated keys per frame</td></tr><tr><td>keys</td><td>struct[key_count]</td><td></td><td>Key description structure</td></tr></tbody></table>

#### **Key structure (`struct[key_count]`)**

<table><thead><tr><th width="161.80078125">Name</th><th width="87.83984375">Type</th><th width="91.9296875">Size</th><th>Description</th></tr></thead><tbody><tr><td>bone_map_index</td><td>uint8</td><td>1</td><td>Bone index from the map <code>BMAP</code> table</td></tr><tr><td>key_flags</td><td>uint16</td><td>2</td><td>Bitmask of animated parameters</td></tr></tbody></table>

#### **Bit mask (`key_flags`)**

<table><thead><tr><th width="110.921875">Meaning</th><th>Description</th></tr></thead><tbody><tr><td><code>0x0001</code></td><td>Position</td></tr><tr><td><code>0x0002</code></td><td>Orientation</td></tr><tr><td><code>0x0004</code></td><td>Sign of a mirrored matrix</td></tr><tr><td><code>0x0008</code></td><td>Turning on visibility</td></tr><tr><td><code>0x0010</code></td><td>Turning off visibility</td></tr><tr><td><code>0x0020</code></td><td>Mesh animation</td></tr><tr><td><code>0x0040</code></td><td>Scale</td></tr></tbody></table>

#### **Key data**

Fields are present only if the corresponding bit is set in `key_flags`.

<table><thead><tr><th>Name</th><th width="121.40625">Type</th><th width="88.25390625">Size</th><th>Description</th></tr></thead><tbody><tr><td>position</td><td>float[3]</td><td>12</td><td>Position</td></tr><tr><td>orientation</td><td>float[3]</td><td>12</td><td>Normalized form of a quaternion</td></tr><tr><td>scale</td><td>float[3]</td><td>12</td><td>XYZ scale</td></tr><tr><td>mesh</td><td>struct</td><td></td><td>Mesh animation</td></tr><tr><td>mesh.size</td><td>int32</td><td>4</td><td>Data size</td></tr><tr><td>mesh.data</td><td>uint8[size]</td><td></td><td>Binary data of mesh animation</td></tr></tbody></table>
