Cutscenes Part 5: Somewhere Above the City

From The DarkMod Wiki
Revision as of 00:03, 21 September 2010 by Grayman (talk | contribs)
Jump to navigationJump to search

NOTE: This article is under construction until this NOTE goes away.

Somewhere Above the City

I created SATC for the 2010 Summer Vertical Contest. Since it involved traversing a very long vertical distance up, I didn't want to ask the player to climb all the way back down. Instead, once the player has satisfied all objectives, a cutscene wraps up the storyline and ends the mission.

The Scene

The scene takes place in the Builder church, with two actors: a guard and a bishop discussing the outcome of the previous night's events. Without giving too much away, let's just say that a defrocked priest named Penshawk stirred up some trouble, and the mission was to deal with it.

Download [vault.zip] and extract it into your Doom 3 folder. What you're getting is the set for the cutscene, the vocals, and a script to run everything.

Open vault.map in Dark Radiant.

The Opening

Dead or Alive?

Two Choices

There are two possible conversations in this cutscene. One if the player killed Penshawk, and another if the player knocked out Penshawk. SATC started the cutscene once the player had satisfied all objectives, and the decision as to which conversation to play was based on a check of Penshawk's health. Since Penshawk doesn't exist in Vault, the player decides which path to take at the start, by stepping on one of two floorpads. The one on the left plays the scene that goes with Penshawk's death. The one on the right plays the scene that goes with Penshawk's being knocked out.

Since both scenes are the same except for a few lines, we'll discuss the Dead scene. You can review the Alive scene afterward to see the differences.

Opening Shot

When you step on the leftmost floorpad, the script function playCutsceneDead() is called:

void playCutsceneDead()
{
   penshawkHealth = 0;
   playCutscene();
}

This sets a flag that says Penshawk is dead. SATC determined this at runtime using:

   penshawkHealth = $Penshawk2.getHealth(); // is Penshawk dead or unconscious?

This flag is checked later to pick the correct conversation.

playCutsceneDead() calls playCutscene(), so let's look at the latter's first few lines:

