$proceduralbones tells the engine to animate certain bones itself. See this thread for details.
$proceduralbones <configuration file>
Configuration files are special VRD (Valve rig data (?)) files. They are described below.
VRD files are essentialy keyframe animations for the helper bone with 'triggers' as keyframes. When Source sees that your control bone (e. g. the wrist) is closing towards a specified rotation, it will start rotating and translating (lerp) the helper bone (e. g. the forearm) towards the 'keyframed' position and rotation. E. g. forearm twist has three keyframes, one for the base position and two extremes. IF the hand is twisted right, the forearm twist right too and vice versa.
VRD files support C++-style comments, tabs, spaces, etc.
Declaring a procedural bone
<helper> hlp_forearm_L bip_lowerArm_L bip_lowerArm_L bip_hand_L
This tells the engine that we want a procedural bone
hlp_forearm_L, its root bone is
bip_lowerArm_L, its parent is
bip_lowerArm_L, too, and its movements will be driven by
Declaring a base position
<basepos> X Y Z
Basepos specifies the base translation of the helper bone. It should normally correspond to the helper's default position in your model's default state. Use a 3D editor to read the values or write a script/plugin.
The numbers can also be found as the first three numbers in the $definebone line of that bone.
NB: All translation values and rotation angles are in parent bone's space. All angles are Euler rotations, and are in degrees.
Declaring a keyframe (trigger)
<trigger> AngleOfInfluence Vec3D_WatchedControlBoneRotation Vec3D_DesiredHelperRot Vec3D_DesiredHelperPos
For every keyframe Source checks if the difference between the control bone's current rotation and
WatchedControlBoneRotation is smaller than the
AngleOfInfluence (think of this angle as a cone). If it is smaller, then Source 'lerps' the helper's rotation and position towards
DesiredHelperPos is given as an offset from basepos. The closer is the control bone's rotation to the
WatchedControlBoneRotation, the closer will the helper's rotation and position be to
// AoI Watched control rotation Desired helper rotation Desired helper translation <trigger> 90 -179.149 -81.8242 -179.905 81.3212 -37.0352 -157.273 0 0 0
Example: Hand-made VRD file for HWM Femscout model
Source Filmmaker was used to setup keyframes for that model, but you can use any 3D app that supports Source models in some flavor.
<helper> hlp_forearm_R bip_lowerArm_R bip_lowerArm_R bip_hand_R <basepos> -0.0502548 4.76207 -0.0109539 <trigger> 90 -0.116485 -7.07782 0.923253 -26.1455 -71.739 -60.6497 0 0 0 <trigger> 90 -0.288436 72.9621 0.610626 -72.1773 -44.2586 -20.2743 0 0 0 <trigger> 90 -179.149 -81.8242 -179.905 81.3212 -37.0352 -157.273 0 0 0 <helper> hlp_forearm_L bip_lowerArm_L bip_lowerArm_L bip_hand_L <basepos> -0.0003 -4.7578 -0.000685692 <trigger> 90 -0.140879 -7.0729 0.923253 2.05439e-06 -0.00011566 -0.0109454 0 0 0 <trigger> 90 -157.919 -89.6281 158.827 0.101044 -61.3622 -0.505184 0 0 0 <trigger> 90 -0.905463 81.1157 0.0128013 -1.79037e-05 49.6029 -0.0109647 0 0 0
This model with source files is available here on MaxOfS2D's website.
This Facepunch guide (backed up on steam) describes the process of crafting such a file, using Source Filmmaker in detail. However, it is easier to do it entirely in Blender as this Steam Guide shows.
You can specify a useless name for a trigger:
<trigger> 90 -6.75868e-015 1.59028e-015 3.18055e-015 0 0 0 0 0 0 UselessTriggerName
As this example highlights, that is completely useless in-engine and does nothing.
There is a <display> keyword. This is used by Softimage Mod Tool to store the attributes for helper's appearance in Mod Tool's viewport. Useless to anyone who doesn't use Softimage.
Certain characters in any of the bone names used will cause the compiler to abort. Note that this includes the "." character (a "period") that is commonly used in the naming of certain Valve bone sets.