Jump to content

Home

Dialogue Tutorial


MacTavish

Recommended Posts

Hello, I was wondering if anyone knew of a tutorial for advanced dialogue making. I have read the one by Doom Dealer and the dialogue is small. But is there a tutorial that teaches you to make something long and complex like when talking to Malak at the end of K1?

 

Thanks :)

Link to comment
Share on other sites

Mod note: Added a copy of this post to the tutorial forum to make it easier for others to find. :) ~M

 

 

I’m going to use my own, terribly written, dialogues as examples to introduce you to the wonderful world of dialogue editing and creation. Below is an overview of what you might see if you opened up a conversation in tk102’s dialogue editor. The way things look is entirely due to whether you have the mode set to KotOR or KotOR II. You can change the mode by clicking on “Mode” then selecting “Toggle Mode: KotOR” or “Toggle Mode: TSL.”

 

overviewk1iv9.th.jpg

An overview of what you might see in K1 mode.

 

overviewk2pg2.th.jpg

An overview of what you might see in K2 mode.

 

The system is simple. Each line you see is called a node. Red coloured nodes are nodes that the NPC will speak and blue ones are the player’s options. If the NPC speaks over multiple nodes a blue (continue) will be in between the nodes, this will be skipped over in the game, allowing the NPC to talk over many nodes before the player can next choose something to say. If (already listed) appears beside a node then it is a link to another node, a copy of it, essentially – these prevent you from having to type out multiple copies of the same line (much handier than you can possibly realise now). You can find the original by right clicking on it and selecting “Jump to original.”

 

To add an NPC node simply press Ctrl+E or go to “Edit” and click “Add new entry.” To add a player reply node press Ctrl+R or go to “Edit” and click “Add new reply.” You should be able to type what you want the player to see in the large, white text box over to the right hand side of the screen.

 

Scripting and dialogues

 

Scripting can be confusing, especially to newcomers with no background in programming (heck, it still confuses me and I’ve been doing it for two years now). Unfortunately, it’s something you have to learn if you want to create more sophisticated mods for KotOR.

 

There are two types of scripts that can be attached to a KotOR dialogue conditional and action. A conditional script will return TRUE or FALSE. If the conditions are met then the node will be shown to the player (hurrah!) if they are not (boohoo) then the dialogue will drop down to the node beneath it. If there is no node beneath it then the game will exit the dialogue. In this way we can create dialogues with multiple openings, or even change the way an NPC talks to the player depending on the player’s actions.

 

multiplenodesex0.th.jpg

 

If the condition for 1 is not met then the game will try 2. If that doesn’t work then it will go to 3 and so on. It is sometimes useful (for debugging purposes) to create a node right at the bottom with no conditions attached to it saying something like “I SHOULD NOT BE HERE.” This tells you that there is a fault in the checking of or setting of conditions and that nothing else is going wrong. In KotOR dialogue files there is space for just one conditional script; in TSL we have the added luxury of being able to use two. Also, in TSL, we have the “Not” tick-box. This means that if a script returns FALSE then the dialogue will read it as TRUE. For example, if you had a script that checked if the global number “000_FooBar_Talked” was set to 1 and you wanted to check if it was not 1 without creating another script you could just check this box!

 

Action scripts are a little more exciting but not a lot; not when compared to the prospect of finding a real, living gizka in your bathroom – though, admittedly, that may be a little freaky. These are used throughout the game to accomplish a wide variety of tasks ranging from turning the NPC hostile to giving the player the Awesome Lightsaber of +5 Wisdom. Suffice it to say: they’re useful. Again, with KotOR there is space for just one script but there are two fields in TSL.

 

I’m not going to go over the basics of scripting conditionals and actions in this post as it is already on the verge of becoming long enough to make people want to hang themselves after reading it – or during, of course.

 

Writing conversations

 

Well… we’re finally here… writing the conversation. The first stage, and this may seem a little obvious but it’s where I went wrong when attempting to write my first conversation, is to open tk102’s editor and. Go to File --> New to open up a new dialogue. It should be devoid of anything save the root node which in tk’s editor appears as the file pathway or (until the dialogue is saved) “New Dialog.” Click on this wonderful root and add a new node (as we discussed above). Type what you will in there. The first line after the root is always an NPC line.

 

Now click on that entry and add in three responses using Ctrl+R as we discussed above. Every time you add an empty response you’ll have to click on the NPC line again because the editor will switch focus to the new line. Type whatever you wish to fill these lines.

 

