?Publish

Docs

PLAYER PROGRESS

Pick up where you left off

Save levels, inventory, characters and quests so signed-in players can continue on another device. You export and restore game state; the platform handles cloud storage, backups and conflicts.

RECOMMENDED

JavaScript SDK

For HTML, Canvas, Phaser and other web games. Supply export, restore and summary functions to reuse local persistence, retries and conflict handling.

/sdk/cloud-saves-v1.js
CUSTOM INTEGRATION

Native REST / engine bridge

For existing save systems or engine web exports with a JavaScript bridge. Read and write JSON over HTTP and implement the startup gate, offline queue and platform commands.

Read the native contract →

Three steps

  1. Enable and define the format

    Enable cloud saves on the game page, decide which state to restore and set schemaVersion.

  2. Load before play

    Wait for initialize before starting. A failed read is not an empty save; play offline only when the player chooses.

  3. Save at checkpoints

    Call save() after levels and key actions. Background saves show a corner notice only; no pop-ups, no pausing.

APIs and examples

Minimal SDK integration

Replace the sample state, rebuildScene, startGameLoop and showStartupError with your game implementation. Use the generated game ID and save-format version.

<script src="https://www.ai-made.games/sdk/cloud-saves-v1.js"></script>
<script>
let state = { level: 1, inventory: [], playSeconds: 0 };

async function boot() {
  try {
    await AIWanna.saves.initialize({
      platformOrigin: 'https://www.ai-made.games',
      gameId: 'YOUR_GAME_ID',
      schemaVersion: 1,
      gameVersion: '1.0.0',
      exportState: () => structuredClone(state),
      importState: async data => {
        state = data;
        await rebuildScene(state);
      },
      summary: data => 'Level ' + data.level
    });
    startGameLoop();
  } catch (error) {
    showStartupError(error.message);
  }
}

async function checkpointReached() {
  try { await AIWanna.saves.save(); }
  catch (error) { console.warn('Save needs attention:', error.code); }
}
boot();
</script>
Native REST read/write example

This is a transport example. A complete integration also needs the dedicated cloud-save-session handshake, local retry queue and management-command acknowledgments described in the full protocol.

// Transport example: token comes from the cloud-save-session handshake.
// Call only after validating game/account identity. Do not use a leaderboard token.
const platformOrigin = 'https://www.ai-made.games';
const gameId = 'YOUR_GAME_ID';
const endpoint = platformOrigin + '/api/v1/games/' + gameId + '/saves/main';

async function readProgress(token) {
  const response = await fetch(endpoint, {
    credentials: 'omit',
    headers: { Authorization: 'Bearer ' + token },
    signal: AbortSignal.timeout(15000)
  });
  const result = await response.json();
  if (!response.ok) throw Object.assign(new Error(result.error.message), {
    code: result.error.code
  });
  return result; // { save: snapshot | null, revision }
}

// Only prepare after readProgress succeeds and the player resolves any conflict.
// Persist this exact { key, body } locally before sending it.
function prepareCheckpoint(lastRead, state, schemaVersion) {
  return {
    key: crypto.randomUUID(),
    body: JSON.stringify({
      protocolVersion: 1, schemaVersion, gameVersion: '1.0.0',
      summary: 'Level ' + state.level,
      baseRevision: lastRead.revision, data: state
    })
  };
}

async function sendCheckpoint(token, pending) {
  const response = await fetch(endpoint, {
    method: 'PUT', credentials: 'omit',
    headers: {
      Authorization: 'Bearer ' + token,
      'Content-Type': 'application/json', 'Idempotency-Key': pending.key
    },
    body: pending.body, signal: AbortSignal.timeout(15000)
  });
  const result = await response.json();
  if (!response.ok) throw Object.assign(new Error(result.error.message), {
    code: result.error.code, retryAfter: response.headers.get('Retry-After')
  });
  return result; // Metadata and revision; state stays in the acknowledged local snapshot.
}
// Retries reuse pending.key and pending.body, even after refreshing a token.
// On 409, retain both versions and obtain the player's choice before a NEW write.
// Add the local queue, startup gate and command acknowledgements from the full guide.
Common save endpoints
ActionEndpoint or methodResult or requirement
InitializeAIWanna.saves.initialize(options)Wait for restoration before play
CheckpointAIWanna.saves.save()Complete state snapshot
Read cloud saveGET /api/v1/games/{gameId}/saves/mainsave + revision
Write cloud savePUT /api/v1/games/{gameId}/saves/mainbaseRevision + Idempotency-Key
Size limits, migrations and conflicts
  • One main slot per account and game, with three previous snapshots. The full request is limited to 256 KiB of UTF-8 data.
  • Save only the JSON data needed to resume. Do not collect all of localStorage or include credentials and private information.
  • Increase schemaVersion for format changes and provide migrateState(data, fromVersion, toVersion). Preserve unreadable newer saves instead of overwriting them with a fresh game.
  • Revisions detect device conflicts. Retain both versions and await the player’s choice. Guest imports and account changes must not silently mix progress.
  • After gameplay begins, background retries must not restore checkpoints, rebuild scenes or capture input. Replace active progress only after an explicit player load.

Before launch

Try each one from Start game on the game page. The game must also work when opened on its own.

Cloud saves

0 of 6

Stuck? Send us the error and your prompt here.