Godot Templates

Godot templates for one-save, slots, account restore, and connect-later.

Use the PersistlyGameSaves addon facade first. Start with save_data for one current save, move to save_slot for named slots, restore known account sessions through attach_account, or connect anonymous progress to Firebase, Supabase, or Auth0 later.

One SaveMultiple SlotsAccount + SlotsConnect Later

One Save

Godot one-save starter

When to use this: Use this for Godot games that only need one current save at first.

Godot starter

Godot one-save starter

Copy this into your game-facing save service, then adapt the data type and safe sync moments to your game.

GDSCRIPT
extends Node

func save_game(game_state: Dictionary) -> void:
    PersistlyGameSaves.save_data(game_state)

func load_game() -> Dictionary:
    var loaded = PersistlyGameSaves.load_data()
    if loaded.get("status", "") == "local_found":
        return loaded.get("data", {})
    return {}

func sync_after_checkpoint() -> void:
    PersistlyGameSaves.force_sync_data({ "bypassCooldown": true })

Configure the Persistly addon once during boot.

Use save_data and load_data for the default one-save flow.

Call force_sync_data from safe scene or checkpoint transitions.

Multiple Slots

Godot multiple-slot starter

When to use this: Use this when Godot save selection needs named saves, campaigns, or slots.

Godot starter

Godot multiple-slot starter

Copy this into your game-facing save service, then adapt the data type and safe sync moments to your game.

GDSCRIPT
extends Node

func save_slot(slot_id: String, game_state: Dictionary) -> void:
    PersistlyGameSaves.save_slot(slot_id, game_state, {
        "slotInfo": { "label": slot_id }
    })

func load_slot(slot_id: String) -> Dictionary:
    var loaded = PersistlyGameSaves.load_slot(slot_id)
    if loaded.get("status", "") == "local_found":
        return loaded.get("data", {})
    return {}

func read_save_menu() -> Array:
    return PersistlyGameSaves.list_slot_data()

Use stable slot ids such as autosave, slot-1, slot-2, or mage.

Store save-menu labels and preview state in slotInfo.

Use list_slot_data for local save-menu rendering without a network request.

Account + Slots

Godot account + slots starter

When to use this: Use this when Godot account restore is coordinated by your own sign-in system.

Godot starter

Godot account + slots starter

Copy this into your game-facing save service, then adapt the data type and safe sync moments to your game.

GDSCRIPT
extends Node

func export_session_for_backend() -> Dictionary:
    return PersistlyGameSaves.get_account_session({ "includeToken": true })

func restore_known_account(account_id: String, account_session_token: String) -> void:
    PersistlyGameSaves.attach_account(account_id, account_session_token)

func save_signed_in_slot(slot_id: String, game_state: Dictionary) -> void:
    PersistlyGameSaves.save_slot(slot_id, game_state, {
        "slotInfo": { "label": slot_id }
    })
    PersistlyGameSaves.force_sync(slot_id, { "bypassCooldown": true })

Store account_id and account session token only in your trusted account system.

Call attach_account before loading a signed-in player's slots on another device.

Keep normal save writes on save_slot after account restore.

Connect Later

Godot anonymous-first connect-later starter

When to use this: Use this when Godot players can start immediately, save progress, and connect Firebase, Supabase, or Auth0 later.

Godot starter

Godot anonymous-first connect-later starter

Copy this into your game-facing save service, then adapt the data type and safe sync moments to your game.

GDSCRIPT
extends Node

func save_before_sign_in(game_state: Dictionary) -> void:
    PersistlyGameSaves.save_data(game_state)
    await PersistlyGameSaves.force_sync_data({ "bypassCooldown": true })

func connect_firebase(firebase_id_token: String) -> Dictionary:
    var result = await PersistlyGameSaves.connect_with_firebase_token(firebase_id_token)
    if result.get("status") == "account_auth_conflict":
        show_auth_conflict_choices_ui(result.get("error", {}))
    return result

Configure anonymousFirst so local saves work before sign-in.

Get provider tokens from your Firebase, Supabase, or Auth0 integration.

On account_auth_conflict, keep local progress. Let the player retry with a different provider account or explicitly discard local Persistly state before using the existing provider-linked account.