VCD

From Valve Developer Community
Revision as of 13:41, 11 May 2025 by Le Glaconus (talk | contribs) (added every category that should be added, but it is still wip, examples are here for the time being)
Jump to navigation Jump to search
English (en)中文 (zh)Translate (Translate)

Stub

This article or section is a stub. You can help by expanding it.

Under construction.png
This page is actively undergoing a major edit.
As a courtesy, please do not edit this while this message is displayed.
If this page has not been edited for at least several hours to a few days, please remove this template. This message is intended to help reduce edit conflicts; please remove it between editing sessions to allow others to edit the page.

The user who added this notice, should you wish to contact them, is: Le Glaconus tr = idir.
Additional Notes: 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 data.

VCDs are authored in 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).

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 text, numbers, or other objects and are denoted using a simple system of key-value pairs without separators.

The basic notation is as follows:

// 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_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 defaultcurvetype=curve_catmullrom_normalize_x_to_curve_catmullrom_normalize_x { ... }
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"
 } 
Note.pngNote: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.

Object hierarchy/order

  • 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. 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.

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 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 a comment
channel "look_at"
{
   ...
}

Scene properties

Map name

mapname 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.

Format : mapname (string)

Window settings

Todo: move scalesettings info here, along with additional info

Fps

fps 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.

Format : fps (integer)

Snap

snap is used by Faceposer to save if the user wants snapping enabled, it is disabled by default.

Format : snap on/off

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

Format : ignorePhonemes on/off

Actor properties

Model

faceposermodel is the tied model name.

Note.pngNote:It is stored as an absolute path, unlike mapname

Format : faceposermodel (string)

Activity

active is used for the actor disabling feature.

Note.pngNote:If it is 1, it will simply not be written

Format : active (boolean)

Channel properties

Activity

active is used for the channel disabling feature.

Note.pngNote:If it is 1, it will simply not be written

Format : active (boolean)

Event subtypes

Subtype table

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

Common properties

Every event share these properties :

  • time (float) (float)
Note.pngNote: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.
  • param (string)
  • [param2 (string)]
  • [param3 (string)]
  • fixedlength
Note.pngNote:Makes resizing the event in Faceposer impossible.
  • resumecondition
  • [active (bool)]
Note.pngNote:active is simply non-existant if set to 1.
  • [tags { ... }]
  • (string) (float)
  • ...
Note.pngNote: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)
  • ...
Note.pngNote: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 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

This event takes a phoneme class as its first parameter and a phoneme as its second. The most common phoneme classes to exist are phonemes, phoneme_weak, phoneme_strong because they are always precached. The Half-Life 2 series Half-Life 2 series additionaly precaches random and randomAlert.

Example :

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

WAV File

Example :

speak "Sound event 1"
{
  time 0.000000 1.000000
  param "npc_citizen.question06"
  param2 "VOL_NORM"
  fixedlength
  cc_type "cc_master"
  cctoken ""
}

Gesture

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
  }
  absolutetags shifted_time
  {
    "apex" 0.160000
    "accent" 0.240000
    "loop" 0.320000
    "end" 0.440000
  }
}

Look at actor

This event takes an actor name as its first parameter and an optional pitch and yaw.

Todo: What is the lowest and highest accepted value for both ?

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

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. param2 can take Walk, Run or CrouchWalk. If a sequence name is specified, it will be used instead.

Todo: Find what param3 really does

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

This event takes an actor name as its first parameter and optionally a flag for not moving the legs.

Example :

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

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.

Example :

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

Generic(AI)

This event takes an AI action as its first parameter and optionally an actor name as its second. 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.

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

Example :

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

Flex animation

[Todo]

Sub-scene

[Todo]

Confirm:Is the sub-scene path absolute ? I didn't see a single sub-scene in all of the first party games VCDs

Interrupt

Example :

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

Permit Responses

Example :

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

Camera

(in all games since Alien Swarm)

Example :

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

Script

(in all games since Alien Swarm)

Example :

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

Section Pause

Example 1 :

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

Example 2 :

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

Loop

Example :

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

Fire Completion

Example :

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