inkle / inkle/ink

Incorrect choice selected after story state is restored and story script has changed

Open
#545 1 comment 0 reactions 0 assignees View on GitHub
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.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.