TF2 HUD Editing Guide


This is a guide to creating a custom TF2 HUD. TF2 is the game Team Fortress 2. HUD stands for Heads Up Display, which refers to the information shown on your screen while playing the game.

This guide covers getting started, that basics of TF2 HUDs, the core concepts and which files to edit.

Written by Doodles, Last updated 10th Sep 2013.
top

1. Getting Started


Software

You will need the following software:
  • GFCScape: The program is free at Nem's Tools
  • Any Text Editor: Windows Default Notepad works fine, I prefer Notepad++ because of its tab feature mainly
  • Steam with TF2: for testing obviously

Extracting the Resource Files

You'll need to extract the default hud files and create a folder for your new hud inside TF2's custom folder. This will give you a base point to start editing from. The files you extract define how the HUD looks, so if you edit the files, you change how the HUD looks. Putting edited versions of these files in the custom folder means the game will load them instead of the default files.
  1. Install and open GFCScape
  2. Open tf2_misc_dir.vpk from your Steam/steamapps/common/team fortress 2/tf directory with GFCScape
  3. Inside GFCScape Extract the resource and scripts folders (right click > extract) - Close GFCScape
  4. Navigate to your Steam/steamapps/common/team fortress 2/tf/custom - create a folder in here for your HUD
  5. Move the extracted resource and scripts folders to your newly created HUD folder
  6. A lot of excess files come in the resource and scripts folders, so look below at the resource list section to figure out which files you want/need - delete the ones you do not

Setting up TF2

There are a few things you can do to run TF2 in a way that makes editing easier.

Running TF2 in no-border window mode: TF2 will run the full size of your screen but will be in window mode, and without the standard window frame. This allows you to switch between windows (with alt+tab), such as TF2 and your text editor. To run TF2 in no-border window mode you'll need to use the following command line options:

    -windowed -noborder

Using the hud_reloadscheme command in game: The hud_reloadscheme command reloads all the resource files for the ingame hud (but none of the main menu resource files). You can even bind this command to a key, so that when you press the key the command is executed. To do this type "bind f2 hud_reloadscheme" (replace f2 with any key you like) into the ingame console.

With TF2 in no-border window mode and the hud_reloadscheme command you can edit the hud in your text editor, switch to TF2, reload the scheme, and see what your changes have done. Thus avoiding having to launch TF2 for every little change.
top

2. The Basics


resource and scripts Folders

Inside the resource folder there are files with the extension .res, these are Resource Files. Resource files define how the HUD looks in game. The folder structure and names of these files matter - so don't change them.

Inside the scripts folder there are only two files that we're interested in, hudanimations_tf.txt and hudlayout.res - more on them below.

Resource Files (.res)

Resource Files are plain text files that define how things on the HUD appear. They use a simple scripting language in which controls are defined in a braced structure.

Controls

Control is a computer programming term meaning an element of a graphical user interface (more info on that here). Basically controls are things on the HUD. Such as your health and ammo numbers. The basic control types are:
  • Label (Label, CExLabel): A piece of text.
  • Button (Button, ImageButton, CExButton, CExImageButton): Objects that execute functions when clicked.
  • Panel (ImagePanel, EditablePanel): Pictures and blocks of color.
Each control is encased by braces, containing a list of properties (with their values) and sometimes sub-controls. Here is an example of one:
"DoodleHUDLabel"
{
    "ControlName"	"CExLabel"
    "fieldName"		"DoodleHUDLabel"
    "font"		"DefaultLarge"
    "labelText"		"DoodleHUD"
    "textAlignment"	"center"
    "xpos"		"c-128"
    "ypos"		"c-40"
    "zpos"		"-2"
    "wide"		"256"
    "tall"		"64"
    "visible"		"1"
    "enabled"		"1"
    "fgcolor_override"	"0 153 0 255"
}

The Control's name, opening brace, list of properties and then the closing brace.

Properties

A property is a piece of data that defines a specific aspect of a control. There are a few properties that apply to all controls, and there are properties that only apply to certain controls types. Below is a list of the main properties:

ControlName - this is the type of control. This must be of an existing control type. You can't make up your own.

fieldName - the unique name of the control. For existging HUD controls you must leave this as is. For controls you are adding yourself this must be unique within the the parent control's sub-controls, and only use letters and numbers.

xpos and ypos - this is the position of the control's top left corner within it's parent control. Numbers (such as 64 and -128) are positioned from the left (or top) of the parent. Numbers preceeded with a c (such as c24 and c-96) are positioned from the center of the parent. Numbers preceeded with an r (such as r100 and r-40) are positioned from the right of the parent. Also note that for r positions the positive and negative values work opposite to normal and c positions.

zpos - determines what layer the control is within the parent control. Layers are the order in which things are drawn. If you want something to appear on top of something else in the hud, for example a label on top of a image panel, you must has it's zpos higher. zpos can be negative. Sub-Controls are drawn with their parent control no matter their zpos (but in their zpos order).

tall and wide - the width and height of he control. Any sub-controls that partially or fully out of these bounds will be clipped (visually). You can use any positive integer. Also, entering f0 will give you the full screen size. Every control is defined with a box area with these two properties, and their contents are displayed within the box. So, for example, labels will require a box long enough to contain their full text, else clipping will occur.