We just spoke about the dialogue dropping down to the node below and we’re about to use it. Imagine the power at your fingertips! You may cackle evilly if you wish… just no wearing spandex and dressing up like Darth Malak, please. Click on our stylish root node and add a new entry as we discussed above and type something for the NPC to say the second time the player comes to speak to them and add in your beautifully crafted player responses.

 

Now… we’re going to attach some global scripts. These are standard game resources. We’re using them to check if the player has spoken to the NPC beforehand. If your dialogue if for KotOR then type “k_act_talktrue” in the “Script that fires when spoken” field on your first speaker node and then type “k_con_talkedto” in the “Script that determines availability” field. In TSL the principle is the same. Set conditional #1 to “c_talkedto” and set the script #1 field to “a_talktrue.” Any scripts that you ever place in these fields should not have the extension attached.

 

Creating links is another thing we touched on above. These are very useful… so much so that I could marry them if the state would allow it but alas… we’re a bit behind the times in these parts. To create a link simply copy a node and paste it elsewhere in the dialogue – simple as that!

 

Shockingly… that’s it for basic conversations – hope that wasn’t too soul destroying to read through.

 

Other interesting thingmobobs

 

Click on your root node and revealed to you will be an entirely new set of options – the fun just doesn’t stop, does it? The fields of interest here are mainly grouped in the area shown below:

 

propertiesbo6.th.jpg

 

Script that fires when conversation ends – As it says… this is the script to have the game execute when the dialogue ends

Ambient track – the name of a music file in the streammusic folder that you want to play over the dialogue (without the extension, as ever). It is, however, advisable to stop the area music via a script when using this feature.

Camera model – the name of the animated camera your dialogue will use.

Skippable – Please, unless you’re dealing with a plot essential cutscene, always check this. There is nothing more annoying than a pazaak player with an “unskippable” dialogue.

Animated Cut – Sets whether or not this is uses an animated camera – this must be checked to make use of the camera you specified in the “Camera model” field.

UnequipHItem – Unequip headgear from all NPCs for the duration of this dialogue, they will be added back later.

UnequipItems – Unequip all other items from NPCs for the duration of the dialogue. Again, they will be returned at the end of the conversation.

 

Apologies for the ridiculous size of this post... I just got a little carried away. I'm also not sure if any of this is of use to you but I was a little bored, you see.

Link to comment
Share on other sites

  • 4 weeks later...

Hello!

 

This is a good (and entertaining!) tutorial, thank you!

 

For my After Ending Mod I want to talk to Bastila after the Starforge is destroyed. How can I make it that the conversation options are only available at a certain point in the game (in my case after the destruction of the Starforge)?

 

Thanks and take care

Link to comment
Share on other sites

You could come up with your own conditional but it would take less time to use one that's already in the game and is present after any possible conversations with Bastila (one like k_psta_malak2 or k_psta_malak1). Just add one like that to the dialogue tree you want to have with her. (Also remember to put the script in your module since as-is it only exists in one area.)

Link to comment
Share on other sites

Thanks Emperor Devon!

 

How do I implement the condition into the conversation?

 

If I want to talk to Bastila, which entry goes to the Cutscene Model (Participant) field, or is that determind somewhere else?

 

What meaning do the other fields of the node have: Speaker, Listener, Script that determines availability, etc.?

 

Thanks and take care

Link to comment
Share on other sites

Speaker - The tag of the NPC who will be speaking the node - if none is specified it will use the creature that initiated the dialogue, otherwise known as the owner. So, in dialogues where it's just the player and the NPC, there's no need to specify anything in here.

Listener - The tag of the object the NPC is talking to. If left blank they will orientate themselves on the player but if a tag has been specified before then it will use that one. To get the player back to being the listener, simply type "PLAYER" in the box :).

Cutscene Model - I don't actually know - whenever there's a Malak cutscene (with all the special animations) or Kreia's Fall is another example (again... with nice, new animations) the model names are specified. These are stunt models with extra animations to make the scene flow nicely. I'm going to make an educated guess and say that the game needs this to play the custom animations from the dialogue file. You don't have to worry about this unless you want to sit atop a tall mountain in a lightning storm and cackle while trying to experiment with animated cutscenes. Read: ignore it.

 

Script that determines availability is just the field for the conditional script :).

Link to comment
Share on other sites

Originally Posted by Seamhainn

I am old, so I ask for a bit more patience then usual, please.

 

How do I make it that the dialogue file "knows" that it "belongs" to Bastila?

 

How do I make it that it is only available after the Starforge?

 

