The GSkinAnimation (GSA) file format

Last updated: 2002-09-22, current with gsmhacking 3.1.47.

Animations in SWAT3 are stored in GSkinAnimation format, a proprietary format created by Sierra. No documentation or source code for the .gsa file format is availble.

All actions performed by characters (and objects) in the game are controlled by animations. This is easy enough to see in the case of, say, a character walking or running through the map. It is also true for a character standing stationary, pointing his weapon at a target. Here, the character is performing an animation with only one frame but an animation nonetheless.

The .gsa file format is quite simple. Leaving aside the magic, it consists of no more than a skeleton definition (which is identical to that in a .gsm file), a list of bones that are moved or rotated by the animation and then a bunch of frames. For each frame, the file lists each bone's position and orientation. Frames may also contain Events, which I will discuss in a separate section.

And that's it. If an animation has five frames and moves seven bones there are thirty-five bone positions in the file. Nothing more complicated than that.

Sections of the .gsa file

The .gsa file is composed of five sections:

  1. The .gsa file header
  2. The framerate (and other stuff)
  3. Skeleton and bones information
  4. The animated bone list
  5. Frame information

Each frame is described in three sections:

  1. Frame's location and orientation in space
  2. Bone locations and orientations
  3. Events

If you haven't studied the .gsm file format

Please refer to the .gsm documentation for details on conventions I'll use in this document.

The sections in detail

The .gsa file header

Description Size Comments or example
Magic 16 octets GSA magic is 0xCF 0xD0 0x09 0xA8 0x2A 0x1F 0xD2 0x11 0x87 0x49 0x00 0x20 0xAF 0xE6 0x36 0xEE 0x00 0x20 0xAF 0xE6 0x36 0xEE
GSA exporter version char (minor) char (major) Always 0x01 0x04 (version 4.1) or 0x02 0x04 (version 4.2)

There are two types of GSA files in the wild. The earlier (exporter version 4.1) files do not contain event information, whereas the newer (exporter version 4.2, the one available for download) do. Both versions are happily accepted by SWAT but gsmhacking needs to work with the newer format files in order to complete certain operations. Luckily, gsmhacking is capable of converting old files into the new format.

The framerate (and other stuff)

UNKNOWN short  
Framerate short In frames per second
UNKNOWN short  

The framerate is actually irrelevant as SWAT always plays the animation at 10 fps. Indeed the GSA exporter won't let you alter this value when you save a .gsa file. As to the two unknown values, they don't appear to be very important whatever they are. gsmhacking is able to process animations without worrying too much about these numbers.

Bones information

The skeleton and bone descriptions in GSA files are exactly the same as in GSM files. Please refer to the relevant section of the GSM documentation for more details.

In fact, SWAT doesn't pay any attention at all to the skeleton data. It would appear that the bone descriptions are used only to define the number of bones that are available to be animated. Either that or Sierra originally wrote one plugin that could export both GSM and GSA files and then split them into two without removing the redundant skeleton data from the .gsa format.

Animated bones list

Although SWAT pays no attention to the skeleton structure at the start of the .gsa file, you do need to provide a valid skeleton for the character class that will use your animation. So if you want to make an animation for a 52-bone SWT character, for example, you must define 52 bones in your animation. However, you may not always want to animate all those bones. Take the weapon aiming animations, for instance. Only the upper body is relevant to those animations; the character's legs stay still. To reduce the .gsa file size, the animated bones list enables you to list a set of bones that the animation will affect, leaving the others untouched.

End of bone stream short This marker has the value 0xFF 0xFF; it always follows the skeleton data
Number of animated bones short  
Bone ID short Bone ID of the first bone to be animated
Bone ID

In the special case where the number of animated bones is set to zero, no more values follow (ie there are no bone IDs listed) and all bones are assumed to be animated.


Number of frames short  
Frame   See below

Each frame looks like this:

Frame origin X co-ordinate float Frame's offset relative to position in first frame
Frame origin Y co-ordinate float Frame's offset relative to position in first frame
Frame origin Z co-ordinate float Frame's offset relative to position in first frame
Frame origin rotation quaternion X component float Frame's orientation relative to first frame
Frame origin rotation quaternion Y component float Frame's orientation relative to first frame
Frame origin rotation quaternion Z component float Frame's orientation relative to first frame
Frame origin rotation quaternion scalar component float Frame's orientation relative to first frame
Root bone X co-ordinate float Root bone's offset from its start position in the first frame
Root bone Y co-ordinate float Root bone's offset from its start position in the first frame
Root bone Z co-ordinate float Root bone's offset from its start position in the first frame
Bone position   See below
Bone position
Number of events short Events are only present in version 4.2 animations
Events   See below

The frame position and orientation are doubtless designed to allow for the creation of new co-ordinate systems when performing the animation. However, the is fixed at the origin for all frames in all GSAs in the wild. Another set of complicated maths we don't have to worry about.

Each bone listed in the animated bones list (or "all bones" when the list is empty) has its rotation for the current frame described next.

Rotation quaternion X component float  
Rotation quaternion Y component float  
Rotation quaternion Z component float  
Rotation quaternion scalar component float  

Finally, any events in the frame are listed:

Number of events short  
Event   See below

Each event looks like this:

Length of event name short Including trailing \0 terminator
Event name See above Including trailing \0 character (eg <name> 0x00)

What "events" are

Events are very cool and very powerful but what are they? And why are they called Events anyway?

Simply put, events allow you to trigger certain actions from an animation file. What this amounts to in real terms is the ability to play sounds at certain points in the animation. Six types of event have been observed:

To cut a long story short, no-one really knows what the first four are all about, although the dialogue from Sierra's animation event editor suggests that they have something to do with walking. The sound=XXX and itemsound=XXX types are understood, however.

When a frame containing a sound=XXX event is played, the sound XXX from sounds.dat (or modsounds.dat or missionsounds.dat) is triggered. For example, BG1_Secure.GSA contains the event sound=cuff on frame 12. This calls the cuff sound at that frame. The result is that cuffing a BG1 character (thus calling the animation) plays the handcuffing sound.

An itemsound=XXX event is similar, only sounds.dat is searched for a sound whose name is composed of the character's current inventory item and XXX. If that sounds confusing, consider the example of SWT_Handgun_Reload.GSA - the secondary weapon reloading animation. Frame 11 lists the event itemsound=magout and frame 19 has the event itemsound=magin. If the character playing the animation is holding a 1911 (guns.dat name "1911"), sounds.dat is searched for the sounds magout_1911 and magin_1911 respectively. If he had the HK SOCOM Mk23 suppressed (guns.dat name "mk23_s"), the sounds played would be magout_mk23_s and magin_mk23_s. You can see that using an itemsound event in this way enables you to tailor sounds to weapons (or tactical aids) in animations.

As to the question of why events are called events, it's because the GSA exporter for 3D Studio MAX looks for an object called EventObject at a specific frame when writing the event data. We needed a name for these triggers and "event" (from EventObject) just stuck.


Send any comments to