VCD: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
(added every category that should be added, but it is still wip, examples are here for the time being)
m (maybe I should just reread myself)
 
(7 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{LanguageBar}}
{{LanguageBar}}
 
{{toc-right}}
{{stub}}
 
{{wip|Le Glaconus|I wrote all of my observations about every category in this page in an external document, please wait until I finish copying them here}}


'''Valve Choreography Data''' ('''VCD''') is a proprietary file format used to store [[Choreography_Tool|choreography]] data.
'''Valve Choreography Data''' ('''VCD''') is a proprietary file format used to store [[Choreography_Tool|choreography]] data.


VCDs are authored in [[Faceposer]] and played in your map via the {{ent|logic_choreographed_scene}} entity.  
VCDs are authored in {{faceposer|4|nt=0}} and played in your map via the {{ent|logic_choreographed_scene}} entity.  
{{warning|The filename should contain only one period before the file extension; otherwise, the scene file cannot be found.}}
{{warning|The filename should contain only one period before the file extension; otherwise, the scene file cannot be found.}}
{{note|VCD files must be compiled into {{ent|scenes.image}} before they can be used {{src07|since}}.}}
{{note|VCD files must be compiled into {{ent|scenes.image}} before they can be used {{src07|since}} {{mapbase|not}}.}}


== Format ==
== Format ==


VCD uses a plain-text format that superficially resembles a simplified version of {{wiki|JSON}} and can be edited with any text editor. Each file contains a nested list of objects that each have properties of their own. Properties can be text, numbers, or other objects and are denoted using a simple system of key-value pairs without separators.
VCD uses a plain-text format that superficially resembles a simplified version of {{wiki|JSON}} and can be edited with any text editor. Each file contains a nested list of objects that each have properties of their own. Properties can be strings, floats, or other objects and are denoted using a simple system of key-value pairs without separators.


The basic notation is as follows:
The basic notation is as follows:


// comment
<source>
object_type (object subtype) "name" (parameters)
// Very insightful comment
{
object_type <object subtype> "name" <parameters>
  property "value"
{
  property value
  property "value"
  object_type (name) (parameters)
  property value
  {
  object_type <name> <parameters>
    property "value"
  {
  }
    property "value"
}
  }
}
</source>


=== Objects ===
=== Objects ===


Each object is denoted using the syntax <code>type (subtype) "name" (parameters)</code>. Names, subtypes and paremeters may be optional depending on object type; the most simple declaration possible consists solely of an object type, such as with <code>event_ramp</code>. Common objects are actors, channels, and events.
Each object is denoted using the syntax <code>type (subtype) "name" (parameters)</code>. Names, subtypes and paremeters may be optional depending on object type; the most simple declaration possible consists solely of an object type, such as with {{mono|event_ramp}}. Common objects are actors, channels, and events.


==== Object types ====
==== Object types ====
Line 38: Line 37:
! Type !! Function !! Takes a name ? !! Parameters !! Example
! Type !! Function !! Takes a name ? !! Parameters !! Example
|-
|-
| <code>actor</code> || A single actor, with channels as children || Yes || none || <code>actor "Alyx" { ... }</code>
| {{mono|actor}} || A single actor, with channels as children || Yes || None || {{code|preset=1|actor "Alyx" { ... } }}
|-
|-
| <code>channel</code> || A single channel, with events as children || Yes || none || <code>channel "look at" { ... }</code>
| {{mono|channel}} || A single channel, with events as children || Yes || None || {{code|preset=1|channel "look at" { ... } }}
|-
|-
| <code>event</code> || A single event, possibly with an event ramp or tags as children || Yes || none || <code>event lookat "look_player" { ... }</code>
| {{mono|event}} || A single event, possibly with an event ramp or tags as children || Yes || None || {{code|preset=1|event lookat "look at player" { ... } }}
|-
|-
| <code>event_ramp</code> || Used for storing ramp data for blending events || No || none || <code>event_ramp { ... }</code>
| {{mono|event_ramp}} || Used for storing ramp data for blending events || No || None || {{code|preset=1|event_ramp { ... } }}
|-
|-
| <code>tags</code> || Used for event timing tags || No || none || <code>tags { ... }</code>
| {{mono|tags}} || Used for event timing tags || No || none || {{code|preset=1|tags { ... } }}
|-
|-
| <code>absolutetags</code> || Used for gestures || No || <code>playback_time</code> or <code>shifted_time</code> || <code>absolutetags shifted_time{ ... }</code>
| {{mono|absolutetags}} || Used for gestures || No || <code>playback_time</code> or <code>shifted_time</code> || {{code|preset=1|absolutetags shifted_time { ... } }}
|-
|-
| <code>relativetags</code> || Unimplemented, meant to be used for WAV events || No || Unknown || Unknown
| {{mono|relativetags}} || Unimplemented, meant to be used for WAV events || No || Unknown || Unknown
|-
|-
| <code>flexanimations</code> || Used for flex animation data || No || See its dedicated section || <code>flexanimations defaultcurvetype=curve_catmullrom_normalize_x_to_curve_catmullrom_normalize_x { ... }</code>
| {{mono|flexanimations}} || Used for flex animation data || No || See its dedicated section || {{code|preset=1|flexanimations <options> { ... } }}
|-
|-
| <code>flextimingtags</code> || Used for flex animation tags || No || none || <code>flextimingtags { ... }</code>
| {{mono|flextimingtags}} || Used for flex animation tags || No || None || {{code|preset=1|flextimingtags { ... } }}
|-
|-
| <code>scalesettings</code> || Obsolete way of saving UI data || No || none ||  
| {{mono|scalesettings}} || Obsolete way of saving UI data || No || None ||{{clr}}
  scalesettings
<source>
  {
scalesettings
    "CChoreoView" "25"
{
    "ExpressionTool" "100"
  "CChoreoView" "25"
    "GestureTool" "100"
  "ExpressionTool" "100"
    "RampTool" "52"
  "GestureTool" "100"
    "SceneRampTool" "100"
  "RampTool" "52"
  }
  "SceneRampTool" "100"
:{{note|While it is written in most VCD files, it doesn't have any effect on the UI, because the UI data is stored in registry keys.}}
}</source>
|}
|}


==== Object hierarchy/order ====
==== Object hierarchy/order ====
<small>{{todo|Make this pretty}}</small>


* Actor(s)
* Actor(s)
Line 81: Line 82:
=== Properties ===
=== Properties ===


Properties of objects are denoted using their name (key) without parentheses, followed by a one or more values separated by spaces. Text is enclosed in double quotes (" "), numbers are not. Properties may be other objects, each with their own properties. The amount and type of available or required properties depend on the object type.
Properties of objects are denoted using their name (key) without parentheses, followed by a one or more values separated by spaces. Strings are enclosed in double quotes (" "), floats are not. Properties may be other objects, each with their own properties. The amount and type of available or required properties depend on the object type.


A few properties are common across many object types, such as <code>time (float) (float)</code> and <code> param (string)</code>, indicating time codes and parameters that are to be passed to certain events. One such example is the <code>lookat</code> type event, which takes two time values for its position and duration or end point on the timeline and one param value to determine the entity an actor should look at:
A few properties are common across many object types, such as <code>time (float) (float)</code> and <code> param (string)</code>, indicating time codes and parameters that are to be passed to certain events. One such example is the <code>lookat</code> type event, which takes two time values for its position and duration or end point on the timeline and one param value to determine the entity an actor should look at:


