Challenges #

Challenges enable social and competitive experiences by allowing players to compete in time-bound events with friends. Learn more in the Challenges concept guide.

Overview #

Challenges provide time-bound competitive experiences where players can:

  • Compete against friends or other players
  • Track progress through leaderboards
  • Earn rewards for participation and performance

Prerequisites #

  • C++ project set up with Hiro SDK
  • Nakama System integrated

Managing Challenges #

Creating a Challenge #

Create new challenges with custom parameters:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
ChallengeCreateRequest createRequest;
createRequest.templateId = "daily_race";
createRequest.name = "Daily Race Challenge";
createRequest.description = "Compete for top daily times";
createRequest.invitees = { "player2", "player3" };
createRequest.open = true;
createRequest.maxScores = "3";
createRequest.startDelaySec = "0"; // Start immediately
createRequest.durationSec = "86400"; // 24 hours
createRequest.maxParticipants = "10";
createRequest.category = "racing";

auto onChallengeCreate = [](const Challenge& challenge) {
    std::cout << "Created challenge: " << challenge.name << std::endl;
};

auto onError = [](const Nakama::NError& error) {
    std::cout << Nakama::toString(error.code) << ": " << error.message << std::endl;
};

hiroClient->challengeCreate(session, createRequest, onChallengeCreate, onError);

Parameters:

  • open: Allow any player to join without an invitation
  • maxScores: Max submissions per player
  • durationSec: 0 = unlimited duration

Listing Challenges #

Get active challenges with optional filtering:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
ChallengeListRequest listRequest;
listRequest.categories = { "racing" };
listRequest.withScores = true;

auto onChallengesList = [](const ChallengesList& challenges) {
    for (const auto& challenge : challenges.challenges) {
        std::cout << "Challenge: " << challenge.name << std::endl;
    }
};

hiroClient->challengesList(session, listRequest, onChallengesList, onError);

Searching Challenges #

Find public challenges by name/category:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
ChallengeSearchRequest searchRequest;
searchRequest.name = "weekly";
searchRequest.category = "racing";
searchRequest.limit = "5";

auto onChallengesSearch = [](const ChallengesList& challenges) {
    for (const auto& challenge : challenges.challenges) {
        std::cout << "Found challenge: " << challenge.name << std::endl;
    }
};

hiroClient->challengesSearch(session, searchRequest, onChallengesSearch, onError);

Inviting Players #

Add participants to existing challenges:

1
2
3
4
5
6
7
8
9
ChallengeInviteRequest inviteRequest;
inviteRequest.challengeId = "CHALLENGE_123";
inviteRequest.invitees = { "player4" };

auto onChallengeInvite = [](const Challenge& challenge) {
    std::cout << "Invited players to challenge: " << challenge.id << std::endl;
};

hiroClient->challengeInvite(session, inviteRequest, onChallengeInvite, onError);

Tracking Progress #

Submitting Scores #

Update player standings in a challenge:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
ChallengeSubmitScoreRequest submitScoreRequest;
submitScoreRequest.challengeId = "CHALLENGE_123";
submitScoreRequest.score = "1500";
submitScoreRequest.subscore = "0";
submitScoreRequest.metadata = "{\"lap_times\":[120]}";

auto onSubmitScore = [](const Challenge& challenge) {
    std::cout << "Score submitted to challenge: " << challenge.id << std::endl;
};

hiroClient->challengeSubmitScore(session, submitScoreRequest, onSubmitScore, onError);

Joining/Leaving #

Manage player participation:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// Join an open challenge
ChallengeJoinRequest joinRequest;
joinRequest.challengeId = "CHALLENGE_456";

auto onChallengeJoin = [](const Challenge& challenge) {
    std::cout << "Joined challenge: " << challenge.id << std::endl;
};

hiroClient->challengeJoin(session, joinRequest, onChallengeJoin, onError);

// Leave a challenge
ChallengeLeaveRequest leaveRequest;
leaveRequest.challengeId = "CHALLENGE_456";

auto onChallengeLeave = [](const Challenge& challenge) {
    std::cout << "Left challenge: " << challenge.id << std::endl;
};

hiroClient->challengeLeave(session, leaveRequest, onChallengeLeave, onError);

Rewards #

Claiming Rewards #

Claim earned rewards after challenge completion:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
ChallengeClaimRequest claimRequest;
claimRequest.challengeId = "CHALLENGE_123";

auto onChallengeClaim = [](const Challenge& challenge) {
    std::cout << "Claimed reward for challenge: " << challenge.id << std::endl;
};

hiroClient->challengeClaim(session, claimRequest, onChallengeClaim, onError);

// Refresh the economy system to see new rewards
hiroClient->economyRefresh(session, onEconomyRefresh, onError);