Threaded choice divert param retains original argument after loading StoryState JSON
- Dominant language
- C#
- Stars
- 4.9k
- Forks
- 540
- PR merge metrics
- No merged PRs in 30d
Description
The divert parameter (e.g. `-> goback`) of a threaded choice is not stored correctly when converted to/from JSON.
The second time a choice inside the thread is chosen (with a different argument for `-> goback`), the Ink script incorrectly redirects to the original `-> goback` argument ... which should no longer exist!
**A failing C# NUnit test is included below** that passes only if the save/load StoryState JSON portion is commented out. This may be related to an earlier issue I originally reported via blade-ink (which was graciously resolved with a one-liner!): https://github.com/inkle/ink/issues/267
This issue is important because it prevents using the same thread in multiple knots.
**To reproduce:**
```
-> start
=== common_choices(-> goback) ===
+ No
Try again. <>
-> goback
=== start ===
Choice ONE?
<- common_choices(-> start) # First, select 'No'
+ Yes # Second, select 'Yes' then save/load StoryState JSON
-> asktwo
=== asktwo ===
Choice TWO?
<- common_choices(-> asktwo) # Third, select 'No'. It incorrectly diverts to 'start'!
+ Yes
You win!
-> END
```
Read the Ink script comments above to understand the issue most clearly, following the steps 1-3 when running the story. **If save/load to JSON is removed, the script works correctly.** This indicates the problem is with the save/load to JSON. If additional explanation is required, see the NUnit test below.
**C# Failing NUnit Test:**
```cs
[Test()]
public void TestThreadedChoiceParamJSON()
{
String inkStory = @"
-> start
=== common_choices(-> goback) ===
+ No
Try again. <>
-> goback
=== start ===
Choice ONE?
<- common_choices(-> start)
+ Yes
-> asktwo
=== asktwo ===
Choice TWO?
<- common_choices(-> asktwo)
+ Yes
You win!
-> END
";
Story story = CompileString(inkStory);
Assert.AreEqual("Choice ONE?\n", story.ContinueMaximally());
/** This threaded choice point must be visited twice for the error to occur (on the second visit).
* - Here, it correctly redirects back to 'start'.
* - Next time, it should redirect back to 'asktwo'. But, it incorrectly redirects to 'start' instead! **/
story.ChooseChoiceIndex(0); // start -> No (in thread)
Assert.AreEqual("No\nTry again. Choice ONE?\n", story.ContinueMaximally());
story.ChooseChoiceIndex(1); // start -> Yes (in knot)
Assert.AreEqual("Yes\nChoice TWO?\n", story.ContinueMaximally());
/** If these lines saving StoryState to/from JSON are commented out, the test passes as expected. **/
String savedStateJson = story.state.ToJson();
story = CompileString(inkStory);
story.state.LoadJson(savedStateJson);
/*******/
// ERROR If 0 - should redirect to 'asktwo', but it redirects back to 'start'! (only if state loaded from JSON)
// - #0 is a previously visited threaded choice
// NORMAL If 1 - always correctly ends the script
story.ChooseChoiceIndex(0); // asktwo -> No (in thread) ... should redirect back to asktwo
Assert.AreEqual("No\nTry again. Choice TWO?\n", story.ContinueMaximally());
Assert.IsFalse(story.hasError);
}
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.