# Implement Progression

The Progression methods allow you to store, recall, and update player data at any time within the game, unlocking personalized player experiences.&#x20;

### General Custom Progression Game Scene Flow

1. Create keys in Developer Console for `PlayerData and/or InGameItems namespaces`
2. From client, retrieve player data using GetProgressionUserData at any time, prior, during, or at end of match play
3. Call SubmitScore at the conclusion of the match
4. Call UpdateProgressionUserData to update player data
5. Present the player with the custom progression scene
6. Call ReturnToMiniTon to return to the MiniTon BOT

### Progression API

#### Namespaces

There are three namespaces used to segment Progression data:

* **`DefaultPlayerData`**
  * For read-only player data and is game-specific. Keys such as `games_played`, `games_won`, `install_date,` and more are found here.
* **`PlayerData`**
  * For player data and is game specific. Store and retrieve custom player statistics and other custom progression-related data here.
* **`InGameItems`**
  * In-game items are shared across all games in the publisher's portfolio. Store and retrieve virtual goods and global custom progression-related data here.

{% hint style="info" %}
INFO

In order to store data in the **PlayerData** and **InGameItems** namespaces, you must first create your custom keys via the MiniTon Developer Console. Remember to publish your keys to Production when you are ready to distribute your game builds that contain Progression.
{% endhint %}

#### Get Progression User Data

Retrieve data for the current user. The GetProgressionUserData method requires `callback` methods that allow you to handle success and fail scenarios.

{% tabs %}
{% tab title="Unity/C#" %}
{% code overflow="wrap" %}

```csharp
public static void MiniTonCrossPlatform.GetProgressionUserData(string progressionNamespace, List<string> userDataKeys, Action<Dictionary<string, ProgressionValue>> successCallback, Action<string> failureCallback)
```

{% endcode %}

**Parameters**

`progressionNamespace` One of the namespace string constants

* **`ProgressionNamespace.PLAYER_DATA`**
* **`ProgressionNamespace.DEFAULT_PLAYER_DATA`**
* **`ProgressionNamespace.IN_GAME_ITEMS`**

`userDataKeys` String key list of desired fields.

`successCallback` Action delegate to handle successful callback. The method must be defined in the implementation.

`failureCallback` Action delegate to handle failed callback. The method must be defined in the implementation.

**Sample Implementation**

{% code title="MatchController.cs" overflow="wrap" %}

```csharp
using MiniTonSDK;
using UnityEngine;
using System;

public class MatchController : MonoBehaviour

    // Define list of keys to look up within the target namespace
    List<String> keys = new List<String>()
    {
        "games_played",
        "games_won",
        "average_score"
    };

    // Handle success response
    void OnReceivedData(Dictionary<string, MiniTonSDK.ProgressionValue> data)
    {
        Debug.LogWarning("Success");
        // Do something with the data, such as populate a custom Progression scene

        // Example manipulation of the returned data
        // Printing each key/value to console
        foreach(var kvp in data)
            Debug.LogWarning("Progression default player data key: " + kvp.Key + ", value: " + kvp.Value.Value);
    }

    // Handle failure response
    void OnReceivedDataFail(string reason)
    {
        Debug.LogWarning("Fail: " + reason);
        // Continue without Progression data
    }

    public void GetData()
    {
        MiniTonCrossPlatform.GetProgressionUserData(ProgressionNamespace.DEFAULT_PLAYER_DATA, keys, OnReceivedData, OnReceivedDataFail);
    }
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript" %}
For retrieving progression user data using the `MiniTonCrossPlatform.GetProgressionUserData` method, you can use the following JavaScript code:

```javascript
// Define the ProgressionNamespace constants
const ProgressionNamespace = {
    PLAYER_DATA: "PlayerData",
    DEFAULT_PLAYER_DATA: "DefaultPlayerData",
    IN_GAME_ITEMS: "InGameItems"
};

// Simulate MiniTonCrossPlatform and Action delegates (replace with actual implementation)
const MiniTonCrossPlatform = {
    GetProgressionUserData: function (progressionNamespace, userDataKeys, successCallback, failureCallback) {
        // Simulate data retrieval (replace with your actual logic)
        const userData = {
            // Simulated data for demonstration purposes
            games_played: 10,
            games_won: 5,
            install_date: "2023-01-01",
            // Add more key-value pairs as needed
        };

        // Simulate success or failure callback (replace with your actual logic)
        if (userData) {
            successCallback(userData);
        } else {
            failureCallback("Failed to retrieve user data");
        }
    }
};

