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 #

  • Typescript 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
const createRequest = new ChallengeCreateRequest();
createRequest.template_id = "daily_race";
createRequest.name = "Daily Race Challenge";
createRequest.description = "Compete for top daily times";
createRequest.invitees = ["player2", "player3"];
createRequest.open = true;
createRequest.setMaxScoresNumeric(3);
createRequest.setStartDelaySecNumeric(0); // Start immediately
createRequest.setDurationSecNumeric(86400); // 24 hours
createRequest.setMaxParticipantsNumeric(10);
createRequest.category = "racing";

const challenge = await hiro.challengeCreate(session, createRequest);
console.log(`Challenge created: ${challenge.name}`);

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
const listRequest = new ChallengeListRequest();
listRequest.categories = ["racing"];
listRequest.with_scores = true;

const challenges = await hiro.challengesList(session, listRequest);
challenges.challenges?.forEach((challenge) => {
  console.log(`Challenge: ${challenge.name}`);
});

Searching Challenges #

Find public challenges by name/category:

1
2
3
4
5
6
7
8
9
const searchRequest = new ChallengeSearchRequest();
searchRequest.name = "weekly";
searchRequest.category = "racing";
searchRequest.setLimitNumeric(5);

const challenges = await hiro.challengesSearch(session, searchRequest);
challenges.challenges?.forEach((challenge) => {
  console.log(`Found challenge: ${challenge.name}`);
});

Inviting Players #

Add participants to existing challenges:

1
2
3
4
5
6
const inviteRequest = new ChallengeInviteRequest();
inviteRequest.challenge_id = "CHALLENGE_123";
inviteRequest.invitees = ["player4"];

const challenge = await hiro.challengeInvite(session, inviteRequest);
console.log(`Invited to challenge: ${challenge.id}`);

Tracking Progress #

Submitting Scores #

Update player standings in a challenge:

1
2
3
4
5
6
7
8
const submitScoreRequest = new ChallengeSubmitScoreRequest();
submitScoreRequest.challenge_id = "CHALLENGE_123";
submitScoreRequest.setScoreNumeric(1500);
submitScoreRequest.setSubscoreNumeric(0);
submitScoreRequest.metadata = '{"lap_times":[120]}';

const challenge = await hiro.challengeSubmitScore(session, submitScoreRequest);
console.log(`Score submitted to challenge: ${challenge.id}`);

Joining/Leaving #

Manage player participation:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// Join an open challenge
const joinRequest = new ChallengeJoinRequest();
joinRequest.challenge_id = "CHALLENGE_456";

const challenge = await hiro.challengeJoin(session, joinRequest);
console.log(`Joined challenge: ${challenge.id}`);

// Leave a challenge
const leaveRequest = new ChallengeLeaveRequest();
leaveRequest.challenge_id = "CHALLENGE_456";

const challenge = await hiro.challengeLeave(session, leaveRequest);
console.log(`Left challenge: ${challenge.id}`);

Rewards #

Claiming Rewards #

Claim earned rewards after challenge completion:

1
2
3
4
5
const claimRequest = new ChallengeClaimRequest();
claimRequest.challenge_id = "CHALLENGE_123";

const challenge = await hiro.challengeClaim(session, claimRequest);
console.log(`Claimed reward for challenge: ${challenge.id}`);