# Challenges

**URL:** https://heroiclabs.com/docs/hiro/unreal/challenges/
**Summary:** Challenges enable social and competitive experiences by allowing players to compete in time-bound events with friends.
**Keywords:** challenge, player progression
**Categories:** hiro, unreal, challenges

---


# 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](../../concepts/challenges/_index.md).

## 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

- Unreal project set up with Hiro SDK
- Nakama System integrated

## Managing Challenges

### Creating a Challenge

Create new challenges with custom parameters:

```cpp
FHiroChallengeCreateRequest CreateRequest;
CreateRequest.TemplateId = TEXT("daily_race");
CreateRequest.Name = TEXT("Daily Race Challenge");
CreateRequest.Description = TEXT("Compete for top daily times");
CreateRequest.Invitees = { TEXT("player2"), TEXT("player3") };
CreateRequest.Open = true;
CreateRequest.MaxScores = 3;
CreateRequest.StartDelaySec = 0; // Start immediately
CreateRequest.DurationSec = 86400; // 24 hours
CreateRequest.MaxParticipants = 10;
CreateRequest.Category = TEXT("racing");

FHiroOnChallengeCreate OnChallengeCreate;
OnChallengeCreate.AddDynamic(this, &AMyActor::OnChallengeCreate);
FOnError OnError;

HiroClient->ChallengeCreate(Session, CreateRequest, OnChallengeCreate, OnError);

void AMyActor::OnChallengeCreate(const FHiroChallenge& Challenge)
{
    UE_LOG(LogTemp, Log, TEXT("%s"), *Challenge.ToJson());
}
```

**Parameters:**

- `Open`: Allow any player to join without an invitation
- `MaxScores`: Max submissions per player
- `DurationSec`: 0 = unlimited duration

### Listing Challenges

Get all the challenges the player is a participant in or was invited to, with optional filtering:

```cpp
FHiroChallengeListRequest Request;
Request.Categories.Add(TEXT("racing"));
Request.WithScores = true;

FHiroOnChallengesList OnChallengesList;
OnChallengesList.AddDynamic(this, &AMyActor::OnChallengesList);
FOnError OnError;

HiroClient->ChallengesList(Session, Request, OnChallengesList, OnError);
```

### Searching Challenges

Find public challenges by name/category. 
Calling this function with empty or `null` arguments returns all the public challenges:

```cpp
FHiroChallengeSearchRequest SearchRequest;
SearchRequest.Name = TEXT("weekly");
SearchRequest.Category = TEXT("racing");
SearchRequest.Limit = 5;

FHiroOnChallengesSearch OnChallengesSearch;
OnChallengesSearch.AddDynamic(this, &AMyActor::OnChallengesSearch);
FOnError OnError;

HiroClient->ChallengesSearch(Session, SearchRequest, OnChallengesSearch, OnError);
```

### Inviting Players

Add participants to existing challenges:

```cpp
FHiroChallengeInviteRequest InviteRequest;
InviteRequest.ChallengeId = TEXT("CHALLENGE_123");
InviteRequest.Invitees = { TEXT("player4") };

FHiroOnChallengeInvite OnChallengeInvite;
OnChallengeInvite.AddDynamic(this, &AMyActor::OnChallengeInvite);
FOnError OnError;

HiroClient->ChallengeInvite(Session, InviteRequest, OnChallengeInvite, OnError);
```

## Tracking Progress

### Submitting Scores

Update player standings in a challenge:

```cpp
FHiroChallengeSubmitScoreRequest SubmitScoreRequest;
SubmitScoreRequest.ChallengeId = TEXT("CHALLENGE_123");
SubmitScoreRequest.Score = 1500;
SubmitScoreRequest.Subscore = 0;
SubmitScoreRequest.Metadata = TEXT("{\"lap_times\":[120]}");

FHiroOnChallengeSubmitScore OnSubmitScore;
OnSubmitScore.AddDynamic(this, &AMyActor::OnSubmitScore);
FOnError OnError;

HiroClient->ChallengeSubmitScore(Session, SubmitScoreRequest, OnSubmitScore, OnError);
```

### Joining/Leaving

Manage player participation:

```cpp
// Join an open challenge
FHiroChallengeJoinRequest JoinRequest;
JoinRequest.ChallengeId = TEXT("CHALLENGE_456");

FHiroOnChallengeJoin OnChallengeJoin;
OnChallengeJoin.AddDynamic(this, &AMyActor::OnChallengeJoin);
FOnError OnError;

HiroClient->ChallengeJoin(Session, JoinRequest, OnChallengeJoin, OnError);

// Leave a challenge
FHiroChallengeLeaveRequest LeaveRequest;
LeaveRequest.ChallengeId = TEXT("CHALLENGE_456");

FHiroOnChallengeLeave OnChallengeLeave;
OnChallengeLeave.AddDynamic(this, &AMyActor::OnChallengeLeave);

HiroClient->ChallengeLeave(Session, LeaveRequest, OnChallengeLeave, OnError);
```

## Rewards

### Claiming Rewards

Claim earned rewards after challenge completion:

```cpp
FHiroChallengeClaimRequest ClaimRequest;
ClaimRequest.ChallengeId = TEXT("CHALLENGE_123");

FHiroOnChallengeClaim OnChallengeClaim;
OnChallengeClaim.AddDynamic(this, &AMyActor::OnChallengeClaim);
FOnError OnError;

HiroClient->ChallengeClaim(Session, ClaimRequest, OnChallengeClaim, OnError);

// Refresh the economy system to see new rewards
HiroClient->EconomyRefresh(Session, OnEconomyRefresh, OnError);
```
