Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Save, Back and story end

Lives in: game.json → session · save files next to the player · screen actions

A session is one playthrough from New Game / Continue / Load until you return to title (or quit). Progress lives next to the player as manual slots, one autosave, and a separate prefs file.

Early — not final UX. Multi-slot save/load grids and multi-story packs are shipped and usable, but menus, labels, hub screens, and overall player comfort are still a first cut. Prefer the simple one-slot "save" / "load" wiring unless you need the grid or packs — In development.

Most stories

  • Keep pause/title hooks as "save" / "load" for a simple one-slot feel (always slot 1).
  • Or point menus at screen:save / screen:load for a multi-slot picker — define your own save / load screens with the save_slots block; none ship built-in.
  • Title Continue resumes the autosave.
  • Set session.allow_back if you want Back / rollback.
  • Set session.post_story_screen (and usually post_story_return_to_title) for credits after the last line.
  • Changing node ids or restructuring the story can invalidate old saves — that is intentional.

Where this lives

IdeaFile / surfacePath
Back + story-end + slot countgame.jsonsession
Continue / Load visibilityscreens.jsonshow_if: has_autosave / has_save
Slot picker UIscreens.jsonyour own save / load screens + save_slots block
Files on diskNext to the playersee below
{
  "session": {
    "allow_back": true,
    "back_retype": false,
    "back_limit": 0,
    "save_slots": 9,
    "boot": "title",
    "hud_screen": "hud",
    "post_story_screen": "credits",
    "post_story_return_to_title": true
  }
}

"hud_screen": "hud" (default) auto-shows that screens.json entry with role: "hud" when a session starts. Set "hud_screen": "" to disable. Extra HUD mid-story: screen command.

{ "label": "Save", "interaction": { "hooks": { "on_click": "save" } } }
{ "label": "Save game", "interaction": { "hooks": { "on_click": "screen:save" } } }

Players never write save files by hand. Authors configure session and the screen actions that read those files.

session keys

KeyTypeDefaultEffect
allow_backboolfalseEnable Back / history. History is only stored in saves when this is true
back_retypeboolfalseAfter Back: false finishes typing instantly; true retypes the line
back_limitint0Max Back steps per forward stretch; 0 = unlimited
save_slotsint9Manual slot count (clamped 1–99)
default_storystringfirst pack / mainPack id for bare new_game — Several stories
bootstring"title"Cold start: "title" or "new_game" (skip title)
post_story_screenstring""Screen id after the story ends (e.g. "credits")
post_story_return_to_titlebooltrueEnd session and show title (then optionally the post-story screen)
hud_screenstring"hud"HUD id at session start; "" disables

If post_story_screen is empty and post_story_return_to_title is false, the runtime still returns to title.

Map: game.json → session.

Files on disk

FileRole
save-1.json … save-N.json (author) or save-N.sav (player build)Manual slots
autosave.json / autosave.savContinue only
prefs.jsonVolumes, display, UI prefs, last_used_slot, and (when using multi-story) last_story_id / campaign (always plain JSON)
Manual slotAutosave
Written byPlayer Save / save_slot:N / key SRuntime after progress; also after successful Back, Title/Quit flush, window close
Read byLoad / load_slot:N / key L (in play)Continue only
PreferencesNo — see prefs.jsonNo

Immediate actions: "save" / "load" always use slot 1.
Keyboard: S quick-saves the last-used slot (fallback 1); L in play loads that slot. Title L still prefers Continue when an autosave exists.
New Game starts a fresh session; it does not delete these files.

Title buttons typically use show_if: "has_save" / "has_autosave". Those checks also require a compatible file, so broken or outdated saves hide Continue/Load. has_save is true if any slot is occupied and compatible.

Author vs player encode

ModeWhenSlot / autosave format
Plain JSONEditor and author-mode player.json — readable for debugging
ObfuscatedProduction game build.sav — not casually readable in a text editor

Obfuscation is comfort (raise the bar vs peeking), not DRM. Prefs stay plain so volumes/locale remain easy to inspect.

Where files live

ContextLocation
Player build (one shipped game)saves/ next to the executable
Author player (many projects)saves/<project-id>/ — id is a slug from game.json title
Web buildBrowser storage — survives reload when storage is allowed; private mode and some iframe blocks do not

Saves are player progress, not part of your project folder.

What a save holds

Story cursor: current node id, flags, shuffle seed, plus save_version, story_id (pack), and story_hash for compatibility.

Stage and chrome (restored in a fixed order): background, character layout profile, on-stage characters, BGM, sprites, objects, screen shader, running animations, panels, theme_style / choice_style overrides, cursor profile.

Also: rollback history (only if allow_back), dialogue backlog. Preferences live only in prefs.json (volumes, display, UI, last_used_slot, last_story_id, campaign unlock flags).

Node-local overrides are not kept; drivers re-sync after load or Back.

Multiple stories (early)

One shared slot list + one autosave for the whole game. Each save stamps story_id. Hub screen: new_game:<id> and optional show_if: story_unlocked:<id>. Slot labels can use {story} / {story_title}. Full contract: Several stories in one project.

Back / rollback

Requires allow_back, enough history, and room under back_limit.

  • History snapshots are taken after a node’s command batch finishes.
  • Back restores the previous snapshot and skips “transit” nodes (no text and no choices) so the player lands on something interactive.
  • Successful Back also writes a live autosave.
  • Backlog trims to the restored node.

Default Back key is remappable (dialogue_back in keybindings.json) — Keys.

Story end

When there is no valid next (or a choice targets null):

  1. Fade out.
  2. Clear autosave — Continue is gone for that finished run.
  3. End session (reset stage/flags; title if configured).
  4. Fade in.
  5. Optionally push post_story_screen.

Manual slots and prefs are not cleared on story end.

Usually you need

WantWrite
Allow Back"allow_back": true
Skip title (test)"boot": "new_game"
Credits after ending"post_story_screen": "credits"
More save slots"save_slots": 12

Title, pause and settings screens · Gameplay HUD · save_slots content block · Sticky state and clear · Several stories