inkjs
inkjs copied to clipboard
Error when calling Continue() when canContinue is true
Describe the bug
I'm attempting to load state json from localStorage. When I do so Ink js crashes.
To Reproduce
load the following json:
'{"flows":{"DEFAULT_FLOW":{"callstack":{"threads":[{"callstack":[{"cPath":"start.0.c-13","idx":5,"exp":true,"type":0}],"threadIndex":36,"previousContentObject":"start.0.c-13.4"}],"threadCounter":36},"outputStream":[],"currentChoices":[]}},"currentFlowName":"DEFAULT_FLOW","variablesState":{"name":"^Portside","ninja":{"list":{"states.dead":2}},"samurai":{"list":{"states.dead":2}}},"evalStack":[],"visitCounts":{"":1,"start":1,"start.0.c-0":1,"start.0.g-0":2,"start.0.c-1":1,"start.0.c-13":1},"turnIndices":{},"turnIdx":2,"storySeed":79,"previousRandom":0,"inkSaveVersion":10,"inkFormatVersion":21}'
run story.Continue()
Expected behavior
no error.
Ink files
just load zip/sandbox/story.json Ink.tar.gz
Environment
Chromebook running latest ChromeOS
At what point of the story did you save ?
Any point, loading a save causes the scenario.
in the root of the sandbox I killed the ninja, then the samurai, and then saved. if thats the context you're looking for.
I can confirm that the included save file does crash, but saving and restoring manually works correctly. The part that seems to cause the crash is this, specifically "idx": 5
(it's 0 in manual saves):
{ "cPath": "start.0.c-13", "idx": 5, "exp": true, "type": 0 }
Path c-13 calls an external function called saveGame
which would be the prime suspect. Can you show the code for that function?
Saving the state while the callstack is still in execution is probably why it's failing.
Have you considered using a tag instead, that would trigger the save after the continue
has finished executing ?
heres the contents of the saveGame function:
story.BindExternalFunction("saveGame", (waypointName) => {
localStorage.setItem('quickSave', story.state.toJson());
console.log("SAVE GAME")
saveMode = true;
return 'Returning to Story...';
}, false)
Thank You! Your comments helped, I came up with a solution to use the saveMode
boolean to call story.state.toJson() after execution is completed.
My problem is fixed, but I would like to offer two suggestions. We are using inkjs in this project and would like it to be a little less fragile.
-
Is there a way to recover from this bad savestate? we don't want end users to get stuck with a broken save state that causes the game to crash. I know we could just wrap it in a try catch block but I also don't want to start the game over if there is a bad save. It would be great if we could have inkjs load what it can and discard what causes errors. (we've already encountered bad saves in our beta which currently dumps state after each choice is made, so things like server crashes or users closing their browser could create corrupt save states.)
-
Also It would be helpful if inkjs would throw an error when attemtping to dump json at the wrong time. If the dumped json will be invalid for restoring the state then I would prefer not to save it in the first place. Would it be possible to throw an error when
story.state.toJson()
is called during execution, or if the resulting json would be corrupt in some other way?