Page 1 of 2
get variables from saved without applying to database?
Posted: Fri Mar 10, 2023 10:58 am
by joeylu
Hi Tony
In my project, I use PersistentDataManager.ApplySaveData(PlayerPrefs.GetString(slotname)) to apply all variables, items, actor, etc to dialogue database, that works perfectly.
However, say if I need to debug something during developing, I want to get Variables or Items that has saved in on slot(string), and analyze those data without append them to Dialogue Database, is it possible?
Something like PersistentDataManager.GetSaveData.Variables[var_name] ?
Re: get variables from saved without applying to database?
Posted: Fri Mar 10, 2023 12:33 pm
by Tony Li
Hi,
You can create a temporary Lua environment (see the Lua.cs class), feed it the save data, and then get the variable value. Example:
Code: Select all
var tempLuaEnvironment = Language.Lua.LuaInterpreter.CreateGlobalEnviroment();
Language.Lua.LuaInterpreter.Interpreter("Actor = {}; Item = {}; Quest = Item; Location = {}; Conversation = {}; Variable = {}; Variable[\"Alert\"] = \"\"", tempLuaEnvironment);
Language.Lua.LuaInterpreter.Interpreter(saveData, tempLuaEnvironment);
var variableValue = new Lua.Result(Language.Lua.LuaInterpreter.Interpreter("return Variable['Foo']", tempLuaEnvironment));
bool boolValue = variableValue.asBool;
Or just search through the save data string if you prefer.
[EDIT: Added line to initialize Lua tables.]
Re: get variables from saved without applying to database?
Posted: Sat Mar 11, 2023 10:14 am
by joeylu
tks, that work
a follow up question, once I get what I need from that temporary Lua environment, do I need to do anything to dispose/destroy the temporary Lua environment?
Re: get variables from saved without applying to database?
Posted: Sat Mar 11, 2023 10:16 am
by Tony Li
No; garbage collection will take care of it since there will be no more references to it.
Re: get variables from saved without applying to database?
Posted: Sat Mar 11, 2023 10:27 am
by joeylu
Sorry but I got another issue after I call the temp environment in runtime
I got error when running the second line (filling saveData)
Code: Select all
var tempLuaEnvironment = Language.Lua.LuaInterpreter.CreateGlobalEnviroment();
Language.Lua.LuaInterpreter.Interpreter(saveData, tempLuaEnvironment);
Error Message:
Exception: Lookup of field 'test_data' in the table element failed because the table element itself isn't in the table.
test_data is an Item (marked as a quest item)
The saveData string:
Item["test_data"].State="active";
any idea? tks
Re: get variables from saved without applying to database?
Posted: Sat Mar 11, 2023 11:28 am
by Tony Li
I just added a line of code to my post above:
Code: Select all
Language.Lua.LuaInterpreter.Interpreter("Actor = {}; Item = {}; Quest = Item; Location = {}; Conversation = {}; Variable = {}; Variable[\"Alert\"] = \"\"", tempLuaEnvironment);
This line initializes the DS tables.
If your Dialogue Manager's Persistent Data Settings > Include All Item Data checkbox is unticked, you'll also need to initialize the Item table further:
Code: Select all
foreach (var item in DialogueManager.masterDatabase.items)
{
Language.Lua.LuaInterpreter.Interpreter($"Item['{DialogueLua.StringToTableIndex(item.Name)}'] = {{ Name='{item.Name}' }}", tempLuaEnvironment);
}
Re: get variables from saved without applying to database?
Posted: Sun Mar 12, 2023 1:21 am
by joeylu
Hi Tony, I'm still getting an error after adding the additional line
NullReferenceException: Cannot assign to a null value. Are you trying to assign to a nonexistent table element?
I think it has something to do with the Item={} part, from the savedData string, there is no Item={...}, it's not like Variable={...} or Actor={...}, all items are saved as a single object in the savedString, something like
Code: Select all
Item["test_item"] = {}
Item["test_quest"] = {}
Item["test_something"] = {}
ps: The nullable exception error occurs whether or not ticking the "Include All item" checkbox, and adding the additional
Code: Select all
foreach (var item in DialogueManager.masterDatabase.items)
{
Language.Lua.LuaInterpreter.Interpreter($"Item['{DialogueLua.StringToTableIndex(item.Name)'] = { Name='{item.Name}' }", tempLuaEnvironment);
}
doesn't make any difference
Re: get variables from saved without applying to database?
Posted: Sun Mar 12, 2023 12:03 pm
by Tony Li
Hi,
Here's a complete test script:
Code: Select all
using UnityEngine;
using PixelCrushers.DialogueSystem;
public class TestLua : MonoBehaviour
{
string saveData;
void Update()
{
if (Input.GetKeyDown(KeyCode.F1))
{
saveData = PersistentDataManager.GetSaveData();
Debug.Log(saveData);
}
else if (Input.GetKeyDown(KeyCode.F2))
{
var tempLuaEnvironment = Language.Lua.LuaInterpreter.CreateGlobalEnviroment();
Language.Lua.LuaInterpreter.Interpreter("Actor = {}; Item = {}; Quest = Item; Location = {}; Conversation = {}; Variable = {}; Variable[\"Alert\"] = \"\"", tempLuaEnvironment);
foreach (var item in DialogueManager.masterDatabase.items)
{
var itemIndex = DialogueLua.StringToTableIndex(item.Name);
Language.Lua.LuaInterpreter.Interpreter($"Item['{itemIndex}'] = {{ Name='{item.Name}' }}", tempLuaEnvironment);
}
Language.Lua.LuaInterpreter.Interpreter(saveData, tempLuaEnvironment);
var variableValue = new Lua.Result(Language.Lua.LuaInterpreter.Interpreter("return Variable['enemiesKilled']", tempLuaEnvironment));
Debug.Log($"enemiesKilled: {variableValue.asInt}");
}
}
}
I added it to DemoScene1 and played the scene.
Pressing [F1] gets the save data, which includes a variable named "enemiesKilled".
Pressing [F2] (after pressing [F1]) extracts the value of "enemiesKilled" from the save data and logs the value to the Console.
p.s. - I fixed a couple of typos in the 'for' loop of my previous reply.
Re: get variables from saved without applying to database?
Posted: Wed Mar 15, 2023 10:26 am
by joeylu
Hi Tony, tks for the reply
I'm still getting the same null error from lua
one thing that I can think of is that in my savedData, items records are like this:
Code: Select all
Item["test_Data"].State="active";
Item["test_Data"].Track=true;
Item["test_Data"].Entry_1_State="active";
Item["test_2_Data"].State="unassigned";
Item["test_2_Data"].Track=true;
Item["test_2_Data"].Entry_1_State="active";
and the for loop you provided are a bit unmatch with the above structure, would this causing the problem? tks
Re: get variables from saved without applying to database?
Posted: Wed Mar 15, 2023 10:55 am
by Tony Li
As long as that 'for' loop -- foreach (var item in DialogueManager.masterDatabase.items) -- is running before your save data, it should be fine.
Try adding my test script to DemoScene2. Then play the scene, press [F1] to save the data, and [F2] to get the "enemiesKilled" variable from the saved data without applying it to the database.