Weapon script
While it is perfectly possible to define a weapon's properties entirely in C++, Valve tend to use weapon scripts instead. These allow changes to be applied by a server restart, with no need to shut the game down and recompile its code.
Weapons scripts should be located at game\scripts\<classname>.txt
, and everything inside should be a child of a single WeaponData
key.
A weapon's scripted values are accessed from its GetWpnData()
function.
Standard keys
These are the keyvalues that will be read by CBaseCombatWeapon
. All weapons support them. Script keys are on the left, C++ variables on the right.

Viewmodel and UI
printname / szPrintName
- The friendly name shown to players in the UI. Max 80 characters (but can be a localisation key).
viewmodel / szViewModel
- Path to the viewmodel seen by the player holding the weapon. Relative to the game root, so be sure to include the
models\
folder. Max 80 characters. bucket / iSlot
- The HUD weapon selection in the X axis. 0 being the melee weapons by default.
bucket_position / iPosition
- The HUD weapon selection in the Y axis. 0 Being the pistol in the (1) X axis by default.
weight / iWeight
- Used to determine the weapon's importance when the game autoselects one. Nothing to do with physical weight!
autoswitchto / bAutoSwitchTo
- Whether to switch to this gun on running out of ammo for another. Defaults true.
autoswitchfrom / bAutoSwitchFrom
- Whether to switch away from this weapon when picking up another weapon or ammo. Defaults true.
showusagehint / bShowUsageHint
- Show on-screen hints about how to use the weapon. Defaults false.
BuiltRightHanded / m_bBuiltRightHanded
- Weapon viewmodel is right-handed. Defaults true.
AllowFlipping / m_bAllowFlipping
- Allow the viewmodel to be mirrored if the user wants left handed weapons. Defaults true.
- Template:EP2 add
- Which rumble effect to use when fired. Todo: Only on Xbox, or on PC with a supported gamepad too?
Worldmodel
playermodel / szWorldModel
- Path to the weapon's regular model that is seen in the world. Relative to the game root, so be sure to include the
\models
folder. Max 80 characters. anim_prefix / szAnimationPrefix
- Prefix of the animations that should be played by characters wielding this weapon (e.g. prefix_idle, prefix_reload). Max 16 characters.
Ammunition
clip_size / iMaxClip1
clip2_size / iMaxClip2
- Bullets in each clip. -1 means clips are not used.
default_clip / iDefaultClip1
default_clip2 / iDefaultClip2
- Amount of ammo in the weapon when it spawns.
primary_ammo / szAmmo1
secondary_ammo / szAmmo2
- The AmmoDef name of the hitscan ammunitions this weapon fires. Both default to "none". Max 32 characters each.
MeleeWeapon / m_bMeleeWeapon
- Weapon is a crowbar, knife, fists, etc. Defaults false.
SoundData
The SoundData
subkey defines the sounds that should play when the weapon fires a bullet, fires dry, reloads, and so on. CBaseCombatWeapon will understand (but not necessarily use) the following:
empty
single_shot
single_shot_npc
double_shot
double_shot_npc
burst
reload
reload_npc
melee_miss
melee_hit
melee_hit_world
special1
special2
special3
taunt
TextureData
Flags
1 / ITEM_FLAG_NOAUTORELOAD
- Weapon does not automatically reload.
2 / ITEM_FLAG_NOAUTOSWITCHEMPTY
- Weapon does not automatically switch to another weapon when empty.
3 / ITEM_FLAG_LIMITINWORLD
- Weapon is limited in world.
4 / ITEM_FLAG_EXHAUSTIBLE
- A player can totally exhaust their ammo supply and lose this weapon. The Frag Grenade has this flag.
5 / ITEM_FLAG_DOHITLOCATIONDMG
- This weapon takes hit location into account when applying damage.
6 / ITEM_FLAG_NOAMMOPICKUPS
- Don't draw ammo pickup sprites/sounds when ammo is received.
6 / ITEM_FLAG_NOITEMPICKUP
- Don't draw weapon pickup when this weapon is picked up by the player.
Parsing new keys
You will at some point probably want to parse additional keys from a weapon script. You may want to simply because important values like cycle time (how long between each bullet) and bullets per shot are not read from scripts by Valve's code.
Doing it is incredibly easy:
#include "cbase.h"
#include "weapon_parse.h"
#include "KeyValues.h"
class MyWeaponParse : public FileWeaponInfo_t
{
public:
DECLARE_CLASS_GAMEROOT( MyWeaponParse, FileWeaponInfo_t );
virtual void Parse( ::KeyValues* pKeyValuesData, const char* szWeaponName );
float m_flCycleTime;
int m_iBullets;
};
void MyWeaponParse::Parse( ::KeyValues* pKeyValuesData, const char* szWeaponName )
{
BaseClass::Parse( pKeyValuesData, szWeaponName );
m_flCycleTime = pKeyValuesData->GetFloat( "CycleTime", 0.15 );
m_iBullets = pKeyValuesData->GetInt( "Bullets", 1 );
}
// This function probably exists somewhere in your mod already.
FileWeaponInfo_t* CreateWeaponInfo()
{
return new MyWeaponParse;
}
From outside the weapon
To load weapon script keys from outside the weapon class (e.g. for VGUI use):

KeyValues
for other ways to access data from a FileWeaponInfo_t
object.Client:
const FileWeaponInfo_t &weaponInfo = C_BasePlayer::GetLocalPlayer()->GetActiveWeapon()->GetWpnData();
wchar_t* wepname = g_pVGuiLocalize->Find(weaponInfo.szPrintName); // Loading a localised string
Server:
// TODO
Encryption
To prevent server operators from changing the behaviour of your weapons, you can ICE encrypt them. This isn't totally secure as your ICE key can be extracted from your mod's binaries by anyone with enough knowledge, but it will head off most tampering.
To implement encryption, choose a secret eight-character alphanumeric key and run your weapon scripts through VICE with it. Then create const unsigned char* GetEncryptionKey()
in your GameRules class and have it return the key.
Once your mod starts loading ICE-encrypted files (.ctx) it will not load normal .txt files, even if a CTX is missing.