Godot 4 · GDScript
Cloud saves
Cloud saves let a player keep progress across devices. Each save lives in a numbered slot (1-10) and is a free-form data object validated against the schema you define in the panel.
Panel Configuration
In the panel, enable cloud saving and define the save schema: the fields your save object may contain and their types. The number of slots and the size limit depend on your plan.
Saves are validated against this schema on the server: a field not in the schema, or a wrong type, is rejected.
Save to a Slot
Write (or overwrite) a slot with your save data. Listen to save_completed.
Gamdato.save_completed.connect(_on_saved)
Gamdato.save_game(1, {"level": 5, "coins": 120, "unlocked": ["sword"]})
func _on_saved(ok: bool, slot: int, meta: Dictionary, error_code: String) -> void:
if ok: print("Saved slot %d (%d bytes)" % [slot, meta.size_bytes])
else: print("Save failed: %s" % error_code)error_code may be plan (cloud saves not in your plan), too_large, storage_full or validation (data does not match the schema).
Load a Slot
Read a slot back. An empty slot is not an error: found is simply false.
Gamdato.save_loaded.connect(_on_loaded)
Gamdato.load_game(1)
func _on_loaded(slot: int, found: bool, data: Dictionary, error_code: String) -> void:
if found:
_apply_save(data)
else:
_new_game()# save_loaded(slot: int, found: bool, data: Dictionary, error_code: String)
# found = false for an empty slot (not an error)
# data = the Dictionary you saved, verbatim:
{ "level": 5, "coins": 120 }List Slots
List which slots are used, with their size and last-updated time (no data). Useful for a save-slot menu. Arrives through saves_listed.
Gamdato.saves_listed.connect(_on_saves)
Gamdato.list_saves()
func _on_saves(saves: Array) -> void:
for s in saves:
print("Slot %d - updated %s" % [s.slot, s.updated_at])# saves: Array, each used slot (metadata only, no data):
{
"slot": int,
"size_bytes": int,
"updated_at": String
}
# save_completed -> meta has the same shape (slot, size_bytes, updated_at).Delete a Slot
Remove a slot. Deleting an empty slot is harmless (it still reports success).
Gamdato.save_deleted.connect(_on_deleted)
Gamdato.delete_save(1)
func _on_deleted(ok: bool, slot: int, error_code: String) -> void:
if ok: print("Slot %d cleared" % slot)