void playCutscene()
{
   // Fade to black, then fade back in

   sys.trigger($FadeOut);
   sys.wait(2);
   $VaultTeleport4.activate($player1); // Move the player to the start of the vault cutscene
   sys.trigger($FadeIn);
   ...
FadeOut and FadeIn

FadeOut and FadeIn are trigger_fade entities, and VaultTeleport4 is a func_teleporter.

So the screen fades out, waits 2 seconds, then fades in. When the screen is dark, you're teleported to where you can properly hear the sounds in the upcoming shot.

Let's look at the next set of lines, where we start the bishop--who's been waiting on a path_waitfortrigger, start the camera (VaultCamera3) and mover (anchor3) along their spline (spline3), and begin tracking a target_null sitting on the bishop's shoulders.

   ...
   // Camera3 - priest walking down hall, away from camera

   sys.trigger($VaultBishop); // get the Bishop started
   $VaultCamera3.activate($player1); // The camera takes over the view
   $anchor3.time(7);        // How many seconds it will take to move along the spline
   $anchor3.accelTime(0.1); // How long it takes to get up to speed
   $anchor3.decelTime(0.1); // How long it takes to decelerate
   $anchor3.disableSplineAngles(); // Allow the camera to point in different directions as it follows the spline
   $anchor3.startSpline($spline3); // Start the func_mover $anchor3 moving along the spline
   thread update_camera4();  // Call the function update_camera4() as a thread so it can run in parallel
                             // to update the camera's focal point each frame. We need to start this thread
                             // here, even before camera4 is active, because the target_null it's focused on
                             // will be moving when the priest starts walking. If we don't, then there's a
                             // hitch at the start of camera4's frames when it changes focus from where
                             // the target_null spawned, and where the priest has taken it.
   sys.waitFor($anchor3);    // Wait for $anchor3 to finish its movement
   ...
VaultCamera3

This presents an opening dolly shot rising from the floor as the bishop walks by, bound ... where? The picture shows VaultCamera3, with anchor3 and spline3 below it. Right behind it is VaultTeleport4, where we place the player.

The script line thread update_camera4() starts a separate thread (discussed in Roll Camera 6 in Part 2) to track the target_null attached to the bishop. We don't need that for VaultCamera3's shot, but we'll need it in the next shot. We have to kick it off early, otherwise the camera that points at it will have an abrupt hitch at the start of its view because the bishop has traversed almost all of the hall by then.

So the bishop walks by. Light streams from the windows, indicating it's daytime, and the city has survived to see another day. Barking dogs give a hint of life beyond the windows.

Turning Into the Archway

VaultCamera4

It's time to switch to the next camera, for a better view of the bishop turning into the archway. The picture shows, from top to bottom, target_setkeyval_4, VaultCamera4, anchor4, and spline4. VaultCamera4 is bound to anchor4, and we've already seen that target_setkeyval_4 was told to track the movement of target_null_4, attached to the bishop.

Here's the script that switches control to VaultCamera4:

   ...
   // Camera4 - priest turning into small doorway

   $VaultTeleport2.activate($player1); // Move the player so he can hear the priest's footsteps
   $VaultCamera4.activate($player1);   // Switch views
   $anchor4.time(2.5);                 // How many seconds it will take to move along the spline
   $anchor4.accelTime(0.1);            // How long it takes to get up to speed
   $anchor4.decelTime(0.1);            // How long it takes to decelerate
   $anchor4.disableSplineAngles();     // Allow the camera to point in different directions as it follows the spline
   $anchor4.startSpline($spline4);     // Start the func_mover $anchor4 moving along the spline
   sys.waitFor($anchor4);              // Wait for $anchor4 to finish its movement
   sys.killthread("aim_loop4");        // Kill the thread "aim_loop4"
   sys.wait(2.5);		       // No camera movement
   ...

The first thing that happens is we move the player to VaultTeleport2, which is closer to the action. This lets the player hear the bishop's footsteps as he passes from left to right.

Then VaultCamera4 takes over, and anchor4 is sent on its way along spline4's path. VaultCamera4 dollies from left to right, following the bishop into the archway, tracking his head as he walks.

Dolly for 2.5 seconds, then stop. Kill the "aim_loop4" thread (responsible for updating VaultCamera4 with target_null_4's position). Allow the camera to film for 2.5 more seconds w/o dollying.

The bishop walks off to the right.

The Staircase

VaultCamera5

Since the bishop left the previous shot to the right, we want to see him coming into the next shot from the left. He'll descend a staircase, left to right, filmed by a stationary camera above him, looking down.

The picture shows, from top to bottom, VaultCamera5, VaultTeleport3, and target_null_5.

Here's the small bit of script that controls this camera:

   ...
   // Camera5 - The priest on the stairs

   $VaultTeleport3.activate( $player1 ); // Move the player so he can hear the priest's footsteps
   $VaultCamera5.activate( $player1 );   // Switch views
   sys.wait(8);
   ...

The player moves to VaultTeleport3, where he'll hear the bishop moving left to right.

VaultCamera5 takes over and shoots for 8 seconds.

The Vault

This is the most complicated set of shots, involving the guard setting up the vault room by lighting candles, awaiting the bishop's arrival, and then talking with the bishop.

Lighting the Candles

A dollying camera shows the guard lighting two candles in anticipation of the bishop's arrival. There are two main actions occurring in this shot: the moving camera, and the guard following a path.

VaultCamera6

The picture shows, from left to right, target_setkeyval_6, VaultCamera6, anchor6, and spline6 (coincident with anchor6).

VaultCamera6

Here's the script that controls this camera:

   ...
   // Camera6 - the Guard

   sys.trigger($VaultGuard);           // get the guard moving
   sys.wait(1);
   $VaultTeleport1.activate($player1); // Move the player to the vault so he can hear the conversation
   $VaultCamera6.activate( $player1 ); // Switch views
   $anchor6.time(13);                  // How many seconds it will take to move along the spline
   $anchor6.accelTime(0.1);            // How long it takes to get up to speed
   $anchor6.decelTime(0.1);            // How long it takes to decelerate
   $anchor6.disableSplineAngles();     // Allow the camera to point in different directions as it follows the spline
   $anchor6.startSpline($spline6);     // Start the func_mover $anchor6 moving along the spline
   thread update_camera6();            // Call the function update_camera6() as a thread so it can run in parallel
   sys.wait(9.5);                      // guard lights candles
   ...

The first thing that happens is we trigger the guard to start him on his way. We want him moving when VaultCamera6 starts to film, so give him a second to get started.

Move the player to VaultTeleport1, directly over the lightning artifact in the alcove. This lets the player hear the conversation with the correct sound orientation.

Then VaultCamera6 takes over, and anchor6 is sent on its way along spline6's path. VaultCamera6 dollies from right to left, targetting the stationary target_null_6. Even though target_null_6 is not moving, we have to use a separate thread (update_camera6()) to reorient the camera each frame.

Though we've told anchor6 to travel for 13 seconds, we only show 9.5 seconds of VaultCamera6's view. This was determined through trial-and-error, stopping the shot at the moment the guard turns away from the rightmost candle.

The Guard

Lighting the Middle Candle

There are three candles at the front of the vault room, one on each wall to the left and right, and one in the middle. As this shot begins, the left candle is lit and the guard is walking to the middle candle.

The highlighted entities in the picture control the first half of the guard's actions. They are, from left to right:

  • path_corner_2 (where the guard waits to start the scene)
Lighting the Right Candle

The Conversation

Anteroom

Several entities important to the conversation are in a small room off the back of the vault room.

The picture shows, from left to right (ignoring the light and the chest):

  • atdm_conversation_info_3 (holds the "KO" conversation)
  • atdm_conversation_info_2, (holds the "Dead" conversation)
  • atdm_target_startconversation_2, (starts the "KO" conversation)
  • atdm_target_startconversation_1, (starts the "Dead" conversation)
  • EndMission (a target_setobjective_state that sets the final objective to end the mission)
  • BishopLeaves (path_corner the bishop walks to after the conversation)
  • path_corner_1 (the final stop on the bishop's opening walk)


Ending the Mission

Text.

Wrapup

In Part 5, we broke down the cutscene from the ending of Somewhere Above the City. Hopefully it provided a look at how to build a complex cutscene involving several cameras and a detailed conversation.

As was mentioned in the title page of this tutorial, you can leave comments and questions here.

Enjoy!