The latest released version of gsmhacking is gsmhacking 3.1.51.
Quick tutorial
Known bugs
Command list
Information functions
Texture functions
Material functions
Animation functions
Conversion functions
Diagnostic functions
Debugging modes
Reporting bugs
Technical notes

Please check the known bugs and read "How to submit bug reports" before reporting bugs or asking for help.


SWAT3 character and weapon model data files are stored in GSM format, which stands for GSkinMesh. To make a new .gsm model, you need to have 3D Studio Max 2.5 and Character Studio 2.1. Then you can make a model, map textures to it and export it as a .gsm file.

As anyone who's read the [furryclan] uniform guide will know, you can still make mods even if you don't have 3D Studio Max, by "reskinning" existing .gsm files. This means editing the file data to replace the filenames of textures used by the model.

Until now, this had to be done using a hex editor. You would load your .gsm file into an editor, search for the texture name you wanted to replace and overwrite the characters in its name one by one. Any mistakes, such as adding or deleting characters, are fatal because the length of the filenames is encoded in the data, though if you know enough about the file format you can compensate for that.

gsmhacking to the rescue

The days of hand editing .gsm files are over. gsmhacking allows you to list and modify the textures in a .gsm file from the command line as well as offering more "advanced" features for adventurous hackers. It fully understands the GSM file format and thus lets you enter filenames of any length. The C source code to gsmhacking is included in the zip file. You should be able to compile it on any machine with a C compiler (erm, any machine that uses little-endian byte order and where ints are 32 bits). It has been tested on Windows 2000 (using cygwin) and Linux.


With the release of version 3.1.6, gsmhacking can handle GSkinAnimation files as well as GSkinMesh files.

Installation and quick usage guide for Windows

Installing gsmhacking

After you have unzipped, copy gsmhacking.exe and the Cygwin DLLs to somewhere in your %PATH%. On Windows NT/2000, C:\WINNT is as good a place as any. For Windows 95/98/ME users, C:\WINDOWS\COMMAND should suffice. C:\WINDOWS\SYSTEM32 will do for Windows XP/2003 (and later) users.

Now bring up a DOS box. If you don't know how to do this, here's where you learn. On NT, go to the Start Menu and select Run. Type cmd in the box and press enter. On 9x, select Run in the same way but type command instead. NT also has command but cmd is nicer: you can press the up arrow key to get back the last thing you typed, for example.

An even better solution (not described here) is to download the cygwin tools and use a real shell: bash...

In your DOS box, type gsmhacking -V. Please note that that is a capital V. Lowercase -v has a different meaning. You should see something like this:

gsmhacking version 1.2 by [furrycat], 2001-07-15

Getting started

The remainder of this section will show how to use gsmhacking to edit the textures in the [furryclan] uniform mod. If you want to follow along, head over to the [furryclan] downloads page and pick up the latest version of the mod. Unzip it into some directory other than your SWAT3 mods directory. Say C:\downloads for example. It doesn't matter. Now go to the furryclan-uniform directory (using cd c:\downloads\furryclan-uniform). We'll check out the [furryclan] guest model, which is defined in swt_fc00_high.gsm.

gsmhacking -l -m swt_fc00_high.gsm
00 SWT_fche00.bmp
01 SWT_fcp00.bmp
02 SWT_ELEM_VISOR.bmp - not found!
03 SWT_HISP_FACE.bmp - not found!
04 SWT_fcv00.bmp
03 SWT_fcp00.bmp
03 SWT_fcp00.bmp
03 SWT_fcp00.bmp
03 SWT_fcp00.bmp
05 SWT_fcp00.bmp
06 SWT_fcp00.bmp
07 SWT_fcl00.bmp
07 SWT_fcp00.bmp
09 SWT_fcp00.bmp
10 SWT_fcl00.bmp
11 SWT_fcp00.bmp
12 SWT_fcp00.bmp
13 SWT_fcp00.bmp
14 SWAT_fc_N.bmp

The above is a list of all the texture files referenced in the guest model. You will see that two have been marked as not found. This means the textures were not found in the current directory or any of its subdirectories. In the case of SWT_ELEM_VISOR.bmp and SWT_HISP_FACE.bmp this is no big deal because those files are included in the game anyway.

