Dialogue

For the game I am making, I want dialogue to be a big feature so that’s what I’ve been working on. It’s also where I have hit the first roadblock while trying to code it. Been banging my head against it for a few hours so I am pretty sure at this point, my brain has gone derp. I am just going to ask some questions and would appreciate some answers.

1)What’s the best way to offer a list of topics, get the info and return to the start of the topic lists?

2)I want multiple choices. No, really. I want loads of them as possible. How do you keep track of many snippets of dialogue without using something stupid as making a new label for every potential path?

3)I’ve been using lots of *if or *else statements but that feels unwieldy especially if I want the conversation to flow naturally by having it jump to another part of a dialogue snippet. Is there a more efficient method?

4)How do I combine all of the above?

@Marius I haven’t myself used any particularly deep conversations so others might have better suggestions for 2-4 from their own practical experience. However, I can at least answer #1 for you:

*label return_here *choice *hide_reuse #topic1 text blah blah blah *goto return_here *hide_reuse #topic2 text blah blah blah *goto return_here *etc.

Bearing in mind the above won’t show correct tabulation, but it should be easy enough to figure out.

What the above will do is offer a list of topics once only. As soon as the player has selected that option and the text is displayed, it will display the full choice list again less any previously-chosen ones.

Thanks, Vendetta!

Just need to figure out how to do the rest but that will serve as a nice foundation to build upon. Been trying to code the rest of the options but I am starting to think I might need to pare it down a little instead of making it complex.

I am no coder so will not be able to offer any good ideas. I am using a lot of interactive conversations, it is a ton of *if and true/false for me. It gets very complex to follow and I wrote it lol. If someone comes up with a good idea I am all ears.

I’ve given it some more thought (I have some deeper conversational scenes coming up in the near future and this topic got me thinking!) but I’m sorry to say I haven’t yet come up with an ‘easy’ answer. I can see myself using lots of *if / *elseif statements and probably a large number of temp variables to keep track of various states–combined with a whole host of labels embedded within the text for *goto jumps to add particular paragraphs as needed (as the only viable alternative to that would probably be to repeat large chunks of both code and text, which would at least keep it simpler to follow but would not be the ‘proper’ way of doing things).

All considered, I’m hoping to have some bright ideas occur when actually tackling it . . . or for someone like @JimD or @Reaperoa to wade in here with a few creative examples we can all borrow. :smiley:

Nods. ^:)^

I’d also be eager to hear from anyone who’s got an easy way of doing it… but yeah, for me it’s a lot of *ifs and variables (some temp, many not).

For the key NPCs, I keep a numeric relationship variable. Some key choices kick it up a bracket. E.g. if b_rel = 1, you’ve met B, 2 you’ve flirted with him/her, 3 you’re his/her lover, all of which can affect your conversation/choice options… but if you betray B, it kicks it up +10.

So then if b_rel > 9, B will respond to you as a traitor; if b_rel = 13, B’s especially pissed at you, and so on. The traitor thing will affect most conversations, but some conversation options are only affected if e.g. you are/were B’s lover, in which case it’s an “if b_rel = 3 or b_rel = 13” code.

Maybe that’s overly elaborate? :slight_smile:

I tried to make the dialogues random but got complicated.

I think uses variables and if commands are the only way.

@Havenstone That’s the direction which I am going towards if I understand it correctly.

How do you code it so it affects conversation? I mean the text displayed, not conversation choices. And I presume the code can be scaled up for multiple sentences depending on variables? So for example, I have a npc giving a speech. He has a standard speech but all the sentences in the speech can be changed depending on variables?

If that’s what I think it is, it sounds much better than what I have.

There are 2 method I use in Zombie Exodus:

  1. Tree structure – comprised of if/elseif/else statements. Variables have to be tracked for what was said if major outcomes occur. I generally use this structure for more dynamic conversations and when relationship scores should change. It takes much longer to write to make it seem more natural than artificial.

  2. Topic structure – this is similar to what is listed earlier in this thread – just listing lots of topics and allowing players to loop back and continue picking topics until they choose to end the conversation. I use this when I need to provide a lot of skippable content, mainly in dealing with NPC backgrounds or other non-critical content.

You can also add conditions of course to choices. Other than that, I don’t know of other ways in Choicescript to do it.

The only thing I can add to that if you use the tree system have a note book or spreadd sheet to track it all. It is easy to lose a conversation.

Further to the above, for deeper conversations it might be worth bearing in mind that you can in fact also use a combination of *if & *selectable_if and *if & *hide_reuse within your actual *choice topics. Example follows–bearing in mind that tabulation will not be shown correctly here, but the basic logic / rules apply as normal.

*label return_here *choice *if ((condition_a) and (condition_b)) or (condition_c) *selectable_if (condition_d) #TOPIC 1 text blah blah blah *goto return_here *selectable_if (condition_e) #TOPIC 2 text blah blah blah *goto return_here *if ((condition_f) and (condition_g)) or ((condition_h) and (condition_i)) *hide_reuse #TOPIC 3 text blah blah blah *goto return_here #TOPIC 4 (in case all of the above can fail!) blah blah blah *goto return_here

