Use case sample: Reward top players with in-game currency at the end of season
Reward your top players with in-game currency at the end of a season using Triggers.
Read time 6 minutesLast updated 18 hours ago
This use case sample demonstrates how to reward your top players with in-game currency at the end of a season. The sample uses the
resetPrerequisites
First, you need to create a service account with the required access roles and configure the UGS CLI.Authenticate using a Service Account
Before you can call the Triggers service, you need to authenticate with a service account.- Navigate to the Unity Dashboard.
- Select Administration > Service Accounts.
- Select the New button and enter a name and description for the service account.
- Select Create.
- Select Manage product roles.
- Add the following roles to the Service Account:
- From the LiveOps dropdown, select the following roles:
- Triggers Configuration Editor
- Triggers Configuration Viewer
- Economy Resource Editor
- Economy Resource Viewer
- Leaderboards Admin
- Leaderboards Viewer
- If you're deploying a Cloud Code module, add the following roles:
- Cloud Code Editor
- Cloud Code Viewer
- If you're deploying a Cloud Code script, add the following roles:
- Cloud Code Editor
- Cloud Code Viewer
- Cloud Code Publisher
- From the Admin dropdown, select Unity Environments Viewer.
- From the LiveOps dropdown, select the following roles:
- Select Save.
- Select Add Key.
- Encode the Key ID and Secret key using base64 encoding. The format is “key_id:secret_key”. Note this value down.
Configure the UGS CLI
Follow the steps below to get started with the UGS CLI:- Install the UGS CLI.
-
Use the following to configure your Project ID and Environment:
ugs config set project-id <your-project-id>
ugs config set environment-name <your-environment-name> - Use the service account you authenticated earlier to authenticate. Refer to Get Authenticated.
Examine the reset
event
The Leaderboards service emits a resetresetThe event payload passes on to Cloud Code as parameters. Refer to the Leaderboards Reset event for more information.{ "leaderboardId": "string", "leaderboardVersionId": "string"}
Create deployment files
This sample implements by deploying configuration files for each service with the UGS CLI. To implement the use case sample, you need to set up the following files:- : Contains the Economy currency configuration.
COIN.ecc - : Contains the Leaderboards configuration.
leaderboard.lb - : Contains the Triggers configuration.
triggers-config.tr - A Cloud Code module or script to define logic for rewarding your top players with in-game currency when the leaderboard is reset.
reward-top-playersSet up Economy
To reward your top players with in-game currency, you need to create a virtual currency in Economy. Create a Economy config file using the UGS CLI:Add the following content to theugs economy currency new-file COIN.ecc
COIN.eccThe configuration defines a virtual currency and the name{ "$schema": "https://ugs-config-schemas.unity3d.com/v1/economy/economy-currency.schema.json", "initial": 0, "name": "Coin"}
CoinSet up Leaderboards
Create a Leaderboard config file using the UGS CLI:Add the following content to theugs leaderboards new-file leaderboard.lb
leaderboard.lbThe configuration defines a leaderboard with ascending sort order and keeps the best score. The file name corresponds to the leaderboard ID.{ "$schema": "https://ugs-config-schemas.unity3d.com/v1/leaderboards.schema.json", "SortOrder": "asc", "UpdateType": "keepBest", "Name": "leaderboard"}
Set up Cloud Code
You need to create either a Cloud Code module or script to define logic for rewarding your top players with in-game currency when the leaderboard is reset.Cloud Code C# module
You can use the Economy and Leaderboards Client SDKs to interact with the Economy and Leaderboards services. Create a new Cloud Code module using the UGS CLI:Then, add the following contents to the sample solution. Create a module function with a string argumentugs cc m new-file RewardTopPlayers RewardTopPlayers
leaderboardIdusing System;using System.Collections.Generic;using System.Threading.Tasks;using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Logging;using Unity.Services.CloudCode.Apis;using Unity.Services.CloudCode.Core;using Unity.Services.CloudCode.Shared;using Unity.Services.Economy.Model;using Unity.Services.Leaderboards.Model;namespace RewardTopPlayers;public class RewardTopPlayers{ private const string CoinsKey = "COIN"; private const int Amount = 10; private readonly ILogger<RewardTopPlayers> _logger; public RewardTopPlayers(ILogger<RewardTopPlayers> logger) { _logger = logger; } [CloudCodeFunction("IssueReward")] public async Task Reward(IExecutionContext ctx, IGameApiClient gameApiClient, string leaderboardId, string leaderboardVersionId) { var top5Players = await GetTop5(ctx, gameApiClient, leaderboardId, leaderboardVersionId); foreach (var score in top5Players) { try { // Retrieve the player's configuration to ensure currency configuration is synced var configResponse = await gameApiClient.EconomyConfiguration.GetPlayerConfigurationAsync(ctx, ctx.ServiceToken, ctx.ProjectId, score.PlayerId); var res = await gameApiClient.EconomyCurrencies.IncrementPlayerCurrencyBalanceAsync(ctx, ctx.ServiceToken, ctx.ProjectId, score.PlayerId, CoinsKey, new CurrencyModifyBalanceRequest(amount: Amount), configResponse.Data.Metadata.ConfigAssignmentHash); _logger.LogInformation("Incremented balance for playerId {playerId} by {amount}", score.PlayerId, Amount); } catch (ApiException e) { _logger.LogError(e, "Failed to increment balance for playerId {playerId}. Error: {Error}", score.PlayerId, e.Message); throw; } } } public async Task<List<LeaderboardEntry>> GetTop5(IExecutionContext ctx, IGameApiClient gameApiClient, string leaderboardId, string leaderboardVersionId) { try { var results = await gameApiClient.Leaderboards.GetLeaderboardVersionScoresAsync(ctx, ctx.ServiceToken, new Guid(ctx.ProjectId), leaderboardId, leaderboardVersionId, 0, 5); return results.Data.Results; } catch (ApiException e) { _logger.LogError(e, "Failed to get top players for leaderboard: {LeaderboardId}. Error: {Error}", leaderboardId, e.Message); throw new Exception($"Failed to get top players for leaderboard: {leaderboardId}. Error: {e.Message}"); } } public class ModuleConfig : ICloudCodeSetup { public void Setup(ICloudCodeConfig config) { config.Dependencies.AddSingleton(GameApiClient.Create()); } }}
Cloud Code JavaScript script
You can achieve the same outcome by creating a Cloud Code script. Create a new Cloud Code script using the UGS CLI:Then, add the following contents to the sample script file:ugs cc s new-file RewardTopPlayers.js
JavaScript
const axios = require("axios");const { CurrenciesApi, ConfigurationApi } = require("@unity-services/economy-2.4");const { LeaderboardsApi } = require("@unity-services/leaderboards-1.1");module.exports = async ({ params, context, logger }) => { // Get top 5 players from the Leaderboard const leaderboardsApi = new LeaderboardsApi(context); const cointAmount = 10; let result; try { result = await leaderboardsApi.getLeaderboardVersionScores(context.projectId, params.leaderboardId, params.leaderboardVersionId, 0, 5); } catch (err) { logger.error("Failed to retrieve players from the leaderboard", { "error.message": err.message }, { leaderboardId: params.leaderboardId }); throw err; } const currencyId = "COIN"; const currenciesApi = new CurrenciesApi(context); const configApi = new ConfigurationApi(context); // Reward currency to every player const promises = result.data.results.map(async (score) => { try { // Retrieve the player config to get the configAssignmentHash. // This is needed to ensure the currency is synced var config = await configApi.getPlayerConfiguration({ playerId: score.playerId, projectId: context.projectId, }); await currenciesApi.incrementPlayerCurrencyBalance({ currencyId, playerId: score.playerId, projectId: context.projectId, configAssignmentHash: config.data.metadata.configAssignmentHash, currencyModifyBalanceRequest: { amount: cointAmount }, }); } catch (err) { logger.error("Failed to increment currency for player", { "error.message": err.message }, { affectedPlayerId: score.playerId }); return; } }); await Promise.all(promises);};
Set up Triggers
To connect your Cloud Code resource to the schedule, create a trigger. The trigger executes the Cloud Code script or module when the event fires, for example, when the leaderboard resets.If you created a Cloud Code module, use the following configuration:ugs tr new-file triggers-config.tr
If you created a Cloud Code script, use the following configuration:{ "$schema": "https://ugs-config-schemas.unity3d.com/v1/triggers.schema.json", "Configs": [ { "Name": "reward-leaderboard", "EventType": "com.unity.services.leaderboards.reset.v1", "ActionUrn": "urn:ugs:cloud-code:RewardTopPlayers/IssueReward", "ActionType": "cloud-code" } ]}
{ "$schema": "https://ugs-config-schemas.unity3d.com/v1/triggers.schema.json", "Configs": [ { "Name": "reward-leaderboard", "EventType": "com.unity.services.leaderboards.reset.v1", "ActionUrn": "urn:ugs:cloud-code:RewardTopPlayers", "ActionType": "cloud-code" } ]}
Deploy the configuration files
You should have the following files in yourreward-top-players- - Contains the Economy currency configuration.
COIN.ecc - - Contains the Leaderboard configuration.
leaderboard.lb - - Contains the Trigger configuration.
triggers-config.tr
- folder - Contains the Cloud Code module.
RewardTopPlayers.sln - - Contains the Cloud Code script.
RewardTopPlayers.js
ugs deploy .
Optional: Add scores to the leaderboard
You can run the following Cloud Code script to add scores to the leaderboard from the Unity Dashboard. Make sure to select the Generate icon to regenerate the Player ID token on every test run to add a new player.JavaScript
This allows you to add scores to the leaderboard and test the use case sample.const { LeaderboardsApi } = require("@unity-services/leaderboards-1.1");const _ = require("lodash-4.17");module.exports = async ({ params, context, logger }) => { const leaderboardsApi = new LeaderboardsApi({ accessToken: context.accessToken }); const leaderboardID = "leaderboard"; var randomScore = _.random(1, 100); try { await leaderboardsApi.addLeaderboardPlayerScore(context.projectId, leaderboardID, context.playerId, { score: randomScore }); } catch (err) { logger.error("Failed to add score to the leaderboard", { "error.message": err.message }); }};
Validate the result
To validate the result, note down a player ID from the leaderboard before it's reset:- Navigate to the Unity Dashboard.
- Select Products > Leaderboards.
- Select the Overview section.
- Select the leaderboard.
leaderboard - Select the Entries tab.
- Note down one of the top player IDs.
- Navigate to the Unity Dashboard.
- Select Products > Leaderboards.
- Select the Overview section.
- Select the leaderboard.
leaderboard - Select Reset Leaderboard .
- Enable Archive current scores.
- Select Products > Player Management.
- In the search field, enter the player ID you noted down earlier and select Find Player.
- Navigate to the Economy > Currencies section. If successful, you can find that the player has been rewarded with 10 coins.