The check for missing files is only performed if --missing is specified.

You can also get a detailed list of the textures using the --verbose flag.

gsmhacking -v -l -m swt_fc00_high.gsm
Texture 00 at 0xa490: H:\SWAT3_cqb\FINAL_CHARACTERS\SWT_TEAM\SWT_fche00.bmp (53)
Texture 01 at 0xa4c9: H:\SWAT3_cqb\FINAL_CHARACTERS\SWT_TEAM\SWT_fcp00.bmp (52)
Texture 02 at 0xa501: H:\SWAT3_cqb\FINAL_CHARACTERS\SWT_TEAM\SWT_ELEM_VISOR.bmp (57) - not found!
Texture 03 at 0xa53e: H:\SWAT3_cqb\FINAL_CHARACTERS\SWT_TEAM\SWT_HISP_FACE.bmp (56) - not found!
Texture 04 at 0xa57a: H:\SWAT3_cqb\FINAL_CHARACTERS\SWT_TEAM\SWT_fcv00.bmp (52)
Texture 05 at 0xa5b2: H:\SWAT3_cqb\FINAL_CHARACTERS\SWT_TEAM\SWT_fcp00.bmp (52)
Texture 06 at 0xa5ea: H:\SWAT3_cqb\FINAL_CHARACTERS\SWT_TEAM\SWT_fcp00.bmp (52)
Texture 07 at 0xa622: H:\SWAT3_cqb\FINAL_CHARACTERS\SWT_TEAM\SWT_fcp00.bmp (52)
Texture 08 at 0xa65a: H:\SWAT3_cqb\FINAL_CHARACTERS\SWT_TEAM\SWT_fcp00.bmp (52)
Texture 09 at 0xa692: H:\SWAT3_cqb\FINAL_CHARACTERS\SWT_TEAM\SWT_fcp00.bmp (52)
Texture 10 at 0xa6ca: H:\SWAT3_cqb\FINAL_CHARACTERS\SWT_TEAM\SWT_fcp00.bmp (52)
Texture 11 at 0xa702: H:\SWAT3_cqb\FINAL_CHARACTERS\SWT_TEAM\SWT_fcl00.bmp (52)
Texture 12 at 0xa73a: H:\SWAT3_cqb\FINAL_CHARACTERS\SWT_TEAM\SWT_fcp00.bmp (52)
Texture 13 at 0xa772: H:\SWAT3_cqb\FINAL_CHARACTERS\SWT_TEAM\SWT_fcp00.bmp (52)
Texture 14 at 0xa7aa: H:\SWAT3_cqb\FINAL_CHARACTERS\SWT_TEAM\SWT_fcl00.bmp (52)
Texture 15 at 0xa7e2: H:\SWAT3_cqb\FINAL_CHARACTERS\SWT_TEAM\SWT_fcp00.bmp (52)
Texture 16 at 0xa81a: H:\SWAT3_cqb\FINAL_CHARACTERS\SWT_TEAM\SWT_fcp00.bmp (52)
Texture 17 at 0xa852: H:\SWAT3_cqb\FINAL_CHARACTERS\SWT_TEAM\SWT_fcp00.bmp (52)
Texture 18 at 0xa88a: H:\SWAT3_cqb\FINAL_CHARACTERS\SWT_TEAM\SWAT_fc_N.bmp (52)
found 19 textures in swt_fc00_high.gsm
missing 2 files in directory

Here we see the hex offset in the file where the texture is found, which is useful if you want to hexedit the file manually and (in brackets at the end) the filename length. Note that the filename length is largely irrelevant now that gsmhacking can write arbitrary length filenames but it used to be important.

Your first texture hack

Using your favourite image editing program, load SWAT_fc_N.bmp. This is the [furryclan] logo for the back of the uniform. Change it to a logo of your own and save the new file as SWAT_TEAM_LOGO.bmp. Now we will tell gsmhacking to replace the [furryclan] texture with yours.

gsmhacking -r SWAT_fc_N.bmp SWAT_TEAM_LOGO.bmp swt_fc00_high.gsm
replaced one occurrence of SWAT_fc_N.bmp

gsmhacking can be used to search for a particular substring in the texture list:

