Cutscenes Part 3: Lighting, Placing the Player, and Conversations

From The DarkMod Wiki
Revision as of 01:22, 2 May 2021 by Geep (talk | contribs) (→‎Mute the Actors: To avoid console warning, use "atdm:ai_vocal_set_mute", not "mute")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search


Open in Dark Radiant.

Remember how the guard's medium shot in Part 1 was dark? snitch3 includes a few lighting changes. A down light now sits above the bulletin board, with an ambient light at face-level to soften the shadows from the down light. Both actors should be properly lit now.

Placing the Player

When a cutscene plays, the player is frozen, unable to do anything. If they're too far away from the actors, they won't be able to hear what's being said. So it's important to place the player in a spot where they can hear a conversation without being in the way. Even though the player is invisible in the camera's view, the player is still there, and can obstruct actor movement.

For Snitch, the best place to hear the actors' lines is to stand just behind them. Since the player can't walk to this spot on their own, we have to move the player in the script code, with help from a func_teleporter.

  • Just behind the path_corners in front of the bulletin board, create a func_teleporter entity (darkmod/func/func_teleporter). Give it these Property/Value pairs:
  • "name" "Tport1"
  • "angle" "90"

angle sets the player's orientation when the actors arrive, and is important so their voices come from the correct directions. When Tport1 is triggered, the player will be brought to it from wherever they are in the map.

  • For the player to leave after the scene, place another func_teleporter back on the porch with the player start. Give it these Property/Value pairs:
  • "name" "Tport2"
  • "angle" "90"

If you have multiple shots strung together that require the player to move from one to the next for sound reasons, simply move the player along via func_teleporters.

Camera 7

Camera7 and target_null_7

Place a new func_cameraview just above and behind Tport1. Give it the following Property/Value pairs:

  • "name" "Camera7"
  • "trigger" "1"

Create another target_null and place it in front of target_null_1 by the bulletin board. Give it the following Property/Value pair:

  • "name" "target_null_7"

Now point Camera7 at its target by giving it the following Property/Value pair:

  • "target" "target_null_7"

Camera7 will give us a shot of both actors. This will be our primary conversation camera.

That's it for the scene setup. Let's move on to what the actors will say.


The key element in conversations is what the actors have to say. The dialogue files for Snitch are in the snitch/sound folder. We'll talk about how to create your own dialogue files and the associated definition files that TDM needs to play them.

For background information on adding sounds to your mission, please read Sound.

Creating the Dialogue

The ideal way to record sound for games is to use a digital recorder that can feed the results into your computer for editing. However, not many of us own one, so we have to fall back on the lower quality "mic plugged into the sound card" method. For sounds that are heard one or two times during a mission, this is an acceptable solution. Anything that's going to be heard multiple times (like TDM's AI voices) should be done in a professional manner with high-quality equipment.

Steps to create a sound:

  • Use your favorite recording method to get the sound into the computer
  • Edit with sound-editing software:
  • remove background noise (essential)
  • remove low bass if needed
  • de-ess if needed to remove unwanted hissing
  • normalize to around 50%

OGG Format

The sound format TDM uses is OGG, so if you can't record directly in this format, you'll need a way to convert your recording format to OGG. FlicFlac is a free program that can do this for you.

Sound Shaders and Folders

In snitch/sound, you'll find tdm_maps_snitch.sndshd, the sound shader (definition) file, and the folder voices/snitch/conversations, where the sound files live.

  • Place your OGG sound files into voices/snitch/conversations
  • Add a definition to tdm_maps_snitch.sndshd for each new sound

For example, let's say you add the sound file snitch_Informant_1.ogg (the informant's first line) to the conversations folder. To use it in the mission, add the following to the tdm_maps_snitch.sndshd file:

   minDistance 8
   maxDistance 25
   volume 12


For snitch3, all the vocals for our conversation are already included, and tdm_maps_snitch.sndshd is set up to use them.

