From Valve Developer Community
Jump to: navigation, search

The $definemacro QC command defines a string substitution macro. A macro can be used as a short hand way to specify other QC commands. The macro creates a block a named block of text, that when referred to will virtually insert that text into the QC file, along with replacing the named parameters with the specified values.


$definemacro (macroname) [arg_name1] [arg_name2] [...] \\
  • Defines a string substation macro.
  • The macro definition begins on the next line, and all subsequent lines that end with \\ (two backslashes).
  • Arguments are referenced by surrounding them with $’s (i.e. $arg_name1$ ), and can be embedded inside of other words.
  • To use the macro, type $macroname and the next N tokens will be taken as arguments.


$definemacro testmacro seqname filename endframe \\
$sequence $seqname$01 $filename$ { \\
    frames 0 $endframe$ \\
    subtract $seqname$ 0 delta \\
    weightlist justbody \\

Then, to use the macro, do:

$testmacro small_flinch "npc flinch 01" 20

Another example:

$definemacro makeidlenoise idleNoiseName fileName \\
$sequence $idleNoiseName$ {\\
     $fileName$ \\
     subtract $idleNoiseName$ 0 \\
     iklock lfoot 1 0 iklock rfoot 1 0 \\
     delta \\
     hidden \\
     realtime \\

$makeidlenoise idleNoise03 "Idle03"
$makeidlenoise idleNoise04 "Idle04_v32"

Macro Nesting

You can execute macros from within macros. This is useful if you need to execute a series of commands several times. In this example we use it to create blend spaces for each weapon.

$definemacro makerundirections direction weapon \\
$animation run_$direction$ ani/run_$direction$ { \\
LX LY \\
worldspaceblend a_run_$weapon$_pose \\
} \\
$definemacro makerun weapon activity \\
$animation a_run_$weapon$_pose ani/aimlayers/aimlayer_$weapon$ frame 5 5 \\
$makerundirections $weapon$ s \\
$makerundirections $weapon$ sw \\
$makerundirections $weapon$ w \\
$makerundirections $weapon$ nw \\
$makerundirections $weapon$ n \\
$makerundirections $weapon$ ne \\
$makerundirections $weapon$ e \\
$makerundirections $weapon$ se \\

$animation a_run_$weapon$_C "jb3_skeleton.smd" { \\
	LX LY \\
	worldspaceblend a_$locomotion$_$weapon$_pose \\
} \\
$sequence $locomotion$_$weapon$ { \\
	a_run_$weapon$_SW  a_run_$weapon$_S a_run_$weapon$_SE \\
	a_run_$weapon$_W	a_run_$weapon$_C a_run_$weapon$_E  \\
	a_run_$weapon$_NW  a_run_$weapon$_N a_run_$weapon$_NE \\
	blendwidth 3 blend move_y -1 1 blend move_x -1 1 \\
	addlayer aimlayer_$weapon$ \\
	fadein 0.3 fadeout 0.5 loop \\
	node "locomotion" \\
	$activity$ 1 \\
	} \\
$makerun smg ACT_RUN_SMG
$makerun pistol ACT_RUN_PISTOL
$makerun crowbar ACT_RUN_CROWBAR

Passing Macro Commands Down

You can also pass tokens down a macro nest. This is super useful if you want to create a top level interface for your commands, as well as creating macros that can be used with multiple skeletons.

$definemacro makeholdtype weapon activity weights \\
$makeaimlayer9frame $weapon$ \\
$makeidle $weapon$ ACT_IDLE_$activity$ \\
$MakeLocomotion run $weapon$ ACT_RUN_$activity$ $weights$ \\
$MakeLocomotion crouch $weapon$ ACT_CWALK_$activity$ $weights$ \\
$MakeLocomotion swim $weapon$ ACT_SWIM_$activity$ $weights$ \\
$makeholdtype pistol_twohand PISTOL_TWOHAND weights_worldspaceblend
$makeholdtype smg SMG weights_worldspaceblend
$makeholdtype rifle RIFLE weights_worldspaceblend
$makeholdtype physcannon PHYSCANNON weights_worldspaceblend
$makeholdtype shotgun SHOTGUN weights_worldspaceblend
$makeholdtype grenade GRENADE weights_worldspaceblend_dual


  • You can not contain tokens within quotes. EX: "animations/$macroexample$_run" will not work; the compiler will read it as-is and look for "animations/$macroexample$_run.smd" instead of replacing it.
  • You can use macro tokens when defining other macros as long as there is SOME text behind it. Ex: "$macroexamplecommand token1 token2 $macrotoken3$" will fail the compile with "macro expand overflow", but "$macroexamplecommand example token1 $macrotoken3$ token2" will work. You can also do "$macroexamplecommand example token1 token2 $macrotoken3$ dummy"

See also