Skip to content

Persistent Storage

The Storage module provides asynchronous key-value persistence in the browser (client-side). Use it for save games, settings, and progress that should survive page reloads — not for cloud sync (use project APIs separately).

Basic usage

local Storage = require 'engine/storage'

-- Write (synchronous send)
Storage.set("level", 3)
Storage.set("playerName", "Alex")

-- Read (returns a Promise)
Storage.get("level"):next(function(value)
    if value ~= nil then
        self.currentLevel = value
    end
end)

Storage.remove("tempFlag")
Storage.clear()   -- wipe all keys

Listing keys

Storage.keys():next(function(allKeys)
    for _, key in ipairs(allKeys) do
        print(key)
    end
end)

Save-game pattern ---------------

function SaveManager:save()
    Storage.set("checkpoint", {
        level = self.level,
        health = self.health,
        position = self.node:getTransform().position:toData(),
    })
end

function SaveManager:load()
    Storage.get("checkpoint"):next(function(data)
        if not data then return end
        self.level = data.level
        self.health = data.health
        self.node:withTransform(function(t)
            t.position = Vector3.fromData(data.position)
        end)
    end)
end

Store JSON-serializable tables and primitives. Complex userdata (scene objects, items) cannot be persisted directly — save IDs or paths instead.

Variable sets vs Storage

Variable sets Live gameplay state, visible in Studio Variables view, shared across scripts during a session
Storage Persists across browser sessions on the client

See Variable Sets for in-session global state.

Further reading