Properties not followed by any value are flags. For instance : <code>fixedlength</code>. Every flag is optional, but they might be forced to appear by Faceposer.
Properties not followed by any value are flags. For instance : <code>fixedlength</code>. Every flag is optional, but they might be forced to appear by {{faceposer|2|nt=0}}.


  // from scenes/eli_lab/al_cmon.vcd
<source>
// From scenes/eli_lab/al_cmon.vcd
 
...
 
event lookat "look_player"
{
  time 0.053333 2.553333
  param "!player"
   ...
   ...
  event lookat "look_player"
}
  {
</source>
    time 0.053333 2.553333
    param "!player"
    ...
  }


=== Comments ===
=== Comments ===
Line 100: Line 105:
Single-line comments may be created by prefacing a line with two slashes, for example:
Single-line comments may be created by prefacing a line with two slashes, for example:


// this is a comment
<source>
channel "look_at"
// This is another insightful comment
{
channel "look_at"
    ...
{
}
  ...
}
</source>


== Scene properties ==
== Scene properties ==
Line 110: Line 117:
=== Map name ===
=== Map name ===


<code>mapname</code> is the name of the tied .bsp, which is used for loading entity names. It should be a relative path starting from the <code>maps/</code> folder.
;<code>mapname <[[string]]></code> : It is the name of the tied .bsp, which is used for loading entity names. It should be a relative path starting from the {{path|maps/}} folder.


'''Format :''' <code>mapname (string)</code>
=== Window settings ===


=== Window settings ===
<code>scalesettings</code>is an obsolete way of storing UI preferences, it doesn't have any effect on the UI as this data is stored in registry keys. It is however always written in VCD files by {{faceposer|2|nt=0}}.
{{confirm|Does it work in {{SourceBranch|2004}} {{faceposer|1|nt=0}} ?}}


{{todo|move <code>scalesettings</code> info here, along with additional info}}
'''Format''' :
  scalesettings
  {
    "CChoreoView" "scale"
    <[[string]]> <[[string]]>
  }
{{note|Window names are written in function of their names in the "View" tab.}}
{{note|While every other window setting is optional, <code>CChoreoView</code> settings (the timeline window) are always written.}}


=== Fps ===
=== Fps ===