Thanks and take care

Do you mean the partymember Bastila or an NPC Bastila? If you mean an encounter with a "new" npc, you must add the name of the dlg-file to the conversation field of the "new" Bastila's utc-file. If you mean the partymember or an existing npc you must edit the existing dlg-file. It has been specified as Bastila's dlg in the utc.

 

To make a branch of dialogue only available after the Star Forge, you must add a starting conditional script to it. You must select a global variable that is only changed at the Star Forge or create a new one and make a starting conditional that returns 1 or TRUE only if the variable is changed. If you use a new variable, you must also make a script that changes it and attach it to something at the end of the starforge. For example Malak's dialogue. For existing planets or ships there are scripts included in the game for checking if the party is at the specified location. For example the one for the Ebon Hawk is k_con_at_ebon.

Link to comment
Share on other sites

I mean the npc.

 

You mean I must edit k_hbas_dialog? Isn't that a big file to share in a mod? And what happens if another modder edits the file?

 

Is this new dialog for a specific occasion (cutscene etc), or whenever the player chooses to talk to Bastila after the Star Forge?

 

If it's for a specific scene you can put it in a separate DLG file and then make the script that initiates the conversation fire your own DLG file instead.

 

If it's for whenever you want to talk to Bastila, you'll either need to modify her DLG file, as said above, or modify the k_hen_dialogue01 script to use your custom DLG file instead of the one set in the UTC template if conversation is initiated after some global var has been set (some that gets set near/after the duel with Malak preferably).

Link to comment
Share on other sites

Actually its for whenewer the pc wants to talk to Bastila after the Starforge is destroyed. I want them to talk about Battle Meditation. Though, of course, I plan that they talk about other topics later on, too. And I want that the pc talks to the other party members also. Whats the best way to accomplish that?

 

I am sorry to ask all those newbie questions. Most terms and consepts are very alien to me still, but I try very hard to get accustomed to it.

 

Thanks and take care

Link to comment
Share on other sites

I'd create a new OnDialogue script and place it in the .utc file :). If you have TSL then k_hen_attondlg is a perfect example of how to do this. More specifically, this function:

 

void SelectAndRunDLG() {

   //prevent FMP 7722 kds
   if ( GetPartyLeader() == OBJECT_SELF )
   {
       BeginConversation();
       return;
   }


   // If player has done psychotic behavior, call the react script.
   if( GetGlobalNumber ( "000_Psychotic" ) == 1  ) {
       BeginConversation( "000react" );
       return;
   }

   // If Atton is on escape from 650DAN to 006EBO.
   else if( GetModuleName() == "006EBO" ) {
       BeginConversation( "AttonEnd" );
       return;
   }

   // If Atton is on the icy plateau of Telos.
   // Note that this was an unusual case because BeginConversation
   // doesn't allow for dialogues to NOT be affected by distance, so
   // another scripting function had to be used.
   else if( GetModuleName() == "262TEL" ) {
       // Define Atton and Kreia.
       // object oAtton = GetObjectByTag ( "Atton" );
       // object oKreia = GetObjectByTag ( "Kreia" );
       // Now assign the command irrespective of distance.
       // AssignCommand( oAtton, ActionStartConversation ( oKreia, "262Atton", FALSE, CONVERSATION_TYPE_CINEMATIC, TRUE ) );
       BeginConversation( "262Atton" );
       return;
   }


   // If Atton is on the Ebon Hawk after escaping Peragus, but haven't escaped Telos yet.
   else if ( ( GetModuleName() == "003EBO" ) && ( GetGlobalNumber ("262TEL_Escape_Telos") == 0 ) ) {
       BeginConversation( "003Atton" );
       return;
   }

   // If Atton has not joined the party, then Atton will use the 101 file.
   // Cheat mode must NOT be active in order to get this node.
   else if( GetGlobalNumber("101PER_Atton_Joined") == 0 &&
            GetModuleName() == "101PER" )
   {
       BeginConversation( "101Atton" );
   }

   // JAB-OEI 7/27/04
   // this needs to happen so things don't break when we use debug warp
   else if ( GetFirstPC() == OBJECT_SELF )
   {
       BeginConversation("");
       return;
   }

   else if( 0 /*Remove the 0 and check a condition here*/ ) {
       BeginConversation( "YourDLGResRefHere2" );
   }
   // Add as many else if()'s as you want for selecting
   // various DLGs, but leave the 'else' below as the default
   // case.
   else
   {

       // This uses the DLG attached in the editor.
       BeginConversation();
   }
}

 

