inkle / inkle/ink

HasFunction method evaluates regular knots as True

Open
#928 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
4.9k
Forks
540
PR merge metrics
No merged PRs in 30d

Description

### Context:

Original issue was posted on the unity integration repo, and was requested to be reposted here.
https://github.com/inkle/ink-unity-integration/issues/209

I have two ink containers, one a regular knot, and the other a function:

```
=== goblin_talk ===
...

=== function has_revived ===
...
```
If I call upon `Story.cs`'s method `HasFunction`, it evaluates both `goblin_talk` and `has_revived` as `True` (and therefore functions).

This seems to me as incorrect. `goblin_talk` is a regular knot and should evaluate to `False`, while `has_revived` is a function knot and should evaluate to `True`.

This can lead to accidentally attempting to evaluate a non-function knot which then results with the following exception:
```
Exception: Expected external function evaluation to be complete. Stack trace: === THREAD 1/1 (current) ===
[TUNNEL]
Ink.Runtime.StoryState.CompleteFunctionEvaluationFromGame () (at Assets/Ink/InkLibs/InkRuntime/StoryState.cs:1265)
Ink.Runtime.Story.EvaluateFunction (System.String functionName, System.String& textOutput, System.Object[] arguments) (at Assets/Ink/InkLibs/InkRuntime/Story.cs:1868)
Ink.Runtime.Story.EvaluateFunction (System.String functionName, System.Object[] arguments) (at Assets/Ink/InkLibs/InkRuntime/Story.cs:1822)
Core.StoryManager.EvaluateFunction (System.String function, System.Object[] arguments) (at Assets/Scripts/Nosfuratu/Managers/StoryManager.cs:404)
```

### Problem:

I'm looking at the `HasFunction` defined in `Story.cs`. It looks like it's not exclusive to just functions, and actually returns True for values that represent regular knots (not functions).

Looking at the implementation of the method, this makes sense as it is calling upon `KnotContainerWithName` which in turn is just searching the contents of the main container:
```
public bool HasFunction (string functionName)
{
try {
return KnotContainerWithName (functionName) != null;
} catch {
return false;
}
}

...

public Runtime.Container KnotContainerWithName (string name)
{
INamedContent namedContainer;
if (mainContentContainer.namedContent.TryGetValue (name, out namedContainer))
return namedContainer as Container;
else
return null;
}
```
Is this an oversight?

### Attempted Solutions:

Looking at the containers themselves, there doesn't really seem to be a clear way to discern if a container is a regular Knot or a Function. The only thing I can see is that if I search within the contents of the container, Functions tend to have a `ControlCommand` entry labeled `PopFunction`

This may be one way to discern, but seems hacky. Not sure if that `PopFunction` could appear elsewhere other than an explicit function knot.

I've posted a pull request with this solution here:
https://github.com/inkle/ink/pull/927

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.