visible and enabled - visible determines whether the Control is visible in game. enabled determines whether the Control is enabled in game. The values for both these properties can be either 1 for true or 0 for false. Controls with visible set to 0 are still loaded, but are not visible. Controls with enabled set to 0 are not loaded and therefore not visible anyway. They do effectively the same thing. A lot of in game HUD entities have their visible and enabled properties animated (for example your health and ammo are not visible while you're dead) so setting them to 0 wont do anything. hiding controls the right way

FgColor - the color of the text of the control. You must enter a color for this property. More about colors in the next section. Most control types have a set scheme of colors, so changing this value on them wont do anything. For those you must override the font color by using the fgcolor_override property instead. You can enter a color directly or one defined in ClientScheme.res.

BgColor - the background color of the control. You must enter a color for this property. More about colors in the next section. Most control types have a set scheme of colors, so changing this value on them wont do anything. For those you must override the font color by using the bgcolor_override property instead. You can enter a color directly or one defined in ClientScheme.res.

border - the outline of the control. This property is for things like buttons and panels. Values must be a border defined in the ClientScheme.res (more about that in the next section).

font - this is the font of the text in the control (for things like labels and buttons with text). You must use a font defined in the ClientScheme.res (more about that in the next section). This property will include the size of the text as well as the font.

labelText - the text on the control. You can enter letters, numbers, spaces and a few symbols. & symbol trick

textAlignment - As mentioned under tall and wide, all controls are defined as boxes, this property defines the alignment of text within that box. This property uses the cardinal directions for values as well as "left", "right" and "center". To enter more than one alignment you must use the cardinal directions with the vertical alignment first, for example "north-west" for top left alignment.

textinsetx and textinsety - distance from the edge of the controls box the text starts. I recommend only using these with text aligned to the top or left.

image - the path and name of the image used in the control. The path is relative to the tf/materials/vgui folder. I strongly advise you not to use custom images on the in-game hud as sv_pure servers will disable them (sv_pure is a server setting that disables custom content, used as a preventative measure to cheating).

paintbackground and paintborder - paintbackground determines whether the background of the control is visible, paintborder determines the same thing for the border. The values for both these properties can be either 1 for true or 0 for false. I recommend using a completely transparent background color and NoBorder to get rid of the background and border instead of these. But they are often required to turn on the background and border of controls since the set scheme for some controls is 0.
top

3. Core Files


Most resource files define 1 or 2 things on the HUD. There are a few files that contribute over all things. It's important to go over these files. There are two in the resource folder, ClientScheme.res and SourceScheme.res. And there are two in the scripts folder, HudAnimations_tf.txt and hudlayout.res.

ClientScheme.res and SourceScheme.res

TF2 is built on the Source Engine. Source Engine games come with a default user interface. TF2 has its own ui built on top, but still has several dialogs in the default source ui (such as: server browser, create server, options, achievents). SourceScheme.res defines the default source ui. ClientScheme.res defines all the TF2 dialogs.

Most custom HUDs only have edited ClientScheme.res, so this guide will focus on that. The structure to SourceScheme.res is the same as ClientScheme.res. A lot of custom stuff can be defined in ClientScheme.res that can be used in all other HUD files (except HudAnimations_tf.txt). As such, while editing your HUD, you will most likely have ClientScheme.res open the whole time.

ClientScheme.res has too much to explain here, it has been done in another section. jump to the ClientScheme.res section

hudlayout.res

This file defines the layout of the ingame HUD enities on the screen. It is of the HUD entities with mostly only there layout properties (size, position).

This file is loaded before all ingame HUD resource files. So if the HUD entities are positioned in their own files, the positioning of this file will be ignored. With this in mind, we can move the layout of any entities we like from this file to their respective resource file. Or you could move the layout of any HUD entity into this file.

HudAnimations_tf.txt

This file defines the animations of certain HUD entities during certain events ingame. For example; the animation of your health cross when you are overhealed.

The animations capable are rather simple. You can change the value of properties of controls/entities over a defined time period. There is more information about this at the top of HudAnimations_tf.txt, where you are given a brief explanation on it.
top

4. ClientScheme.res


ClientScheme.res contains 5 important sections: Colors, Base, Fonts, Borders and Custom Fonts. These sections are where you define custom things to use in your HUD.

Colors

This is a list of defined colors. The color name on the left and the color code on the right. Colors defined here can be used in any other resource files, you enter the name of the color into the FgColor or BgColor property of any control.
"CustomColorOne"   	"255 128 0 255"
"CustomColorTwo"      	"128 128 128 255"
"CustomColorThree"     	"74 99 117 255"
"CustomColorFour"   	"100 120 179 255"
"CustomColorFive"   	"66 56 78 255"
"CustomColorSix"   	"0 255 227 255"
"DoodleHUDLabel"
{
    "ControlName"	"CExLabel"
    "fieldName"		"DoodleHUDLabel"
    "fgcolor_override"	"CustomColorThree"
}

Example of Custom colors and one being used as the FgColor of a control

The code on the left would be in the Colors section of ClientScheme.res and the code on the right could be in any other file in the HUD.
The color code used is RGBA format. It is four 8-bit (8-bit means the value can be from 0 to 255) numbers seperated by a space. The first number is the amount of red, second is green, third is blue and the forth number is the alpha transparency (255 is visible, 0 is transparent).

Base

A list of default property values for UI controls. This section can be ignored as it doesn't apply to most of the HUD.

Fonts

This is a list of font instances usable by any font property. The structure is slightly more complicated than a control. You have the font instances name, then enclosed in braces a list of numbered braces, and inside each of those braces a font instance is defined, with all of its properties. Here is an example:
"Default"
{
    "1"
    {
        "name"		"Verdana"
        "tall"		"12"
        "weight"	"900"
        "range"		"0x0000 0x017F" 
        "yres"	"480 599"
    }
    "2"
    {
        "name"		"Verdana"
        "tall"		"13"	[$WIN32]
        "tall"		"20"	[$X360]
        "weight"	"900"
        "range"		"0x0000 0x017F"
        "yres"	"600 767"
    }
    "3"
    {
        "name"		"Verdana"
        "tall"		"14"
        "weight"	"900"
        "range"		"0x0000 0x017F" 
        "yres"	"768 1023"
        "antialias"	"1"
    }
}
The font instance is named Default and has three numbered braces in it. The reason there is three and not just one is because 2 and 3 are fallthrough settings for Default. TF2 attempts to load the settings from 1, if they fail to display properly (due to low screen resolution) then 2 will be tried. If 2 fails then 3. If a font has only 1 then is will display that regardless of whether you can read it. Font properties define how the font is displayed, here is how they work:
  • name: the name of the font used in the font instance. This must be the name of a font installed on the system (Windows or Mac) or a custom font listed under custom fonts.
  • tall: how tall the text is. This is basically the font size.
  • weight: the thickness of the font. This can be one of; 0, 100, 200, 300, 400, 500, 600, 700, 800 or 900. Some fonts have a lower limit higher than the actual lower limit (0). Having a weight lower than their limit will just be substituted for its actual lower limit.
  • range: this is a hexidecimal range for defined for the range of characters we want to use. If you don't know much about font files, don't worry about this, just leave it for existing fonts and don't bother adding it for custom fonts.
  • yres: I don't know what this does. Ive never put it on any custom font instances and they look fine.
  • antialias: leaving this out or setting it to 0 will leave the text pixelated on the HUD in certain situations. Setting this property to 1 will make the make sure the text has smooth edges.
  • outline: setting this to 1 will give the text a black outline. The outline looks a bit ugly in certain font sizes.

Borders

This is a list of all the borders usable by any property that requires a border as a value. There are two types of borders: image and line. For image borders an image is defined which is sliced and tiled. For line borders you define the lines around the border individually.

Image Borders are a border and a background too. They are made by slicing it and tiling an image. They look like this:
BackpackItemBorder_Unique
{
    "bordertype"		"scalable_image"
    "backgroundtype"		"2"
    "color"			"QualityColorUnique"
    "image"			"backpack_rect_color"
    "src_corner_height"		"24"
    "src_corner_width"		"24"
    "draw_corner_width"		"5"
    "draw_corner_height" 	"5"	
}

the name of the border, opening brace, properties of the border, closing brace

  • bordertype and backgroundtype: these two properties define the type of border, in this case image border, leave them how they are.
  • color: some images allow a color filter. The backpack rectangle is used many times, for different quality items, and is colored differently for each. Some images do not work with coloring however.
  • image: the image used. This path is relative to the tf/materials/vgui directory.
  • src_corner_height and src_corner_width: the sample size for the corners of the image.
  • draw_corner_width and draw_corner_height: the size of the corner on the control that uses this border.
Line Borders are just lines around the edge of the control. The border is made by defining each of the lines. They look like this:
StoreItemBorder
{
    "inset" "0 0 1 1"
    "backgroundtype"		"2"
    Left
    {
        "1"
        {
            "color" "TanDarker"
            "offset" "0 1"
        }
    }
    Right
    {
        "1"
        {
            "color" "TanDarker"
            "offset" "1 0"
        }
    }
    Top
    {
        "1"
        {
            "color" "TanDarker"
            "offset" "0 0"
        }
    }
    Bottom
    {
        "1"
        {
            "color" "TanDarker"
            "offset" "0 0"
        }
    }
}
inset defines the distance from each edge each border is. Its best to use the default inset (used in the example). The left, right, top and bottom borders are defined in their own braces. Use the offset used in the example. The color is the color of each line. Each border will be 1 unit thick, but you can make borders thicker by adding more lines within the sides braces like this:
Left
{
    "1"
    {
        "color" "TanDarker"
        "offset" "0 1"
    }
    "2"
    {
        "color" "TanDarker"
        "offset" "1 1"
    }
}

notice the second brace is numbered 1 more and the x offset is 1 more - two unit thick border

Custom Fonts

Custom fonts are extra fonts you want to use in your HUD. This section is telling the game that the font file exists. Here is an example:
"4" 
{
    "font" "resource/COUTURE-Bold.ttf"
    "name" "COUTURE"
}
The number in front of the braces does not matter, as long as the list of custom fonts is numbered in ascending integers. The font property is the font file, and path, which is relative to the tf directory. Any custom font you use must be of the True Type Font (.ttf) type, and I recommend you put it in the resource folder. The name property must font's actual name (in the meta data). You cannot make up your own name. To find out the proper name you should use here you can install the font on your system and check in a word program. Windows default font viewer shows the font's name at the top.
top

5. Resource List


This is a list of the resource files not covered under the Core Files section and what they define in the HUD. I have seperated them into two catagories; menu and ingame. They are also grouped by folder.

Ingame Resource Files cover everything you see while playing the game (health, ammo, etc) and incldues all in game dialogs (such as "you are now defending")
Menu Resource Files cover everything else pretty much. The main menu, all menu dialogs, the store, the backpack, the mann vs machine lobby.

Some files don't have any information. Either I couldn't figure out what they did or they are fragments or other parts of the HUD. These small fragments often have no effect on the visual aspects of the entities they make up.

Ingame Resource Files

resource\ui\
AbuseReportSubmitDialog.resAbuse Report dialog
AnnotationsPanelCallout.resIngame Callout panel. Used in training mode
CheatDetectionDialog.resThe dialog a player gets when they are detected for cheats. VAC or item stuff.
Classmenu.res
ClassSelection.resChoose Class menu when you join a server
ClassTipsItem.res
ClassTipsList.res
CoachedByPanel.resCoached by ingame hud panel. information/controls shown when you're being coached
ControlPointCountdown.resthe countdown number that appeats at the beginign of koth/cp maps at the bottom of the screen
ControlPointIcon.resControl Point icon - including timer and status
ControlPointProgressBar.resThe little dialog that appears when a point is being capped or you're standing on a point
DisguiseStatusPanel.resspy disguide status hud stuff
EnemyCountPanel.res MVM wave information. What robots will be attacking and how many of them there are.
FlagStatus.resIntelligence Pointer on CTF and MvM
FreezePanelCallout.res
FreezePanelKillerHealth.resExtra Images for freezecam killer health
FreezePanel_Basic.resFreezecam of your killer. the health and stuff.
GiveawayItemPanel.res
HealthIconPanel.res
HudAccountPanel.resEngineer Metal and Metal Icon
HudAchievementFloatingNumber.res
HudAchievementTrackerItem.resAchievements added to the HUD
HudAlert.resTeam Ballance alert
HudAmmoWeapons.resClip Ammo and Reserve Ammo
HudArenaCapPointCountdown.resCountdown number for the point in ARENA mode. on top of the point hud thing at the bottom of the screen.
HudArenaClassLayout.resDialog that appears at the begining of an ARENA round showing you your teams class makeup.
HudArenaNotification.resARENA playing notification - tells you if you're playing or not
HudArenaPlayerCount.resARENA live player count - at top middle of screen
HudArenaTeamMenu.resARENA mode team menu - fight or spec
HudArenaVsPanel.res
HudArenaWinPanel.resARENA mode win/loss dialog
HudBossHealth.resHalloween Boss Health
HudBowCharge.resDistance Charge gauge for the Huntsman weapon
HudCurrencyAccount.res
HudDamageAccount.resDamage Indicator - text showing you how much damage you do, need to have hud_combattext set to 1
HudDemomanCharge.resDemoman Stickybomb launcher distance charge gauge: stickybomb, scottish resistance, sticky jumper
HudDemomanPipes.resCharge Meter for the Chargin' Targe and Splendid Screen
HudHealthAccount.res
HudInspectPanel.res
HudItemEffectMeter.resCharge Meter for various weapons
Scout: sandman, wrap assasin
Soldier: buff banner, concheror, battalions backup
Pyro: phlogistinator
Heavy: sandvich, buffalo steak sandvich
Sniper: jarate
Spy: invis watch, dead ringer
HudItemEffectMeter_Cleaver.resCharge Meter for the Flying Guillotine scout weapon
HudItemEffectMeter_Demoman.resHead count for the Eyelander
HudItemEffectMeter_Engineer.resCrit count for the man melter and the frontier justice
HudItemEffectMeter_ParticleCannon.resAmmo meter for the Cow Mangler
HudItemEffectMeter_Pomson.resAmmo meter for the Pomson
HudItemEffectMeter_PowerupBottle.resMann vs Machine Canteen
HudItemEffectMeter_Raygun.resAmmo meter for the Righteous Bison
HudItemEffectMeter_Scout.resCharge Meter for Scout Weapons: bonk! atomic punch, crit-a-cola, mad milk
HudItemEffectMeter_Sniper.resHead count for the Bazaar Bargain
HudItemEffectMeter_SniperFocus.resCharge Meter for the Hitman's Heatmaker
HudItemEffectMeter_SodaPopper.resCharge Meter for the Soda Popper and Baby Face's Blaster
HudItemEffectMeter_Spy.resCrit count for the Diamondback
HudItemEffectMeter_SpyKnife.resSpycicle recharge meter
HudMannVsMachineStatus.resMann vs Machine status stuff - wave, boss health, etc
HudMedicCharge.resMedic Ubercharge percentage and Charge bar.
HudObjectiveFlagPanel.resFlag/Intelligence display for CTF mode
HudObjectiveKothTimePanel.resTimer displays for KOTH mode
HudObjectiveStatus.res
HudObjectiveTimePanel.resRound Timer for various game modes
HudPlayerClass.resPlayer Class Image in the bottom left
HudPlayerHealth.resHealth and health status images (milk, marked for death, bleeding)
HudPVEWinPanel.resMann vs Machine win dialog
HudStalemate.res
HudStopWatch.res
HudTeamGoal.res
HudTeamGoalTournament.res
HudTeamSwitch.resYou have been ballanced dialog
HudTournament.resTournament Mode - setup panel - top middle
HudTournamentSetup.resTournament Mode - change team name/status dialog
HudTraining.resPositioning for training hud things
HudTrainingMsg.resTraining instruction messages
HudUpgradePanel.resMann vs Machine Upgrage dialog
HudWarCount.resWAR mode demos/soldiers killed
HudWeaponSelection.res
hud_obj_dispenser.resDispencer Display - Engineer
hud_obj_sapper.res
hud_obj_sentrygun.resSentry Display - Engineer
hud_obj_sentrygun_disp.res
hud_obj_tele.res
hud_obj_tele_entrance.resTeleporter Entrance Display - Engineer
hud_obj_tele_exit.resTeleporter Exit Display - Engineer
IntroMenu.resVideo explanation screen when playing game types for the first few times
ItemQuickSwitch.resingame loadout stuff. must be bound: "+quickswitch"
ItemSelectionPanel.resItem selection - when choosing an item to craft or equip
LayeredMapPanel.resContainer frame for Map Info dialog
LayeredMapPanelItem.res
LayeredMapPanelToolTip.res
LeaderboardEntry.res
MapInfoMenu.resMap Info dialog - shown when joining a server
MedicCallerPanel.resMedic call speech bubble - you see over someones head when they call for medic
MvMBombCarrierProgressPanel.resMann vs Machine bomb carrier level up progress stuff
MvMCreditSpendPanel.resMann vs Machine -
MvMCreditSubPanel.resMann vs Machine -
MvMEconRequirementDialog.resMann vs Machine -
MvMScoreboard.resMann vs Machine - Scoreboard
MvMScoreboardEnemyInfo.resMann vs Machine -
MvMStatEntry.resMann vs Machine -
MvMVictoryContainer.resMann vs Machine - Victory - container
MvMVictoryMannUpEntry.resMann vs Machine - Victory - mann up content
MvMVictoryMannUpLoot.resMann vs Machine - Victory - mann up content
MvMVictoryMannUpPanel.resMann vs Machine - Victory - mann up content
MvMVictoryPanel.resMann vs Machine - Victory - normal
MvMVictorySplash.resMann vs Machine - Victory - normal
MvMWaveLossPanel.resMann vs Machine - Lost Dialog
NavigationPanelTest.res
NewRecipeFoundDialog.res
ObjectiveStatusEscort.resPayload display stuff at the bottom of the screen
ObjectiveStatusMultipleEscort.resPayload Race display stuff at the bottom of the screen
RoundInfo.res
ScoreBoard.resScore board and map stats (kills, deaths, etc) - when you press TAB
SelectPlayerDialog.res
SelectPlayerDialog_Coach.res
SelectPlayerDialog_Duel.resSelect a player to challenge to a duel dialog
ServerNotConnectedToSteam.res
Spectator.resSpectator HUD - Waiting to Respawn stuff
SpectatorCoach.res
SpectatorGUIHealth.resTarget ID Health Box - See Target ID
SpectatorTournament.resTournament Mode - Spectator HUD - Waiting to Respawn stuff
SpectatorTournamentGUIHealth.resTournament Mode - Target ID Health Box
StatPanel_Base.res
TankProgressBar.resMann vs Machine -
TankStatusPanel.resMann vs Machine -
TargetID.resTarget ID
Teammenu.resTeam Select Menu - when you join a server
TextWindow.resMOTD - when you enter a server
TextWindowCustomServer.resMOTD - when you enter a server
TrainingComplete.resDialog shown when you complete a leg of training
TrainingDialog.res
TrainingDialog_old.res
TrainingItemPanel.res
UpgradeBoxDialog.resMann vs Machine -
UpgradeBuyPanel.resMann vs Machine - Upgrade vendor dialog
VideoPanel.res
votehud.res
WaitingForPlayersPanel.res
WaveCompleteSummaryPanel.resMann vs Machine - Wave complete dialog
WaveStatusPanel.resMann vs Machine - Wave status
winpanel.resMost Valuable Player and Score - round end dialog
XboxDialogs.res
resource\ui\build_menu\
base_active.resbuild menu - active - base file
base_already_built.resbuild menu - already built - base file
base_cant_afford.resbuild menu - not enough metal - base file
base_selectable.resbuild menu - buildable - base file
base_unavailable.resbuild menu - not available - base file
dispenser_active.resbuild menu - dispencer active
dispenser_already_built.resbuild menu - dispencer already built
dispenser_cant_afford.resbuild menu - dispencer not enough metal
dispenser_selectable.resbuild menu - dispencer buildable
dispenser_unavailable.resbuild menu - dispencer not available
HudMenuEngyBuild.resEngineer Build Menu - main file - See Build Menu
sentry_active.resbuild menu - sentry active
sentry_already_built.resbuild menu - sentry already built
sentry_cant_afford.resbuild menu - sentry not enough metal
sentry_selectable.resbuild menu - sentry buildable
sentry_unavailable.resbuild menu - sentry not available
tele_entrance_active.resbuild menu - teleporter entrance active
tele_entrance_already_built.resbuild menu - teleporter entrance already built
tele_entrance_cant_afford.resbuild menu - teleporter entrance not enough metal
tele_entrance_unavailable.resbuild menu - teleporter entrance not available
tele_exit_active.resbuild menu - teleporter exit active
tele_exit_already_built.resbuild menu - teleporter exit already built
tele_exit_cant_afford.resbuild menu - teleporter exit not enough metal
tele_exit_unavailable.resbuild menu - teleporter exit not available
tele_selectable.resbuild menu - teleporter selectable
resource\ui\destroy_menu\
base_active.resdestroy menu - built base
base_inactive.resdestroy menu - not built base
dispenser_active.resdestroy menu - dispencer built
dispenser_inactive.resdestroy menu - dispencer not built
HudMenuEngyDestroy.resEngineer destroy Menu - main file - See Destroy Menu
sentry_active.resdestroy menu - sentry built
sentry_inactive.resdestroy menu - sentry not built
tele_entrance_active.resdestroy menu - teleporter entrance built
tele_entrance_inactive.resdestroy menu - teleporter entrance not built
tele_exit_active.resdestroy menu - teleporter exit built
tele_exit_inactive.resdestroy menu - teleporter exit not built
resource\ui\disguise_menu\
demoman_blue.resdisguise menu - class image - demoman
demoman_red.resdisguise menu - class image - demoman
engineer_blue.resdisguise menu - class image - engineer
engineer_red.resdisguise menu - class image - engineer
heavy_blue.resdisguise menu - class image - heavy
heavy_red.resdisguise menu - class image - heavy
HudMenuSpyDisguise.resSpy Disguise Menu - main file - See Disguise Menu
medic_blue.resdisguise menu - class image - medic
medic_red.resdisguise menu - class image - medic
pyro_blue.resdisguise menu - class image - pyro
pyro_red.resdisguise menu - class image - pyro
scout_blue.resdisguise menu - class image - scout
scout_red.resdisguise menu - class image - scout
sniper_blue.resdisguise menu - class image - sniper
sniper_red.resdisguise menu - class image - sniper
soldier_blue.resdisguise menu - class image - soldier
soldier_red.resdisguise menu - class image - soldier
spy_blue.resdisguise menu - class image - spy
spy_red.resdisguise menu - class image - spy
resource\ui\notifications\
base_notification.resIn game notification base - See Notifications
notify_enemy_flag_captured_blue.resIn game notification - enemy flag capture - blue
notify_enemy_flag_captured_red.resIn game notification - enemy flag capture - red
notify_enemy_flag_dropped_blue.resIn game notification - enemy flag dropped - blue
notify_enemy_flag_dropped_red.resIn game notification - enemy flag dropped - red
notify_enemy_flag_returned_blue.resIn game notification - enemy flag returned - blue
notify_enemy_flag_returned_red.resIn game notification - enemy flag returned - red
notify_enemy_flag_taken_blue.resIn game notification - enemy flag taken - blue
notify_enemy_flag_taken_red.resIn game notification - enemy flag taken - red
notify_golden_wrench.res
notify_no_invuln_with_flag_blue.resIn game notification - cant uber with flag - blue
notify_no_invuln_with_flag_red.resIn game notification - cant uber with flag - red
notify_no_tele_with_flag_blue.resIn game notification - cant tele with flag - blue
notify_no_tele_with_flag_red.resIn game notification - cant tele with flag - red
notify_special.res
notify_touching_enemy_ctf_cap_blue.res
notify_touching_enemy_ctf_cap_red.res
notify_your_flag_captured_blue.resIn game notification - your flag captured - blue
notify_your_flag_captured_red.resIn game notification - your flag captured - red
notify_your_flag_dropped_blue.resIn game notification - your flag dropped - blue
notify_your_flag_dropped_red.resIn game notification - your flag dropped - red
notify_your_flag_returned_blue.resIn game notification - your flag returned - blue
notify_your_flag_returned_red.resIn game notification - your flag returned - red
notify_your_flag_taken_blue.resIn game notification - your flag taken - blue
notify_your_flag_taken_red.resIn game notification - your flag taken - red

Menu Resource Files

resource\
GameMenu.resAll the buttons on the main menu. See Main Menu
resource\ui\
AchievementsDialog.resAchievement Dialog - default source engine ui
CharInfoLoadoutSubPanel.resLoadout Main Page content - select a class, backpack, crafting, catalog
CharInfoPanel.resLoadout/Stats frame
ClassLoadoutPanel.resClass Loadout
CharInfoArmorySubPanel.resMann co. Item Catalog
CraftingPanel.resCrafting Page content
CraftingStatusDialog.resprogress dialog that appears when crafting
ItemRenameDialog.resRename Item Dialog - using nametag in backpack
ItemRenameInvalidDialog.resInvalid name - nametag rename
ItemRenameConfirmationDialog.resRename Confirmation Dialog when using a nametag in backpack
LoadoutPresetPanel.resA, B, C and D buttons in loadout
LobbyContainerFrame.resMann vs. Machine lobby frame
LobbyPanel.resMann vs. Machine lobby content
MainMenuOverride.resEverything on the main menu: buttons, tf2 logo, character image. Main Menu Notifications. News Dialog (motd). Main Menu Tooltips. Main menu explanation dialogs. See Main Menu
MainMenu_SaxxyAwards.resSaxxy Awards dialog
PublishedFileBrowserDialog.res
PublishFileDialog.res
QuickPlayBusyDialog.resQuicklay Searching for Servers dialog - when you click "Play Now"
QuickplayDialog.resQuicklay Dialog
SaxxyAwards_SubmitForm.res
SelectMostHelpfulFriendDialog.resSelect Most helpful friend - when F2P account upgrades to premium. More Info
StatSummary.resStats Summary on the loading screen. Map info loading screen.
StatSummary_Embedded.resStats Summary from the Main Menu > Loadout/Stats
SteamWorkshopDialog.res
SteamWorkshopItem.res
StyleSelectDialog.res
TestItemBotControls.res
TestItemDialog.res
TestItemRoot.res
TFAdvancedOptionsDialog.resAdvanced Options dialog
ViewRecipesPanel.res
resource\ui\econ\
BackpackPanel.resBackpack panel content
ComboBoxBackpackOverlayDialog.resbackpack - style select dialog
ConfirmApplyCardUpgradeApplicationDialog.resConfirm Tool Use: Magic Spells - 2012 halloween items
ConfirmApplyDecodeDialog.res
ConfirmApplyGiftWrapDialog.resConfirm Tool Use: Gift Wrap
ConfirmApplyPaintCanDialog.resConfirm Tool Use: Paint
ConfirmApplyStrangePartApplicationDialog.resConfirm Tool Use: Strange Part
ConfirmApplyTeamColorPaintCanDialog.resConfirm Tool Use: Team Paint
ConfirmCollectDialog.res
ConfirmCustomizeTextureDialog.res
ConfirmDialogAbandonNoPenalty.resMann vs Machine abandon game - no penalty
ConfirmDialogAbandonPenalty.resMann vs Machine abandon game - penalty
ConfirmDialogAbandonSafe.resMann vs Machine abandon game
ConfirmDialogOptOut.res
ConfirmItemPreviewDialog.resItem Test Run dialog - from Catalog
GenericNotificationToast.res
GenericNotificationToastMainMenu.res
GenericWaitingDialog.res
ItemDiscardPanel.resDiscard Item dialog - when you get an item with full backpack
ItemModelPanel.resItem Box - all the slots in the backpack
ItemPickupPanel.resView New Items dialog
NotificationQueuePanel.res
NotificationsPresentPanel.resYou have Notifications - box that appears (not ingame) telling you have a notification on main menu
NotificationToastContainer.res
NotificationToastControl.resMain Menu Notification content
TradingPanel.resOld Trading Window - no longer used
TradingStartDialog.resStart Trade dialog - from loadout/stats
resource\ui\econ\store\v2\
StoreHome_Base.resStore - Home Content
StoreHome_FreeTrial.resStore - Home Content - free to play
StoreHome_Premium.resStore - Home Content - permium
StoreItemControls.res
StoreMapStampsInfoDialog.resStore - Map Stamp explanation dialog
StorePage.resStore Page - Layout
StorePage_Bundles.resStore Bundles Page
StorePage_Items.resStore Items Page
StorePage_Maps.resStore Maps Page
StorePanel.resStore dialog frame
StorePreviewItemPanel.resStore - item preview
StorePreviewItemPanel_Fullscreen.resStore - item preview fullscreen
StorePreviewItemPanel_Maps.resStore - item preview map stamps
StoreViewCartPanel.resStore - View Cart
resource\ui\training\
main.resTraining and Practice main frame
basictraining\classdetails.resTraining Class Selected Content
basictraining\classpanel.resChoose Class control type
basictraining\classselection.resTraining Class Selection content
modeselection\modepanel.resTraining and Practice choose mode content
modeselection\modeselection.resTraining and Practice choose mode container
offlinepractice\mapselection.resPractice Map selection content
offlinepractice\practicemodeselection.resPractice Game type selection content
top

6. More Information


More information on a few things, as well as a few tips and tricks I have picked up.

Main Menu

The Main Menu is defined in two files. GameMenu.res and MainMenuOverride.res. GameMenu.res is a remnant of the default Source ui, where the main menu was defined as a list of buttons with a uniform style. MainMenuOverride.res is from the TF2 ui. It employs the default list style as well as custom buttons.

Inside MainMenuOverride.res there is the MainMenuOverride control which has a sub-control button_kv, which is the default list of buttons on the main menu. You can edit this to change the default list. I recommend creating all your main menu buttons customly.

All buttons on the main meun need to be listed in GameMenu.res. There are options to have buttons that only appear while in game or have buttons that only appear while at the menu (not in game). Heres how:
"QuitButton"
{
    "label" "Quit"
    "command"   "quit"
    "OnlyAtMenu"    "1" // this button only shows while at the menu
}
"DisconnectButton"
{
    "label" "Disconnect"
    "command"   "Disconnect"
    "OnlyInGame"    "1" // this button only shows while in game
}
Buttons on the main menu work by having an EditablePanel control with the button as a sub-control.

Buttons

Buttons have a lot of special properties to give them the appearance of a button. They have three styles: default, armed and depressed. Default is the normal style of the button. Armed is the style of the button when the mouse cursor is over it. Depressed is the style when the button is clicked. Heres how:
"ExampleButton"
{
    "ControlName"	"CExButton"
    "fieldName"		"ExampleButton"
    "xpos"		"0"
    "ypos"		"0"
    "wide"		"169"
    "tall"		"24"
    "visible"		"1"
    "enabled"		"1"
    "font"		"DoodleFontMainMenu"
    "textAlignment"	"west"
    "paintbackground"	"1" // this needs to be 1 for bgcolor
    
    // default style
    "defaultBgColor_override"	"DoodleColorGreyDark"
    "defaultFgColor_override"	"DoodleColorWhite"
    "border_default"		"DoodleBorderMidGrey"
        
    // armed style
    "armedBgColor_override"	"DoodleColorBlueDark"
    "armedFgColor_override" 	"DoodleColorWhite"
    "border_armed"		"DoodleBorderGreen"
    
    // depressed style    
    "depressedBgColor_override"	"DoodleColorButBack"
    "depressedFgColor_override" "DoodleColorButTextNope"
}
Some buttons can have sub-controls. Like the CExImageButton has a image on it.

Frames and Content - Loadout/Stats, Store, MvM Lobby

A few of the main dialogs for the main menu are setup with frames and content. They have a frame res file which has a header and footer. Then they have one or more content res files which are placed inside the header/footer of the frame.

Labels

Labels are defined as an area, some text and an allignment. The area is the bounding box of the label, the text is the text of the label and the allignment is the texts allignment within the area.

Dynamic and Reference Labels
Some labels use dynamic text and others use reference text.

Dynamic text is found mainly on the ingame HUD. Things such as health and ammo change while you're looking at the HUD, which therefore need to be dynamic. Here is an example of a dynamic label:
"AmmoInClip"
{
    "ControlName"	"CExLabel"
    "fieldName"		"AmmoInClip"
    "font"		"Default"
    "textAlignment"	"west"	
    "labelText"		"%Ammo%"
    
}
The % symbol is the identifier here (all dynamic text will have this). This label will be continually updated as your ammo is changed.

Reference text is found everywhere. TF2 has made pointers for most labels to a language file. This is done so that the game can support multiple languages (by changing the language file) with the same HUD. Here is an example of a reference label:
"ArmoryLabel"
{
    "ControlName"	"Label"
    "fieldName"		"ArmoryLabel"
    "font"		"HudFontMediumSmallBold"
    "labelText"		"#Armory"
    "textAlignment"	"west"
}
The reference identifier is the # symbol. Reference text points to resource/tf_english.txt for English.
Shadows
The outline property of fonts looks kind of ugly in most places. So for things like your Health and Ammo it is better to use a shadow label.

To make a shadow label you:
  • Duplicate a Label (copy one and paste it underneath) - the second one will act as the shadow
  • Change the fieldName of the shadow label
  • Change the zpos of the shadow label - be careful with this step, the zpos may be depended upon for appearances
  • Change the FgColor of the shadow label to a black or dark color
  • Change the xpos and ypos of the shadow label to 1 or 2 more
Here is an example (some properties removed, not important for this example):
"AmmoInClip"
{
    "ControlName"	"CExLabel"
    "fieldName"		"AmmoInClip"
    "font"		"HudNumbers"
    "fgcolor"		"White"
    "xpos"		"0"
    "ypos"		"0"
    "zpos"		"5"
    "wide"		"200"
    "tall"		"80"
}
"AmmoInClipShadow"
{
    "ControlName"	"CExLabel"
    "fieldName"		"AmmoInClipShadow"
    "font"		"HudNumbers"
    "fgcolor"		"Black"
    "xpos"		"2"
    "ypos"		"2"
    "zpos"		"4"
    "wide"		"200"
    "tall"		"80"
}
s The offset of the xpos and ypos with the dark FgColor will give it a shadow look. The zpos is to make sure its behind the original label.

Target ID (Health)

Target IDs are the health popup when you are looking at someone or healing/being-healed. It is a little bar with the name, health and sometimes another line of info. There are three.

CMainTargetID: Who you're looking at. Friendly players and buildings.
CSecondaryTargetID: Who you're healing. Or who is healing you.
CSpecatatorTargetID: Who you're spectating.

All three are defined in TargetID.res and positioned in hudlayout.res. The health number and image is defined in SpectatorGUIHealth.res which is used in TargetID.res.

Tournament Mode

Tournament mode is server mode designed for competitive play. More information here. There are alternate versions of the Target IDs and the Spectator HUD for Tournament Mode. As well as various other things. Details on tournament resource files are under the Resource List.

Build/Destroy Menu, Notifications, Disguise Menu

To avoid repeated code these sections (as well as others) have been sperated into multiple files. These seperated files fit into one and another.
Notifications
In game notifications are messages that appear ingame for a few seconds to tell you information. These are defined in the resource\ui\notifications folder. There is a main file that defines pretty much everything about the notification and several specific files that use the main file as a base and change a few things for each notification. The main file is base_notification.res and the specific files are all the files in that folder that use base_notification.res as a base like this:
#base "base_notification.res"

"Resource/UI/notifications/notify_enemy_flag_captured_red.res"
{	
	"Notification_Background"
	{
		"image"			"../hud/score_panel_blue_bg"
	}
	
	"Notification_Icon"	
	{
		"icon"			"ico_notify_flag_home"
	}
	
	"Notification_Label"
	{	
		"labelText"		"#TF_CTF_PlayerTeamCapture"
	}
}
Build/Destroy Menu
The Build and Destroy menus are the engineers build and destroy menus (pretty obvious there). They are defined in resource\ui\build_menu and resource\ui\destroy_menu.

The main file for the Build menu is HudMenuEngyBuild.res in the resource\ui\build_menu folder. All other files in the resource\ui\build_menu are the states of the buildings which are shown within the main file depending on the situation. The four building spots can have different states (built, not built, can't afford) which are defined in files (base_active.res, base_already_built.res, base_cant_afford.res) and the specifics for each building defined in their respective files (sentry_active.res, sentry_already_built.res...etc...).

The main file for the Destroy menu is HudMenuEngyBuild.res in the resource\ui\destroy_menu folder. All other files in the resource\ui\destroy_menu are the states of the buildings which are shown within the main file depending on the situation. The four building spots can have two different states (built, not built) which are defined in files (base_active.res, base_inactive.res) and the specifics for each building defined in their respective files (dispenser_active.res, dispenser_inactive.res...etc...).
Disguise Menu
The disguise menu is the spy's disguise menu (again pretty straightforward). It is defined in resource\ui\disguise_menu. The main file is HudMenuSpyDisguise.res, the rest of the filesin the folder are the class images that are shown on the default disguise menu.

Removing Controls from Your HUD

In some cases when you are editing your HUD you will come across a control you do not want on your HUD. It could be anything, the point is you want to get rid of it. What is important to note is that most controls on the ingame HUD are animated. They are animated by having their properties changed. Some controls disappear and reappear, some change position, some controls grow and shrink and some controls do all three. What this animation stuff means for getting rid of controls is that simply setting the visible property to 0 does not work for some controls.

Removing the control from the resource file is NOT recommended for the ingame HUD, and in most cases will not work. The control is instantiated anyway (it still remains in base files) and as mentioned above its animation will put it on the HUD.

There are a few things you can do to get rid of controls: set visible and enable to 0, set the size to 0 and set the position off the screen. I like to replace the entire controls properties with all three, like this:
"StupidControl"
{
    "ControlName"	"CExButton"
    "fieldName"		"StupidControl"
    "xpos"		"9999"
    "ypos"		"9999"
    "wide"		"0"
    "tall"		"0"
    "visible"		"0"
    "enabled"		"0"
}
This will remove any control from your HUD, except one.

The spy disguise outline is animated in HudAnimations_tf.txt to appear, change size and position. So all of the properties we set to get rid of it dont work. The solution to get rid of this is to edit the animations. Open up HudAnimations_tf.txt, find the "Spy Disguise" section and remove ALL animations of the "OutlineImage" control.

Stubborn Controls

Some properties of specific controls are un-editable. Sometimes this is because the properties are animated, sometimes this is because the control doesn't allow that property to be customised. There is two ways around this.

Changing the Control Type - Changing the ControlName property from CExImageButton to CExButton or from ImagePanel to EditablePanel can open up locked properties. Its important you know what you'redoing here. You need to recognise what properties should be in the new control type.

Replacing the Control - Removing the control and adding in a replica control can unlock properties. You can duplicate the original control and change the fieldName of the duplicated version. You then "Remove" the original control with the method above. The duplicated control will be editable because animations are made to specific fieldNames.

Button Shortcut Keys

For most of the menu and a few ingame dialogs it is possible to link buttons to a key on the keyboard, so that when you press the key the button is triggered. You do this by adding the & sumbol before the desired letter in the buttons labelText property. Here is an example:
"PrevPageButton"
{
    "ControlName"	"CExButton"
    "fieldName"		"PrevPageButton"
    "xpos"		"c185"
    "ypos"		"290"
    "zpos"		"1"
    "wide"		"20"
    "tall"		"20"
    "visible"		"1"
    "enabled"		"1"
    "labelText"		"&A"
    "textAlignment"	"center"
    "Command"		"prevpage"
}
The example above is the button from the backpack that moves to the previous page. In this case pressing the A key will move to the previous page.

You can used only letters, numbers and a few symbols as shortcut keys. I recommend only using letters and numbers. You can see examples of this already in use in the default HUD; the team select and class select menus ingame.

Min Mode

There is a client side setting in TF2 for different versions of the HUD. It is cl_hud_minmode, and takes either a 1 for true or a 0 for false. The default TF2 HUD has a minimal hud with less and smaller entities when cl_hud_minmode is set to 1 and its normal HUD when its set to 0.

You can use this setting do to have whatever alternate version of your hud you desire, for example, a smaller scoreboard for competitive play.

Min Mode is setup by having properties with _minmode appended and alternate values. Like this:
"xpos"		"c185"
"xpos_minmode"		"r120"
"ypos"		"290"
"zpos"		"1"
"wide"		"200"
"wide_minmode"		"110"
"tall"		"20"
"tall_minmode"		"15"
You have the default values for the properties and the min mode values, so the control appears differently in min mode. You can append _minmode to most properties (including visible). It's mostly used on control layouts.

Main Menu Engine Commands

TF2 is run on the Source Engine, which has an interface where you can enter commands into the engine. This is the developer console (or just console). The main menu is a ui, which runs seperate from the console. The Main Menu Buttons work by invoking a command when they are clicked. These commands are passed by the ui, not the engine.

In order for TF2 Console commands invoked by menu buttons to be passed to the engine they must be preceeded by the engine keyword. Like this:
"MinModeButton"
{
    "ControlName"	"CExButton"
    "fieldName"		"MinModeButton"
    "xpos"		"c185"
    "ypos"		"290"
    "zpos"		"1"
    "wide"		"20"
    "tall"		"20"
    "visible"		"1"
    "enabled"		"1"
    "labelText"		"Change to Minmode"
    "textAlignment"	"center"
    "Command"		"engine cl_hud_minmode 1"
}
This button sends the command "cl_hud_minmode 1" to the engine where is it executed. With this little trick the sky is the limit. You can execute any command the console can execute, including connecting to a server (engine connect 192.168.1.1:27015). You can even execute an alias (provided it is already setup in the autoexec.cfg or somewhere).

System Specific Properties

TF2 includes support for different Computer Systems. For the HUD this is done by having different properties for specific properties (and sometimes controls). The property is followed by a system selector to define which system the property is for. Like this:
"tall"		"13"	[$WIN32] // windows
"tall"		"20"	[!$WIN32] // all but windows
"tall"		"20"	[$X360] // xbox 360
"tall"		"13"	[$DEMO] // watching a demo
"tall"		"36"	[$OSX] // mac
You can ignore all of this stuff since windows and mac HUDs aren't that much different and no one plays TF2 on XBOX. Lolololol.

Public Use

If you intend to release you HUD for public use you must consider a few things.

Direct X Level - The game appears quite differently in different Direct X levels. You should test your HUD in multiple levels. I recommend 81 and 95.

Screen Resolution - On lower resolutions text is smaller and entities are closer together. You should test in different resolutions to check for overlaps and unreadable text.

Game Mode - You should change to a map of each gametype to see how the hud looks. Payload, Payload Race, Capture the Flag, Arena.