# Unlockables

**URL:** https://heroiclabs.com/docs/hiro/cpp/unlockables/
**Keywords:** unlockables, hiro
**Categories:** hiro, cpp, unlockables

---


# Unlockables

Read more about the Unlockables system in Hiro [here](../../concepts/unlockables/).

## Create a random unlockable

Create a random unlockable to assign to a slot (or overflow) unless there are no slots.

```cpp
void onUnlockablesCreate(const Hiro::UnlockablesList& unlockablesList)
{
    std::cout << "Successfully created random unlockable: " << unlockablesList.instanceId << '\n';
}

void onError(const Nakama::NError& error)
{
    std::cout << Nakama::toString(error.code) << ": " << error.message << '\n';
}

hiroClient->unlockablesCreate(session, onUnlockablesCreate, onError);
```

## Get in progress unlockables

Get the unlockables which are currently in progress for the player.

```cpp
void onUnlockablesGet(const Hiro::UnlockablesList& unlockablesList)
{
    for (auto it = unlockablesList.unlockables.begin(); it != unlockablesList.unlockables.end(); it++)
    {
        std::cout << "Found in-progress unlockable: " << it->name << '\n';
    }
}

void onError(const Nakama::NError& error)
{
    std::cout << Nakama::toString(error.code) << ": " << error.message << '\n';
}

hiroClient->unlockablesGet(session, onUnlockablesGet, onError);
```

## Start an unlock

Start the unlock timer for an unlockable in the specified slot.

```cpp
void onUnlockablesUnlockStart(const Hiro::UnlockablesList& unlockablesList)
{
    for (auto it = unlockablesList.unlockables.begin(); it != unlockablesList.unlockables.end(); it++)
    {
        std::cout << "Found unlockable: " << it->name << '\n';
    }
}

void onError(const Nakama::NError& error)
{
    std::cout << Nakama::toString(error.code) << ": " << error.message << '\n';
}

Hiro::UnlockablesRequest request;
request.instanceId = "unlockable_instance_1";

hiroClient->unlockablesUnlockStart(session, request, onUnlockablesUnlockStart, onError);
```

## Purchase an unlockable

Purchase an unlockable with soft currency based on the remainder cost calculated by the offset left to wait.

```cpp
void onUnlockablesPurchaseUnlock(const Hiro::UnlockablesList& unlockablesList)
{
    for (auto it = unlockablesList.unlockables.begin(); it != unlockablesList.unlockables.end(); it++)
    {
        std::cout << "Found unlockable: " << it->name << '\n';
    }
}

void onError(const Nakama::NError& error)
{
    std::cout << Nakama::toString(error.code) << ": " << error.message << '\n';
}

Hiro::UnlockablesRequest request;
request.instanceId = "unlockable_instance_1";

hiroClient->unlockablesPurchaseUnlock(session, request, onUnlockablesPurchaseUnlock, onError);
```

## Purchase a new unlockable slot

Purchase a new slot to be used to store unlockables.

```cpp
void onUnlockablesPurchaseSlot(const Hiro::UnlockablesList& unlockablesList)
{
    std::cout << "Successfully purchased slot, total slots: " << unlockablesList.slots << '\n';
}

void onError(const Nakama::NError& error)
{
    std::cout << Nakama::toString(error.code) << ": " << error.message << '\n';
}

hiroClient->unlockablesPurchaseSlot(session, onUnlockablesPurchaseSlot, onError);
```

## Claim an unlockable

Claim an unlockable whose start timer has completed or completion was fast tracked with a purchase.

```cpp
void onUnlockablesClaim(const Hiro::UnlockablesReward& unlockablesReward)
{
    std::cout << "Successfully claimed unlockable!\n";
}

void onError(const Nakama::NError& error)
{
    std::cout << Nakama::toString(error.code) << ": " << error.message << '\n';
}

Hiro::UnlockablesRequest request;
request.instanceId = "unlockable_instance_1";

hiroClient->unlockablesClaim(session, request, onUnlockablesClaim, onError);
```