By this means you should be able to implement just about any ‘depth’ of conversation and based on all sorts of criteria / previous replies given, etc. Obviously the more complex you make it, the more certain you have to be that there will always be at least one valid option in any given situation. All good fun . . . *cough*

Damn, without the correct tabs that’s as confusing as hell, so let’s try that again shall we . . . :smiley:

*label return_here
*choice
–*if ((condition_a) and (condition_b)) or (condition_c)
----*selectable_if (condition_d) #TOPIC 1 text
------blah blah blah
------*goto return_here
----*selectable_if (condition_e) #TOPIC 2 text
------blah blah blah
------*goto return_here
–*if ((condition_f) and (condition_g)) or ((condition_h) and (condition_i))
----*hide_reuse #TOPIC 3 text
------blah blah blah
------*goto return_here
#TOPIC 4 (in case all of the above can fail!)
----blah blah blah
----*goto return_here

@LordIrish For extensive tree structures, as defined by @JimD, I prefer using a labelled top level “subroutine” to control the conversational flow in the file. I favor keeping the dialog entirely in the labelled subsidiary subroutines which are often parallel to each other instead of nested. This makes the main routine more concise, and thus easier to read, follow, and troubleshoot. It also prevents the subsidiary subroutines from getting too big to keep in your head as well. So there are a lot of *gosubs and *returns passing control back and forth. It may seem like extra work in the beginning, but over the long term it makes life quite a bit easier. Example:


*label main conversation
*gosub topic1
*if (topic1_choice="war")
  *gosub topic1a_war
*else 
  *gosub topic1b_peace
*gosub topic2
...
*finish 


*label topic1
...
*return


*label topic1a_war
...
*return


*label topic1b_peace
...
*return


*label topic2
...
*return


etc...

The key is keeping them a good bite size, too big and you’ll choke on the code block, too small and you’ll just be wasting energy.

I use a lot of gosubs but I find that if I do not place them at the very end of the page I get odd spaceing complaints, of course be just an IE issue. But I have always kept them to the buttom with lots of *comments to help keep track of what thay are.

I do have a method for tracking a very complex tree, but its not exactly suited for CoG. So I only use it when I find I am spending way to much time tracking down a gosub or a set of varibles. I use yWriter5, it was design for novel writing. So I can break it up into chapters and scenes. Very simple to use. But formatting is a problem, I can transfer it all easy enough but spend a lot of time cleaning it up. I have on my todo list to talk to the creater of this program and see if he can add a feature to this program. But that is not any time soon.

I agree with @P_Tigris that using *gosub and *return can help with organizing complex conversations. I also like @Havenstone’s idea of using numeric variables to track relationship status, and am still forming my own similar system.

Sometimes a conversation will need to be only slightly different depending on the situation, and in those cases I like to set up variables that hold the conditional bits of dialogue at the earliest possible time, and then display them later, during the conversation. For example, suppose earlier in the story the main character made a choice regarding a mode of transportation in getting to an important meeting, with corresponding adventures based on the chosen mode of transportation, but now the important meeting is occurring. The main character is late (which you have conveniently set up to be the case regardless of which mode of transportation the main character chose).

Using *if commands, the conversation might look like this (forgive the extra lines between the intended lines):

"You're late," Phillips mutters. "I almost thought you weren't coming."

"Sorry," you say.
*if (transport = "car")
  "I was tied up in traffic.
  *goto end_transport
*elseif (transport = "bus")
  "The bus broke down and we had to wait for another one.
  *goto end_transport
*elseif (transport = "bike")
  "My bike had a flat.
  *goto end_transport
*else
  "My car wouldn't start, I missed the bus, and someone stole my bike.
  *goto end_transport
*label end_transport
But I'm here now. Let's do this."

The thing is, when the decision was first made as to the mode of transportation, that’s a perfect time to set a variable to use during this conversation. You can then dispense with all of the *if and *elseif commands above. It might look something like this, including the early part of the story where the mode of transportation was chosen:

*temp excuse
In all the excitement, you almost forgot about Phillips.
He'll be expecting to see you soon, and the meeting
place is clear across town. How will you get there?
*choice
  #Drive my car
    *set excuse "I was tied up in traffic."
    *goto car
  #Grab a ride on the bus
    *set excuse "The bus broke down and we had to wait for another one."
    *goto bus
  #Ride my bike
    *set excuse "My bike had a flat."
    *goto bike
  #Run
    *set excuse "My car wouldn't start, I missed the bus, and someone stole my bike."
    *goto run

Some other things happen, and then the meeting occurs…

"You're late," Phillips mutters. "I almost thought you weren't coming."

"Sorry," you say. "${excuse} But I'm here now. Let's do this."

In this particular situation, one might suggest simply doing without the excuse and so avoid using another variable or the block of *if/*elseif commands. But such situational flavor, even when you could do without it, can help give the reader a stronger feeling of control over the story, because it’s clear that the story is still recognizing that earlier choice the reader made.

Thanks for contributing everyone! Great suggestions and advice.

^:)^

Think a lot of the info in this thread would make a great addition to content in the wiki. I’m trying to write my first ‘proper’ dialogue with a character, and all of the comments are really helping me.