get variables from saved without applying to database?

Announcements, support questions, and discussion for the Dialogue System.
joeylu
Posts: 111
Joined: Sun May 17, 2020 1:07 pm

get variables from saved without applying to database?

Post 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] ?
User avatar
Tony Li
Posts: 22133
Joined: Thu Jul 18, 2013 1:27 pm

Re: get variables from saved without applying to database?

Post 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.]
joeylu
Posts: 111
Joined: Sun May 17, 2020 1:07 pm

Re: get variables from saved without applying to database?

Post 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?
User avatar
Tony Li
Posts: 22133
Joined: Thu Jul 18, 2013 1:27 pm

Re: get variables from saved without applying to database?

Post by Tony Li »

No; garbage collection will take care of it since there will be no more references to it.
joeylu
Posts: 111
Joined: Sun May 17, 2020 1:07 pm

Re: get variables from saved without applying to database?

Post 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
User avatar
Tony Li
Posts: 22133
Joined: Thu Jul 18, 2013 1:27 pm

Re: get variables from saved without applying to database?

Post 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);
}
joeylu
Posts: 111
Joined: Sun May 17, 2020 1:07 pm

Re: get variables from saved without applying to database?

Post 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
User avatar
Tony Li
Posts: 22133
Joined: Thu Jul 18, 2013 1:27 pm

Re: get variables from saved without applying to database?

Post 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.
joeylu
Posts: 111
Joined: Sun May 17, 2020 1:07 pm

Re: get variables from saved without applying to database?

Post 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
User avatar
Tony Li
Posts: 22133
Joined: Thu Jul 18, 2013 1:27 pm

Re: get variables from saved without applying to database?

Post 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.
Post Reply