gsmhacking -v -s LOGO swt_fc00_high.gsm
Texture 18 at 0xa88a: SWAT_TEAM_LOGO.bmp (18)
found 1 texture in swt_fc00_high.gsm

Finally, repeat the procedure for the low polygon count version of the model:

gsmhacking -r SWAT_fc_N.bmp SWAT_TEAM_LOGO.bmp swt_fc00_low.gsm
replaced one occurrence of SWAT_fc_N.bmp

Copy the furryclan-uniform directory to your SWAT3 mods directory. Activate the furryclan-uniform mod (NOT the zip you downloaded earlier) and start a LAN game with AI officers. Choose the [furryclan] guest for everyone. They should have your logo instead of [furryclan].


If things don't work out, check out these common problems.

Detailed command list

gsmhacking is usually invoked in the following way:

gsmhacking [options] commands filenames [commands filenames...]

In version 3 you can provide a list of options and/or a list of filenames. All options apply to the filenames that follow. For example, you can replace textures in multiple files like this:


Alternatively you can apply multiple options to a single file:


You can even apply multiple options to multiple files. The following example replaces two textures in two files, then replaces a texture in another file.


Any "trailing" options, that is options that follow the last filenames, are applied to that filename group. Thus the following two commands are synonymous:


You always need at least one filename and at least one option, however if you don't give an option gsmhacking will assume you want --summary. The exceptions to this are calling gsmhacking -h to get help or gsmhacking -V to get version information.

Most options have a short form and may have (several) aliases. Instead of typing -h you could use --help and instead of typing --make-suspect you could use --make-tac. Here's a list of all the commands and options.


Information functions:
-C,  --classify: determine model type
-S,  --summary: print short summary about the model
-D,  --describe: print detailed description of the model
     --export-skin-o-matic: print a very short summary of the model

Texture functions:
-l,  --list-textures: list contents of .gsm
-s,  --search-textures <pattern>: search for a specific texture
-r,  --replace-textures <pattern> <replacement>: replace textures in .gsm
-t,  --set-texture <number> <filename>: set a texture by its number
     --optimise-textures: perform some texture optimisations
-uv, --generate-uv-maps: create UV mappings for a group

Material functions:
-mt, --map-texture <material> <type> <number>: set a texture by its number
-cm, --clear-map <material>: clear maps from a material
-T,  --material-transparency <material> <percentage>: set a material's transparency level
-N,  --material-name <material> <name>: set a material's name
     --optimise-materials: perform some material optimisations
     --copy-material: copy materials and associated geometry from an external GSM
     --list-map-types: show map types understood by gsmhacking

     --fix-hit-detect <filename>: import hit detection from an external GSM

Animation functions
     --john-woo: slow down an animation
-ae, --add-event <frame> <event>: add an event to a frame
-ce, --clear-events <frame>: clear events from a frame
     --rotate-bone <bone> <axis> <angle> <first frame> <last frame>: rotate a bone in a set of frames

Conversion functions
     --import-milkshape <file>: read a Milkshape .ms3d file and write out a GSM
     --make-swat: convert a hostage or suspect model or animation into a playable SWAT character or animation
     --make-kid: convert a SWAT officer, hostage or suspect model or animation into a child hostage character or animation
     --make-suspect: convert a SWAT or hostage model or animation into a suspect character or animation
     --make-female-suspect: convert a SWAT or hostage model or animation into a suspect character or animation
-R,  --make-rifle: fix broken secondary weapons so they can be used as primaries
-F,  --add-flashlight: add a flashlight to weapons that have none
-O,  --optimise: perform any necessary optimisations


-m,  --missing: check for missing textures
-o,  --outfile <filename>: write the new GSM to given <filename>
     --prefix <prefix>: write the new GSM using a filename composed of <prefix> and the original filename
     --suffix <suffix>: write the new GSM using a filename composed of the original filename and <suffix>
-h,  --help: print usage instructions and examples
-V,  --version: print version information
-v,  --verbose: print more information
-d,  --debug: print debugging information
-sd, --super-debug: set maximum debugging
-q,  --quiet: no output at all

Classify command

-C, --classify
Try to determine what a GSM or GSA file actually is. For GSMs, --classify looks at the number of bones and grippers in the model, as well as examining material names, to make its guess. For GSAs, all we can work with is the number of bones. Be advised that the result of this command is not always right!
Interpret the output of --classify as follows:

Options: --verbose
When --verbose is given with --classify, gsmhacking prints a more detailed description of the model.

Summary command

-S, --summary
Print a summary of the GSM file's attributes. This option may not be of much interest to most people.

Describe command

-D, --describe
Print a detailed description of the model or animation.

Options: --verbose
With each occurrence of the --verbose option, gsmhacking will print more information in its description. Without --verbose, gsmhacking prints bone, texture, material, grip and gripper information. With --verbose, gsmhacking also prints full bone, texture, shared triangle list and gripper information, and summaries of vertex, vertex to bone assignment, blended vertex, texture co-ordinate, effective vertex and triangle data. With --verbose --verbose, gsmhacking prints everything about the model.

Skin-o-Matic export command

Prints a summary of the GSM in a format that can be read by the Skin-o-Matic. You definitely won't have any use for this.

List textures command

-l, --list-textures
List the texture names in the .gsm file. The list command shows the basename of each filename and will, if --missing is set, attempt to find the file in the current directory and any subdirectories. This is to warn you if you need to copy files into your mod directory before zipping up your mod. If a texture is referenced multiple times in the .gsm, gsmhacking will print out its name more than once. This is by design.
As of gsmhacking version 1.8, --missing is NOT the default. This is because it takes too long to look for the files on Windows.

Options: --verbose, --search-textures
When --verbose is given with --list-textures, gsmhacking will print the full path to the texture as encoded in the .gsm file. The offset within the file of each texture is printed (this is why each occurrence of a texture is printed), along with the length of the full path. In verbose mode, --list-textures will also print the number of textures found in the .gsm file.
When --search-textures <pattern> is given with --list-textures, gsmhacking will print only those textures whose name contains the substring pattern. Pattern matching is case-insensitive. In verbose mode, only the number of names matching the pattern are counted when printing the number of texture in the file.

Aliases: --list-texture --texture-list --textures-list

Search textures command

-s, --search-textures <pattern>
Using --search-textures as a command is entirely synonymous with using it as an option to --list-textures.

Options: --verbose

Aliases: --search-texture --texture-search

Replace textures command

-r, --replace-textures <pattern> <replacement>
Replaces the filenames that match <pattern> with the filename given in replacement. All matching occurrences of the filename are replaced. Note the maximum filename length the GSM file format can handle is 65536 characters.

Options: --verbose
When --verbose is given with --replace-textures, gsmhacking explains which patterns matched and which textures were replaced.

Aliases: --replace-texture --texture-replace

Set texture command

-t, --set-texture <number> <filename>
Sets the filename for texture with number number to filename. This is a quicker way to set one texture (or multiple textures if you call the option more than once) than using complicated search and replace patterns. Use --list-textures to find the texture number you wish to replace and then call --set-texture with that number.

Aliases: --set-textures

Optimise textures command

Removes all textures that are not mapped by any map in any material. Specifically, removes any textures with a texture number that is not part of any map in any material. Another option that probably isn't of interest to most people.

Aliases: --optimize-textures

UV map generation command