<code>fps</code> is the fps number used for snapping. Its default value is 60. In Faceposer, the minimum value acceptable is 1 and the maximum is the 32 bit signed integer limit (2'147'483'647). But when loaded, the values will be snapped to 10 and 240.
;<code>fps <[[int]]></code> : It is the fps number used for snapping. Its default value is 60. In {{faceposer|2|nt=0}}, the minimum value acceptable is 1 and the maximum is the 32 bit signed integer limit (2'147'483'647). But when loaded, the values will be snapped to 10 and 240 respectively.
 
'''Format :''' <code>fps (integer)</code>


=== Snap ===
=== Snap ===


<code>snap</code> is used by Faceposer to save if the user wants snapping enabled, it is disabled by default.
;<code>snap <on/off></code> : It is used by {{faceposer|2|nt=0}} to save if the user wants snapping enabled, it is disabled by default.
 
'''Format :''' <code>snap on/off</code>


=== Ignore phonemes ===
=== Ignore phonemes ===


{{todo}}
{{todo}}
{{confirm|{{SourceBranch|2007}} addition, doesn't seem to have any effect on Faceposer or the game. Cannot be toggled in Faceposer}}
{{confirm|{{SourceBranch|2007}} addition, doesn't seem to have any effect on {{faceposer|1|nt=0}} or the game. Cannot be toggled in {{faceposer|1|nt=0}}}}
{{note|Off by default}}
{{note|Off by default}}


'''Format :''' <code>ignorePhonemes on/off</code>
;<code>ignorePhonemes <on/off></code>


== Actor properties ==
== Actor properties ==
Line 142: Line 153:
=== Model ===
=== Model ===


<code>faceposermodel</code> is the tied model name.
;<code>faceposermodel <[[string]]></code> : It is the tied model name.
{{note|It is stored as an absolute path, unlike <code>mapname</code>}}
{{note|It is stored as an absolute path, unlike <code>mapname</code>.}}
 
'''Format :''' <code>faceposermodel (string)</code>


=== Activity ===
=== Activity ===


<code>active</code> is used for the actor disabling feature.
;<code>active <[[bool]]></code> : It is used for the actor disabling feature.
{{note|If it is 1, it will simply not be written}}
{{note|If it is 1, it will simply not be written.}}
 
'''Format :''' <code>active (boolean)</code>


== Channel properties ==
== Channel properties ==
Line 158: Line 165:
=== Activity ===
=== Activity ===


<code>active</code> is used for the channel disabling feature.
;<code>active <[[bool]]></code> : It is used for the channel disabling feature.
{{note|If it is 1, it will simply not be written}}
{{note|If it is 1, it will simply not be written.}}
 
'''Format :''' <code>active (boolean)</code>


== Event subtypes ==
== Event subtypes ==


=== Subtype table ===
=== Subtype table ===
"1D events" are events with an end time of -1.


{| class="wikitable"
{| class="wikitable"
|-
|-
! Faceposer event type !! VCD subtype
! Faceposer event type !! VCD subtype || Is 1D ?
|-
|-
| Unspecified || <code>unspecified</code>
| Unspecified || {{mono|unspecified}} || ---
|-
|-
| Expression || <code>expression</code>
| Expression || {{mono|expression}} || No
|-  
|-  
| WAV File || <code>speak</code>
| WAV File || {{mono|speak}} || No
|-
|-
| Gesture || <code>gesture</code>
| Gesture || {{mono|gesture}} || No
|-
|-
| Look at actor || <code>lookat</code>
| Look at actor || {{mono|lookat}} || No
|-
|-
| Move to actor || <code>moveto</code>
| Move to actor || {{mono|moveto}} || No
|-
|-
| Face actor || <code>face</code>
| Face actor || {{mono|face}} || No
|-
|-
| Fire Trigger || <code>firetrigger</code>
| Fire Trigger || {{mono|firetrigger}} || Yes
|-
|-
| Generic(AI) || <code>generic</code>
| Generic(AI) || {{mono|generic}} || No
|-
|-
| Sequence || <code>sequence</code>
| Sequence || {{mono|sequence}} || No
|-
|-
| Flex animation || <code>flexanimation</code>
| Flex animation || {{mono|flexanimation}} || No
|-
|-
| Sub-scene || <code>subscene</code>
| Sub-scene || {{mono|subscene}} || No
|-
|-
| Interrupt || <code>interrupt</code>
| Interrupt || {{mono|interrupt}} || No
|-
|-
| Permit Responses || <code>permitresponses</code>
| Permit Responses || {{mono|permitresponses}} || No
|-
|-
| Camera {{since|{{asw}}}} || <code>camera</code>
| Camera {{asw|since}} || {{mono|camera}} || No
|-
|-
| Script {{since|{{asw}}}} || <code>script</code>
| Script {{asw|since}} || {{mono|script}} || Yes
|-
|-
| The following subtypes are not treated as regular events by Faceposer || ---
| The following subtypes are not treated as regular events by {{faceposer|1|nt=0}} || --- || ---
|-
|-
| Section Pause || <code>section</code>
| Section Pause || {{mono|section}} || Yes
|-
|-
| Loop || <code>loop</code>
| Loop || {{mono|loop}} || Yes
|-
|-
| Fire Completion || <code>stoppoint</code>
| Fire Completion || {{mono|stoppoint}} || Yes
|-
|-
|}
|}
Line 217: Line 224:
Every event share these properties :
Every event share these properties :


* <code>time (float) (float)</code>
;<code>time <[[float]]> <[[float]]></code>
:{{note|If the second float is 0 (it is always written -1 by Faceposer) or lower, the event will act like a single point. It will disable the "End time" checkbox.}}
:{{note|If the second float is 0 (it is always written -1 by {{faceposer|2|nt=0}}) or lower, the event will act like a single point. It will disable the "End time" checkbox.}}
* <code>param (string)</code>
;<code>param <[[string]]></code>
* <code>[param2 (string)]</code>
;<code>[param2 <[[string]]>]</code>
* <code>[param3 (string)]</code>
;<code>[param3 <[[string]]>]</code>
* <code>fixedlength</code>
;<code>fixedlength</code> : Makes resizing the event in {{faceposer|2|nt=0}} impossible.
:{{note|Makes resizing the event in Faceposer impossible.}}
;<code>resumecondition</code>
* <code>resumecondition</code>
;<code>[active <[[bool]]>]</code> : <code>active</code> is simply nonexistent if set to 1.
* <code>[active (bool)]</code>
;<code>[tags { ... }]</code>
:{{note|<code>active</code> is simply non-existant if set to 1.}}
:;<code><[[string]]> <[[float]]></code>
* <code>[tags { ... }]</code>
:;<code>...</code>
:* <code>(string) (float)</code>
:The string represents a name, and the float a timestamp.
:* <code>...</code>
:{{note|The string represents a name, and the float a timestamp.}}
:{{note|There can only be 128 tags for one event.}}
:{{note|There can only be 128 tags for one event.}}
* <code>[event_ramp { ... }]</code>
;<code>[event_ramp { ... }]</code>
:* <code>(float) (float)</code>
:;<code><[[float]]> <[[float]]></code>
:* <code>...</code>
:;<code>...</code>
:{{note|The first float represents a timestamp, and the second a ratio.}}
:The first float represents a timestamp, and the second a ratio.
:{{note|There can only be 128 ramp values for one event.}}
:{{note|There can only be 128 ramp values for one event.}}


=== Unspecified and unhandled events ===
=== Unspecified and unhandled events ===


These events cannot be edited or exported, but can be moved and imported in Faceposer. The "Unspecified" event should never appear in Faceposer in normal circumstances. Every unhandled event (such as the "Script" event) will acts in the same way in Faceposer, but they might function properly in-game.
These events cannot be edited or exported, but can be moved and imported in {{faceposer|2|nt=0}}. The "Unspecified" event should never appear in {{faceposer|1|nt=0}} in normal circumstances. Every unhandled event (such as the "[[VCD#Script|Script]]" event) will acts in the same way in {{faceposer|1|nt=0}}, but they might function properly in-game.


=== Expression ===
=== Expression ===


This event takes a phoneme class as its first parameter and a phoneme as its second. The most common phoneme classes to exist are <code>phonemes</code>, <code>phoneme_weak</code>, <code>phoneme_strong</code> because they are always precached. The {{hl2series|4}} additionaly precaches <code>random</code> and <code>randomAlert</code>.
;<code>param <[[string]]></code> : Takes a phoneme class.
:{{note|The most common phoneme classes to exist are <code>phonemes</code>, <code>phoneme_weak</code>, <code>phoneme_strong</code> because they are always precached.}}
::{{note|The {{hl2series|4}} additionaly precaches <code>random</code> and <code>randomAlert</code>.}}
;<code>param2 <[[string]]></code> : Takes a phoneme.


'''Example :'''
'''Example :'''
<syntaxhighlight lang=js>
<source lang=js>
expression "Expression event 1"
expression "Expression event 1"
{
{
Line 254: Line 262:
   param2 "w"
   param2 "w"
}
}
</syntaxhighlight>
</source>


=== WAV File ===
=== WAV File ===


'''Example :'''
;<code>param <[[string]]></code> : Takes a [[soundscript]] or a raw sound name.
<syntaxhighlight lang=js>
;<code>param2 <[[string]]></code> : Takes a float (in text form, between quotes) or <code>VOL_NORM</code>for its sound volume.
:{{note|In {{SourceBranch|2004}}, <code>param2</code> has to take one of these following dB values : <br>
:* <code>60dB</code>
:* <code>65dB</code>
:* <code>70dB</code>
:* <code>75dB</code>
:* <code>80dB</code>
:* <code>85dB</code>
:* <code>90dB</code>
}}
::{{confirm|Does it still work in games made after {{SourceBranch|2006}} ?}}
;<code>fixedlength</code> : Is always set by {{faceposer|2|nt=0}} because sounds cannot be stretched.
;<code>cctype <[[string]]></code> : Is used for closed captions, it can be <code>cc_master</code>, <code>cc_slave</code> or <code>cc_disabled</code>.
:;<code>cc_slave <[[string]]></code> : Is related to combined audio files, it doesn't emit captions.
::{{note|It can be changed in {{faceposer|1|nt=0}} with the "change selector" curved line pointing to one of the WAV events.}}
:;<code>cc_disabled <[[string]]></code> : Is tied to the "Disable Captions" checkbox.
;<code>cctoken <[[string]]></code> : Can be used to override caption tokens. It is most notably used for combined audio files.
;<code>[cc_noattenuate]</code> : Is tied to the "Don't attenuate captions" checkbox.
;<code>[cc_usingcombinedfile]</code>
 
 
{{expand|title=Example :|{{clr}}
<source lang=js>
speak "Sound event 1"
speak "Sound event 1"
{
{
   time 0.000000 1.000000
   time 0.000000 3.407483
   param "npc_citizen.question06"
   param "npc_citizen.question06"
   param2 "VOL_NORM"
   param2 "VOL_NORM"
Line 268: Line 298:
   cc_type "cc_master"
   cc_type "cc_master"
   cctoken ""
   cctoken ""
  cc_noattenuate
}
}
</syntaxhighlight>
</source>
}}


=== Gesture ===
=== Gesture ===


'''Example :'''
;<code>param <[[string]]></code> : Takes a sequence name.
<syntaxhighlight lang=js>
;<code>[synctofollowingestures]</code>
;<code>absolutetags playback_time</code> : It is the data in the playback time section.
:;<code>apex <[[float]]></code>
:;<code>accent <[[float]]></code>
:;<code>loop <[[float]]></code>
:;<code>end <[[float]]></code>
:;<code><[[string]]> <[[float]]></code>
 
 
;<code>absolutetags shifted_time</code> : It is the data in the original time section. It shouldn't be modifiable in {{faceposer|2|nt=0}}.
::{{note|It stores the data taken directly from the sequences' <code>[[$keyvalues]]</code> block. See [[Creating Faceposer gestures]] for more information.}}
:;<code>apex <[[float]]></code>
:;<code>accent <[[float]]></code>
:;<code>loop <[[float]]></code>
:;<code>end <[[float]]></code>
:;<code><[[string]]> <[[float]]></code>
 
:{{note|Tags have to be defined in both blocks.}}
 
;<code>sequenceduration <[[float]]></code> : Defines the duration of the currently used sequence, it is read-only.
 
 
{{expand|title=Example :|{{clr}}
<source lang=js>
event gesture "Gesture event 1"
event gesture "Gesture event 1"
{
{
Line 286: Line 341:
     "loop" 0.155300
     "loop" 0.155300
     "end" 0.728225
     "end" 0.728225
    "exampletag" 0.165000
   }
   }
   absolutetags shifted_time
   absolutetags shifted_time
Line 293: Line 349:
     "loop" 0.320000
     "loop" 0.320000
     "end" 0.440000
     "end" 0.440000
    "exampletag" 0.150000
   }
   }
}
}
</syntaxhighlight>
</source>
}}
 
=== NULL gesture ===
Null gestures are simple gestures with <code>NULL</code> as their name. They can take every property regular gestures can take, but those will not be parsed.
 
'''Example :'''
<source lang=js>
event gesture "NULL"
{
  time 0.000000 1.000000
  param ""
}
</source>


=== Look at actor ===
=== Look at actor ===


This event takes an actor name as its first parameter and an optional pitch and yaw.
;<code>param <[[string]]></code> : Takes an actor name.
{{todo|What is the lowest and highest accepted value for both ?}}
;<code>[pitch <[[float]]>]</code>
;<code>[yaw <[[float]]>]</code>
{{modernConfirm|What is the lowest and highest accepted value for both ? Does it even do anything ? The [https://github.com/ValveSoftware/source-sdk-2013/blob/singleplayer/src/game/server/baseflex.cpp#L1513 code] doesn't seem to care about yaw and pitch.}}


{{expand|title=Examples|{{clr}}
'''Example 1 :'''
'''Example 1 :'''
<syntaxhighlight lang=js>
<source lang=js>
event lookat "Look at player"
event lookat "Look at player"
{
{
Line 309: Line 383:
   param "!player"
   param "!player"
}
}
</syntaxhighlight>
</source>
 
'''Example 2 :'''
'''Example 2 :'''
<syntaxhighlight lang=js>
<source lang=js>
event lookat "Look at desk"
event lookat "Look at desk"
{
{
Line 318: Line 391:
   param "target_desk01"
   param "target_desk01"
}
}
</syntaxhighlight>
</source>
 
'''Example 3 :'''
'''Example 3 :'''
<syntaxhighlight lang=js>
<source lang=js>
event lookat "Look at marker"
event lookat "Look at marker"
{
{
Line 329: Line 401:
   yaw -10
   yaw -10
}
}
</syntaxhighlight>
</source>
}}


=== Move at actor ===
=== Move at actor ===


This event takes an actor name as its first parameter, a move type as its second, an optional actor name as its third, a stop distance and a flag for forcing short movements.
;<code>param <[[string]]></code> : Takes an actor name.
<code>param2</code> can take <code>Walk</code>, <code>Run</code> or <code>CrouchWalk</code>. If a sequence name is specified, it will be used instead.
;<code>param2 <[[string]]></code> : Takes a move type, it can be <code>Walk</code>, <code>Run</code> or <code>CrouchWalk</code>.
:{{note|If a sequence name is specified, it will be used instead.}}
;<code>[param3 <[[string]]>]</code> : Takes an actor name.
{{todo|Find what <code>param3</code> really does}}
{{todo|Find what <code>param3</code> really does}}
;<code>distancetotarget <[[float]]></code>
:{{note|The maximum stop distance in {{faceposer|2|nt=0}} is 200, higher values are still valid, however.}}
;<code>[forceshortmovement]</code>


{{expand|title=Examples :|{{clr}}
'''Example 1 :'''
'''Example 1 :'''
<syntaxhighlight lang=js>
<source lang=js>
event moveto "Run to player"
event moveto "Run to player"
{
{
Line 345: Line 425:
   param2 "Run"
   param2 "Run"
}
}
</syntaxhighlight>
</source>
 
'''Example 2 :'''
'''Example 2 :'''
<syntaxhighlight lang=js>
<source lang=js>
event moveto "Crouch-walk to desk"
event moveto "Crouch-walk to desk"
{
{
Line 357: Line 436:
   forceshortmovement
   forceshortmovement
}
}
</syntaxhighlight>
</source>
}}


=== Face actor ===
=== Face actor ===


This event takes an actor name as its first parameter and optionally a flag for not moving the legs.
;<code>param <[[string]]></code> : Takes an actor name.
;<code>[lockbodyfacing]</code> : Makes the actor's legs not move.


'''Example :'''
'''Example :'''
<syntaxhighlight lang=js>
<source lang=js>
event moveto "Face player"
event moveto "Face player"
{
{
Line 371: Line 452:
   lockbodyfacing
   lockbodyfacing
}
}
</syntaxhighlight>
</source>


=== Fire Trigger ===
=== Fire Trigger ===


This event takes a number ranging from 1 to 16 as its first parameter. It must be used in cunjuction with the ''OnTriggerX'' output.
;<code>param <[[string]]></code> : Takes a number ranging from 1 to 16. It is meant to be used in conjunction with {{ent|logic_choreographed_scene}}'s ''OnTriggerX'' output.


'''Example :'''
'''Example :'''
<syntaxhighlight lang=js>
<source lang=js>
event firetrigger "Fire Trigger event"
event firetrigger "Fire Trigger event"
{
{
Line 384: Line 465:
   param "5"
   param "5"
}
}
</syntaxhighlight>
</source>


=== Generic(AI) ===
=== Generic(AI) ===


This event takes an AI action as its first parameter and optionally an actor name as its second.
;<code>param <[[string]]></code> : Takes an AI action.
 
 
The AI actions can be :
The AI actions can be :
{| class="wikitable"
{| class="wikitable"
Line 394: Line 477:
! Action name !! Takes a target ?
! Action name !! Takes a target ?
|-
|-
| <code>AI_BLINK</code> || No
| {{mono|AI_BLINK}} || No
|-
|-
| <code>AI_HOLSTER</code> || No
| {{mono|AI_HOLSTER}} || No
|-
|-
| <code>AI_UNHOLSTER</code> || No
| {{mono|AI_UNHOLSTER}} || No
|-
|-
| <code>AI_AIM</code> || Yes
| {{mono|AI_AIM}} || Yes
|-
|-
| <code>AI_RANDOMLOOK</code> || No
| {{mono|AI_RANDOMLOOK}} || No
|-
|-
| <code>AI_RANDOMFACEFLEX</code> || No
| {{mono|AI_RANDOMFACEFLEX}} || No
|-
|-
| <code>AI_RANDOMHEADFLEX</code> || No
| {{mono|AI_RANDOMHEADFLEX}} || No
|-
|-
| <code>AI_IGNORECOLLISION</code> || Yes
| {{mono|AI_IGNORECOLLISION}} || Yes
|-
|-
| <code>AI_DISABLEAI</code> || No
| {{mono|AI_DISABLEAI}} || No
|-
|-
| <code>debugtext</code> || No
| {{mono|debugtext}} || No
|}
|}
{{note|<code>debugtext</code> takes one parameter in an untraditional way, it is taken after its name. <code>param "debugtext Hi !"</code> for instance.}}
{{note|<code>debugtext</code> takes one parameter in an untraditional way, it is taken after its name. <code>param "debugtext Hi !"</code> for instance.}}


;<code>[param2 <[[string]]></code> : Takes an actor name used as a target.
{{expand|title=Examples :|{{clr}}
'''Example 1 :'''
'''Example 1 :'''
<syntaxhighlight lang=js>
<source lang=js>
event generic "Holster event"
event generic "Holster event"
{
{
Line 423: Line 511:
   param "AI_HOLSTER"
   param "AI_HOLSTER"
}
}
</syntaxhighlight>
</source>
 
'''Example 2 :'''
'''Example 2 :'''
<syntaxhighlight lang=js>
<source lang=js>
event generic "Aim at Alyx"
event generic "Aim at Alyx"
{
{
Line 433: Line 520:
   param2 "Alyx"
   param2 "Alyx"
}
}
</syntaxhighlight>
</source>
 
'''Example 3 :'''
'''Example 3 :'''
<syntaxhighlight lang=js>
<source lang=js>
event generic "Show debug text"
event generic "Show debug text"
{
{
Line 442: Line 528:
   param "debugtext Hi !"
   param "debugtext Hi !"
}
}
</syntaxhighlight>
</source>
}}


=== Sequence ===
=== Sequence ===
;<code>param <[[string]]></code> : Takes a sequence name.
;<code>fixedlength</code> : Is always set by {{faceposer|2|nt=0}} because only gestures can be resized.


'''Example :'''
'''Example :'''
<syntaxhighlight lang=js>
<source lang=js>
event generic "Play animation"
event generic "Play animation"
{
{
Line 454: Line 544:
   fixedlength
   fixedlength
}
}
</syntaxhighlight>
</source>


=== Flex animation ===
=== Flex animation ===


{{todo}}
Before starting with the suvtype definition, let's define what curvetypes are.
* A curve type always starts with <code>curve_</code>.
* A curvetype takes two curve types separated by <code>_to_</code>
* They can be :
 
{| class="wikitable"
|-
| {{mono|default}}
|-
| {{mono|catmullrom_normalize_x}}
|-
| {{mono|easein}}
|-
| {{mono|easeout}}
|-
| {{mono|easeinout}}
|-
| {{mono|bspline}}
|-
| {{mono|linear_interp}}
|-
| {{mono|kochanek}}
|-
| {{mono|kochanek_early}}
|-
| {{mono|kochanek_late}}
|-
| {{mono|simple_cubic}}
|-
| {{mono|catmullrom}}
|-
| {{mono|catmullrom_normalize}}
|-
| {{mono|catmullrom_tangent}}
|-
| {{mono|exponential_decay}}
|-
| {{mono|hold}}
|}
 
'''Example :'''
<code>"curve_catmullrom_normalize_x_to_curve_catmullrom_normalize_x"</code>
 
 
;<code>param <[[string]]></code> : Is unused, it is therefore left as empty quotes.
;<code>flexanimations samples_use_time defaultcurvetype=<curvetype></code>
:{{note|<code>defaultcurvetype</code> will always be set to <code>curve_catmullrom_normalize_x_to_curve_catmullrom_normalize_x</code> by default.}}
:{{confirm|Is <code>samples_use_time</code> optional ?}}
:;<code><[[string]]> [disabled] [leftedge <curvetype> <[[float]]>] [rightedge <curvetype> <[[float]]>] [combo]</code> : The first string is a flex controller name.
:{{note|There can only be 128 flex animation keyframes.}}
::;<code><[[float]]> <[[float]]> [<curvetype>]</code>
::;<code>[<[[float]]> <[[float]]> [<curvetype>]]</code>
::{{note|The second block is only created if the flex controller supports combo editing.}}
 
 
;<code>flextimingtags</code>
;<code><[[string]]> <[[float]]> <[[bool]]></code> : The string is the tag name, the float is a duration, and the boolean a lock state.
:{{note|There can only be 128 flex timing tags.}}
 
 
{{expand|title=Example :|{{clr}}
<source lang=js>
event flexanimation "Flex event"
{
  time 0.000000 5.000000
  param ""
  flexanimations samples_use_time defaultcurvetype=curve_catmullrom_normalize_x_to_curve_catmullrom_normalize_x
  {
    "lid_tightener" combo
    {
      0.4000 0.6100 "curve_easein_to_curve_easeout"
      2.4000 0.1200 "curve_linear_interp_to_curve_linear_interp"
      4.4000 0.5900 "curve_easein_to_curve_easeout"
      }
      {
        1.0000 0.7700 "curve_bspline_to_curve_bspline"
        1.8000 0.2700 "curve_bspline_to_curve_bspline"
        3.0000 0.7500 "curve_bspline_to_curve_bspline"
        4.0000 0.2900 "curve_bspline_to_curve_bspline"
      }
      "smile" leftedge curve_default_to_curve_hold 0.500 rightedge curve_kochanek_late_to_curve_default 0.250
      {
        0.8000 0.7100
        1.6000 0.2700 "curve_easein_to_curve_easeout"
        2.2000 0.6000 "curve_easein_to_curve_easein"
        3.0000 0.2600 "curve_easeout_to_curve_easeout"
        3.6000 0.5900 "curve_linear_interp_to_curve_linear_interp"
      }
    }
  }
}
</source>
}}


=== Sub-scene ===
=== Sub-scene ===


{{todo}}
;<code>param <[[string]]></code> : Takes a path.
;<code>fixedlength</code> : Is always set by {{faceposer|2|nt=0}} because the length of the sub-scene is defined by the scene itself.
{{confirm|Is the sub-scene path absolute ? I didn't see a single sub-scene in all of the first party games VCDs}}
{{confirm|Is the sub-scene path absolute ? I didn't see a single sub-scene in all of the first party games VCDs}}


=== Interrupt ===
=== Interrupt ===
;<code>param <[[string]]></code> : Takes no parameter, it isn't parsed.
:{{note|Even if <code>param</code> doesn't need to be specified, an empty dropdown exists for it in {{faceposer|1|nt=0}}.}}


'''Example :'''
'''Example :'''
<syntaxhighlight lang=js>
<source lang=js>
event generic "Interrupt event"
event generic "Interrupt event"
{
{
Line 474: Line 660:
   param ""
   param ""
}
}
</syntaxhighlight>
</source>


=== Permit Responses ===
=== Permit Responses ===
;<code>param <[[string]]></code> : Takes no parameter, it isn't parsed.


'''Example :'''
'''Example :'''
<syntaxhighlight lang=js>
<source lang=js>
event permitresponses "Permit responses event"
event permitresponses "Permit responses event"
{
{
Line 485: Line 673:
   param ""
   param ""
}
}
</syntaxhighlight>
</source>


=== Camera ===
=== Camera ===


{{since|{{asw}}}}
{{since|{{asw}}}}
;<code>param <[[string]]></code> : Is a "shot type", it is meant to be used as a simple [[string]]. Called "Camera AI event" by {{faceposer|2|nt=0}}.
;<code>param2 <[[string]]></code> : Takes an actor name.
;<code>param3 <[[string]]></code> : Takes an actor name.
This event finds the first {{ent|point_viewcontrol}}</code> (''NOT'' the closest, the first entity in the entity list) and call the <code>ScriptCameraShot()</code> Vscript function on it. This function has the following syntax : <code>void ScriptCameraShot(string ''pszShotType'', handle ''pSceneEntity'', handle ''pActor1'', handle ''pActor2'', float ''duration'')</code>.
{{note|While it is not used anywhere in {{asw}} or {{portal2}}, it is still functional.}}


'''Example :'''
'''Example :'''
<syntaxhighlight lang=js>
<source lang=js>
event camera "Camera event"
event camera "Camera event"
{
{
Line 500: Line 695:
   param3 "!target2"
   param3 "!target2"
}
}
</syntaxhighlight>
</source>


=== Script ===
=== Script ===


{{since|{{asw}}}}
{{since|{{asw}}}}
{{warning|This event is not handled by {{faceposer|2|nt=0}} ! It must be added in with a text editor.}}
;<code>param <[[string]]></code> : Takes a [[targetname]].
;<code>param2 <[[string]]></code> : Takes a [[Vscript]] function name.
;<code>param3 <[[string]]></code> : Takes a string meant to be used as a function argument.
This event triggers the function referenced in <code>param2</code> from the entity scripts of the entity referenced in <code>param</code> with the arguements written in <code>param3</code> as it follows : <code>void FunctionName(handle ''pActor'', handle ''pThisSceneEntity'', string ''param3'', float ''duration'')</code>.
{{note|While it is not used anywhere in {{asw}} or {{portal2}}, it is still functional.}}


'''Example :'''
'''Example :'''
<syntaxhighlight lang=js>
<source lang=js>
event script "Script event"
event script "Script event"
{
{
Line 515: Line 719:
   param3 "Hi !"
   param3 "Hi !"
}
}
</syntaxhighlight>
</source>


=== Section Pause ===
=== Section Pause ===


;<code>param <[[string]]></code> : Takes options, they can diverge in two different branches in function of if {{faceposer|1|nt=0}}'s "Automatically" flag is checked :
::If the flag is not checked :
::;<code>param "noaction"</code>
::If the flag is checked :
::;<code>param "automate Resume/Cancel <[[float]]>"</code> : The float is a duration.
{{expand|title=Examples :|{{clr}}
'''Example 1 :'''
'''Example 1 :'''
<syntaxhighlight lang=js>
<source lang=js>
event section "Pause point"
event section "Pause point 1"
{
{
   time 1.000000 -1.000000
   time 1.000000 -1.000000
   param "automate Resume 2.000000"
   param "automate Resume 2.000000"
}
}
</syntaxhighlight>
</source>


'''Example 2 :'''
'''Example 2 :'''
<syntaxhighlight lang=js>
<source lang=js>
event section "Pause point"
event section "Pause point 2"
{
{
   time 1.000000 -1.000000
   time 1.000000 -1.000000
   param "noaction"
   param "noaction"
}
}
</syntaxhighlight>
</source>
}}


=== Loop ===
=== Loop ===
;<code>param <[[string]]></code> : Takes a timestamp, which is the loop back point.
;<code>loopcount <[[string]]></code> : Is infinite if set to -1.


'''Example :'''
'''Example :'''
<syntaxhighlight lang=js>
<source lang=js>
event loop "Loop"
event loop "Loop"
{
{
Line 547: Line 763:
   loopcount "5"
   loopcount "5"
}
}
</syntaxhighlight>
</source>


=== Fire Completion ===
=== Fire Completion ===
;<code>param <[[string]]></code> : Doesn't take any parameter, it is only written as <code>noaction</code>.


'''Example :'''
'''Example :'''
<syntaxhighlight lang=js>
<source lang=js>
event stoppoint "Fire Completion"
event stoppoint "Fire Completion"
{
{
Line 558: Line 776:
   param "noaction"
   param "noaction"
}
}
</syntaxhighlight>
</source>
 
== See also ==
* {{ent|logic_choreographed_scene}}
* [[scenes.image]]
* [[VCE]]
* [[Choreography Tool reference]]


[[Category:Choreography]]
[[Category:Choreography]]
[[Category:File formats]]
[[Category:File formats]]

Latest revision as of 11:55, 8 July 2025

English (en)中文 (zh)Translate (Translate)

Valve Choreography Data (VCD) is a proprietary file format used to store choreography data.

VCDs are authored in HLFaceposer Faceposer and played in your map via the logic_choreographed_scene entity.

Warning.pngWarning:The filename should contain only one period before the file extension; otherwise, the scene file cannot be found.
Note.pngNote:VCD files must be compiled into scenes.image before they can be used (in all games since Source 2007) (not in Mapbase).

Format

VCD uses a plain-text format that superficially resembles a simplified version of Wikipedia icon JSON and can be edited with any text editor. Each file contains a nested list of objects that each have properties of their own. Properties can be strings, floats, or other objects and are denoted using a simple system of key-value pairs without separators.

The basic notation is as follows:

// Very insightful comment
object_type <object subtype> "name" <parameters>
{
  property "value"
  property value
  object_type <name> <parameters>
  {
    property "value"
  }
}

Objects

Each object is denoted using the syntax type (subtype) "name" (parameters). Names, subtypes and paremeters may be optional depending on object type; the most simple declaration possible consists solely of an object type, such as with event_ramp. Common objects are actors, channels, and events.

Object types

Type Function Takes a name ? Parameters Example
actor A single actor, with channels as children Yes None actor "Alyx" { ... }
channel A single channel, with events as children Yes None channel "look at" { ... }
event A single event, possibly with an event ramp or tags as children Yes None event lookat "look at player" { ... }
event_ramp Used for storing ramp data for blending events No None event_ramp { ... }
tags Used for event timing tags No none tags { ... }
absolutetags Used for gestures No playback_time or shifted_time absolutetags shifted_time { ... }
relativetags Unimplemented, meant to be used for WAV events No Unknown Unknown
flexanimations Used for flex animation data No See its dedicated section flexanimations <options> { ... }
flextimingtags Used for flex animation tags No None flextimingtags { ... }
scalesettings Obsolete way of saving UI data No None
scalesettings
{
  "CChoreoView" "25"
  "ExpressionTool" "100"
  "GestureTool" "100"
  "RampTool" "52"
  "SceneRampTool" "100"
}

Object hierarchy/order

Todo: Make this pretty
  • Actor(s)
  • Channel(s)
  • Event(s)
  • Event properties
  • Timing tags
  • Channel properties
  • Actor properties
  • Scene properties

Properties

Properties of objects are denoted using their name (key) without parentheses, followed by a one or more values separated by spaces. Strings are enclosed in double quotes (" "), floats are not. Properties may be other objects, each with their own properties. The amount and type of available or required properties depend on the object type.

A few properties are common across many object types, such as time (float) (float) and param (string), indicating time codes and parameters that are to be passed to certain events. One such example is the lookat type event, which takes two time values for its position and duration or end point on the timeline and one param value to determine the entity an actor should look at:

Properties not followed by any value are flags. For instance : fixedlength. Every flag is optional, but they might be forced to appear by HLFaceposer Faceposer.

// From scenes/eli_lab/al_cmon.vcd

...

event lookat "look_player"
{
  time 0.053333 2.553333
  param "!player"
  ...
}

Comments

Single-line comments may be created by prefacing a line with two slashes, for example:

// This is another insightful comment
channel "look_at"
{
  ...
}

Scene properties

Map name

mapname <string>
It is the name of the tied .bsp, which is used for loading entity names. It should be a relative path starting from the 🖿maps/ folder.

Window settings

scalesettingsis an obsolete way of storing UI preferences, it doesn't have any effect on the UI as this data is stored in registry keys. It is however always written in VCD files by HLFaceposer Faceposer.

Confirm:Does it work in Source 2004 Source 2004 Faceposer ?

Format :

 scalesettings
 {
   "CChoreoView" "scale"
   <string> <string>
 }
Note.pngNote:Window names are written in function of their names in the "View" tab.
Note.pngNote:While every other window setting is optional, CChoreoView settings (the timeline window) are always written.

Fps

fps <int>
It is the fps number used for snapping. Its default value is 60. In HLFaceposer Faceposer, the minimum value acceptable is 1 and the maximum is the 32 bit signed integer limit (2'147'483'647). But when loaded, the values will be snapped to 10 and 240 respectively.

Snap

snap <on/off>
It is used by HLFaceposer Faceposer to save if the user wants snapping enabled, it is disabled by default.

Ignore phonemes

[Todo]

Confirm:Source 2007 Source 2007/2009 addition, doesn't seem to have any effect on Faceposer or the game. Cannot be toggled in Faceposer
Note.pngNote:Off by default
ignorePhonemes <on/off>

Actor properties

Model

faceposermodel <string>
It is the tied model name.
Note.pngNote:It is stored as an absolute path, unlike mapname.

Activity

active <bool>
It is used for the actor disabling feature.
Note.pngNote:If it is 1, it will simply not be written.

Channel properties

Activity

active <bool>
It is used for the channel disabling feature.
Note.pngNote:If it is 1, it will simply not be written.

Event subtypes

Subtype table

"1D events" are events with an end time of -1.

Faceposer event type VCD subtype Is 1D ?
Unspecified unspecified ---
Expression expression No
WAV File speak No
Gesture gesture No
Look at actor lookat No
Move to actor moveto No
Face actor face No
Fire Trigger firetrigger Yes
Generic(AI) generic No
Sequence sequence No
Flex animation flexanimation No
Sub-scene subscene No
Interrupt interrupt No
Permit Responses permitresponses No
Camera (in all games since Alien Swarm) camera No
Script (in all games since Alien Swarm) script Yes
The following subtypes are not treated as regular events by Faceposer --- ---
Section Pause section Yes
Loop loop Yes
Fire Completion stoppoint Yes

Common properties

Every event share these properties :

time <float> <float>
Note.pngNote:If the second float is 0 (it is always written -1 by HLFaceposer Faceposer) or lower, the event will act like a single point. It will disable the "End time" checkbox.
param <string>
[param2 <string>]
[param3 <string>]
fixedlength
Makes resizing the event in HLFaceposer Faceposer impossible.
resumecondition
[active <bool>]
active is simply nonexistent if set to 1.
[tags { ... }]
<string> <float>
...
The string represents a name, and the float a timestamp.
Note.pngNote:There can only be 128 tags for one event.
[event_ramp { ... }]
<float> <float>
...
The first float represents a timestamp, and the second a ratio.
Note.pngNote:There can only be 128 ramp values for one event.

Unspecified and unhandled events

These events cannot be edited or exported, but can be moved and imported in HLFaceposer Faceposer. The "Unspecified" event should never appear in Faceposer in normal circumstances. Every unhandled event (such as the "Script" event) will acts in the same way in Faceposer, but they might function properly in-game.

Expression

param <string>
Takes a phoneme class.
Note.pngNote:The most common phoneme classes to exist are phonemes, phoneme_weak, phoneme_strong because they are always precached.
Note.pngNote:The Half-Life 2 series Half-Life 2 series additionaly precaches random and randomAlert.
param2 <string>
Takes a phoneme.

Example :

expression "Expression event 1"
{
  time 0.000000 1.000000
  param "phonemes"
  param2 "w"
}

WAV File

param <string>
Takes a soundscript or a raw sound name.
param2 <string>
Takes a float (in text form, between quotes) or VOL_NORMfor its sound volume.
Note.pngNote:In Source 2004 Source 2004, param2 has to take one of these following dB values :
  • 60dB
  • 65dB
  • 70dB
  • 75dB
  • 80dB
  • 85dB
  • 90dB
Confirm:Does it still work in games made after Source 2006 Source 2006 ?
fixedlength
Is always set by HLFaceposer Faceposer because sounds cannot be stretched.
cctype <string>
Is used for closed captions, it can be cc_master, cc_slave or cc_disabled.
cc_slave <string>
Is related to combined audio files, it doesn't emit captions.
Note.pngNote:It can be changed in Faceposer with the "change selector" curved line pointing to one of the WAV events.
cc_disabled <string>
Is tied to the "Disable Captions" checkbox.
cctoken <string>
Can be used to override caption tokens. It is most notably used for combined audio files.
[cc_noattenuate]
Is tied to the "Don't attenuate captions" checkbox.
[cc_usingcombinedfile]


Example :
speak "Sound event 1"
{
  time 0.000000 3.407483
  param "npc_citizen.question06"
  param2 "VOL_NORM"
  fixedlength
  cc_type "cc_master"
  cctoken ""
  cc_noattenuate
}

Gesture

param <string>
Takes a sequence name.
[synctofollowingestures]
absolutetags playback_time
It is the data in the playback time section.
apex <float>
accent <float>
loop <float>
end <float>
<string> <float>


absolutetags shifted_time
It is the data in the original time section. It shouldn't be modifiable in HLFaceposer Faceposer.
Note.pngNote:It stores the data taken directly from the sequences' $keyvalues block. See Creating Faceposer gestures for more information.
apex <float>
accent <float>
loop <float>
end <float>
<string> <float>
Note.pngNote:Tags have to be defined in both blocks.
sequenceduration <float>
Defines the duration of the currently used sequence, it is read-only.


Example :
event gesture "Gesture event 1"
{
  time 1.000000 4.502899
  param "G_shrug"
  synctofollowinggesture
  absolutetags playback_time
  {
    "apex" 0.077650
    "accent" 0.116475
    "loop" 0.155300
    "end" 0.728225
    "exampletag" 0.165000
  }
  absolutetags shifted_time
  {
    "apex" 0.160000
    "accent" 0.240000
    "loop" 0.320000
    "end" 0.440000
    "exampletag" 0.150000
  }
}

NULL gesture

Null gestures are simple gestures with NULL as their name. They can take every property regular gestures can take, but those will not be parsed.

Example :

event gesture "NULL"
{
  time 0.000000 1.000000
  param ""
}

Look at actor

param <string>
Takes an actor name.
[pitch <float>]
[yaw <float>]
Confirm:What is the lowest and highest accepted value for both ? Does it even do anything ? The code doesn't seem to care about yaw and pitch.


Examples

Example 1 :

event lookat "Look at player"
{
  time 0.000000 1.0000000
  param "!player"
}

Example 2 :

event lookat "Look at desk"
{
  time 0.000000 1.000000
  param "target_desk01"
}

Example 3 :

event lookat "Look at marker"
{
  time 0.000000 1.000000
  param "target_desk01"
  pitch 10
  yaw -10
}

Move at actor

param <string>
Takes an actor name.
param2 <string>
Takes a move type, it can be Walk, Run or CrouchWalk.
Note.pngNote:If a sequence name is specified, it will be used instead.
[param3 <string>]
Takes an actor name.
Todo: Find what param3 really does
distancetotarget <float>
Note.pngNote:The maximum stop distance in HLFaceposer Faceposer is 200, higher values are still valid, however.
[forceshortmovement]


Examples :

Example 1 :

event moveto "Run to player"
{
  time 0.000000 1.0000000
  param "!player"
  param2 "Run"
}

Example 2 :

event moveto "Crouch-walk to desk"
{
  time 0.000000 1.0000000
  param "target_desk02"
  param2 "CrouchWalk"
  distancetotarget 15.00
  forceshortmovement
}

Face actor

param <string>
Takes an actor name.
[lockbodyfacing]
Makes the actor's legs not move.

Example :

event moveto "Face player"
{
  time 0.000000 1.0000000
  param "!player"
  lockbodyfacing
}

Fire Trigger

param <string>
Takes a number ranging from 1 to 16. It is meant to be used in conjunction with logic_choreographed_scene's OnTriggerX output.

Example :

event firetrigger "Fire Trigger event"
{
  time 0.000000 -1.000000
  param "5"
}

Generic(AI)

param <string>
Takes an AI action.


The AI actions can be :

Action name Takes a target ?
AI_BLINK No
AI_HOLSTER No
AI_UNHOLSTER No
AI_AIM Yes
AI_RANDOMLOOK No
AI_RANDOMFACEFLEX No
AI_RANDOMHEADFLEX No
AI_IGNORECOLLISION Yes
AI_DISABLEAI No
debugtext No
Note.pngNote:debugtext takes one parameter in an untraditional way, it is taken after its name. param "debugtext Hi !" for instance.


[param2 <string>
Takes an actor name used as a target.


Examples :

Example 1 :

event generic "Holster event"
{
  time 0.000000 1.000000
  param "AI_HOLSTER"
}

Example 2 :

event generic "Aim at Alyx"
{
  time 0.000000 1.000000
  param "AI_AIM"
  param2 "Alyx"
}

Example 3 :

event generic "Show debug text"
{
  time 0.000000 1.000000
  param "debugtext Hi !"
}

Sequence

param <string>
Takes a sequence name.
fixedlength
Is always set by HLFaceposer Faceposer because only gestures can be resized.

Example :

event generic "Play animation"
{
  time 0.000000 1.833334
  param "ThrowItem"
  fixedlength
}

Flex animation

Before starting with the suvtype definition, let's define what curvetypes are.

  • A curve type always starts with curve_.
  • A curvetype takes two curve types separated by _to_
  • They can be :
default
catmullrom_normalize_x
easein
easeout
easeinout
bspline
linear_interp
kochanek
kochanek_early
kochanek_late
simple_cubic
catmullrom
catmullrom_normalize
catmullrom_tangent
exponential_decay
hold

Example : "curve_catmullrom_normalize_x_to_curve_catmullrom_normalize_x"


param <string>
Is unused, it is therefore left as empty quotes.
flexanimations samples_use_time defaultcurvetype=<curvetype>
Note.pngNote:defaultcurvetype will always be set to curve_catmullrom_normalize_x_to_curve_catmullrom_normalize_x by default.
Confirm:Is samples_use_time optional ?
<string> [disabled] [leftedge <curvetype> <float>] [rightedge <curvetype> <float>] [combo]
The first string is a flex controller name.
Note.pngNote:There can only be 128 flex animation keyframes.
<float> <float> [<curvetype>]
[<float> <float> [<curvetype>]]
Note.pngNote:The second block is only created if the flex controller supports combo editing.


flextimingtags
<string> <float> <bool>
The string is the tag name, the float is a duration, and the boolean a lock state.
Note.pngNote:There can only be 128 flex timing tags.


Example :
event flexanimation "Flex event"
{
  time 0.000000 5.000000
  param ""
  flexanimations samples_use_time defaultcurvetype=curve_catmullrom_normalize_x_to_curve_catmullrom_normalize_x
  {
    "lid_tightener" combo 
    {
      0.4000 0.6100 "curve_easein_to_curve_easeout"
      2.4000 0.1200 "curve_linear_interp_to_curve_linear_interp"
      4.4000 0.5900 "curve_easein_to_curve_easeout"
      }
      {
        1.0000 0.7700 "curve_bspline_to_curve_bspline"
        1.8000 0.2700 "curve_bspline_to_curve_bspline"
        3.0000 0.7500 "curve_bspline_to_curve_bspline"
        4.0000 0.2900 "curve_bspline_to_curve_bspline"
      }
      "smile" leftedge curve_default_to_curve_hold 0.500 rightedge curve_kochanek_late_to_curve_default 0.250 
      {
        0.8000 0.7100
        1.6000 0.2700 "curve_easein_to_curve_easeout"
        2.2000 0.6000 "curve_easein_to_curve_easein"
        3.0000 0.2600 "curve_easeout_to_curve_easeout"
        3.6000 0.5900 "curve_linear_interp_to_curve_linear_interp"
      }
    }
  }
}

Sub-scene

param <string>
Takes a path.
fixedlength
Is always set by HLFaceposer Faceposer because the length of the sub-scene is defined by the scene itself.
Confirm:Is the sub-scene path absolute ? I didn't see a single sub-scene in all of the first party games VCDs

Interrupt

param <string>
Takes no parameter, it isn't parsed.
Note.pngNote:Even if param doesn't need to be specified, an empty dropdown exists for it in Faceposer.

Example :

event generic "Interrupt event"
{
  time 0.000000 1.000000
  param ""
}

Permit Responses

param <string>
Takes no parameter, it isn't parsed.

Example :

event permitresponses "Permit responses event"
{
  time 0.000000 1.000000
  param ""
}

Camera

(in all games since Alien Swarm)

param <string>
Is a "shot type", it is meant to be used as a simple string. Called "Camera AI event" by HLFaceposer Faceposer.
param2 <string>
Takes an actor name.
param3 <string>
Takes an actor name.

This event finds the first point_viewcontrol (NOT the closest, the first entity in the entity list) and call the ScriptCameraShot() Vscript function on it. This function has the following syntax : void ScriptCameraShot(string pszShotType, handle pSceneEntity, handle pActor1, handle pActor2, float duration).

Note.pngNote:While it is not used anywhere in Alien Swarm or Portal 2, it is still functional.

Example :

event camera "Camera event"
{
  time 1.000000 5.000000
  param "Hi !"
  param2 "!target1"
  param3 "!target2"
}

Script

(in all games since Alien Swarm)

Warning.pngWarning:This event is not handled by HLFaceposer Faceposer ! It must be added in with a text editor.
param <string>
Takes a targetname.
param2 <string>
Takes a Vscript function name.
param3 <string>
Takes a string meant to be used as a function argument.

This event triggers the function referenced in param2 from the entity scripts of the entity referenced in param with the arguements written in param3 as it follows : void FunctionName(handle pActor, handle pThisSceneEntity, string param3, float duration).

Note.pngNote:While it is not used anywhere in Alien Swarm or Portal 2, it is still functional.

Example :

event script "Script event"
{
  time 1.000000 -1.000000
  param "scriptent"
  param2 "TestFunc"
  param3 "Hi !"
}

Section Pause

param <string>
Takes options, they can diverge in two different branches in function of if Faceposer's "Automatically" flag is checked :
If the flag is not checked :
param "noaction"
If the flag is checked :
param "automate Resume/Cancel <float>"
The float is a duration.


Examples :

Example 1 :

event section "Pause point 1"
{
  time 1.000000 -1.000000
  param "automate Resume 2.000000"
}

Example 2 :

event section "Pause point 2"
{
  time 1.000000 -1.000000
  param "noaction"
}

Loop

param <string>
Takes a timestamp, which is the loop back point.
loopcount <string>
Is infinite if set to -1.

Example :

event loop "Loop"
{
  time 1.000000 -1.000000
  param "2.000000"
  loopcount "5"
}

Fire Completion

param <string>
Doesn't take any parameter, it is only written as noaction.

Example :

event stoppoint "Fire Completion"
{
  time 1.000000 -1.000000
  param "noaction"
}

See also