• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

A dynamic conversation. How would you do it?

Status
Not open for further replies.
Level 3
Joined
Nov 11, 2011
Messages
26
So I've been spending some time trying to make a dynamic conversation where the player can respond in some form of cinematic mode to a unit. Just like in any other rpg where you have options on what you choose to say. I've come to the conclusion that it would be most effective to make these kinds of triggers based on stings that have to do with topics (kind of like the way dialog works in the Elderscrolls games). That way whenever you talked to someone there would be a list of topics and they would be related to strings... but the problem is I'm completely stumped right now on how to make a dynamic conversation that doesn't fall apart.

Any suggestions on where I could start?

PS. I looked for tutorials on this but I could not find any.
 
Level 3
Joined
Nov 16, 2011
Messages
54
You are one of the smartest people on the world or one of the most misguided. Things like this are done by whole team of people and in different games. Warcraft is linear game and you will need more than a miracle to do such a thing. Yet if you even finish your map send me PM to play it i will be the biggest fan :)
 
Level 3
Joined
Nov 11, 2011
Messages
26
A person did it here

I wanted to try and mimic that, but I couldn't get everything down because it was in polish and because I didn't know which variables to use.

One theory I do have that does work is based on commands. It would be the same as I stated above, having to do with topics, but it would just be based on what the player entered into chat. Of course in the conversation a unit would give away what commands to type that would get a certain response. I did that yesterday and it worked but I'm not sure how people playing that map would react... actually typing a question for an npc.
 
Level 3
Joined
Nov 16, 2011
Messages
54
When you are in cinematic mode only the Esc key can be used other keys simply don't work as far as i know. About this system simply do it like in the pictures. Display what is the NPC saying and then the answers like in the screen numerated with 1,2,3,4,5,6,7,8,9. Then depending on what number the player is sending as chat string set your variables and do your actions. For better effects you can display the NPC words in cinematic mode and when it ends there to be the answers that you can possibly choose. Because people don't like to type millions of words make so they only have to type the number of the answer.
Edit: You can do the same thing as this person have done but you will need solid JASS and vJASS knowledge in order to do all of those things work with mouse click and all those visual effects. Note there are not much people out there that can do such a system so your best option is to do it the simple way i told you if not search for person to help you out.
 
Level 3
Joined
Nov 11, 2011
Messages
26
I see what you mean, but I'm not completely sure if I get the entered chat string. Is that when the player hits "enter" and then would type "1" (as in the first option to direct the conversation) or would the player just hit the "1" key?

Let me just make a blueprint conversation to make this thread easier to follow. Say you approach a knight...
Knight: "Hello. You look lost. How may I help you?"
1) Where are we?
2) Tell me about yourself.
3) Goodbye.

If the player presses (or types "1")...
Knight: "We're in the barrens, about to attack the Orc encampment"
1) Why are we fighting the Orcs?
2) Why don't we just kill the night elves an make everyone happy?

As soon as I get to the second part of the conversation, from "1", if I let the player press the "1" key I don't know how to reset the trigger and variable so that only one response to "1" is being displayed.
 
Level 17
Joined
Jan 21, 2010
Messages
2,111
Use dialouge button?
I seen fferpg using this way, and it seems good (although only one quest that they do like this)
The choices is inside the dialouge button, only available for the host
The other player get their unit, and hero paused, after the selection done, the other unit/ hero get unpaused, and also the host's
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
The system is probably best modeled as some form of programable state machine.

The machine needs to get loaded with a model. This should be based on who you are interacting with (fixed NPC) or produced by the game engine at a certain time (cinimatic). The model determines the conversation structure and behaviour, this way you can avoid unnescescary procedural coupling and create a frame work to generate conversations.

Let us think of what such a conversation system needs.
The most apparent requirement is a list of choices. And that is what you make, a list of choices. One can make a mega list with every single possible choice you can give to a certain conversation model.

