locke.bruce@yahoo.com



Introduction : Heavy Metal FAKK2 utilizes a text based scripting system. Generally all threads that control level action are stored in a single script file. Triggers are used to activate these threads. The script file for a level has the same name as the level bsp file and ends with a .scr extension. These are stored in the maps folder with the bsp files, and can be opened with a text editor.

The advantage of this system is that with a well organized script file it can be easy to find and make changes to events. Rather then trying to find triggers and entities throughout the level that have commands, everything is in one place. However, for larger levels the scipt file can become extensive, making it hard to wade through.


Dance Scripting : A major effort put into the dance cinematic was scripting the characters' dance routines. Time was spent viewing animations and choosing ones that would work for dancing. Each dancer had a few different routines which consisted of 2 or 3 animations. When it was time to dance a sequence was randomly chosen and the character would play through the animations. When this was finished another was chosen, and the cycle was repeated. Once the dancing started the characters would continue until the player quit the level. The goal was to give players time to wander around and watch the animations once the cinematic was done.

Here is the script code that has the Julie model ($j1) perform her dance routines. A random number is generated which determines which of three dance sequences she will perform. Each sequence uses two different animations. Comments on the code are given after the // symbol.

julie_dance: //Start of Julie dancing thread.

// ju_dance_st is a location that the thread returns to after a dance sequence is done.
ju_dance_st:

local.rndnum randomint 3 //generates integers 0, 1, or 2

local.rndnum ifequal 0 goto j_anim1

local.rndnum ifequal 1 goto j_anim2

local.rndnum ifequal 2 goto j_anim3


//Here is the first dance sequence.
j_anim1:

//The rotateY command spins Julie around. Here she spins 40 degrees per second.

//To stop rotation use rotateY 0.

$j1 rotateY 40

//The anim command has the script model perform the specified animation.

$j1 anim attack_5

//The attack_5 animation will be played for 1 second before

//the next line of code is read.

wait 1

$j1 anim combat_walk_strafe_right

wait 3

//This sequence is done, so return to ju_dance_st and choose another.

goto ju_dance_st


//Here is the second dance routine.
j_anim2:

$j1 rotateY 10

$j1 anim combat_turn_right

wait 4

$j1 anim hug_step_right

wait 1

goto ju_dance_st


//The third dance sequence.
j_anim3:

$j1 rotateY 60

$j1 anim combat_turn_left

wait 3

$j1 rotateY 0

$j1 anim alternate_fire_chaingun

wait 1

goto ju_dance_st


end //End of julie_dance thread.



For all dancing characters entities called script models were used instead of standard characters. There were two reasons for this.
- First, when characters perform an animation their origin moves. Using dancing characters sent them ambling about the room bumping into each other. Script models use character models, but when they perform animations they stay in place.
- Second, many of the characters will stop their actions and start to talk to Julie if she moves near them. I did not want the dancing characters to talk to the player, and using script models prevented this.


Figure 2 shows a picture of the dance club in the editor. Some items of interest are labeled A through F.

Figure 2 : An editor view of the dance club.

The green box near the entrance (labeled A) is the trigger that begins the sequence. When this is activated a thread in the script is called that removes control from the player and begins the cinematic. The green cubes are way points that define paths characters can be scripted to follow. The way points labeled B indicate the start and finish locations of the path Julie takes when walking to her final position under the light. Here is a Julie script model (C) that was used for the dancing sequences. As explained above, all of the dancing characters used script models. However, it is easier to have characters walk to locations, so when Julie reaches her final location she is hidden and the Julie script model (C) is shown. A similar scheme was used to get the Grawlix (D) to move to its location. The character Grawlix (D) is scripted to walk along its way points (E) to its final destination, where it is replaced by the dancing Grawlix script model (F). In the video you will notice that the Grawlix appears darker when it starts dancing. This happens when the character is replaced by the script model.

Here is the code that moves the Grawlix into place and starts him dancing. $dancegrawlix is the character you see when the cinematic starts, while $dancegrawlix2 is the script model that starts hidden and non solid, but is shown once the dancing begins. Similar (but much longer) code was used to get Julie into place.


//Move the Grawlix to the first way point ($grawlix_wp).
$dancegrawlix walkto $grawlix_wp
//Make sure the Next code line does not start until $dancegrawlix reaches $grawlix_wp.
waitFor $dancegrawlix

$dancegrawlix walkto $grawlix_dance_point
waitFor $dancegrawlix
wait 1

$dancegrawlix remove
$dancegrawlix2 show
$dancegrawlix2 solid



Calzador created a number of moving lights (I) that added greatly to the atmosphere. These are script objects that have their movement controlled by commands. The red bars through the lights mark axes the lights rotate about. Some of the lights have light cones (J). These are non solid script objects that are attached to the light and move with it. These cones can alternate between hidden and shown to simulate flashing lights.


Here is a code sample that moves one of the rotating lights. First the base, the light, and it's beam are connected to each other. In this engine script objects can be influenced by more than one movement command, so the order of attachment is important. As seen below, the light is bound to the base. This means that any movement specified for the base will also effect the light, but the light can be given additional movement that will not effect the base. The base is rotated at a steady rate which also rotates the light, while the light swings up and down around its axis - but this does not swing the base.


//Bind the light beam to the light, and the light to it's base.
//The light beam "binds to" the light, etc.
$dhlight_beam1 bind $dhlight1
$dhlight1 bind $dhlight_base1

// Code that loops the light movement.
dhlight_loop:

//Rotate "_base1" 90 degrees in 1 second then wait for next command.

$dhlight_base1 rotateYup 90

$dhlight1 rotateXup 100

waitFor $dhlight_base1


$dhlight_base1 rotateYup 90

$dhlight1 rotateXdown 90

waitFor $dhlight_base1


$dhlight_base1 rotateYup 90

$dhlight1 rotateXup 80

waitFor $dhlight_base1


$dhlight_base1 rotateYup 90

$dhlight1 rotateXdown 90

waitFor $dhlight_base1


goto dhlight_loop



Summary : I have explained some of the aspects that went into scripting this dance sequence. Script models were used for the dancing characters, since these stay in place when they perform animations and don't talk to Julie when she gets near them. A code example was also shown that explains how the moving lights were done.