Save & Load
The StoryFlow Editor Unity package saves global variables, character state, Data Asset changes and once-only option tracking across play sessions. All slot operations go through StoryFlowManager.Instance.
Overview
StoryFlow saves are story checkpoints, not mid-sentence bookmarks. They capture the cumulative result of all player choices - variable values, used options, character modifications - but not the current position in a dialogue tree. Your game is responsible for knowing which script to start when loading a save, typically by storing a "current scene" identifier in a global variable.
Checkpoint Model
Save between dialogues, not during them. The system is designed for "between conversation" checkpoints. A common pattern is to create a global string variable called currentScene and update it each time the player enters a new scene. On load, read this variable and use it to start the correct script.
Saving
Call SaveToSlot on the manager singleton to serialize the current global state to a named save slot:
bool success = StoryFlowManager.Instance.SaveToSlot("slot1");
if (success)
{
Debug.Log("Save successful.");
} Parameters:
slotName(string) - The name of the save slot. Can be any non-empty string.
Returns: bool - true if the save was written successfully, false if an error occurred.
Saving during active dialogue
SaveToSlot will succeed while dialogue is active. Local script variables (which are per-script and transient) are not included in the save. Only global state is persisted. If you need a clean save, wait until the dialogue session ends.
Loading
Call LoadFromSlot to read a save file and replace the current global state with the saved values:
bool success = StoryFlowManager.Instance.LoadFromSlot("slot1");
if (success)
{
Debug.Log("Load successful. Start the appropriate script now.");
// Read a global variable to know which script to resume
// component.StartDialogue("scripts/chapter2");
}
else
{
Debug.Log("Load failed. Slot may not exist or dialogue is active.");
} Returns: bool - true if the load succeeded, false if the slot does not exist, deserialization failed, or a dialogue is currently active.
Loading refuses while dialogue is active
LoadFromSlot checks whether any StoryFlowComponent currently has an active dialogue. If so, the load is rejected and the function returns false. This prevents a class of bugs where:
- Variable values change underneath a running script, causing incorrect branching
- Character data is swapped mid-dialogue, producing mismatched names or portraits
- Once-only option state is cleared while the player is viewing those options
Always ensure all dialogues are stopped before attempting to load:
var manager = StoryFlowManager.Instance;
if (manager.IsDialogueActive())
{
Debug.LogWarning("Cannot load while dialogue is active.");
return;
}
bool success = manager.LoadFromSlot("slot1"); Managing Save Slots
Two utility methods let you check for existing saves and delete them:
var manager = StoryFlowManager.Instance;
// Check if a save exists
bool exists = manager.DoesSaveExist("slot1");
// Delete a save
manager.DeleteSave("slot1"); These are useful for building save slot UIs - gray out empty slots, show confirmation dialogs before deleting, and enable or disable a "Continue" button based on whether a save exists.
What Gets Saved
When you call SaveToSlot, the following data is serialized into a JSON file:
- Global variable values - All project-level variables with their current values, including arrays of any type. On load, variables are matched by ID and only the
Valuefield is updated, preserving the variable's metadata from the project asset. - Global map variables - Map variables round-trip through save slots, including entry order.
- Character state - Modified character variables, names and images. Saves match characters by runtime path and custom variables by name. Stable IDs in project exports do not migrate old save entries when you rename a character file.
- Data Asset changes - Runtime values written to Data Assets, including arrays and maps.
- Once-only option tracking - The set of
nodeId-optionIdkeys for dialogue options that have been used and should not appear again.
Fixed in v1.2.0: Array Save/Load
Before 1.2.0, array variables did not survive save/load: the save path wrote garbage values that loaded back as empty arrays. Arrays now round-trip correctly, numeric elements are safe under comma-decimal cultures and legacy saves load exactly as before.
The following data is not saved:
- Local script variables - These are per-script and reset every time a script is entered. They are transient by design.
- Current dialogue position / execution state - The current node, call stack, and flow stack are not persisted.
- Audio playback state - Any currently playing dialogue audio is not captured.
- Language choice - Store the player's language in your game's settings and restore it with
SetLanguage.
Save compatibility
The current plugin can load save slots from earlier plugin releases. A save written by the current plugin uses the unified state format, so older plugin releases cannot read it. Keep the plugin updated across your project.
Custom Save Storage
ExportState() returns the same story state used by a slot save as a JSON string. ImportState(json) applies it after dialogues have stopped. Use these methods when your game already owns a save file or needs to move state through its own storage system. Keep Unity file I/O in your game's save layer.
var manager = StoryFlowManager.Instance;
string storyState = manager.ExportState();
// Store storyState with your game's save data.
// After stopping active dialogues:
bool loaded = manager.ImportState(storyState); Save Location
Save files are written to:
Application.persistentDataPath/StoryFlow/Saves/{slotName}.json The directory is created automatically if it does not exist. The save format is JSON. The current plugin also accepts older Unity saves when loading.
// Example save file path on Windows:
// C:/Users/{user}/AppData/LocalLow/{company}/{product}/StoryFlow/Saves/slot1.json
// Example save file path on macOS:
// ~/Library/Application Support/{company}/{product}/StoryFlow/Saves/slot1.json Resetting State
The manager provides three reset methods for returning state to project defaults:
-
ResetGlobalVariables()- Resets all global variables to their default values as defined in the project. Does not affect characters or once-only options. -
ResetRuntimeCharacters()- Resets all character definitions to their project defaults, reverting any in-game modifications to character variables, names, and images. -
ResetAllState()- Resets global variables, runtime characters, and clears the once-only options tracking. This is a full reset intended for a "New Game" flow.
var manager = StoryFlowManager.Instance;
// New Game flow
manager.ResetAllState();
// Optionally delete the old save
manager.DeleteSave("slot1");
// Start the opening script
component.StartDialogue("scripts/intro"); Tracking the current scene
Since StoryFlow saves do not include execution position, you need a way to know which script to start after loading. A common pattern is to create a global string variable called something like currentScene and update it each time the player enters a new scene. On load, read this variable and use it to start the correct script.