The Storage module persists player data: progress, settings, currency, level state. This is required for almost every game. Without it, players lose progress between sessions.
Two storage types
Type
Persistence
Cross-device
Use when
local_storage
Browser/device localStorage
No
Default for offline, single-device progress
platform_internal
Platform cloud servers
Yes
Player is authorized and you want cross-device save
bridge.storage.defaultType returns the storage type preferred by the current platform. Use it by default; pass an explicit storageType only when you need to control where the data is stored.
Implementation order
Required — On game start, call storage.get(...) for the keys you need (level, coins, settings, etc.). Restore the player's state before showing gameplay.
Required — On meaningful state change (level complete, purchase, settings change), storage.set(...) to persist. Avoid saving every frame.
Current Storage Type
Read the default storage type before saving data. It tells you whether Bridge will use local browser storage or platform cloud storage.
bridge.storage.defaultType
Bridge.storage.defaultType
PlaygamaBridge.DefaultStorageType
PlaygamaBridge::DefaultStorageType()
Bridge.storage.default_type
playgama_bridge_storage_default_type()
bridge.storage.default_type()
bridge.storage.defaultType
Possible values: local_storage, platform_internal.
Platform support · all 28 platforms (local) · 20 of 28 platforms (cloud)
Bridge.storage.is_available("local_storage")
Bridge.storage.is_available("platform_internal")
# To use constants for convenience:
Bridge.storage.is_available(Bridge.StorageType.LOCAL_STORAGE)
Bridge.storage.is_available(Bridge.StorageType.PLATFORM_INTERNAL)
// Load data by key
bridge.storage.get('key')
.then(data => {
// Data loaded and you can work with it
// data = null if there is no data for the given key
console.log('Data: ', data)
})
.catch(error => {
// Error, something went wrong
})
// Load data by multiple keys
bridge.storage.get(['key_1', 'key_2'])
.then(data => {
// Data loaded and you can work with it
// data[n] = null if there is no data for the given key
console.log('Data: ', data)
})
.catch(error => {
// Error, something went wrong
})
// Get data by key
private void Start()
{
Bridge.storage.Get("level", OnStorageGetCompleted);
}
private void OnStorageGetCompleted(bool success, string data)
{
// Loading succeeded
if (success)
{
if (data != null)
{
Debug.Log(data);
}
else
{
// No data for the key 'level'
}
}
else
{
// Error, something went wrong
}
}
// Get data by multiple keys
private void Start()
{
Bridge.storage.Get(new List<string>() { "level", "coins" }, OnStorageGetCompleted);
}
private void OnStorageGetCompleted(bool success, List<string> data)
{
// Loading succeeded
if (success)
{
if (data[0] != null)
{
Debug.Log($"Level: {data[0]}");
}
else
{
// No data for the key 'level'
}
if (data[1] != null)
{
Debug.Log($"Coins: {data[1]}");
}
else
{
// No data for the key 'coins'
}
}
else
{
// Error, something went wrong
}
}
// Get data from a specific storage type
private void Start()
{
Bridge.storage.Get("level", OnStorageGetCompleted, StorageType.LocalStorage);
}
private void OnStorageGetCompleted(bool success, string data)
{
// Loading succeeded
if (success)
{
if (data != null)
{
Debug.Log(data);
}
else
{
// No data for the key 'level'
}
}
else
{
// Error, something went wrong
}
}
# Load data by key
func _ready():
Bridge.storage.get("level", funcref(self, "_on_storage_get_completed"))
func _on_storage_get_completed(success, data):
if success:
if data != null:
print(data)
else:
# No data for the key 'level'
print("Data is null")
# Load data by multiple keys
func _ready():
Bridge.storage.get(["level", "coins"], funcref(self, "_on_storage_get_completed"))
func _on_storage_get_completed(success, data):
if success:
if data[0] != null:
print("Level: ", data[0])
else:
# No data for the key 'level'
print("Level is null")
if data[1] != null:
print("Coins: ", data[1])
else:
# No data for the key 'coins'
print("Coins is null")
# Load data from a specific storage type
Bridge.storage.get("level", funcref(self, "_on_storage_get_completed"), Bridge.StorageType.LOCAL_STORAGE)
# Load data by key
func _ready():
Bridge.storage.get("level", Callable(self, "_on_storage_get_completed"))
func _on_storage_get_completed(success, data):
if success:
if data != null:
print(data)
else:
# No data for the key 'level'
print("Data is null")
# Load data by multiple keys
func _ready():
Bridge.storage.get(["level", "coins"], Callable(self, "_on_storage_get_completed"))
func _on_storage_get_completed(success, data):
if success:
if data[0] != null:
print("Level: ", data[0])
else:
# No data for the key 'level'
print("Level is null")
if data[1] != null:
print("Coins: ", data[1])
else:
# No data for the key 'coins'
print("Coins is null")
# Load data from a specific storage type
Bridge.storage.get("level", Callable(self, "_on_storage_get_completed"), Bridge.StorageType.LOCAL_STORAGE)
// Load data by key
var keys = ["coins", "level"]
playgama_bridge_storage_get(json_stringify(keys))
// callback via Async Social Event
if async_load[? "type"] == "playgama_bridge_storage_get_callback" {
if async_load[? "success"] {
var values = json_parse(async_load[? "data"])
var coins = values[0]
var level = values[1]
if is_undefined(coins) {
// there is no stored data for key "coins"
}
if is_undefined(level) {
// there is no stored data for key "level"
}
}
}
local bridge = require("bridge.bridge")
function init(self)
bridge.storage.get(
{ "coins", "level" },
function (_, data)
if data.coins then
print("Coins: ", data.coins)
end
if data.level then
print("Level: ", data.level)
end
end,
function ()
-- error
end
)
end
// Load data by key
bridge.storage.get('key')
.then(data => {
// Data loaded and you can work with it
// data = null if there is no data for the given key
console.log('Data: ', data)
})
.catch(error => {
// Error, something went wrong
})
// Load data by multiple keys
bridge.storage.get(['key_1', 'key_2'])
.then(data => {
// Data loaded and you can work with it
// data[n] = null if there is no data for the given key
console.log('Data: ', data)
})
.catch(error => {
// Error, something went wrong
})
// Save data by key
bridge.storage.set('key', 'value')
.then(() => {
// Data successfully saved
})
.catch(error => {
// Error, something went wrong
})
// Save data by multiple keys
bridge.storage.set(['key_1', 'key_2'], ['value_1', 'value_2'])
.then(() => {
// Data successfully saved
})
.catch(error => {
// Error, something went wrong
})
// Save data by key
private void Start()
{
Bridge.storage.Set("level", "dungeon_123", OnStorageSetCompleted);
}
private void OnStorageSetCompleted(bool success)
{
Debug.Log($"OnStorageSetCompleted, success: {success}");
}
// Save data by multiple keys
private void Start()
{
var keys = new List<string>() { "level", "is_tutorial_completed", "coins" };
var data = new List<object>() { "dungeon_123", true, 12 };
Bridge.storage.Set(keys, data, OnStorageSetCompleted);
}
// Save data to a specific storage type
private void Start()
{
Bridge.storage.Set("level", "dungeon_123", OnStorageSetCompleted, StorageType.LocalStorage);
}
# Save data by key
func _ready():
Bridge.storage.set("level", "dungeon_123", funcref(self, "_on_storage_set_completed"))
func _on_storage_set_completed(success):
print("On Storage Set Completed, success: ", success)
# Save data by multiple keys
Bridge.storage.set(["level", "is_tutorial_completed", "coins"], ["dungeon_123", true, 42], funcref(self, "_on_storage_set_completed"))
# Save data to a specific storage type
Bridge.storage.set("level", "dungeon_123", funcref(self, "_on_storage_set_completed"), Bridge.StorageType.LOCAL_STORAGE)
# Save data by key
func _ready():
Bridge.storage.set("level", "dungeon_123", Callable(self, "_on_storage_set_completed"))
func _on_storage_set_completed(success):
print("On Storage Set Completed, success: ", success)
# Save data by multiple keys
Bridge.storage.set(["level", "is_tutorial_completed", "coins"], ["dungeon_123", true, 42], Callable(self, "_on_storage_set_completed"))
# Save data to a specific storage type
Bridge.storage.set("level", "dungeon_123", Callable(self, "_on_storage_set_completed"), Bridge.StorageType.LOCAL_STORAGE)
var keys = ["coins", "level"]
var values = [42, "dungeon"]
playgama_bridge_storage_set(json_stringify(keys), json_stringify(values))
// callback via Async Social Event
if async_load[? "type"] == "playgama_bridge_storage_set_callback" {
if async_load[? "success"] {
// your logic
}
}
local bridge = require("bridge.bridge")
function init(self)
bridge.storage.set(
{ coins = 42, level = "dungeon" },
function (_)
-- success
end,
function (_)
-- error
end
)
end
// Save data by key
bridge.storage.set('key', 'value')
.then(() => {
// Data successfully saved
})
.catch(error => {
// Error, something went wrong
})
// Save data by multiple keys
bridge.storage.set(['key_1', 'key_2'], ['value_1', 'value_2'])
.then(() => {
// Data successfully saved
})
.catch(error => {
// Error, something went wrong
})
// Delete data by key
bridge.storage.delete('key')
.then(() => {
// Data successfully deleted
})
.catch(error => {
// Error, something went wrong
})
// Delete data by multiple keys
bridge.storage.delete(['key_1', 'key_2'])
.then(() => {
// Data successfully deleted
})
.catch(error => {
// Error, something went wrong
})
// Delete data by key
private void Start()
{
Bridge.storage.Delete("level", OnStorageDeleteCompleted);
}
private void OnStorageDeleteCompleted(bool success)
{
Debug.Log($"OnStorageDeleteCompleted, success: {success}");
}
// Delete data by multiple keys
private void Start()
{
var keys = new List<string>() { "level", "is_tutorial_completed", "coins" };
Bridge.storage.Delete(keys, OnStorageDeleteCompleted);
}
// Delete data from a specific storage type
private void Start()
{
Bridge.storage.Delete("level", OnStorageDeleteCompleted, StorageType.LocalStorage);
}
# Delete data by key
func _ready():
Bridge.storage.delete("level", funcref(self, "_on_storage_delete_completed"))
func _on_storage_delete_completed(success):
print("On Storage Delete Completed, success: ", success)
# Delete data by multiple keys
Bridge.storage.delete(["level", "is_tutorial_completed", "coins"], funcref(self, "_on_storage_delete_completed"))
# Delete data from a specific storage type
Bridge.storage.delete("level", funcref(self, "_on_storage_delete_completed"), Bridge.StorageType.LOCAL_STORAGE)
# Delete data by key
func _ready():
Bridge.storage.delete("level", Callable(self, "_on_storage_delete_completed"))
func _on_storage_delete_completed(success):
print("On Storage Delete Completed, success: ", success)
# Delete data by multiple keys
Bridge.storage.delete(["level", "is_tutorial_completed", "coins"], Callable(self, "_on_storage_delete_completed"))
# Delete data from a specific storage type
Bridge.storage.delete("level", Callable(self, "_on_storage_delete_completed"), Bridge.StorageType.LOCAL_STORAGE)
var keys = ["coins", "level"]
playgama_bridge_storage_delete(json_stringify(keys))
// callback via Async Social Event
if async_load[? "type"] == "playgama_bridge_storage_delete_callback" {
if async_load[? "success"] {
// your logic
}
}
local bridge = require("bridge.bridge")
function init(self)
bridge.storage.delete(
{ "coins", "level" },
function ()
-- success
end,
function ()
-- error
end
)
end
// Delete data by key
bridge.storage.delete('key')
.then(() => {
// Data successfully deleted
})
.catch(error => {
// Error, something went wrong
})
// Delete data by multiple keys
bridge.storage.delete(['key_1', 'key_2'])
.then(() => {
// Data successfully deleted
})
.catch(error => {
// Error, something went wrong
})