// Usage example
const progressionNamespace = ProgressionNamespace.PLAYER_DATA;
const userDataKeys = ["games_played", "games_won", "install_date"];

function handleSuccess(userData) {
    console.log("User Data:", userData);
    // Implement your logic to handle the retrieved user data here
}

function handleFailure(reason) {
    console.error("Error:", reason);
    // Implement your logic to handle the failure here
}

MiniTonCrossPlatform.GetProgressionUserData(progressionNamespace, userDataKeys, handleSuccess, handleFailure);

```

\
We define the `ProgressionNamespace` constants and simulate the `MiniTonCrossPlatform` object and Action delegates for demonstration purposes.&#x20;

The usage example demonstrates how to call `MiniTonCrossPlatform.GetProgressionUserData` with the specified progression namespace, user data keys, success callback, and failure callback.

For retrieving Progression user data using the MiniTonSDK, sample implementation:

```javascript
const MiniTonSDK = {
    GetProgressionUserData: function (progressionNamespace, userDataKeys, successCallback, failureCallback) {
        // Simulate data retrieval (replace with your actual logic)
        const userData = {
            // Simulated data for demonstration purposes
            games_played: { Value: 10 },
            games_won: { Value: 5 },
            average_score: { Value: 75.5 },
            // Add more key-value pairs as needed
        };

        // Simulate success or failure callback (replace with your actual logic)
        if (userData) {
            successCallback(userData);
        } else {
            failureCallback("Failed to retrieve user data");
        }
    },
};

// Simulate Unity's Debug class (replace with actual implementation if applicable)
const Debug = {
    LogWarning: function (message) {
        console.warn(message);
    }
};

// Define list of keys to look up within the target namespace
const keys = ["games_played", "games_won", "average_score"];

// Handle success response
function onReceivedData(data) {
    Debug.LogWarning("Success");
    // Do something with the data, such as populate a custom Progression scene

    // Example manipulation of the returned data
    // Printing each key/value to console
    for (const key in data) {
        if (data.hasOwnProperty(key)) {
            const value = data[key].Value;
            console.warn("Progression default player data key: " + key + ", value: " + value);
        }
    }
}

// Handle failure response
function onReceivedDataFail(reason) {
    Debug.LogWarning("Fail: " + reason);
    // Continue without Progression data
}

// Simulate the MatchController behavior (replace with actual implementation)
const MatchController = {
    GetData: function () {
        MiniTonSDK.GetProgressionUserData("DEFAULT_PLAYER_DATA", keys, onReceivedData, onReceivedDataFail);
    },
};

