Animator's Guide to Unique Animations In-Engine

This guide is written for the sake of adding custom animations into Team Fortress 2 as unique animations. By adding them as unique animations, they will not overwrite any existing animations in the game. Your animation and the one you intended to "Replace" will be able to co-exist. This also will allow for animations to be however long you want them to be and not be the same as a different animation.

This guide in no way explains how to animate. This is something that you will have to do on your own time. If you wish to learn how, I suggest you use Google to find out how. *more information may be added on getting setup for animating in the future

This tutorial now has a video adaptation. If you prefer video based tutorials or become confused in the text tutorial, please reference the below video.

Reference List of what this tutorial covers:

  • Items you will need
  • Getting Started
  • Hexing Your Model
  • Getting your animation ready
  • Defining Bones
  • Creating your QC File
  • Compiling your QC file
  • Testing your new animation in Source SDK
  • Faceposer
  • Assigning your animation to a weapon
  • Testing it in-game

  • Player Models for animating

  • Additional QC Rules

Items you will need

Notepad++ - A text editor. This will come in handy. Compiling QC files with Notepad++ - This is a plugin called NppExec for Notepad++. You will need it to compile your work.

GCFScape - This way you can nose through the TF2 files

XVI32 - A Hex editor.

Source SDK - (Download it under "Tools" in your library) - This is needed if you want to get your animations in-game.

Team Fortress 2 - Obviously you need this

A way to export in SMD - Example for Maya Search out a plugin for your favorite editor--or if yours doesn't have one, get a program that does (Blender, 3DS Max, Maya, etc) and export it so you can open it in one of those programs.

Getting started

You will be working with quite a few files when using this tutorial. I suggest you make a folder on your desktop by the name of TF2Animations. Inside of that, make two more folders. player models and to be compiled.

Hexing Your Model

Before you begin working on the file to compile your animations, you must first extract the model of the class you want to make custom animations for. Let's say you wanted to add a new taunt to Pyro. Open up GCFScape and to go File -> Open. Navigate to your .../Steam/Steamapps directory and open up the team fortress 2 materials.gcf. Navigate to the directory and extract the class.mdl you want to make the animation for (ex: engineer.mdl, soldier.mdl, etc). Extract this model to your player model folder.

Now, find your XVI32 Hex Editor and open up your class.mdl file. Hit ctrl+f on your keyboard and search by text string (instead of hex) and search for "animations". You will come across a string in the right that says classanimations.mdl (example: engineeranimations.mdl)


You can rename the character_animations.mdl file to anything you want, So long as it uses the same amount of characters. For example, you want to rename Engineer animations:

engineer_animations.mdl - 19 characters in length

Would Work:
engineer_my_anim_v1.mdl - 19 characters (Exact Length)

Would NOT Work:
my_custom_engineer_animations.mdl - 29 characters (Too Long)
engie_anims_v1.mdl - 14 characters (Too short)

*Since all the class names are different in length, this will not always be 19. You also do not have to include the character's name in the animation file, though it is suggested

Remember what you name this: You will need it later.

Getting your animation ready

Open up your animator in your 3D modeling program of choice that can has a Valve plugin. Now, go to your export settings and export your animation in .SMD format. Name it whatever you want (mytaunt.smd would work). Now, save it your to be compiled working folder.

Defining Bones *You will need to have launched Source SDK at least one time before the files will appear

You will need to get this file before you compile your work. This step is not hard. All you need to do is go to .../steam/steamapps//sourcesdk_content/tf/modelsrc/player//scripts * and find the class_definebones.qci file and put this in your *to be compiled folder.

Creating your QC File

A QC file is a Quake C file--which Valve used for compiling back in the times of Quake. You will be making one to compile your work together. Create a new text document and name it whatever you want, so long as it ends in qc. (Ex: myspyanimations.qc)

Here is an example qc for Spy:

$modelname "player/spy_anims0_itm.mdl"

$include "spy_definebones.qci"

$poseparameter body_pitch -45.00 90.00 360.00
$poseparameter body_yaw -45.00 45.00 360.00
$poseparameter move_y -1.00 1.00
$poseparameter move_x -1.00 1.00

$cdmaterials "models\player\spy/"

$includemodel "player/spy_animations.mdl"