We'll see below, when we construct the conversation, how to play dialogue sounds.

When you begin testing, you can adjust the volume of each sound in the shader file to an appropriate level. Make sure it can be heard over any ambient music that's playing.

Mute the Actors

TDM AI are given a vocal set by default, so they say random things as they stand idle or walk around, or chase the player, etc. For each actor in your scene, you should turn off this vocal set, since it wouldn't be consistent to have two actors walk up to each other and say something like "Greetings!" when you're about to get them into an argument. To retain control over what your actors say, be sure to set this Property/Value pair on each of them:

  • "def_vocal_set" "atdm:ai_vocal_set_mute"

Another good reason to do this is so you don't have to try to mimic the default voice of the AI when you record its dialogue. A British-sounding AI that suddenly starts talking American (or vice versa) in a conversation will definitely take the player out of the game.


For a discussion of the elements of a conversation, please read Conversations.

Dark Radiant provides an easy-to-use editor to create conversations.

  • Create the conversation_info entity that will hold the conversation (darkmod/Conversations/atdm:conversation_info). Place it near the bulletin board.
  • On the main menu, select Map/Conversation. A Conversation Editor window will appear. Note that atdm_conversation_info_1 is shown in the Conversation entities field. This entity can hold a number of conversations. If you have multiple conversation_info entities, they'll all be shown in that field.
Conversation Editor
  • Click in the Conversations field and hit the Add button. A new conversation named "New Conversation" will appear.
  • Select this and hit the "Edit" button. An Edit Conversation window appears. This is where we'll do the bulk of the work to create our conversation.
