Page 1 of 1

[SOLVED] Add and evaluate conditions at runtime

Posted: Sun Jun 16, 2024 10:56 am
by Mindfolk
Hi.

I'm struggling with what I can only assume is a fringe need. I want to add conditions to my Dialogue Entries at runtime.

I've managed to actually add the LUA logic to the conditions field, but when running the conversation for the first time these don't get evaluated. Only by exiting play-mode and re-entering does the conditions get evaluated.

Summary:
* I add conditions at runtime (through a method subscribing to: DialogueManager.instance.conversationStarted)
* The condition is a Lua function
* The runtime added conditions are not evaluated even though the text is clearly visible and the red "?" symbol are added to the Dialogue Entry Nodes
* I keep the conditions (for testing purposes) after exiting play-mode.
* If I enter play-mode again and enter the same conversation the now already added conditions are evaluated and the correct dialogue entry is selected.

This method was part of a larger evaluation of the system, and might not find its way into the final implementation - but I would like to check if anyone knows if this feature can be made to work?

Can I force some kind of refresh of the conversation?

Here's a snippet of the code for clarity:

Code: Select all

  private bool HeuristicCheck(double id) {
      Debug.Log($"ConditionCheck for {id}");
      int conversationID = DialogueManager.currentConversationState.subtitle.dialogueEntry.conversationID;
      DialogueEntry entry = db.GetDialogueEntry(conversationID,(int)id);

      return Field.LookupInt(entry.fields,"Weight") == allowedWeight;
  }

  private void Started(Transform _) {
      Debug.Log("started...");
      DialogueManager.Pause(); 
      int conversationID = DialogueManager.currentConversationState.subtitle.dialogueEntry.conversationID;
      List<DialogueEntry> allEntriesInConversation = db.GetConversation(conversationID).dialogueEntries;
      Debug.Log($"this conversation has {allEntriesInConversation.Count} entries");
      foreach (var entry in allEntriesInConversation) {
          int weight = Field.LookupInt(entry.fields,"Weight");
          if(weight > allowedWeight) {
              allowedWeight = weight;
          }

          if (entry.outgoingLinks.Count != 0 && string.IsNullOrEmpty(entry.DialogueText)) continue;
          string conditionLUA = string.IsNullOrEmpty(entry.conditionsString) ? "" : " and ";
          string luaCode = $"{nameof(HeuristicCheck)}({entry.id})";
          conditionLUA += luaCode;
          if (entry.conditionsString.Contains(luaCode)) continue;
          entry.conditionsString += conditionLUA;
          Field.SetValue(entry.fields,"temp_condition_lua",conditionLUA);

      }

Re: Add and evaluate conditions at runtime

Posted: Sun Jun 16, 2024 11:09 am
by Mindfolk
With a risk of celebrating to soon, it seems that by unchecking "Warm up conversation controller" the condition expressions are evaluated!

I'll leave the thread up in case others stumble onto the same question or if someone has more knowledge and insights to add.

Re: [SOLVED] Add and evaluate conditions at runtime

Posted: Sun Jun 16, 2024 11:43 am
by Tony Li
Hi,

On your Dialogue Manager GameObject, is Other Settings > Instantiate Database set? Try ticking Instantiate Database if it's not already ticked. This will instantiate and use an in-memory copy of the database. Otherwise, since the database is a ScriptableObject asset, when you make changes to it in the editor's play mode, those changes will persist when you exit play mode. With the Warm Up option, what's probably happening is that you're making changes to the database asset (not the in-memory instance) while the warmup process is instantiating the database and warming up in Start.

If I may suggest some alternate approaches, you can add a script with an OnPrepareConversationLine(DialogueEntry) to the Dialogue Manager. In this method, you can modify the dialogue entry's conditionsString. Or assign a C# method to DialogueManager.isDialogueEntryValid delegate property. In this method, you can do whatever checking you want. If assigned, a dialogue entry will be considered valid to show if the conditionsString is true (or blank) and if the isDialogueEntryValid function returns true.