It is obvious that choices need to be restricted depending on the state of the game. How does one apply a restriction to a list? You filter it (evaulate any restrictions present for each choice in the model and remove it from the list of available choices).

This would be stupidly tedious to use in certain situations where the same basic conversation needs to be incoperated into different models (like the general talk in TES Oblivion). What we could do is allow models to inheret models so it includes everything in models it inherits as well as its own definitions. This might make conversation models overly complicated as well as over complicate the engine due to the mechanics needed. We could also define a certain conversation option behaviour which calls another conversation model. Like function calls this places the current conversation model's internal state into a stack and loads the target conversation model. Once the taget conversation model finishes you can just return back to the previous conversation model using the stack. This would allow nested conversation choices easilly and even allow reuse of smaller conversation components.

Now we need to think about how to filter the actual conversation elements. The simplest form of filter can be a conversation state, so we can make sure that a person is providing a certain set of choices. We might want to make a option dependent on more than 1 state (a list of states) and also perform tests with a certain state. Defining a converstation state pointer as a string would be useful as it avoids accidental referencing and allows states to easilly be transfered when calling another model. You could also use a simple array as a state register but using such a system might prove hard (as you need to make sure the right states get used). More advanced conditions might need an instruction based system allowing you to use nested or and and type conditioning.

It would be stupid if a NPC forgets we ever talked to him before. Imagine being asked "Who are you" every time you walk to a NPC, not an emmersive or relaxing experience (stupid NPC syndrome). Thus we need some way to store state information for a conversation. Some form of hashmap with string indicies would be good to work with the above described state system. This results in a conversation state which you pass to the initializer along with a conversation model when starting a conversation.

So how do we get our buttons to do something? An instruction based system would work. When a reponse is choosen it can then run a chain of instruction. These instructioncs could call another conversation model, return to a calling state model, change a local state, change a remembered state or even call a script function for more advanced gameplay responses. Obviously the most important instruction is one to actually say something in the conversation (some text to the user). After a conversation chain finishes, it should refresh the list of choices you are presented with. Incase you introduce conversation reponse delays such as for cinimatics you need to make sure no futher choices can be choosen until the conversation action completes. Importantly you must allow ESC to skip any time delayed actions.

Finally you might want to alter conversation options based on scripted events. All you need to do is modify the persistent conversation state which will be passed to the conversation with some handy callable function.

This hopefully sends you in the right direction. Can not garuntee such a design will work but the idea should.
 
Level 3
Joined
Nov 16, 2011
Messages
54
It would be stupid if a NPC forgets we ever talked to him before. Imagine being asked "Who are you" every time you walk to a NPC, not an emmersive or relaxing experience (stupid NPC syndrome). Thus we need some way to store state information for a conversation. Some form of hashmap with string indicies would be good to work with the above described state system. This results in a conversation state which you pass to the initializer along with a conversation model when starting a conversation.

What about the (stupid Player syndrome). Your theory is right and i agree with almost every aspect of it. Yet let's don't forget that there is no such thing as dynamic conversation created yet for a game. Every single game have it's limits (linear conversation) no matter how complicated it is there is always limit. We haven't create AI that can upgrade it'self infinitely (I mean Warcraft wise).

@Zahadoom
I will try to create for you a simple map as to see some basics. Don't forget what i said early no matter your plans your conversations must be linear and well planed.
 
Level 3
Joined
Nov 11, 2011
Messages
26
Now we need to think about how to filter the actual conversation elements. The simplest form of filter can be a conversation state, so we can make sure that a person is providing a certain set of choices. We might want to make a option dependent on more than 1 state (a list of states) and also perform tests with a certain state. Defining a converstation state pointer as a string would be useful as it avoids accidental referencing and allows states to easilly be transfered when calling another model. You could also use a simple array as a state register but using such a system might prove hard (as you need to make sure the right states get used). More advanced conditions might need an instruction based system allowing you to use nested or and and type conditioning.

