• Studio

  • Studio API

  • Bots

  • Web API

  • Designer Resources

  • Host Resources

  • Globals

    Storage

    The Storage API provides persistent data storage that survives world restarts and player sessions. Think of it as a database for your world - data is saved permanently until you delete it.

    Common uses:

    • Player progress (levels completed, achievements unlocked)
    • Player preferences (settings, customization choices)
    • World state (time of day, resource counts, building placements)
    • Leaderboards and high scores

    IMPORTANT Limitations:

    • SERVER SIDE ONLY: Can only be called from server scripts (not client scripts)
    • Rate Limited: Limit calls to avoid RequestThrottled errors (roughly 10-20 calls per second recommended)
    • Data Size: Keep individual values reasonable (under 100KB recommended) - use multiple keys for large datasets
    • For player items/currency: Use Inventory API instead (it's optimized for that)

    Supported data types: string, number, boolean, table (nested tables supported), Vector3

    Data Persistence: All data persists permanently across:

    • World restarts
    • Player sessions
    • Server updates Data only deletes when you explicitly call DeleteValue or DeletePlayerValue

    Player-specific vs Global:

    • Player functions (GetPlayerValue, SetPlayerValue, etc.) automatically prefix with player's user ID
    • Global functions use the exact key you provide
    • player.user.id = unique permanent ID across all worlds, player.id = temporary session ID (don't use for storage!)

    Unity Development: Storage file located at Library/localStorage (can view/edit in text editor for testing)

    Methods

    Deletes a player-specific value from storage. Equivalent to: DeleteValue(player.user.id .. "/" .. key, callback) For global values or custom key formats, use DeleteValue instead.

    Storage.DeletePlayerValue(player, "TempData")
    
    Storage.DeletePlayerValue(player, "Progress", function(error)
        if error == StorageError.None then
            print("Player progress reset")
        end
    end)
    

    Parameters

    player
    key
    string

    Returns

    void

    Deletes a player-specific value from storage. Equivalent to: DeleteValue(player.user.id .. "/" .. key, callback) For global values or custom key formats, use DeleteValue instead.

    Storage.DeletePlayerValue(player, "TempData")
    
    Storage.DeletePlayerValue(player, "Progress", function(error)
        if error == StorageError.None then
            print("Player progress reset")
        end
    end)
    

    Parameters

    player
    key
    string
    callback
    (error: StorageError) -> ()

    Returns

    void

    DeleteValue

    ServerOnly

    Deletes a value from storage with the given key.

    -- Delete without callback
    Storage.DeleteValue("TemporaryData")
    
    -- Delete with callback
    Storage.DeleteValue("OldLeaderboard", function(error)
        if error == StorageError.None then
            print("Value deleted")
        end
    end)
    

    Parameters

    key
    string

    Returns

    void

    DeleteValue

    ServerOnly

    Deletes a value from storage with the given key.

    -- Delete without callback
    Storage.DeleteValue("TemporaryData")
    
    -- Delete with callback
    Storage.DeleteValue("OldLeaderboard", function(error)
        if error == StorageError.None then
            print("Value deleted")
        end
    end)
    

    Parameters

    key
    string
    callback
    (error: StorageError) -> ()

    Returns

    void

    GetPlayerValue

    ServerOnly

    Retrieves a player-specific value from storage. Equivalent to: GetValue(player.user.id .. "/" .. key, callback) For global values or custom key formats, use GetValue instead.

    Storage.GetPlayerValue(player, "HighScore", function(value, error)
        if error == StorageError.None then
            print(player.name .. " high score: " .. tostring(value))
        end
    end)
    

    Parameters

    player
    key
    string
    callback
    (value: any, error: StorageError) -> ()

    Returns

    void

    GetValue

    ServerOnly

    Retrieves a value from storage with the given key. The callback receives the value and error code. If the key doesn't exist, value is nil and error is StorageError.None.

    Storage.GetValue("GlobalHighScore", function(value, error)
        if error == StorageError.None then
            print("High score: " .. tostring(value))
        else
            print("Error: " .. tostring(error))
        end
    end)
    

    Parameters

    key
    string
    callback
    (value: any, error: StorageError) -> ()

    Returns

    void

    Increments a player-specific numeric value by the specified amount. Equivalent to: IncrementValue(player.user.id .. "/" .. key, amount, callback) For global values or custom key formats, use IncrementValue instead.

    -- Add points to player
    Storage.IncrementPlayerValue(player, "Points", 10)
    
    -- Add currency with callback
    Storage.IncrementPlayerValue(player, "Coins", 50, function(error)
        if error == StorageError.None then
            print("Coins added")
        end
    end)
    

    Parameters

    player
    key
    string
    amount
    number

    Returns

    void

    Increments a player-specific numeric value by the specified amount. Equivalent to: IncrementValue(player.user.id .. "/" .. key, amount, callback) For global values or custom key formats, use IncrementValue instead.

    -- Add points to player
    Storage.IncrementPlayerValue(player, "Points", 10)
    
    -- Add currency with callback
    Storage.IncrementPlayerValue(player, "Coins", 50, function(error)
        if error == StorageError.None then
            print("Coins added")
        end
    end)
    

    Parameters

    player
    key
    string
    amount
    number
    callback
    (error: StorageError) -> ()

    Returns

    void

    IncrementValue

    ServerOnly

    Increments a numeric value by the specified amount. If the value doesn't exist, it will be set to the amount. Safe for concurrent access - use this instead of UpdateValue for simple number increments.

    -- Increment global player count
    Storage.IncrementValue("TotalPlayers", 1)
    
    -- Decrement with callback
    Storage.IncrementValue("AvailableSlots", -1, function(error)
        if error == StorageError.None then
            print("Slot taken")
        end
    end)
    

    Parameters

    key
    string
    amount
    number

    Returns

    void

    IncrementValue

    ServerOnly

    Increments a numeric value by the specified amount. If the value doesn't exist, it will be set to the amount. Safe for concurrent access - use this instead of UpdateValue for simple number increments.

    -- Increment global player count
    Storage.IncrementValue("TotalPlayers", 1)
    
    -- Decrement with callback
    Storage.IncrementValue("AvailableSlots", -1, function(error)
        if error == StorageError.None then
            print("Slot taken")
        end
    end)
    

    Parameters

    key
    string
    amount
    number
    callback
    (error: StorageError) -> ()

    Returns

    void

    Searches for player-specific values that start with the given key prefix. Equivalent to: SearchValue(player.user.id .. "/" .. key, limit, cursorId, callback) For global values or custom key formats, use SearchValue instead.

    -- Search player's saved levels
    Storage.SearchPlayerValue(player, "level_", 5, nil, function(values, cursorId, error)
        if error == StorageError.None then
            print("Found " .. #values .. " saved levels")
            for i, entry in ipairs(values) do
                print("Level: " .. tostring(entry))
            end
        end
    end)
    

    Parameters

    player
    key
    string
    limit
    number
    cursorId
    string
    callback
    (values: {any}, cursorId: string, error: StorageError) -> ()

    Returns

    void

    SearchValue

    ServerOnly

    Searches for values that start with the given key prefix. Returns up to 'limit' most recent matching values.

    Pagination: Pass nil for cursorId to get first results. Use returned cursorId for next page. If returned cursorId is nil, no more results exist.

    Callback receives: array of values (tables with key-value pairs), cursorId, error

    -- Search for all player scores
    Storage.SearchValue("player_scores/", 10, nil, function(values, cursorId, error)
        if error == StorageError.None then
            for i, entry in ipairs(values) do
                print("Found: " .. tostring(entry))
            end
            
            -- Get next page if available
            if cursorId ~= nil then
                -- Call SearchValue again with cursorId for next page
            end
        end
    end)
    

    Parameters

    key
    string
    limit
    number
    cursorId
    string
    callback
    (values: {any}, cursorId: string, error: StorageError) -> ()

    Returns

    void

    SetPlayerValue

    ServerOnly

    Sets a player-specific value in storage. Equivalent to: SetValue(player.user.id .. "/" .. key, value, callback) For global values or custom key formats, use SetValue instead.

    Storage.SetPlayerValue(player, "Level", 5)
    
    Storage.SetPlayerValue(player, "Inventory", { coins = 100, gems = 5 }, function(error)
        if error == StorageError.None then
            print("Player data saved")
        end
    end)
    

    Parameters

    player
    key
    string
    value
    any

    Returns

    void

    SetPlayerValue

    ServerOnly

    Sets a player-specific value in storage. Equivalent to: SetValue(player.user.id .. "/" .. key, value, callback) For global values or custom key formats, use SetValue instead.

    Storage.SetPlayerValue(player, "Level", 5)
    
    Storage.SetPlayerValue(player, "Inventory", { coins = 100, gems = 5 }, function(error)
        if error == StorageError.None then
            print("Player data saved")
        end
    end)
    

    Parameters

    player
    key
    string
    value
    any
    callback
    (error: StorageError) -> ()

    Returns

    void

    SetValue

    ServerOnly

    Sets a value in storage with the given key. Supported types: string, number, boolean, table, Vector3

    CAUTION: For values that depend on previous values (e.g., leaderboards), use UpdateValue to prevent data loss. For incrementing/decrementing numbers, use IncrementValue instead.

    -- Without callback
    Storage.SetValue("GameMode", "TeamDeathmatch")
    
    -- With callback
    Storage.SetValue("ServerConfig", { maxPlayers = 10, friendlyFire = false }, function(error)
        if error == StorageError.None then
            print("Config saved successfully")
        end
    end)
    

    Parameters

    key
    string
    value
    any

    Returns

    void

    SetValue

    ServerOnly

    Sets a value in storage with the given key. Supported types: string, number, boolean, table, Vector3

    CAUTION: For values that depend on previous values (e.g., leaderboards), use UpdateValue to prevent data loss. For incrementing/decrementing numbers, use IncrementValue instead.

    -- Without callback
    Storage.SetValue("GameMode", "TeamDeathmatch")
    
    -- With callback
    Storage.SetValue("ServerConfig", { maxPlayers = 10, friendlyFire = false }, function(error)
        if error == StorageError.None then
            print("Config saved successfully")
        end
    end)
    

    Parameters

    key
    string
    value
    any
    callback
    (error: StorageError) -> ()

    Returns

    void

    Safely updates a player-specific value based on its current state. Equivalent to: UpdateValue(player.user.id .. "/" .. key, modifier, callback) For global values or custom key formats, use UpdateValue instead.

    Storage.UpdatePlayerValue(player, "Stats", function(currentStats)
        if currentStats == nil then
            return { kills = 1, deaths = 0 }
        else
            currentStats.kills = currentStats.kills + 1
            return currentStats
        end
    end)
    

    Parameters

    player
    key
    string
    modifier
    (value: any) -> (any)

    Returns

    void

    Safely updates a player-specific value based on its current state. Equivalent to: UpdateValue(player.user.id .. "/" .. key, modifier, callback) For global values or custom key formats, use UpdateValue instead.

    Storage.UpdatePlayerValue(player, "Stats", function(currentStats)
        if currentStats == nil then
            return { kills = 1, deaths = 0 }
        else
            currentStats.kills = currentStats.kills + 1
            return currentStats
        end
    end)
    

    Parameters

    player
    key
    string
    modifier
    (value: any) -> (any)
    callback
    (error: StorageError) -> ()

    Returns

    void

    UpdateValue

    ServerOnly

    Safely updates a value based on its current state - prevents data loss from simultaneous updates.

    Why use this instead of Get then Set:

    • PROBLEM: If two players trigger updates at the same time, one update can be lost Example: Player A and B both try to add their score to leaderboard Player A reads 100, adds 50 = 150 Player B reads 100 (before A saves), adds 30 = 130 Result: Only 130 saved, Player A's 50 points lost!
    • SOLUTION: UpdateValue ensures both updates apply correctly (result = 180)

    How it works:

    1. Retrieves current value (nil if doesn't exist)
    2. Calls your modifier function with current value
    3. Saves the value your modifier returns
    4. If another update happened simultaneously, retries automatically with new current value

    The modifier may be called multiple times if concurrent updates detected. Return nil from modifier to cancel the update (no change saved).

    When to use:

    • Leaderboards (adding new high scores)
    • Counters (tracking total events)
    • Lists (adding items to shared arrays)
    • Any value that depends on its previous value

    When NOT to use:

    • Simple overwrites (use SetValue - it's faster)
    • Number increments (use IncrementValue - it's optimized for this)
    -- Update leaderboard with new high score
    Storage.UpdateValue("GlobalHighScore", function(currentScore)
        local newScore = 1000
        if currentScore == nil or newScore > currentScore then
            return newScore
        else
            return nil -- Don't update if score isn't higher
        end
    end, function(error)
        if error == StorageError.None then
            print("High score updated")
        end
    end)
    

    Parameters

    key
    string
    modifier
    (value: any) -> (any)

    Returns

    void

    UpdateValue

    ServerOnly

    Safely updates a value based on its current state - prevents data loss from simultaneous updates.

    Why use this instead of Get then Set:

    • PROBLEM: If two players trigger updates at the same time, one update can be lost Example: Player A and B both try to add their score to leaderboard Player A reads 100, adds 50 = 150 Player B reads 100 (before A saves), adds 30 = 130 Result: Only 130 saved, Player A's 50 points lost!
    • SOLUTION: UpdateValue ensures both updates apply correctly (result = 180)

    How it works:

    1. Retrieves current value (nil if doesn't exist)
    2. Calls your modifier function with current value
    3. Saves the value your modifier returns
    4. If another update happened simultaneously, retries automatically with new current value

    The modifier may be called multiple times if concurrent updates detected. Return nil from modifier to cancel the update (no change saved).

    When to use:

    • Leaderboards (adding new high scores)
    • Counters (tracking total events)
    • Lists (adding items to shared arrays)
    • Any value that depends on its previous value

    When NOT to use:

    • Simple overwrites (use SetValue - it's faster)
    • Number increments (use IncrementValue - it's optimized for this)
    -- Update leaderboard with new high score
    Storage.UpdateValue("GlobalHighScore", function(currentScore)
        local newScore = 1000
        if currentScore == nil or newScore > currentScore then
            return newScore
        else
            return nil -- Don't update if score isn't higher
        end
    end, function(error)
        if error == StorageError.None then
            print("High score updated")
        end
    end)
    

    Parameters

    key
    string
    modifier
    (value: any) -> (any)
    callback
    (error: StorageError) -> ()

    Returns

    void

    Updated 1 day ago

    PocketWorlds Icon

    © 2025 Pocket Worlds. All rights reserved.