inkle / ink-unity-integration

Unity integration for the open source ink narrative scripting language.
http://www.inklestudios.com/ink
Other
570 stars 99 forks source link

Altered LISTs do not have origins set after LoadJson() #167

Closed russellquinn closed 2 years ago

russellquinn commented 2 years ago

If I have a global LIST, e.g.:

LIST some_list = (none), step_one, step_two, completed

I can get this list from within Unity with:

Ink.Runtime.InkList unityList = story.variablesState["some_list"] as Ink.Runtime.InkList;

And when I do unityList.origins, it is populated and usable. I can also use .all and other properties that depend on origins being populated. All good so far.

If I then do SaveJson() and LoadJson() I can get the list from variablesState again, and origins is populated just like before. Still… all good.

However, if the Ink script has changed the value of some_list before the save, e.g.:

~ some_list = step_one

And then I SaveJson() and LoadJson(), when I get the list from variablesState this time, .origins is null.

.origins remains null until the Ink script encounters some code that evaluates this list. (It can be assigning a new value or just checking its contents.) Then origins gets populated once again.

From stepping through the code in ink-unity-integration, it looks like StoryState::PushEvaluationStack(Runtime.Object obj) is responsible for populating origins and I think this is where the problem lies.

When an Ink Story is first loaded from C#, PushEvaluationStack gets called on every global var, thus populating origins in all the lists. If you then do a LoadJson(), and the List value hasn't changed, this initial init is still valid and everything works. But, if the value has changed, it looks like the list is re-created in memory as a new object and this time, PushEvaluationStack does not get called (until it is later referenced in executed Ink code).

In summary, I think the problem in ink-unity-integration might be:

  1. PushEvaluationStack is called on all global Ink vars at the start.
  2. After a LoadJson(), it looks like LISTs that no longer have their default value are re-created in memory.
  3. But, PushEvaluationStack is not called on these, leaving them not fully initialized.
russellquinn commented 2 years ago

This is an Ink Runtime issue, so I'm moving it to that project instead. It's now here: https://github.com/inkle/ink/issues/763