Change Conversation Fields on Runtime

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
elekvault
Posts: 3
Joined: Thu Aug 10, 2023 3:05 pm

Change Conversation Fields on Runtime

Post by elekvault »

Hi, I really need help because this is driving me crazy and I'm out of ideas. It's probably something I'm not getting at all, I'm new with Lua so maybe you can help me.

Context is:

I've got a Dialogue Database with a conversation that has a custom field called CurrentStepID = 0; there is a Start node, then 3 child nodes. Each child node has conditions Conversation[1].CurrentStepID == 0, 1 or 2 respectively. At the end of each branch, it increases the CurrentStepID value using the Lua code Conversation[2].CurrentStepID = 1;

The Dialogue Manager (Dialogue System Controller component) has checked 'Allow Only One Instance', 'Don't destroy on Load', and 'Instantiate Database'.

In-game, I trigger via C# script the conversation and it goes through the first branch, and then changes CurrentStepID to 1. If I run the conversation again in the same playing session, it correctly checks the condition and goes through second branch, and so on. So, for the same playing session, it all runs as expected. For the purpose of this error, we'll run the conversation just once, so CurrentStepID = 1.

I've got a custom save system (because reasons) that saves the value of CurrentStepID on a Dictionary<int, int> with key being Conversation ID. It saves correctly.

Now, on the next play session, on game start, I load the saved data that correctly contains the CurrentStepID = 1 for .
I'm trying to load the saved value into the conversation field, to no success, so when triggered in this new play session it starts at the second branch, but it keeps the CurrentStepID = 0 and triggers the first branch.

I think I understand that the database asset is loaded as read-only, and all the changes are made on the instanced database in-memory, but surely I'm missing something cause no matter what I do, CurrentStepID stays with value 0.

Things that I've tried:

Code: Select all

private void SetFieldsTest()
{
	
	Conversation thisConvo = DialogueManager.MasterDatabase.GetConversation(conversationID);
	if (thisConvo != null)
	{
		//I don't see any effects using this Lua code, it paints the Debug info and no errors are shown, but CurrentStepID stays with value 0.
		string luaCode = string.Format("if not Conversation[{0}].{1} then Conversation[{0}].{1} = '{2}' end\n", conversation.id, "CurrentStepID", 1);
        luaCode += string.Format("Conversation[{0}].{1} = '{2}'\n", conversation.id, "CurrentStepID", 1);
        Lua.Run(luaCode, true, true);
		///////
	
		//Same than previous one, executes OK but I can't see any changes at all in the field inside the conversation (checking the Lua environment too)
		DialogueLua.SetTableField("Conversation", thisConvo.Title, "CurrentStepID", 1);
		
		//This one changes the value on thisConvo, and you can see the change in the inspector while debugging, but it remains unchanged in the Lua Environment.
		thisConvo.fields.Find(x => x.title == "CurrentStepID").value = "1";
		
		//This one gives same result as the previous one, changes the value on thisConvo, and you can see the change in the inspector while debugging, but it remains unchanged in the Lua Environment.
		Field.SetValue(thisConvo.fields, "CurrentStepID", 1);
	}
}
In all cases, the conversation triggers with CurrentStepID = 0. I tried these methods before triggering the conversation, and also in the event OnConversationStart, with same results.
I'm triggering the conversation with this code:

Code: Select all

Conversation conversation = DialogueManager.masterDatabase.GetConversation(conversationID);
if (conversation != null)
	DialogueManager.StartConversation(conversation.Title, transform);
I don't know what I'm missing and it's probably something I don't understand about the instancing and the Lua Environment, but I'm kind of desperate now and it baffles me how easy is to get a field value and how apparently impossible is to set it. Any ideas? Thank you in advance!
User avatar
Tony Li
Posts: 22118
Joined: Thu Jul 18, 2013 1:27 pm

Re: Change Conversation Fields on Runtime

Post by Tony Li »

Hi,
elekvault wrote: Thu Aug 10, 2023 8:10 pmEach child node has conditions Conversation[1].CurrentStepID == 0, 1 or 2 [/b]respectively. At the end of each branch, it increases the CurrentStepID value using the Lua code Conversation[2].CurrentStepID = 1;
I assume you meant to type Conversation[1] both times above?

