# Multi-Device Progress Sync

## Goal

Load saved data when app starts and listen for changes from other devices.

## Actions Required

| Action                         | Purpose                                 |
| ------------------------------ | --------------------------------------- |
| CloudServicesGetValue          | Load saved data                         |
| CloudServicesOnSavedDataChange | Listen for remote updates               |
| CloudServicesGetChangedKeys    | Read changed key list (optional helper) |

## Variables Needed

* playerLevel (Int)
* totalScore (Int)
* changedKeys (Array: String) - PlayMaker Array (set element type to String)
* changeReason (Enum: CloudSavedDataChangeReasonCode)

## Implementation Steps

### 1. State: LoadProgress (On App Start)

**Action:** CloudServicesGetValue

* **Inputs:**
  * key: "player\_level"
  * valueType: Int
* **Outputs:**
  * value → playerLevel

Repeat for each key you want to load.

### 2. State: ListenForChanges

**Action:** CloudServicesOnSavedDataChange

* **Outputs:**
  * changedKeys → changedKeys array
  * changeReason → changeReason
* **Events:**
  * dataChangedEvent → HandleRemoteChange

### 3. State: HandleRemoteChange

Use the `changedKeys` array from `CloudServicesOnSavedDataChange` directly, or call `CloudServicesGetChangedKeys` to fetch the same cached list in a later state. Loop `keyIndex = 0..changedKeys.Length-1` and read each key using PlayMaker Array Get.

1. If you need conflict handling, call `CloudServicesGetCloudAndLocalCacheValues(keyName)` to get both values:
   * decide your policy (cloud wins / local wins / max wins / prompt user)
2. Otherwise, just reload from cloud:
   * If keyName == "player\_level" → `CloudServicesGetValue("player_level", valueType:Int)` and update `playerLevel`
   * If keyName == "total\_score" → `CloudServicesGetValue("total_score", valueType:Int)` and update `totalScore`

If you don’t want a loop, you can also directly use PlayMaker Array actions (Array Get / Array Contains) on `changedKeys`.

## Conflict Resolution Strategies

**Last Write Wins:** Use remote value always **Highest Wins:** Compare local vs remote, keep higher value **Manual Merge:** Prompt user to choose


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://assetstore.essentialkit.voxelbusters.com/features/cloud-services/playmaker/use-cases/use-case-2-multi-device-sync.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
