Page 1 of 1
SetInkList Appears to be Incorrectly Implemented
Posted: Wed Feb 28, 2024 3:29 am
by ryanscottmurphy
Hi Pixel Crushers/Tony,
I'm going a little bit deeper with my Ink/Dialogue System use in Ink and I noticed that the current behaviour attempts to set the List value using only a string object (which fails). I've investigated a little bit, and so far this is my current fix, which at least appears to set the InkList correctly.
DialogueSystemIntegration.cs
Code: Select all
public static void SetInkList(string variableName, string value)
{
// This is good but doesn't account for adding/removing/replacing lists.
Story story = instance.stories[0];
string[] arr = value.Split(',');
InkList newList = story.variablesState[variableName] as Ink.Runtime.InkList ?? new InkList();
foreach (string a in arr)
{
string itemName = a.Trim();
if (itemName.Trim().Contains('.'))
newList.AddItem(new InkListItem(itemName));
else
newList.AddItem(new InkListItem(variableName, itemName));
}
if (m_instance != null) m_instance.SetInkVariableValue(variableName, newList);
}
I wanted to make a post and question some of my assumptions/understandings so far.
Firstly, am I correct that setting lists was implemented, but probably not working correctly? (So far, I think I am correct, but I could be missing something).
Is the intention/assumption of the DialogueSystemIntegration that all interactions in Ink should go through the DialogueSystemIntegration layer so that the Lua script is correctly notified or is this not necessary?
In DialogueSystemIntegration.cs, I've noticed that most Set/Get functions have the following loop:
I'm not really sure what the utility of having multiple stories in a single application is right now, but I'm wondering if you have an opinion about that. Is the assumption that separate stories would/should mirror each other's use of global variables, or at least not share names of global variables across stories?
My thought process is that SetInkList functionality should probably be replaced by Add, Subtract and Intersect behaviour as documented in the Ink.Runtime.InkList class, unless the intention is to interface directly with InkLists as needed. If so I'll probably write that for my own use and drop that here, but your insights are really appreciated so that I know that I'm going in the right direction.
Re: SetInkList Appears to be Incorrectly Implemented
Posted: Wed Feb 28, 2024 9:47 am
by Tony Li
Hi,
Thanks for the detailed writeup. I'll take a look at this and get back to you.
Re: SetInkList Appears to be Incorrectly Implemented
Posted: Wed Feb 28, 2024 11:16 am
by ryanscottmurphy
In the interest of sparing you some time, here is a solution I've made that inserts the Lists correctly, but I haven't got a clear enough understanding of the framework yet to know whether it's best to maintain the DialogueSystemIntegration layer, or whether I should just interface directly with Ink.
I assume that the value of putting it at the DialogueSystemIntegration layer is that I can add Lua functions that are usable from Dialogue System scripts.
Feel free to use this if you think it's on the right track, as it will save me patching it in for myself over and over with updates, though I suppose I can derive my own class over the top of yours if necessary:
Code: Select all
protected static InkList InkListFromCommaSeparatedString(string variableName, string value, Story story)
{
string[] arr = value.Split(',');
InkList list = new InkList(variableName, story);
foreach (string a in arr)
{
string itemName = a.Trim();
if (itemName.Trim().Contains('.'))
list.AddItem(new InkListItem(itemName));
else
list.AddItem(new InkListItem(variableName, itemName));
}
return list;
}
public static void AddInkList(string variableName, string value)
{
InkList newList = null;
foreach (var story in instance.stories)
{
if (story.variablesState.GlobalVariableExistsWithName(variableName))
{
InkList newValues = InkListFromCommaSeparatedString(variableName, value, story);
InkList currentList = story.variablesState[variableName] as Ink.Runtime.InkList;
newList = currentList != null ? currentList.Union(newValues) : newValues;
}
}
if (newList == null) return;
if (m_instance != null) m_instance.SetInkVariableValue(variableName, newList);
}
public static void SubtractInkList(string variableName, string value)
{
InkList newList = null;
foreach (var story in instance.stories)
{
if (story.variablesState.GlobalVariableExistsWithName(variableName))
{
InkList values = InkListFromCommaSeparatedString(variableName, value, story);
InkList currentList = story.variablesState[variableName] as Ink.Runtime.InkList;
newList = currentList != null ? currentList.Without(values) : values;
}
}
if (newList == null) return;
if (m_instance != null) m_instance.SetInkVariableValue(variableName, newList);
}
public static void IntersectInkList(string variableName, string value)
{
InkList newList = null;
foreach (var story in instance.stories)
{
if (story.variablesState.GlobalVariableExistsWithName(variableName))
{
InkList values = InkListFromCommaSeparatedString(variableName, value, story);
InkList currentList = story.variablesState[variableName] as Ink.Runtime.InkList;
newList = currentList != null ? currentList.Intersect(values) : values;
}
}
if (newList == null) return;
if (m_instance != null) m_instance.SetInkVariableValue(variableName, newList);
}
public static void SetInkList(string variableName, string value)
{
InkList newList = null;
foreach (var story in instance.stories)
{
if (story.variablesState.GlobalVariableExistsWithName(variableName))
{
newList = InkListFromCommaSeparatedString(variableName, value, story);
}
}
if (m_instance != null) m_instance.SetInkVariableValue(variableName, newList);
}
Re: SetInkList Appears to be Incorrectly Implemented
Posted: Wed Feb 28, 2024 7:20 pm
by Tony Li
Hi,
Thanks again for the code. I looked it over and added it to the integration. The RegisterLuaFunctions() method is now:
Code: Select all
protected virtual void RegisterLuaFunctions()
{
if (m_registeredLuaFunctions) return;
m_registeredLuaFunctions = true;
Lua.RegisterFunction(nameof(SetInkBool), null, SymbolExtensions.GetMethodInfo(() => SetInkBool(string.Empty, false)));
Lua.RegisterFunction(nameof(SetInkNumber), null, SymbolExtensions.GetMethodInfo(() => SetInkNumber(string.Empty, (double)0)));
Lua.RegisterFunction(nameof(SetInkString), null, SymbolExtensions.GetMethodInfo(() => SetInkString(string.Empty, string.Empty)));
Lua.RegisterFunction(nameof(SetInkList), null, SymbolExtensions.GetMethodInfo(() => SetInkList(string.Empty, string.Empty)));
Lua.RegisterFunction(nameof(AddInkList), null, SymbolExtensions.GetMethodInfo(() => AddInkList(string.Empty, string.Empty)));
Lua.RegisterFunction(nameof(SubtractInkList), null, SymbolExtensions.GetMethodInfo(() => SubtractInkList(string.Empty, string.Empty)));
Lua.RegisterFunction(nameof(IntersectInkList), null, SymbolExtensions.GetMethodInfo(() => IntersectInkList(string.Empty, string.Empty)));
Lua.RegisterFunction(nameof(GetInkBool), null, SymbolExtensions.GetMethodInfo(() => GetInkBool(string.Empty)));
Lua.RegisterFunction(nameof(GetInkNumber), null, SymbolExtensions.GetMethodInfo(() => GetInkNumber(string.Empty)));
Lua.RegisterFunction(nameof(GetInkString), null, SymbolExtensions.GetMethodInfo(() => GetInkString(string.Empty)));
Lua.RegisterFunction(nameof(GetInkList), null, SymbolExtensions.GetMethodInfo(() => GetInkList(string.Empty)));
}
and the functions will behave exactly as in your version, so when you update it should continue to work exactly the same.
Running Ink through the Dialogue System integration lets you tie into the Dialogue System's dialogue UI properly, specify different actors for different lines, run sequences, and receive the Dialogue System's special messages such as OnConversationStart and OnConversationEnd.
Most Ink + Dialogue System users run a single story, typically split across many files using INCLUDE directives. But some do use multiple separate stories, so we support both options.
Re: SetInkList Appears to be Incorrectly Implemented
Posted: Wed Feb 28, 2024 9:47 pm
by ryanscottmurphy
Running Ink through the Dialogue System integration lets you tie into the Dialogue System's dialogue UI properly, specify different actors for different lines, run sequences, and receive the Dialogue System's special messages such as OnConversationStart and OnConversationEnd.
Okay! Good, I didn't want to be adding code to the integration if it wasn't adding any value.
Most Ink + Dialogue System users run a single story, typically split across many files using INCLUDE directives. But some do use multiple separate stories, so we support both options.
I suspected this was the case! Thank you for clarifying. I'm not sure if it's preferable to look for the currently active story or if traversing all stories is best...
For now it works for me, so I'm satisfied, but if it can be improved I'm all about it.
I noticed that registering these Ink specific functions here doesn't appear to add them to the Lua Condition Wizard, is there somewhere I can look if I'm interested in adding that?
As an aside, is there a method for removing the Actions from the DialogueSystemTrigger or DialogueSystemInkTrigger? Once I add them, I can't seem to remove them without removing the whole component and remaking it.
Re: SetInkList Appears to be Incorrectly Implemented
Posted: Thu Feb 29, 2024 12:07 pm
by Tony Li
Hi,
I'll post the updated Ink Support package here later today. To make functions available to the Conditions and Script Lua wizards, they need to be added to a
Custom Lua Function Info asset. The updated Ink Support package's Custom Lua Function Info asset has all of the Ink-related functions in it.
For the Dialogue System Trigger, you can generally either click an 'x' to remove the action (such as with Bark or Start Conversation) or just clear the contents of the action (such as the OnExecute() UnityEvent). Then next time to return to the Dialogue System Trigger in the inspector, that action will no longer be shown.
Re: SetInkList Appears to be Incorrectly Implemented
Posted: Thu Feb 29, 2024 4:11 pm
by Tony Li
Here's the updated Ink Support package:
DS_InkSupport_2024-02-28.unitypackage
Re: SetInkList Appears to be Incorrectly Implemented
Posted: Sun Mar 03, 2024 11:14 pm
by ryanscottmurphy
You're so incredibly prompt and responsive Tony, thanks so much for your help!
Re: SetInkList Appears to be Incorrectly Implemented
Posted: Mon Mar 04, 2024 9:28 am
by Tony Li
Thanks! Glad to help!