Save data
This is how your game persists ANYTHING across sessions — inventory, level progress, settings,
whatever you need. window.localStorage / sessionStorage do exist in the sandbox, but they're polyfilled to in-memory-only storage that is wiped on every
reload, so never rely on them for anything you want to keep.
DavidnetSDK.saveJsonBlob(data, options?)
Persists any JSON-serializable value (object, array, string, number...) as the player's save
file. Max size is about 1MB. Overwrites any previous save in that slot for this player on this
game. Resolves to: { savedAt }
async function onCheckpoint() {
try {
await window.DavidnetSDK.saveJsonBlob({
level: currentLevel,
inventory: playerInventory,
settings: { musicVolume, sfxVolume }
});
} catch (e) {
console.warn("Could not save progress", e);
}
}DavidnetSDK.getJsonBlob(options?)
Returns the player's previously saved value, or data: null if nothing was saved yet — that's the expected result for a brand new player, not an error. Resolves
to: { data, updatedAt }
async function restoreProgress() {
try {
const { data, updatedAt } = await window.DavidnetSDK.getJsonBlob();
if (data === null) {
startNewGame();
return;
}
currentLevel = data.level;
playerInventory = data.inventory;
applySettings(data.settings);
console.log("Loaded save from", new Date(updatedAt));
} catch (e) {
console.warn("Could not load save, starting fresh", e);
startNewGame();
}
}Named save slots
A game can keep MULTIPLE saves: pass { slot: "hardcore" } (letters, numbers, - / _ , up to 50 chars) to use a slot other than the default one. Omit it entirely and you get the classic
one-save-per-player behavior — fully backwards compatible, every game uploaded before slots existed
keeps working unchanged.
// Two independent saves: a normal-mode save and a separate hardcore-mode save.
async function saveNormalMode(state) {
await window.DavidnetSDK.saveJsonBlob(state, { slot: "normal" });
}
async function saveHardcoreMode(state) {
await window.DavidnetSDK.saveJsonBlob(state, { slot: "hardcore" });
}
async function loadHardcoreMode() {
const { data } = await window.DavidnetSDK.getJsonBlob({ slot: "hardcore" });
return data; // null if this player has never played hardcore mode
}
// Multiple numbered save slots, like a classic "3 save files" menu.
async function saveToSlot(slotNumber, state) {
await window.DavidnetSDK.saveJsonBlob(state, { slot: "slot-" + slotNumber });
}
async function loadSlot(slotNumber) {
const { data, updatedAt } = await window.DavidnetSDK.getJsonBlob({ slot: "slot-" + slotNumber });
return { data, updatedAt }; // show updatedAt on the save-file picker, data null if empty
}When to save
- On checkpoint, level-complete, or any other clear "progress" moment.
- On explicit player action (a "Save" button, settings changed).
- Not on every frame, and not on a tight timer — see Rate limits . A good rule of thumb: if the player wouldn't lose anything meaningful by closing the tab right now, you don't need to save yet.