Implement Progression
One of the appealing aspects of the most popular mobile games is the concept of progression. That is, your investment in the gameplay over time yields additional benefits and rewards. This provides a sense of accomplishment players, as well as giving them goals to shoot for, helping to ensure they have a reason to keep coming back again and again.
Progression provides a way for developers to add this critical component, to help drive the success of their games. The Progression methods allow developers to store, recall, and update player data at any time within the game, unlocking personalized player experiences. For a broader overview of Progression features, see Progression and Player Data
General Custom Progression Game Scene Flow
- Create keys in Developer Console for
PlayerData
and/orInGameItems
namespaces - From client, retrieve player data using GetProgressionUserData at any time, prior, during, or at end of match play
- Call SubmitScore at the conclusion of the match
- Call UpdateProgressionUserData to update player data
- Present the player with the custom progression scene
- Call ReturnToSkillz to return to the Skillz UI
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.
- For read-only player data and is game specific. Keys such as
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 and is shared across all games in publisher's portfolio. Store and retrieve virtual goods and global custom progression-related data here.
In order to store data in the PlayerData and InGameItems namespaces, you must first create your custom keys via the Skillz Developer Console. Remember to publish your keys to Production when you are ready to distribute your game builds that contain Progression.
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.
- Unity/C#
- iOS/Swift
- iOS/Objective-C
- Android/Java
public static void SkillzCrossPlatform.GetProgressionUserData(string progressionNamespace, List<string> userDataKeys, Action<Dictionary<string, ProgressionValue>> successCallback, Action<string> failureCallback)
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
using SkillzSDK;
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, SkillzSDK.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()
{
SkillzCrossPlatform.GetProgressionUserData(ProgressionNamespace.DEFAULT_PLAYER_DATA, keys, OnReceivedData, OnReceivedDataFail);
}
func getUserData(
forNamespace progressionNamespace: String?,
withKeys userDataKeys: inout [NSMutableArray],
withSuccess successCompletion: @escaping (_ userData: [NSDictionary : Any]?) -> Void,
withFailure failureCompletion: @escaping (_ error: String?) -> Void
)
Parameters
progressionNamespace
One of the NSString constants
ProgressionNamespacePlayerData
ProgressionNamespaceDefaultPlayerData
ProgressionNamespaceInGameItems
userDataKeys
String key NSMutableArray of desired fields.
successCompletion
Function to handle callback success and NSDictionary return data object.
failureCompletion
Function to handle callback failure and String error message.
Sample Implementation
Skillz.skillzInstance().getUserData(
forNamespace: ProgressionNamespacePlayerData,
withKeys: requestedUserDataKeys,
withSuccess: { [self] userData in
let msg = "Successful GET: \(userData ?? [:])"
requestKeysView.text = msg
requestedUserDataKeys.removeAll()
},
withFailure: { [self] error in
let msg = "Failed to GET: \(error ?? "")"
)
- (void)getUserDataForNamespace:(NSString *)progressionNamespace
withKeys:(NSMutableArray *)userDataKeys
withSuccess:(void (^_Nonnull)(NSDictionary * userData))successCompletion
withFailure:(void (^_Nonnull)(NSString * error))failureCompletion;
Parameters
progressionNamespace
One of the NSString constants
ProgressionNamespacePlayerData
ProgressionNamespaceDefaultPlayerData
ProgressionNamespaceInGameItems
userDataKeys
String key NSMutableArray of desired fields.
successCompletion
Function to handle callback success and NSDictionary return data object.
failureCompletion
Function to handle callback failure and NSString error message.
Sample Implementation
NSMutableArray *keys = [[NSMutableArray alloc] initWithObjects:"games_played", "games_won", "average_score", nil];
[[Skillz skillzInstance] getUserDataForNamespace: ProgressionNamespacePlayerData
withKeys:self.requestedUserDataKeys
withSuccess:^(NSDictionary * userData){
NSString *msg = [NSString stringWithFormat:@"Successful GET: %@", userData];
self.requestKeysView.text = msg;
[self.requestedUserDataKeys removeAllObjects];
} withFailure:^(NSString * error){
NSString *msg = [NSString stringWithFormat:@"Failed to GET: %@", error];
[self.requestKeysView setText:msg];
[self.requestedUserDataKeys removeAllObjects];
}];
public static void SkillzProgression.getUserData(String namespace, List<String> userDataKeys, ProgressionCallback callback)
Parameters
namespace
One of the namespace Strings
ProgressionNamespace.PlayerData
ProgressionNamespace.DefaultPlayerData
ProgressionNamespace.InGameItems
userDataKeys
String key list of desired fields.
callback
ProgressionCallback object to handle callback success or failure. Must be defined in implementation.
Sample Implementation
List<String> keys = new List<String>() {
"games_played",
"games_won",
"average_score"
}
SkillzProgression.getUserData(ProgressionNamespace.DefaultPlayerData, keys, new ProgressionCallback() {
@Override
public void failure(Exception error) {
new AlertDialog.Builder(getActivity())
.setMessage("Request failed! " + error.getMessage())
.setNegativeButton("Ok", null)
.create()
.show();
}
@Override
public void success(Map<String, ProgressionValue> data) {
requestedKeys.clear();
for (String key : data.keySet()) {
requestedKeys.add(key + ": " + data.get(key).value);
}
requestedKeysListAdapter.notifyDataSetChanged();
String result = new GsonBuilder().setPrettyPrinting().create().toJson(data);
progressionTextView.setText(result);
new AlertDialog.Builder(getActivity())
.setMessage("Request successful!")
.setNegativeButton("Ok", null)
.create()
.show();
}
});
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.
The DefaultPlayerData namespace is read-only, and cannot be used with this method.
This method can update up to 25 elements per invocation.
- Unity/C#
- iOS/Swift
- iOS/Objective-C
- Android/Java
public void SkillzCrossPlatform.UpdateProgressionUserData(string progressionNamespace, Dictionary<string, object> userDataUpdates, Action successCallback, Action<string> failureCallback)
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
using Skillz;
using UnityEngine;
public class MatchController : MonoBehaviour
// Define list of keys to update
// Must match keys created in the Developer Console!
Dictionary<String, object> updateDict = new Dictionary<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()
{
SkillzCrossPlatform.UpdateProgressionUserData(ProgressionNamespace.PLAYER_DATA,
updateDict, OnSentDataSuccess, OnSentDataFail);
}
func updateUserData(
forNamespace progressionNamespace: String?,
withUserData userDataUpdates: [NSDictionary : Any]?,
withSuccess successCompletion: @escaping (_ userData: [NSDictionary : Any]?) -> Void,
withFailure failureCompletion: @escaping (_ error: String?) -> Void
)
Parameters
progressionNamespace
One of the String constants
ProgressionNamespacePlayerData
ProgressionNamespaceDefaultPlayerData
ProgressionNamespaceInGameItems
userDataUpdates
Dictionary of key/value pairs to be updated.
successCompletion
Function to handle callback success and NSDictionary return data object.
failureCompletion
Function to handle callback failure and String error message.
Sample Implementation
Skillz.skillzInstance().updateUserData(
forNamespace: ProgressionNamespacePlayerData,
withUserData: userDataUpdates,
withSuccess: { [self] userData in
let textContent = "Successful PUT. Please fetch them to check the values."
updateKeyValuesView.text = textContent
userDataUpdates.removeAll()
- (void)updateUserDataForNamespace:(NSString *)progressionNamespace
withUserData:(NSDictionary *)userDataUpdates
withSuccess:(void (^_Nonnull)(NSDictionary * userData))successCompletion
withFailure:(void (^_Nonnull)(NSString * error))failureCompletion
Parameters
progressionNamespace
One of the NSString constants
ProgressionNamespacePlayerData
ProgressionNamespaceDefaultPlayerData
ProgressionNamespaceInGameItems
userDataUpdates
Dictionary of key/value pairs to be updated.
successCompletion
Function to handle callback success and NSDictionary return data object.
failureCompletion
Function to handle callback failure and NSString error message.
Sample Implementation
[[Skillz skillzInstance] updateUserDataForNamespace: ProgressionNamespacePlayerData
withUserData:self.userDataUpdates
withSuccess:^(NSDictionary * userData){
NSString* textContent = @"Successful PUT. Please fetch them to check the values.";
[self.updateKeyValuesView setText:textContent];
[self.userDataUpdates removeAllObjects];
} withFailure:^(NSString * error){
NSString *msg = [NSString stringWithFormat:@"Failed to PUT: %@", error];
[self.updateKeyValuesView setText:msg];
[self.userDataUpdates removeAllObjects];
}];
public static void SkillzProgression.updateUserData(String namespace, Map<String, Object> userDataUpdates, ProgressionCallback callback)
Parameters
namespace
One of the namespace Strings
ProgressionNamespace.PlayerData
ProgressionNamespace.InGameItems
userDataUpdates
Map of string/object key/value pairs.
callback
ProgressionCallback object to handle callback success or failure. Must be defined in implementation.
Sample Implementation
// Define list of keys to update
// Must match keys created in the Developer Console!
Map<String, Object> updateMap = new Map<String, Object>()
{
{ "achievement_level", 5.5 },
{ "combos_attained", 10 },
{ "character_color", "orange" }
};
SkillzProgression.updateUserData(ProgressionNamespace.PlayerData, updateMap, new ProgressionCallback() {
@Override
public void failure(Exception error) {
new AlertDialog.Builder(getActivity())
.setMessage("Request failed! " + error.getMessage())
.setNegativeButton("Ok", null)
.create()
.show();
}
@Override
public void success(Map<String, ProgressionValue> data) {
new AlertDialog.Builder(getActivity())
.setMessage("Request successful!")
.setNegativeButton("Ok", null)
.create()
.show();
}
});
Default Player Data
These are automatically updating, read-only statistics from the Skillz platform
For use with GetProgressionUserData
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.
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 |
skillz_level | Integer | The player’s global Skillz level |
install_date | Date | The UTC date and timestamp the user installed the game |
Progression Room Entry Point
Configure Progression Room Entry Point
- Configure your Entry Point within the Developer Console by clicking on
Progression -> Entry Points
. Be sure to complete all required fields. HitSave
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!
- 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
- Implement OnProgressionRoomEnter from SkillzDelegate interface to load your progression scene
- Call ReturnToSkillz to return to the Skillz UI
Implement Progression Room
- Unity/C#
- iOS/Swift
- iOS/Objective-C
- Android/Java
For Unity, you need to implement the SkillzMatchDelegate
interface as a regular C# class. This will be instantiated when launching Skillz later.
using SkillzSDK;
using UnityEngine.SceneManagement;
public sealed class SkillzGameController : SkillzMatchDelegate
{
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 OnSkillzWillExit()
{
}
public void OnProgressionRoomEnter()
{
// Load your progression scene here
SceneManager.LoadScene(ProgressionSceneName);
}
}
import UIKit
import Skillz
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, SkillzDelegate {
func tournamentWillBegin(_ gameParameters: [AnyHashable : Any]!, with matchInfo: SKZMatchInfo!) {
}
func skillzWillExit() {
}
func onProgressionRoomEnter() {
// Load progression view here
}
}
#import <UIKit/UIKit.h>
#import <Skillz/Skillz.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate, SkillzDelegate>
@end
@implementation AppDelegate
- (void)tournamentWillBegin:(NSDictionary * _Nonnull)gameParameters
withMatchInfo:(SKZMatchInfo * _Nonnull)matchInfo {
}
- (void)skillzWillExit {
}
- (void)onProgressionRoomEnter {
// Load progression view here
}
@end
For Android, insert your progression activity name in the skillz_progression_activity
element of your app's AndroidManifest.xml
.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="<your_package_name>" xmlns:tools="http://schemas.android.com/tools">
<application>
<meta-data android:name="skillz_game_activity" android:value="<your_game_activity>" />
<meta-data android:name="skillz_exit_activity" android:value="<your_activity_on_skillz_exit>" />
<meta-data android:name="skillz_progression_activity" android:value="<your_progression_activity>" />
</application>
</manifest>
Progression Tools
We've created some tools to help you with testing and troubleshooting your progression setup.
Player Data Lookup
You can lookup a player by their username and view the current progression values stored for that player. This tool is available for both Sandbox and Production users.
The tool can be found in the Developer Console under Progression > Player Data
by selecting the 3 dots on the right corner and clicking Player Lookup
.
Change Log
You can see a log of all the changes that have been made to your custom progression keys and when they were done. The log can be found in the Developer Console under Progression > Player Data
by selecting the 3 dots on the right corner and clicking Change Log