$sequence layer_taunt03b_by_mrkit "taunt03_mrkit.smd" fps 30 hidden
$sequence taunt03b_by_mrkit "taunt03_mrkit.smd" noanimation {
    numframes 150
    fadein 2
    fadeout 2
    blendlayer layer_taunt03b_by_mrkit 0 5 145 149

$ikchain rhand bip_hand_R knee  0.743 0.669 0.000
$ikchain lhand bip_hand_L knee  0.733 -0.680 0.000
$ikchain rfoot bip_foot_R knee  0.751 -0.660 -0.000
$ikchain lfoot bip_foot_L knee  0.730 0.000 0.684`

Now, let's break this down:

$modelname "player/spyanims0itm.mdl"

This is your name of this .mdl file you are compiling. This should match what you hexed your animations file name to be in your player.mdl

$include "spy_definebones.qci"

This is your definebones file that you got from sourcesdk_content. It doesn't matter what what you name the definebones file so long as it matches what you have in here.

$poseparameter bodypitch -45.00 90.00 360.00 $poseparameter bodyyaw -45.00 45.00 360.00 $poseparameter movey -1.00 1.00 $poseparameter movex -1.00 1.00

These won't change. Just copy these into your QC

$cdmaterials "models\player\spy/"

*Be sure to change the last directory to your class's directory * (scout, soldier, pyro, demo, heavy, engineer, medic, sniper, spy)

$includemodel "player/spy_animations.mdl"

You must include this. Be sure to change it to your class's animations file. Without this, the hexed character model you have will ONLY read your custom animations file. That means that your character will be in the T-pose UNLESS he's in your custom animation.

$sequence layertaunt03bbymrkit "taunt03mrkit.smd" fps 30 hidden

To follow the syntax of how taunts are normally added, I normally add this. layer_taunt03b_by_mrkit can be whatever you want to name it. This will show up as its name in the model viewer when you look for it by name. "taunt03_mrkit.smd" MUST be the name of your animation. If you do not correctly identify this, it will spit an error back at you for not identifying your SMD animation.

$sequence taunt03bbymrkit "taunt03mrkit.smd" noanimation { numframes 150 fadein 2 fadeout 2 blendlayer layertaunt03bbymrkit 0 5 145 149 }

Follow the same concepts as the above one for the taunt's name and the SMD specification. Do not put layer_taunt03b_by_mrkit for this one too. Remove the layer_ prefix on this one to differently identify it.

The green is colored differently because this will change depending on what you have your animation doing. It is a good idea to use the above ones in all of your animations as rules when they execute. numframes tells us how many frames you have (this one is 150 frames). faein and fadeout are the number of seconds that your animation fades in and out from the default weapon pose you're using. You may want to change this to fit your taunt. blendlayer is for blending the layers of your animation. Using 5 to 10 frames is a good idea. The syntax of this is:*

blendlayer Ex: blendlayer layer_mytaunt 0 5 95 100

0 is when it starts blending the intro
5 is when it stops blending the intro
95 is when it starts blending the outro
95 is when it stops blending the outro

*For more rules to specify with animations, refer to the QC rules section below this post

$ikchain rhand biphandR knee 0.743 0.669 0.000 $ikchain lhand biphandL knee 0.733 -0.680 0.000 $ikchain rfoot bipfootR knee 0.751 -0.660 -0.000 $ikchain lfoot bipfootL knee 0.730 0.000 0.684

These won't change either. Just copy these into your QC

Compiling your QC file

Once you have completed your QC file, you will need to compile it. If you have installed NppExec correctly, if you hit F6 while your qc file is up, you will be prompted to execute a command. Copy the following [quotes included] into the file and save it as "studiomdl"

"C:/Program files/steam/steamapps//sourcesdk/bin/orangebox/bin/studiomdl.exe" "$(FULL_CURRENT_PATH)"

  • You will need to change the field. You do NOT change $(FULLCURRENTPATH)*

You may need to change the starting directory if you saved your steam installation in a different directory (Mine is F:/Steam/steamapps/... for example).

Once you have done this, hit OK and your qc will compile. If you have done this correctly, you should now have your custom named animations file in your .../steam/steamapps//team fortress 2/tf/models/player folder. If you do, all is well. Now, copy your player.mdl file that you hexed into this directory.

Testing your new animation in Source SDK

Go into Source SDK and open up model viewer. Go to File -> Load Model and to the player directory and find the name of the character model you hexed (spy.mdl, etc). If you did everything correctly, you should be able to click the sequence tab at the bottom and click the first drop-down. You should see a huge list of animations (default animations), and, if you look for the name of your taunt, it should also be in there. Click on it. If it plays like it did in your modeling program, then you're set for the next step. If your character goes into a T pose or you do not see your animation or you see ONLY your animation, you have done something wrong and need to go back.



If your animation plays like you want it to, you will need to go on to Faceposer. Now, before you actually work in Faceposer, you will need to extract some scene VCD files. Open up GCFScape and find your Team Fortress 2 Content.gcf file. Open this up and go to root/tf/scenes/player. Now, open up your tf directory under steam/steamapps//team fortress 2 and make a scenes folder, and inside of that, a player folder. (it should look like team fortress 2/tf/scenes/player). Now, extract the nine classes from the scenes/player folder into your tf/scenes/player folder. Why do this? Whenever you add new VCD animations, Faceposer rebuilds a scenes.image file. This file looks at ALL SCENES in scenes/player folder and references them. If you do not extract them, it will not see them. Your characters will talk, but not move if you forget to extract the corresponding VCD file to their taunt sequence.

Now that you have done this, go ahead and launch Faceposer (if you already have it up, you do not need to close it). Now, in Faceposer, you will first need to load your character model (File -> Load Model -> Player -> spy.mdl). Once you have done this, you will work on creating a scene. The easiest way to do this is to modify an existing scene. For this tutorial, I am adding a spy animation for the knife, so I would load up spy's current knife animation and work from there. (taunt03_v1.vcd is one of two of the spy's knife taunt variations)

First and foremost, I would want to change the animation. Right click on taunt03v1 on the red bar below and go to "Edit Event". You will see a name and a sequence. The sequence should have a list of all animations. Find your animation in the dropdown of sequences. Now, after you have done this, rename this event to something other than taunt03v1 (Anything will do). Hit OK. If you want to change the the spy says, right click Spy.Taunts02 and Edit Event. Rename this to something of your choosing, and then choose a sound file of your wanting in the list and hit OK. You should choose a sound file that is no longer than your animation. If you want to adjust WHEN the sound file plays, drag the sound file sequence bar to where you want the sound to begin.

If you want to change the expressions or add new ones, you can go to Window -> Expressions and see an Expressions window pop up. Find an expression of your liking and drag it down into your Choreography bar. You can click the edge of this expression and drag it to however long you want it to be in your animation. If you add one you don't want, just click it and hit Delete on your keyboard.


*You can add as many expressions or sound files as you like to an animation

Once you have prepped your sequence file to how you like it, it is time to save it. Go to Choreography -> Save as and save your VCD. You should open up to the tf/scenes folder. If not, you will need to navigate here. Now, once you are in this, hit "player" and then the class you are making this VCD for. You will then see a "high" and "low" folder. Taunt sequences are always saved in the "low" folder. Save your sequence to something that does not exist yet. (For my example, I will save this as mytaunt.vcd)

If you are saving a taunt for spy, if you name it anything starting with taunt03 (ex taunt03gamemaster), it will use the taunt kill sequence from the spy's fencing taunt, regardless of what your taunt is intended for. If you do not want this, do NOT save it with taunt03 as the start* *THIS ONLY APPLIES TO TAUNT03 FOR SPY ONLY**

Whenever you have saved your custom VCD, you are ready to rebuild your scenes.image file. Go to File -> Rebuild scenes.image. When this is done, you are ready to close Faceposer and Source SDK

Assigning your animation to a weapon

Once again you will need to venture into GCFScape to extract some files. Open up team fortress 2 content.gcf and navigate to the scripts folder. In it, you will see a "talker" folder. Extract the tf.txt and the response_rules.txt to steam/steamapps//team fortress 2/tf/scripts/talker. For now, we are going to replace an existing set of rules that are setup for the spy. Open up tf.txt and search for "SpyTauntMelee". You will find a sequence that looks like this.

response "SpyTauntMelee"
    scene "scenes/player/spy/low/taunt03_v1.vcd"
    scene "scenes/player/spy/low/taunt03_v2.vcd"

Now, to add my custom taunt, I would replace


response "SpyTauntMelee"
    scene "scenes/player/spy/low/mytaunt.vcd"

This example will replace all Spy melee taunts with my new taunt animation. If you are fine with this, skip to the next section. If you want to specify a specific weapon, read below.

**If you want to specify a specific weapon, the Conniver's Kunai, for example, you will have to open up response_rules.txt to search for a criterion expression. For example, the Direct Hit:

    criterion "WeaponIsDirectHit" "item_name" "The Direct Hit" "required" weight 10

The Direct Hit is already specified with its own criterion, so you do not have to create a custom criteria to make it work.

The Conniver's Kunai however, does not have a custom criterion. We will have to make it. In the response_rules.txt folder, you will need to specify your custom criterion with the current weapon criterion. Below the weapon entries, add these two lines for your weapon.

    criterion "WeaponIs<NAME>"    "item_name"    "WEAPON NAME"    "required" weight 10
    criterion "WeaponIsNot<NAME>" "item_name"    "!=WEAPON NAME" "required" weight 10


    criterion "WeaponIsKunai"    "item_name"    "Conniver's Kunai"    "required" weight 10
    criterion "WeaponIsNotKunai" "item_name"    "!=Conniver's Kunai" "required" weight 10

The "WeaponIs" and the "WeaponIsNot" critera can be followed by anything, it does not need to match any specific criteria. It could be "WeaponIsKunai" or "WeaponIsJapaneseKnife". Make it simple. The criteria that is for "WEAPON NAME" must be exact, however. Weapons will not execute if you misspell a name or add a word that isn't included (for example, some weapons will need "The" (The Amputator) in them while others do not (Conniver's Kunai)

Now that you have made your custom criteria, go to your tf.txt file and find your class's "rule" responses. You will want to create a new rule.

Rules will look like this:

rule SpyTauntKunai
    criteria ConceptPlayerTaunt IsSpy WeaponIsKunai
    response SpyTauntKunai

You may name the "rule" whatever you wish, as well as the "response". The criteria must specify three items specifically, however. It will always be "ConceptPlayerTaunt", "Is", and your weapon criteria, in this case the last two are "IsSpy" and "WeaponIsKunai". Once you have done this, you will go up to your responses and create a response.

response "SpyTauntKunai"
    scene "scenes/player/spy/low/mytaunt.vcd"

*It does not matter if you add your rules and responses in the middle of existing responses or even by each other. However, the rule must ALWAYS come AFTER [below] the response. *

Testing it in-game

That's right, you're finally done. It is time to load up TF2 and test it out. Don't be discouraged if it does not work, there is a lot of room for error in this. I will try to help you out in the process and hopefully update this tutorial to be more in-depth and less confusing. If you have any questions, do not be afraid to ask! Post here and I'll do my best to walk you through.

Frequently Asked Questions (FAQ)

Q: Does the animation I'm making need to be the same amount of frames as the one I am replacing?

A: No. The method in which this animation tutorial uses does not use the same VCD that it would in a client side taunt modification. This mod uses a new VCD that allows the new animation to determine the length of the file, not the pre-existing animation.

** Player Models for Animating

If you are looking for rigged models for animating, I was told that you can find ready to animate SMD models in the steam/steamapps//sourcesdk_content/tf/modelsrc/player//parts/smd

Alternatively, you can download these SMD files converted to FBX for rigging purposes.
Download Here

Weapon Models for Animating

You will need mdldecompiler for this tutorial. Be sure to follow the instructions on the page for installing it. Place the executable in your .../SteamApps/sourcesdk/bin directory, NOT your sourcesdk/tf directory. Create a shortcut to your mdldecompiler on your desktop. You will use this later

If you are trying to use a certain weapon model for your animation, you will need to follow this process in order to decompile a weapon model. Weapon models don't follow any specific name, so you will have to figure out the name on your own time. For this example, we will be doing the Jarate for Sniper.

Open up GCFScape and find team fortress 2 materials.gcf. You will need to navigate to models/weapons/cmodels. In here will be files for many thirdperson weapon models. Some are in c directories, others are not. Jarate is not in a directory, so we do not need to go into one. Jarate is named by the name of urinejar under the c_models directory. What you will need to do is find an empty folder and extract the following files into it.


Once you have done this, you will need to open up urinejar.mdl in a Hex editor. There will be a sequence at the beginning that is IDST0. Change this to be IDST,. You are changing the 0 to a comma. Now save and close urinejar.mdl. Open up mdldecompiler and find urinejar.mdl. You will extract your model into any folder (it MUST exist, however. If the folder you are making it extract to does NOT exist, it will fail). Once you have extracted it, go to your decompiled folder and find physmodel.smd. This SMD is importable into any modelling program with SMD importing support.


Additional QC rules

When you specify your animation in your Qc file, you can add a LOT of events. Below will list some of the event rules that can be used.

*fadein *- Time, in seconds, your animation fades in from your player's current animation. Parameters:


$sequence taunt"taunt.smd" noanimation {
fadein 2

*fadeout *- Time, in seconds, your animation fades out to your player's current animation. Parameters:

[code] $sequence taunt"taunt.smd" noanimation { fadeout 2 } [/code] Parameters:

*blendlayer *- The amount of frames to blend at the beginning and end of your animation Parameters:

[code] $sequence taunt"taunt.smd" noanimation { blendlayer layer_taunt 0 5 95 100 } [/code]

event AEWPNHIDE - The frame to hide the weapon of the taunting player Parameters:

$sequence taunt"taunt.smd" noanimation { event AEWPNHIDE 0 }

event AEWPNUNHIDE - The frame to unhide the weapon of the taunting player Parameters:


$sequence taunt"taunt.smd" noanimation {
    event AE_WPN_UNHIDE 100

event 5004 - Play a sound starting at a frame Parameters: <"SOUND PARAMETER>


$sequence taunt"taunt.smd" noanimation {
event 5004 18 "Taunt.Pyro02Fire"

**You can find a list of sounds you can specify by their name by opening up team fortress 2 content.gcf in GCFScape and going to your scripts folder. Any of the game_sounds text files can have parameters called from them to be used. *

event AECLCREATEPARTICLEEFFECT - Attach a particle effect to a bone Parameters: follow_attachment

$sequence taunt10_by_superaldo "taunt10" fps 30.00 {
  { event AE_CL_CREATE_PARTICLE_EFFECT 5 "pyrotaunt_glow follow_attachment weapon_bone" }

*If you launch TF2 with -tools as a parameter, you can access the particle editor. Use the names of these particles when trying to attach them.

I have only tried attaching to weaponbone and weaponbone_L. I am not certain of what designates the other bones. Somebody may be able to help me regarding this.*

(Unofficial) Steam Workshop Submissions Guidelines

As of right now, there are no official guidelines for accepting animations to the workshop. Matthew Russell has stated that there are currently no currently set guidelines as there numerous factors that need to be taken into account regarding workshop submissions for animations. However, Tony Paloma has stated that so long as an SMD and a youtube link are provided--that we are still welcome to submit them to the workshop. However, I feel this is incomplete and does not include all that should be included for custom animations. Therefore, I have included an unofficial set of guidelines that I--and what I believe, you, as an animator, should submit to the workshop for your animations. (The example assumes Spy as class for submission)

Downloadable Example

What I have included in this example are the following and why:

QC file: The QC file is included to show how your sequence is put together and to show which events and sounds you have used in the making of it. This also shows that the Source Engine can use your animation

definebones.qci: This shows the definebones that you used for your compiling. This is especially important if your definebones differs from Valve's

animation.smd: Your animation. Without it, there's no reason to even be doing this.

Compiled MDL file: This shows a compiled result of your MDL file. This shows that your QC file is solid and a result of your work.

VCD files: VCD files are what have your character's facial expressions and voice lines. Not including these in your SMD is like leaving out half your work. While Valve may not say so, it is vital to include these as a part of your submission. Nothing says that Valve must take them--but it never hurts to go the extra mile, right?

Special Thanks

i-ghost - For teaching me much of this work here

Mr. Kit - For assisting me in compiling custom animation files

Daimao - For assisting me whenever I had trouble with QC file workings