If you need more help creating the script then don't hesitate to ask - but making mistakes and getting messy is the best way to learn! :)

Link to comment
Share on other sites

You see me at a loss here. If I write another OnDialogue script into Bastila's utc file, isn't all the ingame conversation lost? Or must I ADD your code to k_hbas_dialog, which is her OnDialogue script? Then again would that not create conflicts if other modders toy with these things, too?

 

Thanks and take care

Link to comment
Share on other sites

Actually its for whenewer the pc wants to talk to Bastila after the Starforge is destroyed. I want them to talk about Battle Meditation. Though, of course, I plan that they talk about other topics later on, too. And I want that the pc talks to the other party members also. Whats the best way to accomplish that?

 

In that case I'd modify the k_hen_dialogue01 script to modify which DLG files are triggered depending on if some end-game variable has been set. Since all party members use this script (I think) you could handle the dialog swapping for all of them there in one place.

 

Here is an example of a modified k_hen_dialogue01 script that should use dialog files named the same as the tag of the party member + "_e" (e.g. bastila_e.dlg, cand_e.dlg etc) when the player tries to talk to them after Malak is dead (I think, not 100% sure that variable is reliable to use):

 

#include "k_inc_generic"

int ST_DoEndgameDialog();


void main() {
   // Run custom OnDialog event handler if after the EndGame
   if (!ST_DoEndgameDialog()) {
       ExecuteScript("k_ai_master", OBJECT_SELF, 2004);
   }
}


int ST_DoEndgameDialog() {
   // ST: The endgame hasn't been reached yet. Use standard script instead.
   //     Don't know if STA_MALAK_DEAD is safe to use or you should use your own.
   if (!GetGlobalBoolean("STA_MALAK_DEAD")) {
       return FALSE;
   }

   // ST: Endgame reached. Script variant that swaps DLG file.
   int nMatch = GetListenPatternNumber();
   if (!GN_GetSpawnInCondition(SW_FLAG_AI_OFF)) {
       if(GetCommandable()) {
           object oShouter = GetLastSpeaker();
           object oIntruder;
           if (nMatch == -1) {
               ClearAllActions();
               string sConv = GetTag(OBJECT_SELF) + "_e";

               if ( GetFirstPC() == OBJECT_SELF )
                   sConv = "";

               BeginConversation(sConv);
               return TRUE;
           }
           else {
               GN_RespondToShout(oShouter, nMatch, GetLastHostileActor(oShouter));
           }
       }
   }
   if ( nMatch == -1 ) {
       ResetDialogState();
   }

   if (GN_GetSpawnInCondition( SW_FLAG_EVENT_ON_DIALOGUE )) {
       SignalEvent(OBJECT_SELF, EventUserDefined(1004));
   }
   return TRUE;
}

Link to comment
Share on other sites

Compiling worked flawlessly!!! If that works, stoffe, it would be pretty d**n cool!

 

Whats the ndb file for?

 

I am quite busy this weekend with the soccer boys, though I hope I can create the conversation until Monday. Admittedly I am pretty excited!

 

Thanks and take care

Link to comment
Share on other sites

Whats the ndb file for?

 

Script debugger data file. You can delete those since they aren't used by the game.

 

I created a quick dialogue "Hello!" - "Hello to you, too!"/"Hutt up!" and named it bastila_e.dlg. Unfortunately it doesn't trigger.

 

Did you try the dialog after Malak has been killed? Check if the STA_MALAK_DEAD Global Boolean is set in the savegame you are using. Did you compile the script for the correct game (K1), and put the resulting k_hen_dialogue01.ncs file in the override folder? Did you put your test DLG file in the override folder? Do you have any conditional scripts in your dialog that might block it?

Link to comment
Share on other sites

I typed k_hen-dialogue01 wrong - stupid me! It works pretty good now.

 

More questions:

 

1) I assume I must add the standard nodes which go like "We should go on." or somesuch anew. Though new, more importend lines always show on top of those. How do I accomplish that?

 

2) I want that this particular conversation (Battle Meditation) is only available on the Ebon Hawk. How do I do that?

 

Thanks and take care.

Link to comment
Share on other sites

All works well. But unfortunately the text of the npc is only shown for a second or so. How can I prolong the visability?

 

Set the Delay field to the number of seconds a dialog entry node should be shown before proceeding to the next. If you have voiceover sound assigned the delay is automatically set to the sound duration (if the Delay field is set to -1), but if you only have text you'll need to set it manually.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...