Edit Conversation
  • The first thing to do is to name this conversation. Let's call it "Snitch".
  • Because of the nature of our conversation (the actors might not want observers to know they're talking about anything other than the weather), we won't force them to face each other. So uncheck the "Actors always face each other while talking" box. If we want one actor to face the other at some point in the conversation, we'll handle that in the Commands field.
  • Also uncheck the "Actors must be within talk distance" box. Leaving that checked forces the actors to walk toward each other and face each other if they're not within talking distance. We want to control their positions and orientation, so we leave the box unchecked.
  • Now we add our actors. Click the Add button next to the Actors field and an entry "1 New Actor" appears. Single-click that twice and it will highlight for editing. Change it to "SnitchInformant", the name of our informant AI. Hit ENTER to complete the edit.
  • Click the Add button again and change "2 New Actor" to "SnitchGuard", the name of our guard AI.

At this point, the Edit Conversation window should look like this:

Edit Conversation

Let's add a few of our vocals to get started.

  • Click the Add button for the Commands section and the Edit Command window appears.
Edit Command
  • Click the button below Actor and select SnitchInformant.
  • Click the button below Command and select Talk.
  • In the Soundshader field, enter "snitch_informant_1".
Edit Command
  • Leave the Wait until finished box checked.
  • Click OK.

Now you can see the talk command entered on the Edit Command window.

First Command

Add the remainder of the talk commands. Here's the order of the commands. You can tell which actor to assign them to based on the sound shader names:

  1. snitch_informant_1
  2. snitch_guard_1
  3. snitch_informant_2
  4. snitch_informant_3
  5. snitch_guard_2
  6. snitch_informant_4
  7. snitch_guard_3
  8. snitch_informant_5
  9. snitch_guard_4
  10. snitch_informant_6
  11. snitch_informant_7
  12. snitch_guard_5
  13. snitch_guard_6
  14. snitch_informant_8

When all are added, the Commands section should look like this:

Dialogue in place

At this point, we have enough for the basic conversation. We'll add a few extra touches later. For now, let's activate this conversation and see what it looks like.

The following remain to be done:

  • Create a way to start the conversation.
  • Move the player to the spot behind the players (Tport1).
  • Move the player back to the porch (Tport2) when the conversation is finished.
  • To start the conversation, create the entity target_startconversation (darkmod/Targets/atdm:target_startconversation). Move it near the bulletin board and give it these Property/Value pairs:
  • "name" "StartSnitchConversation"
  • "conversation" "Snitch"

The conversation property points to the name of the conversation we just created in the conversation_info entity using the Conversation Editor.

  • Create the entity target_callscriptfunction (darkmod/Targets/atdm:target_callscriptfunction) and put it near the bulletin board. Give it these Property/Value pairs:
  • "name" "Return2Player"
  • "call" "Return2Player"
StartSnitchConversation and Return2Player

Let's return to our conversation and add one more command to return control to the player.

  • Map/Conversation brings up the Conversation Editor.
  • Select Snitch and click on the Edit button.
  • Click the Commands Add button.
  • Fill in the following:
  • Actor: Actor1 (SnitchInformant)
  • Command: ActivateTarget
  • Target: Return2Player
  • Click OK on each of the editing windows until the Editor closes.

A new command is automatically added at the end of the existing command list. In this case, this is where we want it, because it's the last thing we want our conversation to do before it ends.

Now let's look at the Roll6() and Return2Player() functions in snitch3.script.

void Roll6()
   $Tport1.activate($player1);      // put the player behind the actors

   // Camera6 - focus on the Guard's entrance

   $SnitchGuard.activate($player1); // SnitchGuard starts walking
   $Camera6.activate($player1);     // Switch view
   thread update_camera6();         // Call the function update_camera6() as a thread so it can run in parallel
   sys.wait(15);                    // Wait time in seconds
   sys.killthread("aim_loop6");     // Kill the thread "aim_loop6"
   $Camera7.activate($player1);     // Switch view
   sys.trigger($StartSnitchConversation); // pass control to the conversation

void Return2Player()
   $Tport2.activate($player1);  // put the player back on the porch
   $Camera5.activate($player1); // Return control to the player

Roll6() is what we used in Part 2 to control Camera6, to watch the guard arrive. We'll continue to use that, but add the following lines:

  • $Tport1.activate($player1); // put the player behind the actors
  • $Camera7.activate($player1); // Switch view
  • sys.trigger($StartSnitchConversation); // pass control to the conversation

And when the conversation ends, the last thing it will do is activate the entity Return2Player, which in turn will call Return2Player(), which we see puts the player back on the porch and returns control to them.

And that's it.

Save, build, run, and press button 2 on the porch.

We should see a shot from Camera6 as the guard arrives, then switch to Camera7 for the conversation.

The bulk of the conversation is now in place. It's a bit strange that the actors stay by the bulletin board after they're done talking, so we need to embellish the ending. We'll do that in Part 4.

Don't Cross the Line

In film, there's a rule that you shouldn't "cross the line". Imagine a line drawn between two actors. If you start filming them from one side of that line, you should never cross over the line to film from the other side in the same scene. The actor who starts out on the left of the screen should always be shot so he's on the left. The actor on the right stays on the right. Crossing the line disorients viewers. For more on this, see 180 Degree Rule.

How to Handle the Same Actor in Sequential Scenes

If your cutscene is actually several scenes strung together, and one of your actors moves from one scene to the next, follow these rules:

  • If the actor exits on the right side of the screen in the first scene, he should enter from the left side of the screen in the next scene.
  • If the actor exits on the left side of the screen in the first scene, he should enter from the right side of the screen in the next scene.

These rules only apply for scenes that immediately follow each other. If you have other scenes in between (establishing shots, etc.), then these rules don't need to be followed. Ignoring these rules can cause viewer disorientation.


In Part 3, we built the conversation for our scene, learning how to add dialogue and animations.

Alongside and snitch3.script, which we've been using above, you'll find and snitch3a.script, which include the conversation from this lesson. You can build and run and compare it to your own work.

In Part 4, we'll make the ending more interesting and look at extras you can add to your scene.

See also