-uv <group> <colour>
Draws triangles over a bitmap image to generate UV maps for skinning. group is a triangle group index (starting from 0). colour is the colour in which the maps will be drawn, specified in the HTML standard format "#xxxxxx" (eg white is #ffffff, black is #000000 and blue is #0000ff). You can also use "transparent" to tell gsmhacking not to overlay the map on top of the original texture file but to create a 256x256 pixel BMP instead. The resulting maps will be white on black. Use your favourite image editing program to mask the black background and overlay the map.

gsmhacking will create the "transparent" map if it can't find the texture file used by the group's material in the current working directory, or if the material has no texture. The output map is written to a file whose name is derived from the GSM name and the group index.

Aliases: --uv --generate-uv-maps

Map textures command

--map-texture <material> <type> <texture>
Maps the given texture to the given material using the given map type.
The material may be specified either by name or by its index (as shown by --describe). The texture must be specified by its index. Beware that the first index of a material or texture in the model is zero not one. Beware also that material indices are not necessarily the same as texture indices, although there is usually a one-one mapping between them with characters.
You can specify the map type by its name or index (NOT recommended). Use --list-map-types to get a list of all the map types gsmhacking understands. Note that the only ones that are really worth using are diffuse (the most common) and reflection. Diffuse just maps the texture on to the mesh. Reflection also gives the texture reflective properties. Officers' visors and some helmets have this type of map, giving them that shiny feel.
The first use of --map-textures removes any existing maps and inserts the new one. Subsequent uses add to the map you set, though adding different map types isn't usually worthwhile. Use --clear-map to remove maps.

Aliases: --material-texture --set-map-texture --set-material-texture

Clear texture map command

--clear-map <material>
Remove all maps from a material. This command is practically useless and is included for completeness only.

Aliases: --clear-material

Material transparency command

--material-transparency <material> <percentage>
Sets a material's transparency. You can use this to achieve cool effects such as those seen in the Ghost Recon mod. The transparency in that mod is 82%. Visors and sunglasses should be made partially transparent so you can see the officer's face behind.

Aliases: --transparency

Material name command

--material-name <material> <name>
Sets a material's name. A material's name obviously helps you to know which part of the mapped texture is actually used - very useful when modellers pack lots of sections into a single texture file - but it also has some magic properties. See my advanced uniform guide for more details.

Aliases: --name

Optimise materials command

Removes all materials that are not mapped on to any surface. Specifically, removes any materials with a material number that is NOT claimed by any triangle groups. gsmhacking then reorders material numbers in all triangle groups to match the remaining materials to their original group. This is equivalent to removing an unused material from the material editor in 3D Studio MAX and remapping material IDs on faces in the mesh. Yet another option you probably won't ever use.

Aliases: --optimize-materials

Copy material command

--copy-material <filename> <material> <name>
Copies a material (and vertices and triangles mapped with that material) from filename to the working GSM. You can specify material as either its name or its index (starting from 0). By default, gsmhacking will create the copied material with the same name as the source. You can override this with name. Set name to "" to keep the original name (useful if you choose a a material by index without knowing its name).

The primary use of this function is to add objects to models. You could, for example, add a flashlight mesh to a weapon for a more realistic effect than simply --add-flashlight hacking. Or you could give a character a helmet. In both these cases, the technique is to use Milkshape or 3D Studio MAX to create the new object, making sure it is physiqued to an identical skeleton to the destination, and then copy the new materials over.

For example: --copy-material speechbubble.gsm 0 ""

This copies the infamous Martin Brenner speech balloon model (it has only one material, hence material is 0, and we don't care about the name so name is "").

List map types command

Prints the list of map types understood by gsmhacking. As mentioned previously, the only ones really worth using are diffuse and reflection.

Fix hit detection command

--fix-hit-detect <filename>
Repairs a bug in versions of GSkinViewer prior to 1.11, which removed hit detection information from models they reskinned. If you have the original model which was reskinned you can use this command to import hit detection information from that model and apply it to the current GSM. This will only work if the source filename GSM has the same number of triangles and vertices as the GSM to fix.

For example: --fix-hit-detect SWT_ELEM_HIGH.GSM

This copies hit detection information from SWT_ELEM_HIGH, assuming that you previously created a GSM by reskinning that model.

John Woo mode command

Repeats frames in the animation to give a crude slow motion effect.

Aliases: --johnwoo

Add event command

--add-event <frame> <event>

Adds an event to the given frame. Known events are of the form sound=xxx and itemsound=xxx. xxx must be an entry in sounds.dat. Where the event is sound=xxx, the game will play the sound xxx (from sounds.dat) at the given frame. Where the event is itemsound=xxx, the game will play a sound from sounds.dat constructed from xxx and the name of the item currently held by the character being animated.

For example if a SWAT officer is holding an M4 and the SWT_Rifle_Reld_Tac.GSA animation is played (which has itemsound=magin at frame 20), the game plays the sound referenced by MagIn_M4 in sounds.dat.

Four other events seen "in the wild" are LPLANT, LLIFT, RPLANT and RLIFT. I think these have to do with movement animations - raising and planting footsteps - but I'm not sure yet.

The first use of --add-event clears any events already present in the frame. To add more than one event to a frame you must call --add-event multiple times in the same invocation of gsmhacking.

Aliases: --set-event

Clear events command

--clear-events <frame>
Removes all events from frame.

Aliases: --clear-event --delete-events --delete-event

Rotate bone command

--rotate-bone <bone> through <axis> <angle> <first frame> <last frame>
Rotates bone angle degrees about axis in frames first frame through last frame.

bone my be specified either by name or bone ID. Since bone names have spaces in them you will need to put quotes around the name. For example: "Biped L Clavicle"
axis should be X, Y or Z.
angle should be a number in the range -180 to 180. You can use decimal places if you want.
first frame and last frame are either frame numbers (starting from 0) or the words "first" or "last" - you will probably always use "first" and "last" unless you want to do funky stuff.

The co-ordinate system for the rotations is local, which means that the origin is defined at the bone's position. GSM co-ordinates are in the left-handed system.

Please note that gsmhacking does not have an Inverse Kinematics implementation (whereas SWAT3 does) and so attempting to perform extravagant rotations may leave the mesh distorted. If you were to rotate a skeleton's elbow joint in 3D Studio MAX you would see the elbow joint and possibly the wrist joint also rotating so the skeleton wasn't deformed. You must take a shot at guessing what supplementary rotations would be needed if you don't want to create a funny looking mesh. On the other hand, if you DO want to create a funny looking mesh, gsmhacking won't stop you...

Milkshape 3D import command

--import-milkshape <file>
Reads the specifide Milkshape 3D file and generates a GSkinMesh. You must use this command in conjunction with --outfile to set the resulting GSM.

Please read the tutorial before attempting to use this command.

You need gsmhacking version 3.1.37 or later for best results.

Make SWAT command

Converts a suspect or hostage model or animation into a playable SWAT character or animation.

Aliases: --make-swt

Make KID command

Converts a model or animation into a KID class child hostage model or animation. Of dubious usefulness.

Make suspect command

Converts a SWAT officer or hostage to a bad guy. The exact model type that is written depends on the given GSM. If it is a SWT, KID, MH1 or MH2 class model, gsmhacking tries to convert it to TAC. If it is an FH1, FH2 or PRH model, gsmhacking tries to convert it to BF1. Other models are left unchanged. Note that to make a hostage model you need only create a suspect model. The only difference between hostages and suspects is that suspects have grippers but there's nothing to stop you using a model with grippers as a hostage.

If the file you're working on is actually an animation, a new suspect animation will be written.

Aliases: --make-tac --make-sus

Make female suspect command

Similar to the --make-suspect command but makes a 34-bone female suspect/hostage character or animation. Probably only useful for converting SWAT animations (which would be valid for hostages too).


Aliases: --make-bf1 --make-female-sus

Make rifle command

-R, --make-rifle
Fixes secondary weapon models that lack a Grip3 grip. Without this grip, the weapon cannot be used as a primary with the LinkToChest feature, as there is no way for the game engine to know where to draw it on an officer's chest (that's what Grip3 is for). --make-rifle clones the existing grip Grip1 as Grip3, enabling the weapon to be used as a primary.

Add flashlight command

-F, --add-flashlight
Fixes weapon models that don't have a FLASHLIGHT material by cloning the triangle definitions, triangle groups and material properties of the MUZZLE material (which all weapons must have) and names the clone FLASHLIGHT. It is then possible to set Flashlight to 1 in guns.dat and use the weapon with a flashlight.

Optimise command

-O, --optimise
Applies any necessary optimisations to the GSM.

Missing textures option

-m, --missing
When --missing is specified, gsmhacking will check that any texture files referenced in the .gsm actually exist in the current directory or one of its subdirectories. Use --missing to check that your mod will actually work before you zip it up and test it.

Outfile option

-o, --outfile <filename>
If you don't want to overwrite your existing .gsm files, you can use the --outfile option to instruct gsmhacking to write the modified .gsm to a different filename. You can then work on that normally. Note the procedure for writing files is as follows:

Alternatively, you can use --outfile - to write the GSM data to standard output (ie the screen). If you don't know what that means, you don't need this option. If you know what it means but don't know why you'd want to do it, you don't need this option.

You are strongly recommended to write your first change to a different file and use that file for subsequent changes.

Prefix command

--prefix <prefix>

Adds the prefix prefix to the input filename and uses that in place of any output filename. For example, to convert two TAC officers to SWT using the SWT_ prefix you could use: gsmhacking --prefix SWT_ TAC_ONE.GSM TAC_TWO.GSM
This would write the files SWT_TAC_ONE.GSM SWT_TAC_TWO.GSM
Use --prefix for batch conversion of many files.

Suffix command

--suffix <suffix>

Similar to --prefix. For example: gsmhacking --suffix .new *.GSM
Use --suffix for batch conversion of many files.

Help command

-h, --help
When asked for --help, gsmhacking prints usage instructions and some examples.

Version command

-V, --version
Prints the version of the program. I'm always fixing bugs and adding new features so if I say you need such-and-such a version but you can't remember which one you've got, this is the command you need.

Verbose option

-v, --verbose
In verbose mode, gsmhacking prints full pathnames, reports opening file descriptors and counts textures when listing.

Debug option

-d, --debug
In debug mode, gsmhacking prints a whole load of debugging information. Use it if there's a bug (horrors!) or if you want to know what the program's doing at a low level.
If --debug and --verbose are used together, gsmhacking goes into hardcore debugging mode. In this mode, gsmhacking spits out far more information than you would ever be interested in.
This option is only available in debug builds. See how to compile gsmhacking from source for information on how to build a debug build of gsmhacking.

"Super debug" option

-sd, --super-debug
This command is just a shortcut to full debugging.

Quiet option

-q, --quiet
In quiet mode, gsmhacking prints ... nothing. No errors, no output, not even the list of textures it found. Use the program's exit code to interpret its results.

Example usage

Converting Martin Brenner to a SWAT officer:

gsmhacking --make-swt -o SWT_BG3_MAR_BRE_HIGH.GSM BG3_MAR_BRE_HIGH.GSM
converting TAC/MHx model to SWT

This is how I made the "Agent [furrycat]" character in the [furryclan] uniform mod. The agent's sunglasses are set to the VISOR material so they will be coloured either grey, red or blue depending on which team the character is on. I also added a reflection and opacity map on the glasses so you can see my eyes if you look closely:

gsmhacking -o swt_fc01a_high.gsm SWT_AGENT_KANGA_HIGH.GSM --replace-textures SWT_AGENT_KANGA.bmp swt_fc_agent_furrycat_face.bmp
replaced one occurrence of SWT_AGENT_KANGA.bmp
gsmhacking --replace-textures SWT_AGENT_BODY.bmp swt_fc_agent_body.bmp swt_fc01a_high.gsm
replaced 3 occurrences of SWT_AGENT_BODY.bmp
gsmhacking --replace-textures SWT_AGENT_PARTS.bmp swt_fc_agent_parts.bmp swt_fc01a_high.gsm
replaced 8 occurrences of SWT_AGENT_PARTS.bmp
gsmhacking --replace-textures SWT_AGENT_KANGA_HAND.bmp swt_fc_agent_furrycat_hand.bmp swt_fc01a_high.gsm
replaced 4 occurrences of SWT_AGENT_KANGA_HAND.bmp
gsmhacking --replace-textures SWT_AGENT_SHOE.bmp swt_fc_agent_shoe.bmp swt_fc01a_high.gsm
replaced one occurrence of SWT_AGENT_SHOE.bmp
gsmhacking --replace-textures SWT_AGENT_TIE.bmp swt_fc_agent_tie.bmp swt_fc01a_high.gsm
replaced one occurrence of SWT_AGENT_TIE.bmp
gsmhacking --replace-textures SWT_AGENT_SHIRT.bmp swt_fc_agent_shirt.bmp swt_fc01a_high.gsm
replaced one occurrence of SWT_AGENT_SHIRT.bmp
gsmhacking --replace-textures SWT_SUN_GLS_blk.bmp swt_fc_sun_gls_blue.bmp swt_fc01a_high.gsm
replaced 2 occurrences of SWT_SUN_GLS_blk.bmp
gsmhacking --material-name LENSES VISOR swt_fc01_high.gsm
set one material property
gsmhacking --material-transparency VISOR 40 swt_fc01_high.gsm
set one material property
gsmhacking --map-texture VISOR reflection 18 --map-texture VISOR opacity 19 swt_fc01_high.gsm
set 2 maps

Technical notes

The GSM file format is fully documented on its own page. The GSA file format is also documented.

How to compile gsmhacking from source

I've tested gsmhacking on Windows 2000 and Linux. Compiling it should be child's play. If you're using Linux or Cygwin, simply go into the source directory and run

make static

If you want to compile ImageMagick support (need for UV mapping), you must download and install ImageMagick, uncomment -DUSE_IMAGEMAGICK and the IMAGEMAGICK_{CFLAGS,LIBS} lines, then run make static-magick.

It is possible to build gsmhacking using Microsoft Visual C++. I don't know how to write a valid Visual C++ Makefile so you have to cheat. Add all the .c and .h files to a new workspace and hit Rebuild All. gsmhacking should build without error.

Please note that using Cygwin is preferred because the Unix semantics allow you to write to stderr. Also, I had trouble with string functions on VC. Of course, a VC application doesn't need cygwin1.dll...

If you have to do anything funny to get it to build on your system, let me know. Somehow I think I would be able to count the number of people who will compile it from source on one paw.

Debugging mode

Like all traditional commandline tools, gsmhacking shuts up unless it has something worthwhile to say. In debugging mode, it will spew out a lot more information. Much of this will be irrelevant. Some of it may actually tell you why things aren't working.

The two main levels of debugging are called DEBUG and TRACE. In fact, TRACE has multiple levels of verbosity... To put gsmhacking into DEBUG mode, use the --debug switch. Working at DEBUG level, gsmhacking reports opening files, allocating memory for texture information, searching for files (when checking if a referenced texture is available) and searching and replacing textures within the .gsm file as well as a whole load of other stuff. All DEBUG level messages are prefixed with the label DEBUG: to distinguish them from normal output (and TRACE level debugging).

To put gsmhacking into TRACE mode, use --verbose as well as --debug. In TRACE mode, gsmhacking reports practically everything it does. File IO operations, memory allocation and freeing and magic checks may be described, depending on how verbose you ask gsmhacking to be. TRACE level debugging shows clearly which strings are matched when searching for textures, and where they were found. TRACE messages are prefixed with the label TRACE:.

There is normally no reason to run gsmhacking in either kind of debugging mode unless you are terminally curious. Debugging may be useful if something goes wrong. Confused that gsmhacking can't find one of your .bmp files? Debugging may show that you misspelled it...

Please note that "super debug" mode produces a lot of output. Don't use it unless you need to.

How to submit bug reports

If there's a bug in gsmhacking, I want to know about it. I've tested it on multiple machines running multiple operating systems and it hasn't let me down yet. But that doesn't mean it's perfect. Tell me of any problems you find and I'll fix them as soon as I can.

To enable me to work efficiently I need a proper bug report. When you submit your bug report, please tell me which version of Windows you are using, which version of gsmhacking you are using and which .gsm file you are trying to hack. If it isn't a .gsm from the game or from a mod that I have, I may ask you to send it to me but please don't send it unless I ask.

Most importantly, I need to know what you typed (exactly what you typed) and what the computer responded (exactly). It might be helpful to explain what you expected the computer to respond. Then, attach a script of your gsmhacking session.

To get the debugging information I need, use gsmhacking 1.4 or higher. Start a DOS session and go into the directory where your .gsm file lives. Then type:

dir > gsmhacking.debug
gsmhacking -sd your arguments >> gsmhacking.debug

REPLACE your arguments with the exact command line that you tried. So, for example, if you were having problems with gsmhacking -s SWT_Name.bmp MY_GSM.GSM then you'd type gsmhacking -sd -s SWT_Name.bmp MY_GSM.GSM >> gsmhacking.debug.

Finally, send me the file gsmhacking.debug, which should contain a list of files in the current directory followed by the output from gsmhacking. (Please check that it actually does have that information before sending it - an empty file isn't much help!)

A message along the lines of "Hey I tried everything and your program just doesn't work. I gave it the right commands and everything but it says nothing" is of no use whatsoever in helping me to track down any problems.

Known bugs


I'm giving gsmhacking away. I'm giving the source away. Don't ask me for my permission to use it, distribute it or link to it. I already gave you that permission.

The Cygwin DLLs required by gsmhacking are covered by the GNU GPL. You can obtain the full source to Cygwin at

gsmhacking is linked against ImageMagick. You can obtain the full source to ImageMagick at


Send any comments to