It would be stupid if a NPC forgets we ever talked to him before. Imagine being asked "Who are you" every time you walk to a NPC, not an emmersive or relaxing experience (stupid NPC syndrome). Thus we need some way to store state information for a conversation. Some form of hashmap with string indicies would be good to work with the above described state system. This results in a conversation state which you pass to the initializer along with a conversation model when starting a conversation.

So how do we get our buttons to do something? An instruction based system would work. When a reponse is choosen it can then run a chain of instruction. These instructioncs could call another conversation model, return to a calling state model, change a local state, change a remembered state or even call a script function for more advanced gameplay responses. Obviously the most important instruction is one to actually say something in the conversation (some text to the user). After a conversation chain finishes, it should refresh the list of choices you are presented with. Incase you introduce conversation reponse delays such as for cinimatics you need to make sure no futher choices can be choosen until the conversation action completes. Importantly you must allow ESC to skip any time delayed actions.

Finally you might want to alter conversation options based on scripted events. All you need to do is modify the persistent conversation state which will be passed to the conversation with some handy callable function.

This hopefully sends you in the right direction. Can not garuntee such a design will work but the idea should.

I was able to produce exactly what you're talking about using the dialog box. The problem I continuously ran into was that the dialog box and the dialog buttons were buggy. I would talk to someone, select option 1, and it would load option 2. I could go back, select option 2, and it would load option 2. Then when I selected option 1 for the second time, it would run option 1 (the way it should have run to begin with).

Then I integrated a quest. It was very simple. You go and kill a bandit. Then you return and the dialog would be different (which it was). After completing the quest by selecting "<toss him the bandit's head>" I game decided it would only run half of my trigger.

My theory on dialog boxes is that the game must be presented with a different variable every time a new dialog box is presented. So when you approach the footman for the first time and he says, "How can I help you?", the variable "Footman_HowcanIhelpyou is equal to this trigger".

I'm going to go back and trying to make a conversation with dialog boxes using my new "multipe variables theory". Originally every dialog box that appeared was "Dialog_box" and it's buttons were "Dialog_buttons". So maybe that's where the game got thrown off.

