Page 1 of 1
Conversation dynamic weight
Posted: Sun Jan 19, 2020 7:16 am
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.
Re: Conversation dynamic weight
Posted: Sun Jan 19, 2020 9:15 am
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:
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.
Re: Conversation dynamic weight
Posted: Sun Jan 19, 2020 10:56 am
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.
Re: Conversation dynamic weight
Posted: Sun Jan 19, 2020 11:08 am
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#
Re: Conversation dynamic weight
Posted: Sun Jan 19, 2020 2:40 pm
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;
Re: Conversation dynamic weight
Posted: Sun Jan 19, 2020 3:29 pm
by rakkar
Yes, that what I ended up doing. Thanks.