Page 1 of 2
Saving a complex lua variable
Posted: Sat Dec 04, 2021 9:49 pm
by hipsterdufus
Hey there, I have been using DialogueLua.SetVariable to save and load simple data types but I'd like to save a HashSet (I guess in Lua I can use a table?). Is there a way to save and load data structures like arrays or tables instead of just primitives? Thank you.
Re: Saving a complex lua variable
Posted: Sat Dec 04, 2021 10:01 pm
by Tony Li
If you're saving complex data, and if you're using the
save system, I recommend writing a Saver component. Duplicate SaverTemplate.cs and follow the comments on where to add your code. You'll still need to put your data into a format that can be serialized. The save system uses JsonUtility serialization by default, which doesn't serialize HashSets. But you can copy the HashSet into a List.
If you're not using the save system, and if you know the format of your data, you could convert it to a string and store the string in a Lua variable using DialogueLua.SetVariable(). For example:
Code: Select all
string s = string.Join(";", YourHashSet); // Assumes YourHashSet is HashSet<string> of strings w/o semicolons.
DialogueLua.SetVariable("MyHashVar", s);
Re: Saving a complex lua variable
Posted: Sun Dec 05, 2021 1:21 pm
by hipsterdufus
Thanks, converting to a string should work fine. That's a neat trick with string.Join I didn't know about that method.
Another related question I'm having is when I set a lua variable by calling Lua.Run() and providing Variable["MyVariable"] = 1; those variables are not being saved to the Dialogue Database but when I set a variable by calling DialogueLua.SetVariable() those variables are being saved to the Dialogue DB. To clarify - I'm using PersistentDataManager.GetSaveData() to get a string representation of the DialogueDb to save/load it and that's where I'm missing the variables that got set with Variable["x"] but it does have variables that were set at runtime with DialogueLua.SetVariable(). It seems like the variables are set for the session but they just aren't persisted in any way beyond that. Is there a way to set variables in lua code so they are saved to the database?
Re: Saving a complex lua variable
Posted: Sun Dec 05, 2021 2:45 pm
by Tony Li
Variable["MyVariable"] = 1; should work, even if MyVariable isn't already defined in your dialogue database.
Note that indices in the Variable[] table can't have blank spaces or most other punctuation. (
more info)
If you've added a variable named "My Variable" to your dialogue database, the table index will be My_Variable, as in:
Variable["My_Variable"]
DialogueLua.SetVariable("My Variable", 1) will automatically treat "My Variable" as "My_Variable". But if you're running Lua code directly, you must do the translation yourself:
Variable["My_Variable"] = 1
Re: Saving a complex lua variable
Posted: Sun Dec 05, 2021 3:32 pm
by hipsterdufus
Sorry, I was looking at an old file and forgot that I had changed the save file directory! It does appear to be working! Thank you!
Re: Saving a complex lua variable
Posted: Sun Dec 05, 2021 5:10 pm
by Tony Li
Glad it's working!
Re: Saving a complex lua variable
Posted: Mon Dec 06, 2021 12:51 am
by hipsterdufus
Quick follow up question: So I'm trying to create a variable that is a table but I'm not able to get it to work. Here is the syntax I'm trying to use:
I'm adding some data to the table afterwards. Then in my code I'm calling
Code: Select all
DialogueLua.GetVariable("sceneGraph").AsTable;
but it's returning a LuaTableWrapper that says it's not valid and has no values. Am I doing something wrong? Also, I will not be able to easily persist this table correct?
Re: Saving a complex lua variable
Posted: Mon Dec 06, 2021 8:51 am
by Tony Li
The Variable[] table should only contain basic data types, not subtables. (This corresponds with the fact that you can only define basic data types in the Dialogue Editor's Variables section.)
You can, however, create completely new Lua variables that are tables:
Code: Select all
sceneGraph = {};
sceneGraph["Scene1"] = { Filename = "Scene 1", ChallengeRating = 50 }
Keep in mind that, by default, new variables like this won't be included in saved games. Saved games only save the Variable[], Actor[], Item[]/Quest[], and Location[] tables, plus a few other things. However, you can assign a method to PersistentDataManager.
GetCustomSaveData if you want to add other info to the Lua save data.
Re: Saving a complex lua variable
Posted: Mon Dec 06, 2021 10:17 am
by hipsterdufus
I created a table with the syntax you showed but how do I get the table in my C# code afterwards? I cannot use DialogueLua.GetVariable right?
Re: Saving a complex lua variable
Posted: Mon Dec 06, 2021 11:14 am
by Tony Li
Hi,
If you only need a single value, you can use Lua.Run. For example, say you define a table like this:
Code: Select all
Lua.Run("MyTable = { Armor = 'Chainmail', Weapon = 'Sword', Mount = 'Pegasus' }");
Then you can get the table's Weapon element like this:
Code: Select all
string weapon = Lua.Run("return MyTable['Weapon']").asString;
If you need to go through the whole table, get it as a table and loop through keys or values. For example:
Code: Select all
Lua.Run("MyTable = { Armor = 'Chainmail', Weapon = 'Sword', Mount = 'Pegasus' }");
// Get just the weapon element:
string weapon = Lua.Run("return MyTable['Weapon']").asString;
Debug.Log($"weapon = {weapon}");
// Loop through all elements:
var table = Lua.Run("return MyTable").asTable;
foreach (var key in table.keys)
{
var value = table[key];
Debug.Log($"[{key}] = {value}");
}