ink
ink copied to clipboard
How to Save/Load state
Hi,
I cannot achieve to save/load state of my ink stories. I have used inky to write my story, and integrated it in Unity 3d, with the blot example. Everything works fine, but I don't know how to save/load the state of the game. In the manual says:
_Saving and loading To save the state of your story within your game, call: string savedJson = _inkStory.state.ToJson(); ...and then to load it again: inkStory.state.LoadJson(savedJson);
But I don't know what to do with it. Do I have to create a script?
Sorry, I don't know anything about programming, but it's the last thing I need to finish my project and don't make the player to start all over again everytime he runs the game.
Thank you very much.
JL Lopez Morales
Yep, I'm afraid you need to do a bit of scripting. I'd suggest saving the state using Unity's PlayerPrefs.
So, for example, when you first start the game (e.g. when you create your ink story object), try to load a saved game like this:
if( PlayerPrefs.HasKey("inkSaveState") ) {
var savedState = PlayerPrefs.GetString("inkSaveState");
inkStory.state.LoadJson(savedState);
}
Then, every time the player makes a choice, save the state:
var savedState = _inkStory.state.ToJson();
PlayerPrefs.SetString("inkSaveState", savedState);
You'll also need a way to clear the saved game though, in case the player wants to start again from scratch, or perhaps if you get to an ending. To do that, you can clear the PlayerPrefs
, as well as reset the ink story:
PlayerPrefs.DeleteKey("inkSaveState");
_inkStory.ResetState()
Thank you very much for your answer. I will try to do as you say, even I didn't used before the PlayerPrefs. it's a pity that inky doen't have a save/load function, so everything would be easier.
@joethephish Hi Joe, thanks for your explanation. I understand that's the code I need to copy/paste in my C# script. However how do I call it from ink? So let's say the character dies and I give him two options: "Start from last checkpoint" and "Start over". For the first choice I have to call your first piece of code and go back to the respective knot in ink, right? For starting over I have to call your third piece of code and go back to the very first knot in ink. Also, I want to save the game only at selected checkpoints, for that I would create a method Checkpoint() with your second piece of code I guess.
But now the question is - how do I call the methods from ink? I found the following:
- Declare an external function using something like this at the top of one of your ink files, in global scope: EXTERNAL multiply(x,y)
- Bind your C# function. For example: _inkStory.BindExternalFunction ("multiply", (int arg1, float arg2) => { return arg1 * arg2; });
The second one I don't quite understand. If I have for example a function called Checkpoint() (for saving the game state) in the story.cs script (which runs everything related to ink), how would I call it exactly?
External functions aren't a good idea in this situation since they're called in the middle of the ink running, which would be dangerous and probably wouldn't work. The best way is to simply have some special pure text in your story. For example:
== new_chapter ==
CHECKPOINT
You arrive in a cave.
* Start from last checkpoint -> back_to_checkpoint
* Start over -> start_over
== start_over
ENDING
-> END
== back_to_checkpoint
BACK TO CHECKPOINT
-> END
Where you make your calls to story.Continue()
etc, add a thing that checks for the specific strings CHECKPOINT
, ENDING
, and BACK TO CHECKPOINT
. And if it sees one, call your C# specific code.
This is the best way since the ink engine is in a stable state (not in the middle of evaluating) at the point where you read those strings in.
This Load is work for me
string savedJson; void Start(){ // or your start for story if (PlayerPrefs.HasKey("inkSaveState")) {
story = new Story(inkJSONAsset.text);
savedJson = PlayerPrefs.GetString("inkSaveState");
story.state.LoadJson(savedJson);
Debug.Log(savedJson);
RefreshView(); // or refresh();
}
else
{
story = new Story(inkJSONAsset.text);
//RefreshView();
}
} save :
savedJson = story.state.ToJson(); PlayerPrefs.SetString("inkSaveState", savedJson);