Skip to content

Cloud Storage

The Y8 SDK allows your game to store player-specific data in the cloud, enabling players to access their progress across devices.

Cloud Storage is intended for small amounts of persistent data such as save games, preferences, settings, and other player-specific information.

Authentication required

Cloud Storage requires the player to be authenticated.


Storage Guidelines

  • Save only the data your game needs to persist.
  • Use JSON for structured game data where appropriate.
  • Individual values must not exceed 30 KB.
  • Avoid saving data too frequently.
  • If your game supports auto-save, throttle save requests.
  • Prefer batching multiple changes into fewer save operations.

Save Data

Save player data to Cloud Storage.

y8Sdk.saveData({
    key: "save",
    value: JSON.stringify(gameState),
    retries: true
})
.then(() => {
    console.log("Game saved");
})
.catch((error) => {
    console.error(error.message);
});

Parameters

Property Type Required Description
key string Yes Storage key.
value string Yes Value to store. Maximum size: 30 KB.
retries boolean No Automatically retry temporarily rejected saves. Default: true.

Automatic retries

A save can be turned away when the server is rate-limiting the player. By default the SDK handles that for you: it retries up to five times, three seconds apart, before giving up.

A save that survives all of that fails with the code Y8Sdk.saveRejected, which is worth distinguishing from a network error — it means the server deliberately refused, not that the connection dropped:

y8Sdk.saveData({
    key: "save",
    value: JSON.stringify(gameState),
}).catch((error) => {
    if (error.code === Y8Sdk.saveRejected) {
        tellPlayerSaveFailed();
    }
});

Because retries take time, a save can be in flight for up to fifteen seconds before it fails. If you would rather find out immediately and do your own buffering, switch them off:

y8Sdk.saveData({
    key: "save",
    value: JSON.stringify(gameState),
    retries: false
});
JsResponse<SetData> response =
    await Y8.Instance.SaveDataAsync(
        "test_file_key",
        new SaveFileData
        {
            stringValue = "Test save",
            boolValue = true,
            floatValue = 0.01f
        }
    );

if (response.IsSuccess)
{
    Debug.Log("Game saved");
}

Parameters

Parameter Type Required Description
key string Yes Storage key.
value string or serializable class Yes Data to save.

The C3 integration serializes the supplied value as JSON before sending it to Y8.

For structured data, you can use a Construct 3 Dictionary:

saveData → On clicked

    Dictionary → Add key "score" with value score
    Dictionary → Add key "coins" with value coins
    Dictionary → Add key "level" with value level

    Functions → Call saveData
        saveKey: "saveGame"
        saveItem: Dictionary.AsJSON
SaveData

SaveData

Y8.saveData(
    "save",
    gameState
);

The SDK automatically converts the game data to JSON before saving it.

Parameters

Parameter Type Required Description
key String Yes Storage key.
gameState Dynamic Yes Game data to save.

Load Data

Retrieve previously saved player data.

y8Sdk.loadData({
    key: "save"
})
.then((value) => {

    if (value) {
        const gameState = JSON.parse(value);
    }

})
.catch((error) => {
    console.error(error.message);
});

If no value exists for the specified key, the Promise resolves with null.

JsResponse<SaveFileData> response =
    await Y8.Instance.LoadDataAsync<SaveFileData>("test_file_key");

if (response.IsSuccess)
{
    Debug.Log(response.Data.stringValue);
}

If no value exists for the specified key, the returned data is null.

getData → On clicked

    Functions → Call loadData
        saveKey: "saveGame"

SaveData SaveData

When saved data is found, the OnlineDataKeyFound function is triggered.

Construct 3 provides a 'getOnlineSaveData' function for retrieving the data loaded by the most recent loadData() call.

SaveData

The function returns the loaded data as a JSON string.

You can use the JSON with a Construct 3 Dictionary to retrieve individual values.

SaveData

On function OnlineDataKeyFound

    Dictionary → Load from JSON string
                 Functions.getOnlineSaveData

SaveData

When saved data is not found, the OnlineDataKeyNotFound function is triggered. You can use default values for your game variables.

SaveData

Y8.loadData(
    "save",
    function(gameState:Dynamic):Void
    {
        if (gameState != null)
        {
            trace(gameState);
        }
    }
);

The SDK automatically parses the saved JSON data before passing it to the callback.


Remove Data

Delete previously saved data.

y8Sdk.removeData({
    key: "save"
})
.then(() => {
    console.log("Save removed");
})
.catch((error) => {
    console.error(error.message);
});
JsResponse response =
    await Y8.Instance.RemoveDataAsync("test_file_key");

if (response.IsSuccess)
{
    Debug.Log("Save removed");
}

RemoveData → On clicked

    Functions → Call RemoveData
        key: "saveGame"
SaveData SaveData

The player must be authenticated before removing saved data.

Y8.removeData("save");

Best Practices

  • Save only essential player data.
  • Use JSON for structured data where appropriate.
  • Keep saved values below 30 KB.
  • Avoid saving after every gameplay event.
  • Prefer batching changes into fewer save operations.
  • Use a consistent storage key for your game's save data.
  • Ensure the player is authenticated before using Cloud Storage.
  • Handle save and load errors appropriately.
  • Throttle auto-save requests to avoid unnecessary requests.

Platform-Specific Notes

Values are stored as strings. Use JSON.stringify() when saving objects and JSON.parse() when loading them.

Serializable classes can be used for structured Cloud Storage data.

Structured data can be stored using JSON, such as Dictionary.AsJSON.

The SDK automatically converts game data to JSON when saving and parses it when loading.