// Usage example
MatchController.GetData();
```

{% endtab %}
{% endtabs %}

#### Update Progression User Data

Write data for the current user. The UpdateProgressionUserData method requires `callback` methods that allow you to handle success and fail scenarios.

{% hint style="info" %}
**INFO**

The **DefaultPlayerData** namespace is read-only, and cannot be used with this method.

**NOTE**

This method can update up to 25 elements per invocation.
{% endhint %}

{% tabs %}
{% tab title="Unity/C#" %}

<pre class="language-csharp" data-overflow="wrap"><code class="lang-csharp"><strong>public void MiniTonCrossPlatform.UpdateProgressionUserData(string progressionNamespace, Dictionary&#x3C;string, object> userDataUpdates, Action successCallback, Action&#x3C;string> failureCallback)
</strong></code></pre>

**Parameters**

`progressionNamespace` One of the namespace string constants

* **`ProgressionNamespace.PLAYER_DATA`**
* **`ProgressionNamespace.IN_GAME_ITEMS`**

`userDataUpdates` Dictionary of key/value pairs to be updated.

`successCallback` Action delegate to handle successful callback. The method must be defined in the implementation.

`failureCallback` Action delegate to handle failed callback. The method must be defined in the implementation.

**Sample Implementation**

<pre class="language-csharp" data-title="MatchController.cs" data-overflow="wrap"><code class="lang-csharp">using MiniTon;
using UnityEngine;

public class MatchController : MonoBehaviour

    // Define list of keys to update
    // Must match keys created in the Developer Console!
    Dictionary&#x3C;String, object> updateDict = new Dictionary&#x3C;String, object>()
    {
        { "achievement_level", 5.5 },
        { "combos_attained", 10 },
        { "character_color", "orange" }
    };
    // Handle success response
    void OnSentDataSuccess()
    {
        Debug.LogWarning("Successfully updated!");
    }

    // Handle failure response
    void OnSentDataFail(string reason)
    {
        Debug.LogWarning("Fail: " + reason);
    }

    void UpdateData()
    {
<strong>MiniTonCrossPlatform.UpdateProgressionUserData(ProgressionNamespace.PLAYER_DATA,updateDict, OnSentDataSuccess, OnSentDataFail);
</strong>    }
</code></pre>

{% endtab %}

{% tab title="JavaScript" %}
For updating Progression user data using the `MiniTonCrossPlatform.UpdateProgressionUserData` method

{% code overflow="wrap" %}

```javascript
const MiniTonCrossPlatform = {
    UpdateProgressionUserData: function (progressionNamespace, userDataUpdates, successCallback, failureCallback) {
        // Simulate data update (replace with your actual logic)
        const updatedUserData = {};

        // Apply updates to the user data (replace with your actual logic)
        for (const key in userDataUpdates) {
            if (userDataUpdates.hasOwnProperty(key)) {
                updatedUserData[key] = userDataUpdates[key];
            }
        }

        // Simulate success or failure callback (replace with your actual logic)
        if (updatedUserData) {
            successCallback();
        } else {
            failureCallback("Failed to update user data");
        }
    },
};

// Simulate Unity's Debug class (replace with actual implementation if applicable)
const Debug = {
    LogWarning: function (message) {
        console.warn(message);
    }
};

// Define the ProgressionNamespace constants
const ProgressionNamespace = {
    PLAYER_DATA: "PlayerData",
    IN_GAME_ITEMS: "InGameItems"
};

// Define the userDataUpdates dictionary with key/value pairs to be updated
const userDataUpdates = {
    games_played: 11,
    games_won: 6,
    average_score: 78.5,
    // Add more key-value pairs as needed
};

// Handle success response
function onSuccess() {
    Debug.LogWarning("User data updated successfully");
    // Implement your logic to handle the successful update here
}

// Handle failure response
function onFailure(reason) {
    Debug.LogWarning("Failed to update user data: " + reason);
    // Implement your logic to handle the failure here
}

// Simulate the MatchController behavior (replace with actual implementation)
const MatchController = {
    UpdateUserData: function () {
        MiniTonCrossPlatform.UpdateProgressionUserData(
            ProgressionNamespace.PLAYER_DATA,
            userDataUpdates,
            onSuccess,
            onFailure
        );
    },
};

// Usage example
MatchController.UpdateUserData();

```

{% endcode %}

`MiniTonCrossPlatform.UpdateProgressionUserData` with the specified namespace, user data updates, success callback, and failure callback to update Progression user data.

**Sample** **Implementation**

{% code overflow="wrap" %}

```javascript
const MiniTonCrossPlatform = {
    UpdateProgressionUserData: function (progressionNamespace, userDataUpdates, successCallback, failureCallback) {
        // Simulate data update (replace with your actual logic)
        const updatedUserData = {};

        // Apply updates to the user data (replace with your actual logic)
        for (const key in userDataUpdates) {
            if (userDataUpdates.hasOwnProperty(key)) {
                updatedUserData[key] = userDataUpdates[key];
            }
        }

        // Simulate success or failure callback (replace with your actual logic)
        if (updatedUserData) {
            successCallback();
        } else {
            failureCallback("Failed to update user data");
        }
    },
};

// Simulate Unity's Debug class (replace with actual implementation if applicable)
const Debug = {
    LogWarning: function (message) {
        console.warn(message);
    }
};

// Define the userDataUpdates dictionary with key/value pairs to be updated
const userDataUpdates = {
    achievement_level: 5.5,
    combos_attained: 10,
    character_color: "orange",
    // Add more key-value pairs as needed
};

// Handle success response
function onSentDataSuccess() {
    Debug.LogWarning("Successfully updated!");
    // Implement your logic to handle the successful update here
}