Edit: Here is my quest/conversation that bugged out (note that I was just making a template quest so you won't find any triggers about setting up an actual quest but going and killing the bandit was still the objective and could be completed)

  • Ammonites are neutral
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set AmmonitesNeutral = (This trigger)
      • Player - Make Player 1 (Red) treat Player 2 (Blue) as an Neutral
      • Player - Make Player 2 (Blue) treat Player 1 (Red) as an Neutral
And when you approach the knight whom you talk to and who gives you the quest...

  • Neutral Captain Maghel
    • Events
      • Unit - A unit comes within 150.00 of Knight 0091 <gen>
    • Conditions
      • AmmonitesNeutral Equal to Ammonites are neutral <gen>
    • Actions
      • Dialog - Clear DialogBox
      • Dialog - Change the title of DialogBox to Captain Maghel: Gre...
      • Dialog - Create a dialog button for DialogBox labelled Join the Ammonite L...
      • Set DialogButtons[1] = (Last created dialog Button)
      • Dialog - Create a dialog button for DialogBox labelled The previous centur...
      • Set DialogButtons[2] = (Last created dialog Button)
      • Dialog - Create a dialog button for DialogBox labelled Tell me about yours...
      • Set DialogButtons[3] = (Last created dialog Button)
      • Dialog - Create a dialog button for DialogBox labelled Goodbye
      • Dialog - Show DialogBox for Player 1 (Red)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • AmmoniteQuest_EnforcerDead Equal to Bandit Spawn B End <gen>
        • Then - Actions
          • Dialog - Change the title of DialogBox to Captain Maghel: Don...
          • Dialog - Create a dialog button for DialogBox labelled <Toss him the bandi...
          • Set DialogButtons[6] = (Last created dialog Button)
          • Dialog - Create a dialog button for DialogBox labelled Goodbye
          • Dialog - Show DialogBox for Player 1 (Red)
          • Trigger - Run Ammonites become allies <gen> (checking conditions)
        • Else - Actions
          • Do nothing
When you select the various options/sub options/sub sub options...

  • Join the Ammonite Legions 1
    • Events
      • Dialog - A dialog button is clicked for DialogBox
    • Conditions
      • (Clicked dialog button) Equal to DialogButtons[1]
    • Actions
      • Dialog - Clear DialogBox
      • Dialog - Change the title of DialogBox to Captain Maghel: Hm....
      • Dialog - Create a dialog button for DialogBox labelled Bandit Enforcer?
      • Set DialogButtons[5] = (Last created dialog Button)
      • Dialog - Create a dialog button for DialogBox labelled Goodbye
      • Dialog - Show DialogBox for Player 1 (Red)
  • The previous centurion 2
    • Events
      • Dialog - A dialog button is clicked for DialogBox
    • Conditions
      • (Clicked dialog button) Equal to DialogButtons[2]
    • Actions
      • Dialog - Clear DialogBox
      • Dialog - Change the title of DialogBox to Captain Maghel: Ah,...
      • Dialog - Create a dialog button for DialogBox labelled Avenge his death
      • Set DialogButtons[4] = (Last created dialog Button)
      • Dialog - Create a dialog button for DialogBox labelled Goodbye
      • Dialog - Show DialogBox for Player 1 (Red)
  • Tell me about yourself 3
    • Events
      • Dialog - A dialog button is clicked for DialogBox
    • Conditions
      • (Clicked dialog button) Equal to DialogButtons[3]
    • Actions
      • Dialog - Clear DialogBox
      • Dialog - Change the title of DialogBox to Captain Maghel: I u...
      • Dialog - Create a dialog button for DialogBox labelled Goodbye
      • Dialog - Show DialogBox for Player 1 (Red)
  • Avenge his death 4
    • Events
      • Dialog - A dialog button is clicked for DialogBox
    • Conditions
      • (Clicked dialog button) Equal to DialogButtons[4]
    • Actions
      • Dialog - Clear DialogBox
      • Dialog - Change the title of DialogBox to Captain Maghel: The...
      • Dialog - Create a dialog button for DialogBox labelled Goodbye
      • Dialog - Show DialogBox for Player 1 (Red)
  • Bandit Enforcer 5
    • Events
      • Dialog - A dialog button is clicked for DialogBox
    • Conditions
      • (Clicked dialog button) Equal to DialogButtons[5]
    • Actions
      • Dialog - Clear DialogBox
      • Dialog - Change the title of DialogBox to Captain Maghel: You...
      • Dialog - Create a dialog button for DialogBox labelled Goodbye
      • Dialog - Show DialogBox for Player 1 (Red)
This last one is a sub option, after you have killed the bandit, it becomes available and is supposed to run another trigger.

  • Give him the head 6
    • Events
      • Dialog - A dialog button is clicked for DialogBox
    • Conditions
      • (Clicked dialog button) Equal to DialogButtons[5]
    • Actions
      • Dialog - Clear DialogBox
      • Dialog - Change the title of DialogBox to Captain Maghel: Ah,...
      • Dialog - Create a dialog button for DialogBox labelled Goodbye
      • Set DialogButtons[7] = (Last created dialog Button)
      • Dialog - Show DialogBox for Player 1 (Red)
And when you hit "goodbye" the following actions should occur:

  • Ammonites become allies
    • Events
      • Dialog - A dialog button is clicked for DialogBox
    • Conditions
      • (Clicked dialog button) Equal to DialogButtons[7]
    • Actions
      • Player - Add 75 to Player 1 (Red) Current gold
      • Player - Make Player 1 (Red) treat Player 2 (Blue) as an Neutral
      • Player - Make Player 2 (Blue) treat Player 1 (Red) as an Neutral
      • Set AmmoniteRank_Lieutenant = (This trigger)
 
Last edited:
Status
Not open for further replies.
Top