KUMODeck
日本語

Cloud saves

A save is a JSON document stored per user (called players in the API) under a slot key (slot1, profile, settings…): a document, a user's settings, a draft, a game's progress. Saves follow the user to every device they sign in on, and each slot carries a version so two devices cannot silently overwrite each other.

Read and write#

const save = await kumo.saves.get('slot1');        // null if the slot does not exist yet
const state = save?.data ?? { level: 1, hp: 3 };

state.level += 1;
await kumo.saves.set('slot1', state);              // last write wins
MethodReturns
saves.get(key){ key, version, size, updatedAt, data } or null
saves.set(key, data, { ifVersion? }){ key, version, size, updatedAt }
saves.list()[{ key, version, size, updatedAt }] (no data)
saves.delete(key, { ifVersion? })—

Conflict-safe writes#

The simple form overwrites. When a user might use two devices at once, write with ifVersion:

try {
  await kumo.saves.set('profile', profile, { ifVersion: 'latest' });
} catch (e) {
  if (e.code !== 'version_conflict') throw e;
  const cloud = await kumo.saves.get('profile');   // someone else wrote first
  profile = merge(cloud.data, profile);            // your app decides how to merge
  await kumo.saves.set('profile', profile, { ifVersion: cloud.version });
}
  • ifVersion: 'latest' — the version this SDK instance last saw for that slot (0 if it never read it)
  • ifVersion: <number> — write only if the stored version equals it; 0 means "only if the slot does not exist"
  • On mismatch the server answers 409 version_conflict with details.currentVersion

Limits#

LimitValue
Slots per user32 (too_many_saves)
Size per slot256 KB of JSON (save_too_large, HTTP 413, with details.size and details.limit). The SDK counts the bytes before sending and throws the same error without sending; a raw HTTP body over 1 MB gets 413 invalid_request
Slot keylowercase snake_case: starts with a letter, then a-z, 0-9, _; up to 48 characters

Saves are scoped to the environment: development saves never appear in production.

Saves or your own database?#

The user's own browser writes saves, so a modified page can put anything in them. Pick by who may change the data:

Protect in D1, not in saves. Anything a user must not be able to change themselves — scores and rankings, coins, credits, items, purchases, badges, anything shared between users — goes in the project's own Functions + D1. saves holds only what the user may freely write (settings, drafts, a solo game's progress).

Put it inWhatWho writes it
Saveswhat the user may change freely: settings, progress notes, drafts, favorites, a game's savethe user's browser (a changed value hurts nobody)
Your database in Functions (D1)what must be protected: scores and rankings, coins, credits, items, purchases, a verified badge, anything shared between usersonly your server code

When unsure: if a user changing it by hand would be a problem, keep it in your database. Saves hold state, not currency. Your server code cannot read or write a user's saves, so keep the protected copy in your database from the start.