Persist your normal game state through saveData.
JavaScript Templates
JavaScript templates for one-save, slots, account restore, and connect-later.
Use @persistlyapp/sdk through PersistlyGameSaves first. Start with saveData for one current save, move to saveSlot for named slots, attach a known account session from trusted backends, or connect anonymous progress to Firebase, Supabase, or Auth0 later.
One Save
JavaScript one-save starter
When to use this: Use this for idle, casual, and prototype games that keep one current save.
JavaScript starter
JavaScript one-save starter
Copy this into your game-facing save service, then adapt the data type and safe sync moments to your game.
import { PersistlyGameSaveStatus, PersistlyGameSaves } from "@persistlyapp/sdk";
await PersistlyGameSaves.configure({
runtimeKey: "ps_test_replace_me",
});
export async function saveGame(gameState: Record<string, unknown>) {
await PersistlyGameSaves.shared.saveData(gameState);
}
export async function loadGame() {
const loaded = await PersistlyGameSaves.shared.loadData();
return loaded.status === PersistlyGameSaveStatus.LocalFound ? loaded.data : null;
}
export async function syncAfterCheckpoint() {
return PersistlyGameSaves.shared.forceSyncData();
}Read local state first with loadData so the game can boot offline.
Call forceSyncData from pause, checkpoint, manual save, or level-complete moments.
Read the SDK setup, behavior, and facade guidance for this engine.
Open SDK docsDetailed guideOpen the matching SDK guide for save, load, sync, and account restore details.
Open guideTemplate folderOpen the public SDK repository folder for the complete copy-paste template when it is published.
Open GitHubMultiple Slots
JavaScript multiple-slot starter
When to use this: Use this when the game has manual saves, campaigns, save files, or character selection.
JavaScript starter
JavaScript multiple-slot starter
Copy this into your game-facing save service, then adapt the data type and safe sync moments to your game.
import { PersistlyGameSaveStatus, PersistlyGameSaves } from "@persistlyapp/sdk";
await PersistlyGameSaves.configure({
runtimeKey: "ps_test_replace_me",
});
export async function saveCampaign(slotId: string, gameState: Record<string, unknown>) {
await PersistlyGameSaves.shared.saveSlot(slotId, gameState, {
slotInfo: { label: slotId },
});
}
export async function loadCampaign(slotId: string) {
const loaded = await PersistlyGameSaves.shared.loadSlot(slotId);
return loaded.status === PersistlyGameSaveStatus.LocalFound ? loaded.data : null;
}
export async function syncCampaign(slotId: string) {
return PersistlyGameSaves.shared.forceSync(slotId);
}Choose stable developer slot ids such as autosave, slot-1, slot-2, or warrior.
Keep menu labels and timestamps in slotInfo so save selection UI can stay fast.
Sync the active slot from safe lifecycle or manual-save points.
Read the SDK setup, behavior, and facade guidance for this engine.
Open SDK docsDetailed guideOpen the matching SDK guide for save, load, sync, and account restore details.
Open guideTemplate folderOpen the public SDK repository folder for the complete copy-paste template when it is published.
Open GitHubAccount + Slots
JavaScript account + slots starter
When to use this: Use this when your own sign-in flow stores and restores the Persistly account session.
JavaScript starter
JavaScript account + slots starter
Copy this into your game-facing save service, then adapt the data type and safe sync moments to your game.
import { PersistlyGameSaves } from "@persistlyapp/sdk";
await PersistlyGameSaves.configure({
runtimeKey: "ps_test_replace_me",
});
export async function exportSessionForYourBackend() {
await PersistlyGameSaves.shared.ensureAccount();
return PersistlyGameSaves.shared.getAccountSession({ includeToken: true });
}
export async function restoreKnownAccount(accountId: string, accountSessionToken: string) {
await PersistlyGameSaves.shared.attachAccount({
accountId,
accountSessionToken,
});
}
export async function saveSignedInSlot(slotId: string, gameState: Record<string, unknown>) {
await PersistlyGameSaves.shared.saveSlot(slotId, gameState, {
slotInfo: { label: slotId },
});
return PersistlyGameSaves.shared.forceSync(slotId);
}Store accountId and accountSessionToken only in your trusted account system.
Restore with attachAccount before loading or refreshing signed-in slots.
Keep normal gameplay writes on saveSlot so account restore stays facade-first.
Read the SDK setup, behavior, and facade guidance for this engine.
Open SDK docsDetailed guideOpen the matching SDK guide for save, load, sync, and account restore details.
Open guideTemplate folderOpen the public SDK repository folder for the complete copy-paste template when it is published.
Open GitHubConnect Later
JavaScript anonymous-first connect-later starter
When to use this: Use this when players can start immediately, save progress, and connect Firebase, Supabase, or Auth0 later.
JavaScript starter
JavaScript 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.
import { PersistlyGameSaves } from "@persistlyapp/sdk";
await PersistlyGameSaves.configure({
runtimeKey: "ps_test_replace_me",
accountMode: "anonymousFirst",
});
export async function saveBeforeSignIn(gameState: Record<string, unknown>) {
await PersistlyGameSaves.shared.saveData(gameState);
return PersistlyGameSaves.shared.forceSyncData();
}
export async function connectFirebaseAccount(firebaseIdToken: string) {
try {
return await PersistlyGameSaves.shared.connectWithFirebaseToken(firebaseIdToken);
} catch (error) {
if (error && typeof error === "object" && "code" in error && error.code === "account_auth_conflict") {
return { status: "account_auth_conflict", currentAccountPreserved: true };
}
throw error;
}
}Use anonymousFirst so save/load works before player sign-in.
Get the provider token from Firebase, Supabase, or Auth0; Persistly does not provide login UI in this phase.
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.
Read the SDK setup, behavior, and facade guidance for this engine.
Open SDK docsDetailed guideOpen the matching SDK guide for save, load, sync, and account restore details.
Open guideTemplate folderOpen the public SDK repository folder for the complete copy-paste template when it is published.
Open GitHub