Incorrect choice selected after story state is restored and story script has changed
- Dominant language
- C#
- Stars
- 4.9k
- Forks
- 540
- PR merge metrics
- No merged PRs in 30d
Description
Have an issue where Ink selects the incorrect choice if a story state is restored between different versions of a story.
**Story version 1 ( story with three options)**
```
VAR conversation_has_completed_at_least_once = false
-> start
=== start ====
-> all_intents
= all_intents
+ [OneIntent] -> option_one
+ [TwoIntent] -> option_two
+ [ThreeIntent] -> option_three
= option_one
You chose option one
-> restart_conversation
= option_two
You chose option two
+ [OneIntent] -> option_one
+ [TwoIntent] -> option_two
-> restart_conversation
= option_three
You chose option three
-> restart_conversation
=== restart_conversation ===
~ conversation_has_completed_at_least_once = true
-> start
```
**Story version 2 ( story with a new option)**
```
VAR conversation_has_completed_at_least_once = false
-> start
=== start ====
-> all_intents
= all_intents
+ [OneIntent] -> option_one
+ [NewIntent] -> option_new
+ [TwoIntent] -> option_two
+ [ThreeIntent] -> option_three
= option_one
You chose option one
-> restart_conversation
= option_two
You chose option two
+ [OneIntent] -> option_one
+ [TwoIntent] -> option_two
-> restart_conversation
= option_new
You chose option new
+ [OneIntent] -> option_one
+ [ThreeIntent] -> option_three
-> restart_conversation
= option_three
You chose option three
-> restart_conversation
=== restart_conversation ===
~ conversation_has_completed_at_least_once = true
-> start
```
**Test code**
- This code loads story version 1 (three options) and selects the "ThreeIntent" option twice. Story text generates as expected.
- It then mimics saving the story state as a save game
- It then loads story 2 (which has one new option) and restores the story state
- It then selects the "ThreeIntent" option again. **It breaks here by generating the incorrect text saying "You chose option two\n" instead of "You chose option three\n"**
A couple of things to note:
- No warnings or errors are generated to indicate that the story state was not correctly restored (as documented in the V0.8.1 release notes)
- If you uncomment the Debug.Log statement in selectChoice() you can see that the list of choices returned by currentChoices() does not include "NewIntent" when story 2 runs. If you comment out the LoadJson() line (and don't restore the story state) then currentChoices() does include "NewIntent" when story 2 runs.
```
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
using Ink.Runtime;
public class TestInkSession : MonoBehaviour
{
public TextAsset storyThreeOptionsJson;
public TextAsset storyNewOptionsJson;
// play the story through to next set of choices, logging warns and errors
string playStory(Story story)
{
string outText = "";
while (story.canContinue)
{
outText += story.Continue();
if (story.hasWarning)
{
Debug.LogWarning(story.currentWarnings);
}
if (story.hasError)
{
Debug.LogError(story.currentErrors);
}
}
//Debug.Log("Out text:" + outText);
return outText;
}
// select a choice based on its text
void selectChoice(Story story, string choiceText)
{
for (int i = 0; i < story.currentChoices.Count; i++)
{
//Debug.Log(" Choice " + i + ":" + story.currentChoices[i].text);
if (story.currentChoices[i].text == choiceText)
{
story.ChooseChoiceIndex(i);
return;
}
}
throw new Exception("Choice " + choiceText + " not found");
}
// simple string quals assert
void assertEquals(string generated, string expected)
{
if (generated != expected)
{
throw new Exception("Expected :'" + expected + "' got '" + generated +"'");
}
}
void Start()
{
// load first version of story
Story threeOptionsStory = new Story(storyThreeOptionsJson.text);
assertEquals(playStory(threeOptionsStory),"");
selectChoice(threeOptionsStory, "ThreeIntent");
assertEquals(playStory(threeOptionsStory), "You chose option three\n");
selectChoice(threeOptionsStory, "ThreeIntent");
assertEquals(playStory(threeOptionsStory), "You chose option three\n");
// serialize out story state to simulate save game
string storyState = threeOptionsStory.state.ToJson();
// load second version of story
Story newOptionsStory = new Story(storyNewOptionsJson.text);
// deserialize story state from 'save game'
newOptionsStory.state.LoadJson(storyState);
assertEquals(playStory(newOptionsStory), "");
selectChoice(newOptionsStory, "ThreeIntent");
// ***** This fails. Story generates "You chose option two\n"
assertEquals(playStory(newOptionsStory), "You chose option three\n");
}
}
```
**Tested with**
- Unity 2018.4.7f1 (latest LTS version)
- v0.9.1 of Inkle Ink package from Unity Asset store (released 30 Jul 2019)
Also occurs with blade-ink v0.6.0 Java port of Ink that is based on Ink v0.8.3
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.