Back to Blog
Guide
January 10, 20258 min read

Building Cross-Platform Cloud Saves for Godot Games

A complete guide to implementing cloud saves with version control and conflict resolution in Godot.

Cloud saves are essential for modern games. Players expect to continue their progress across devices seamlessly. In this guide, we'll show you how to implement a robust cloud save system in your Godot game using Godot BaaS.

Why Cloud Saves Matter

Cloud saves provide several critical benefits:

  • Players can switch between devices without losing progress
  • Automatic backup prevents data loss
  • Version control helps recover from corrupted saves
  • Conflict resolution handles simultaneous play on multiple devices

Prerequisites

Before implementing cloud saves, make sure you have:

  • Godot BaaS plugin installed and configured
  • Player authentication set up (see our authentication guide)
  • A basic understanding of GDScript

Step 1: Design Your Save Data Structure

First, define what data you need to save. Keep it organized and serializable:

# SaveData.gd
class_name SaveData
extends Resource

@export var player_name: String = ""
@export var level: int = 1
@export var experience: int = 0
@export var gold: int = 100
@export var inventory: Array = []
@export var completed_quests: Array = []
@export var settings: Dictionary = {}

func to_dict() -> Dictionary:
    return {
        "player_name": player_name,
        "level": level,
        "experience": experience,
        "gold": gold,
        "inventory": inventory,
        "completed_quests": completed_quests,
        "settings": settings
    }

func from_dict(data: Dictionary) -> void:
    player_name = data.get("player_name", "")
    level = data.get("level", 1)
    experience = data.get("experience", 0)
    gold = data.get("gold", 100)
    inventory = data.get("inventory", [])
    completed_quests = data.get("completed_quests", [])
    settings = data.get("settings", {})

Step 2: Implement Save Manager

Create a manager to handle saving and loading:

# SaveManager.gd
extends Node

var current_save: SaveData = SaveData.new()
var save_key: String = "player_save"

func save_to_cloud() -> void:
    var save_data = current_save.to_dict()
    var json_string = JSON.stringify(save_data)
    
    GodotBaaS.save_data(save_key, json_string)

func _on_save_success(data):
    print("Save successful! Version: ", data.version)

func _on_save_failed(error):
    print("Save failed: ", error)

func load_from_cloud() -> void:
    GodotBaaS.load_data(save_key)

func _on_load_success(data):
    var parsed = JSON.parse_string(data.content)
    if parsed:
        current_save.from_dict(parsed)
        print("Save loaded! Version: ", data.version)
    else:
        print("Failed to parse save data")

func _on_load_failed(error):
    print("Load failed: ", error)
    # Use default save data

func _ready():
    GodotBaaS.save_completed.connect(_on_save_success)
    GodotBaaS.save_failed.connect(_on_save_failed)
    GodotBaaS.load_completed.connect(_on_load_success)
    GodotBaaS.load_failed.connect(_on_load_failed)

Step 3: Handle Conflicts

When players play on multiple devices, conflicts can occur. Here's how to handle them:

func resolve_conflict(local_data: Dictionary, cloud_data: Dictionary) -> Dictionary:
    # Strategy 1: Use most recent (based on timestamp)
    if local_data.get("last_modified", 0) > cloud_data.get("last_modified", 0):
        return local_data
    
    # Strategy 2: Merge data (keep highest values)
    return {
        "player_name": cloud_data.get("player_name"),
        "level": max(local_data.get("level", 1), cloud_data.get("level", 1)),
        "experience": max(local_data.get("experience", 0), cloud_data.get("experience", 0)),
        "gold": max(local_data.get("gold", 0), cloud_data.get("gold", 0)),
        "inventory": merge_arrays(local_data.get("inventory", []), cloud_data.get("inventory", [])),
        "completed_quests": merge_arrays(local_data.get("completed_quests", []), cloud_data.get("completed_quests", [])),
        "settings": cloud_data.get("settings", {})
    }

func merge_arrays(arr1: Array, arr2: Array) -> Array:
    var merged = arr1.duplicate()
    for item in arr2:
        if item not in merged:
            merged.append(item)
    return merged

Step 4: Auto-Save Implementation

Implement automatic saving to ensure players never lose progress:

var auto_save_timer: Timer
var save_interval: float = 60.0  # Save every 60 seconds

func setup_auto_save():
    auto_save_timer = Timer.new()
    auto_save_timer.wait_time = save_interval
    auto_save_timer.timeout.connect(_on_auto_save)
    add_child(auto_save_timer)
    auto_save_timer.start()

func _on_auto_save():
    save_to_cloud()
    print("Auto-save triggered")

func _notification(what):
    if what == NOTIFICATION_WM_CLOSE_REQUEST:
        # Save before closing
        save_to_cloud()
        await get_tree().create_timer(1.0).timeout
        get_tree().quit()

Step 5: Version Control

Godot BaaS automatically versions your saves. You can retrieve previous versions:

func load_previous_version(version: int):
    GodotBaaS.load_data_version(save_key, version)

func list_save_versions():
    GodotBaaS.list_save_versions(save_key)

func _on_versions_loaded(versions: Array):
    print("Available save versions:")
    for version in versions:
        print("Version ", version.version, " - ", version.created_at)

Best Practices

  • Compress large saves: Use compression for save files larger than 100KB
  • Validate data: Always validate loaded data before using it
  • Handle offline mode: Cache saves locally and sync when online
  • Show save indicators: Give players visual feedback when saving
  • Test conflict resolution: Simulate multi-device scenarios

Testing Your Implementation

Test your cloud save system thoroughly:

  1. Save data and verify it appears in the dashboard
  2. Load data on a different device or after clearing local storage
  3. Test offline mode and sync behavior
  4. Simulate conflicts by playing on two devices simultaneously
  5. Test version rollback functionality

Ready to implement cloud saves?

Get started with Godot BaaS and give your players seamless cross-platform progression.

Start Building Free