Conversation dynamic weight

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
rakkar
Posts: 51
Joined: Mon Jan 13, 2020 10:39 pm

Conversation dynamic weight

Post by rakkar »

In my game each turn I pick a conversation randomly. However, not all conversations should have the same chance to be selected, but instead somehow query at runtime. As a C# example

// Returned from Werewolf conversation
float GetConversationWeight()
{
if (IsFullMoon()) return 1.0f;
return 0.0f;
}

Preferably this would be Lua script in the conversation that calls into a game code function, so my writer can set it up.

Is this possible, and if so how would I set it up?

Thanks.
User avatar
Tony Li
Posts: 22055
Joined: Thu Jul 18, 2013 1:27 pm

Re: Conversation dynamic weight

Post by Tony Li »

Hi,

To set it up within the dialogue database and Lua, always start the same conversation. Make that conversation immediately link to the "real" conversations. The starting conversation acts as a common entrypoint that gets the Dialogue System to the correct conversation based on current conditions. Link to the first node of each conversation that follows <START>. Don't link to the conversations' <START> nodes themselves. To link to another conversation, inspect the originating link (e.g., the <START> node of the entrypoint conversation). In the Inspector, from the "Links To:" dropdown select "(Another Conversation)".

Your writer can specify Conditions on each conversation's first node. For those conversation, you can use Dialogue System variables or Lua functions. For example, you might set a Dialogue System variable named isFullMoon to true or false, and set the node's Conditions to:

Code: Select all

Variable["isFullMoon"] == true
In your gameplay C# code, you can set isFullMoon using DialogueLua.SetVariable:

Code: Select all

using PixelCrushers.DialogueSystem;
...
DialogueLua.SetVariable("isFullMoon", true);
Your writer can specify the condition above using the "..." dropdowns without having to type anything.

You can also register your own C# functions with Lua, and optionally configure a Custom Lua Function Info asset to make them available in the "..." dropdowns so your writer doesn't have to type them manually.

Finally, make use of priority values on links between nodes. If you always want the Werewolf conversation to take precedence as long as its first node's Conditions are true, set its priority to High.
rakkar
Posts: 51
Joined: Mon Jan 13, 2020 10:39 pm

Re: Conversation dynamic weight

Post by rakkar »

Thanks for the quick and detailed reply. Using conditions works if the condition is boolean, such as in my Werewolf example.

However, I have 75 different conversations and I am currently selecting by weighted random numbers https://stackoverflow.com/questions/176 ... om-numbers

I just happen to return 0 if the conversation is unavailable, but usually most would be available.

From the dialogue I would pick the child conversation that has the highest weight. If priority was a number instead of an enum, and I could set the priority dynamically from the linked conversation that would work.
rakkar
Posts: 51
Joined: Mon Jan 13, 2020 10:39 pm

Re: Conversation dynamic weight

Post by rakkar »

Here's kind of hacky way I thought of to do it.

From C#
Iterate through all conversation
If a conversation can be randomly selected, put some kind of tag in the name, such as _RANDOM_
For all conversations that can be randomly selected, run lua code that was stuffed into the description. The Lua code is expected to return a double
Choose one using weighted random selection
Start that conversation from C#
User avatar
Tony Li
Posts: 22055
Joined: Thu Jul 18, 2013 1:27 pm

Re: Conversation dynamic weight

Post by Tony Li »

Hi,

You can put your Lua code in a custom Text field instead of Description if you prefer -- for example, a field named RandomFormula.

You could also add another Boolean field to mark if the conversation can be randomly selected. Or just check if the RandomFormula field has any content.

Then you can get all of the randomly-selectable conversations with something like this:

Code: Select all

List<Conversation> conversations = DialogueManager.masterDatabase.conversations.FindAll(conversation => !string.IsNullOrEmpty(conversation.LookupValue("RandomFormula")));
To evaluate the current weight, something like:

Code: Select all

float weight = Lua.Run(conversation.LookupValue("RandomFormula")).asFloat;
rakkar
Posts: 51
Joined: Mon Jan 13, 2020 10:39 pm

Re: Conversation dynamic weight

Post by rakkar »

Yes, that what I ended up doing. Thanks.
Post Reply