At runtime, the Dialogue System creates a Lua environment and copies the conversations' fields into it, in Conversation[#] Lua tables. When you run this Lua code:

Code: Select all

Conversation[1].CurrentStepID = 1;
you're not actually changing the database. You're changing the Conversation[#] table in the Lua environment.

If you want to save the state of the Lua environment, inspect your Dialogue Manager GameObject/prefab. Tick Persistent Data Settings > Include All Conversation Fields. Then use this C# code to save it as a string:

Code: Select all

string s = PersistentDataManager.GetSaveData();
Then you can save that string using your save system.

To restore the Lua environment:

Code: Select all

PersistentDataManager.ApplySaveData(s);

However, if you only want to save and load the conversations' CurrentStepID values, you can use the DialogueLua class to get each one like:

Code: Select all

int id = DialogueLua.GetConversationField(1, "CurrentStepID").asInt;
There is no corresponding DialogueLua.SetConversationField(), so you'll need to use Lua.Run():

Code: Select all

Lua.Run($"Conversation[1].CurrentStepID = {id}");
elekvault
Posts: 3
Joined: Thu Aug 10, 2023 3:05 pm

Re: Change Conversation Fields on Runtime

Post by elekvault »

Tony Li wrote: Thu Aug 10, 2023 8:34 pm
I assume you meant to type Conversation[1] both times above?
Thanks for you answer. Yes, I meant Conversation[1] both times.

As I said, I have no trouble persisting the value of CurrentStepID, and I'm not using the included Save system, I'm using my own. My problem is only setting the field value, so I'm interested in this you pointed out:
Tony Li wrote: There is no corresponding DialogueLua.SetConversationField(), so you'll need to use Lua.Run():

Code: Select all

Lua.Run($"Conversation[1].CurrentStepID = {id}");
Why is there no DialogueLua.SetConversationField(), the same as for Actor or Quest?
How does the Lua code you put differ from the one I already used?:

Code: Select all

	string luaCode = string.Format("if not Conversation[{0}].{1} then Conversation[{0}].{1} = '{2}' end\n", conversation.id, "CurrentStepID", 1);
        luaCode += string.Format("Conversation[{0}].{1} = '{2}'\n", conversation.id, "CurrentStepID", 1);
        Lua.Run(luaCode, true, true);
It's the same as the second line, isn't it? I tried that and it's not doing anything.
I tried with id as int and id as string as well. I don't know if that's relevant to the Lua interpreter.
User avatar
Tony Li
Posts: 22118
Joined: Thu Jul 18, 2013 1:27 pm

Re: Change Conversation Fields on Runtime

Post by Tony Li »

Hi,

No DialogueLua.SetConversationField() was just an oversight. It'll be in 2.2.40.

Try setting the value as a number, not a string. So instead of:

"Conversation[{0}].{1} = '{2}'\n"

use:

"Conversation[{0}].{1} = {2}\n"

Also, make sure you're running this after the Dialogue System has initialized itself. Maybe your code is running in a Start() method before the Dialogue Manager's DialogueSystemController.Start() has finished. To know when it's initialized, you can either hook into the C# event DialogueManager.instance.initializationComplete or check the Boolean property DialogueManager.instance.isInitialized.
elekvault
Posts: 3
Joined: Thu Aug 10, 2023 3:05 pm

Re: Change Conversation Fields on Runtime

Post by elekvault »

Thank you, Tony! On a first try, it seems waiting for the initializationComplete worked! I was getting the value on a Start() method and maybe I was getting there too soon as you said. I also double-checked and overloaded the methods where I run the Lua code so it uses the proper type (int, bool, string...) for each field and avoid any confussion or miss-type.

Hopefully the rest will be a piece of cake :D
User avatar
Tony Li
Posts: 22118
Joined: Thu Jul 18, 2013 1:27 pm

Re: Change Conversation Fields on Runtime

Post by Tony Li »

Glad to help!
Post Reply