Concurrent Players
LootLocker SDKs support managing multiple concurrent users in your game. This is useful for local multiplayer, hot seat, or any scenario where more than one player is authenticated at the same time.
How it Works
Whenever you successfully authenticate a player (using any supported authentication method), the SDK automatically adds or updates that player's session in the multi user state. You do not need to manually add users. Just authenticate them as usual.
Each player is tracked by their ULID, and you can make API calls for a specific player by providing their ULID.
Example: Start Concurrent Sessions and Submit Scores
This example is, of course, simplistic and abstracts away all the game logic that would go in between these two events. The example is here to show you how to make requests when there are multiple local users.
While we recommend you to always pass the ULID of the player you wish to make a request for, included in this example is a request to fetch the current scores that uses the default player, simply to show the difference between performing a request on the behalf of a specific player, or the default player.
// Replace with your actual leaderboard key
public static string leaderboardKey = "your_leaderboard_key_here";
public void OnLoginButtonPressed()
{
// Replace with your actual player identifier retrieval logic
string guest_player_identifier = GetGuestIdentifierFromInput();
if (string.IsNullOrEmpty(guest_player_identifier))
{
Debug.LogWarning("Please enter a valid guest player identifier.");
return;
}
LootLockerSDKManager.StartGuestSession(guest_player_identifier, response =>
{
if (!response.success)
{
Debug.LogError($"Login failed: {response.errorData}");
return;
}
Debug.Log($"Login successful for guest player: {guest_player_identifier} with ulid {response.player_ulid}. The default player ulid is {LootLockerSDKManager.GetDefaultPlayerUlid()}");
});
}
public void OnShowScoresButtonPressed()
{
// Fetch the top 10 scores from the leaderboard, while we recommend always specifying which player
// you want to make the request for, this is an example of making a request for the default player (simply not specifying a player).
LootLockerSDKManager.GetScoreList(leaderboardKey, 10, 0, response =>
{
if (!response.success)
{
Debug.LogError($"Failed to retrieve scores: {response.errorData}");
return;
}
Debug.Log($"Scores retrieved successfully: {response.text}");
// Replace with your actual UI display logic
DisplayScoresInUI(response.items);
}/*, lootLockerPlayerUlid <- To make the request for a specific player you'd add this parameter*/);
}
public void OnMatchFinished_SubmitScores()
{
// Replace with your actual game logic
MatchData matchData = GetCurrentMatchData();
foreach (var playerScore in matchData.PlayerScores)
{
// Submit each player's score to the leaderboard
LootLockerSDKManager.SubmitScore("", playerScore.Score, leaderboardKey, response =>
{
if (!response.success)
{
Debug.LogError($"Failed to submit score for player {playerScore.PlayerId}: {response.errorData}");
}
else
{
Debug.Log($"Score submitted successfully for player {playerScore.PlayerId}: {response.text}");
}
}, /* IMPORTANT: */ playerScore.LootLockerPlayerULID /* This makes the score submission for *this* player */);
}
}// Replace with your actual leaderboard key
FString leaderboardKey = "your_leaderboard_key_here";
void OnLoginButtonPressed()
{
// Replace with your actual player identifier retrieval logic
FString guest_player_identifier = GetGuestIdentifierFromInput();
if (guest_player_identifier.IsEmpty())
{
UE_LOG(<LogCategory>, Warning, TEXT("Please enter a valid guest player identifier."));
return;
}
ULootLockerSDKManager::GuestLogin(FLootLockerSessionResponse::CreateLambda([](const FLootLockerAuthenticationResponse& response) {
if (!response.success)
{
UE_LOG(<LogCategory>, Error, TEXT("Login failed: %s"), *response.errorData);
return;
}
UE_LOG(<LogCategory>, Log, TEXT("Login successful for guest player: %s with ulid %s. The default player ulid is %s"),
*guest_player_identifier, *response.player_ulid, *ULootLockerSDKManager::GetDefaultPlayerUlid());
}), guest_player_identifier);
}
void OnShowScoresButtonPressed()
{
// Fetch the top 10 scores from the leaderboard, while we recommend always specifying which player
// you want to make the request for, this is an example of making a request for the default player (simply not specifying a player).
ULootLockerSDKManager::GetScoreList(leaderboardKey, 10, 0, FLootLockerGetScoreListResponseDelegate::CreateLambda([](const FLootLockerGetScoreListResponse& response)
{
if (!response.success)
{
UE_LOG(<LogCategory>, Error, TEXT("Failed to retrieve scores: %s"), *response.ErrorData.Message);
return;
}
UE_LOG(<LogCategory>, Log, TEXT("Scores retrieved successfully: %s"), *response.text);
// Replace with your actual UI display logic
DisplayScoresInUI(response.items);
})/*, lootLockerPlayerUlid <- To make the request for a specific player you'd add this parameter*/);
}
void OnMatchFinished_SubmitScores()
{
// Replace with your actual game logic
MatchData matchData = GetCurrentMatchData();
for (const auto& playerScore : matchData.PlayerScores)
{
// Submit each player's score to the leaderboard
ULootLockerSDKManager::SubmitScore("", leaderboardKey, playerScore.Score, FLootLockerSubmitScoreResponseDelegate::CreateLambda([playerScore](const FLootLockerSubmitScoreResponse& response)
{
if (!response.success)
{
UE_LOG(<LogCategory>, Error, TEXT("Failed to submit score for player %s: %s"), *playerScore.PlayerId, *response.ErrorData.Message);
}
else
{
UE_LOG(<LogCategory>, Log, TEXT("Score submitted successfully for player %s: %s"), *playerScore.PlayerId, *response.text);
}
}, /* IMPORTANT: */ playerScore.LootLockerPlayerULID /* This makes the score submission for *this* player */);
}
}Starting sessions in a multi user context works the exact same as in a single user context. The only difference is that it becomes imperative to store the player ULID as that is what is used later to specify which player a request should be made on behalf of.
Below is an example of fetching the score list using the default user (not specifying which player ULID to execute the request as). While we recommend always specifying which user to perform the request as in a multi user game, this is how you use the default user.
And finally, when the imaginary match finishes, submit the match scores for each player.
Last updated


