Skip to content

Saving a playthrough

What a save carries and what it deliberately does not, the two load rules that are not configurable, and why the text is the artifact.

All documentation — Reference
On this page

A save is two halves composed: the engine’s — where the player is, what they have taken, the rollback window — and the runtime’s, which is variables, the entity overlay, the spawned entity instances, visit counts and the random generator’s state.

The session’s Save produces one; Restore puts it back. Both are on the session and forwarded by the TaleShard Player component.

What Save gives you

A TaleShardPlaythroughSave struct with one pin that matters: Json, the save as text, exactly as the engine wrote it — UTF-8, a fixed key order, one trailing newline. The text is the artifact. Store it, and hand it back to Restore.

Save is refused, with the reason, when nothing has been presented yet or when the story is waiting on a command. The session’s Get Pending Command Code lets you say cannot save during startCombat rather than cannot save.

Where to put it

Two shapes, and the difference is whether the story is the only thing you save.

Your gameUse
has nothing else to saveSave Story to Slot and Load Story from Slot on the TaleShard Story actor, or on its TaleShard Player component (Get Player). Each takes a slot name and a user index, and does the whole job in one node, below
wants the save-game object in handTaleShardSaveGame, a save-game object that carries one playthrough. Store keeps a save with the project id; Get Save hands it back to Restore; Has Save answers whether one is held
has its own save gameone string field holding the save’s Json, and the project id beside it

The project id is there so a save is never restored into another story. Check it before offering a Continue button.

Save Story to Slot, Load Story from Slot

Save Story to Slot is Save, then a TaleShardSaveGame holding the save and the project id, written to the slot. Load Story from Slot reads the slot and hands what it holds to Restore, with the same report. Each answers false with the reason, and changes nothing, when:

NodeRefuses when
Save Story to SlotSave is refused, as above, or the slot cannot be written
Load Story from Slotthe slot is empty, holds no TaleShard playthrough, or holds a playthrough of another project’s story — or Restore refuses the text

The project-id check is done for you here.

What a save carries

Notes
Positionboard, node, and the call stack — how a save inside a sub-board resumes into its caller
Historythe rollback window, oldest first. The last entry is where the player stands
Taken choicesone key per choice already taken — what marks an option as seen. Stored rather than derived, because it is derivable from neither the capped history nor from visit counts
Said linesone key per line already said, least recently said first — what a list playing Least recently said and a row ticked Once read. Stored for the same reason: a line Next Line returned is in no moment at all. Each history entry also carries the said lines as they stood when it was drawn, so a restored moment shows the line it showed then. Absent from the text when nothing has been said
Stateevery variable, the entity overlay, every spawned instance, visit counts, the random generator
Language

The rollback window is capped at fifty moments. That bounds the save, not the live session: a running playthrough’s transcript is every step; a reloaded one can step back fifty times and no further.

What a save deliberately does not carry

  • The steps themselves. They are re-derived on load, so a save cannot go stale against an edited board.
  • The roll-forward stack.
  • Anything older than the fifty-moment window.

What a restore does

Restore is legal at any time, including while a command is in flight — anything pending is abandoned, and every in-flight completion goes stale.

The two rules that are not configurable

SituationWhat happens
A variable the save predatestakes its authored default
A variable the project no longer declaresdropped

Neither is an option, and that is deliberate: two supported load behaviours would mean two sets of saves in the field.

Both are reported, because a silently defaulted variable makes “why is my gate false after loading?” unanswerable.

Spawned instances

Every instance the session spawned (Entity scripts and instances) is saved under its own id, with the id and the code of the entity it copies, and its overlay travels with the rest. A restore brings the instances back before the overlay and replaces every live one: an instance spawned after the save is gone, and one despawned after it is back. Its template is found by id first and by code second, as an overlay entry is. An instance whose template the project no longer has, or whose id an authored entity now holds, is dropped with its overlay and reported under Dropped Entities.

A playthrough that never spawned anything writes no instances key, so its save is byte for byte the one it always was.

The report

Restore hands back a TaleShardSaveLoadReport: what the load had to change, so you can tell the player.

PinNotes
Dropped Momentshow many rollback moments were dropped because their node no longer exists — the back window is shorter than the save’s
Dropped Entitiesoverlays dropped because the entity is gone, and instances whose template is gone
Dropped Variablescodes the project no longer declares
Defaulted Variablesvariables the save predates. Each took its authored default
Refused Valuesvalues refused for exceeding the size budget
Is Cleannothing was dropped or defaulted

Is Clean is the one to branch on. Everything else is what you show when it is false.

Restore is refused outright, never partially applied, when the text cannot be read: empty, too long, unparseable, or a format version that is absent, older or newer. The reason names which.

What is not in a save

The engine’s language is. Your own game state is not, and neither is anything you keep outside the runtime: an inventory you modelled in your own Blueprints rather than as project variables is yours to persist, in the same save game, beside the story’s text.

The rule of thumb: if a script could write it, it is in the save. If only your code could, it is not.

Written for
Unity developers · Advanced integrators
Last updated