// Handle failure response
function onSentDataFail(reason) {
    Debug.LogWarning("Fail: " + reason);
    // Implement your logic to handle the failure here
}

// Simulate the MatchController behavior (replace with actual implementation)
const MatchController = {
    UpdateData: function () {
        MiniTonCrossPlatform.UpdateProgressionUserData(
            ProgressionNamespace.PLAYER_DATA,
            userDataUpdates,
            onSentDataSuccess,
            onSentDataFail
        );
    },
};

// Usage example
MatchController.UpdateData();
```

{% endcode %}
{% endtab %}
{% endtabs %}

#### Default Player Data

These are automatically updating, read-only statistics from the MiniTon platform

For use with GetProgressionUserData

{% hint style="info" %}
INFO

Default Player Data values are calculated with completed matches that have a result. In progress games that have not yet matched with another player are excluded, and do not update the values.
{% endhint %}

| Key                   | Data Type | Description                                            |
| --------------------- | --------- | ------------------------------------------------------ |
| games\_played         | Integer   | A count of the games a player has entered              |
| cash\_games\_played   | Integer   | A count of the cash games a player has entered         |
| games\_won            | Integer   | A count of the total games a player has won            |
| cash\_games\_won      | Integer   | A count of the total cash games a player has won       |
| best\_score\_lifetime | Float     | The best score achieved by this player                 |
| average\_score        | Float     | The average of all scores by this player               |
| player\_level         | Integer   | The player’s level for this game                       |
| MiniTon\_level        | Integer   | The player’s global MiniTon level                      |
| install\_date         | Date      | The UTC date and timestamp the user installed the game |

### Progression Room Entry Point

#### Configure Progression Room Entry Point

1. Configure your Entry Point within the Developer Console by clicking on `Progression -> Entry Points`. Be sure to complete all required fields. Hit `Save` to immediately see your room in Sandbox. Publish & Assign is used to share your entry point with your players in production. You can create dynamic text in the Title and Subtitle fields by inserting your progression keys names directly into the input box. Example: You have `${Custom_Key_Name}` challenges remaining!
2. Implement OnProgressionRoomEnter from MiniTonDelegate interface to load your progression scene
3. Call ReturnToMiniTon to return to the MiniTon BOT

#### Implement Progression Room

{% tabs %}
{% tab title="Unity/C#" %}
For Unity, you need to implement the `MiniTonMatchDelegate` interface as a regular C# class. This will be instantiated when launching MiniTon later.

{% code title="MiniTonGameController.cs" overflow="wrap" %}

```csharp
using MiniTonSDK;
using UnityEngine.SceneManagement;

public sealed class MiniTonGameController : MiniTonMatchDelegate
{
    private const string GameSceneName      = "Level1";  // Your game scene name
    private const string StartMenuSceneName = "StartMenu";  // Your menu scene (optional)
    private const string ProgressionSceneName = "PlayerProgress"; // Your progression scene

    public void OnMatchWillBegin(Match matchInfo)
    {
    }

    public void OnMiniTonWillExit()
    {
    }

    public void OnProgressionRoomEnter()
    {
        // Load your progression scene here
        SceneManager.LoadScene(ProgressionSceneName);
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript" %}

```javascript
const MiniTonSDK = {
    Match: {
        // Define any properties or methods needed for the match info
    },
};

const SceneManager = {
    LoadScene: function (sceneName) {
        console.log("Loading scene: " + sceneName);
        // Implement your scene loading logic here (e.g., using Unity's SceneManager)
    },
};

class MiniTonGameController {
    constructor() {
        this.GameSceneName = "Level1";  // Your game scene name
        this.StartMenuSceneName = "StartMenu";  // Your menu scene (optional)
        this.ProgressionSceneName = "PlayerProgress"; // Your progression scene
    }

    OnMatchWillBegin(matchInfo) {
        // Implement your logic when the match begins
    }

    OnMiniTonWillExit() {
        // Implement your logic when MiniTon is about to exit
    }

    OnProgressionRoomEnter() {
        // Load your progression scene here
        SceneManager.LoadScene(this.ProgressionSceneName);
    }
}

// Usage example
const miniTonGameController = new MiniTonGameController();
miniTonGameController.OnProgressionRoomEnter();

```

{% endtab %}
{% endtabs %}
