Unlockables #

Time-based unlockable reward chests in Squad Alpha by Say Games.
Time-based unlockable reward chests in Squad Alpha by Say Games.

Unlockables are a Hiro meta system which allows the player to unlock rewards in the game. The rewards can be anything from a new character, a new weapon, or anything relevant for your game. Unlockables can be unlocked by the player by waiting for a period of time or by watching a rewarded video.

You can configure unlockables so that players only have a limited number of slots for active unlockables at any time, and also provide players the ability to purchase extra slots to store more unlockables, up to a maximum limit.

Customization parameters #

All unlockables and their configuration is done through a JSON definition.

The following JSON represents the customization parameters you can use to configure the default user experience for the Unlockables system.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
{
    "max_active_slots": 3,
    "active_slots": 1, // Initial number of active slots.
    "slots": 4,
    "slot_cost": {
        "currencies": {
            "gems": 50
        }
    },
    "unlockables": {
        "unlockable_id1": {
            "probability": 100,
            "category": "",
            "start_cost": {
                "currencies": {
                    "coins": 5
                }
            },
            "cost": {
                "currencies": {
                    "coins": 10
                }
            },
            "cost_unit_time_sec": 60,
            "description": "",
            "name": "Tiny Reward Chest!",
            "reward": {
                "guaranteed": {
                "currencies": {
                    "gold": {
                        "min": 100
                    }
                },
                "items": {
                    "hero_card": {
                        "min": 1,
                        "max": 5
                    }
                }
            },
            "wait_time_sec": 14400, // 4 hours.,
            "additional_properties": {
                "<propertyName>": "value"
            }
        }
    }
}

Unlockable slots #

PropertySubpropertyDescription
max_active_slotsThe maximum number of slots a player can have active at any time.
active_slotsThe number of active slots, if any, each player starts with.
slotsThe total number of slots, active and inactive, a player can have.
slot_costThe cost to purchase additional active slots.
currenciesA string:int dictionary of the currencies and amounts required to purchase additional slots.

Unlockable #

Each unlockable is keyed by id and may define the following properties:

PropertySubpropertyDescription
probabilityAn int value indicating the likelihood this unlockable item is the one received by the player.
nameThe name of this unlockable.
categoryThe category, if any, of this unlockable.
descriptionThe description of this unlockable.
start_costThe cost to begin unlocking this unlockable.
currenciesA string:int dictionary of the currencies and amounts required as the start cost.
wait_time_secThe total time (in seconds) a player must wait before this item in unlocked.
costThe cost to advance the wait time by one unit of time, defined in cost_unit_time_sec.
currenciesA string:int dictionary of the currencies and amounts required.
cost_unit_time_secThe amount of time to be advanced on wait_time_sec for each cost purchase.
rewardAn object that defines what rewards the player should receive after unlocking this unlockable.
additional_propertiesA string:string dictionary of key value pairs that can contain additional context.

Initializing the unlockables system #

The unlockables system relies on the Nakama System which must be passed in as dependency via the constructor.

1
2
var unlockablesSystem = new UnlockablesSystem(nakamaSystem);
systems.Add(unlockablesSystem);

Subscribing to changes in the unlockables system #

You can listen for changes in the unlockables system so that you can respond appropriately, such as updating the UI, by implementing the appropriate interface.

1
2
3
4
5
var disposer = SystemObserver<UnlockablesSystem>.Create(unlockablesSystem, system => {
  Instance.Logger.Info($"System updated.");

  // Update UI elements etc as necessary here...
});

Refreshing the unlockables system #

To ensure the unlockables system has the latest information from Nakama you can refresh it.

1
await unlockablesSystem.RefreshAsync();

Listing available unlockables #

You can list available unlockables.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
foreach (var unlockable in unlockablesSystem.Unlockables)
{
    Debug.Log($"{unlockable.Name} - {unlockable.Description}. Cost:");

    foreach (var currencyKvp in unlockable.Cost.Currencies)
    {
        Debug.Log($"{currencyKvp.Key}: {currencyKvp.Value}");
    }
    
    foreach (var consumableKvp in unlockable.Cost.Consumables)
    {
        Debug.Log($"{consumableKvp.Key}: {consumableKvp.Value}");
    }
    
    foreach (var collectable in unlockable.Cost.Collectables)
    {
        Debug.Log(collectable);
    }
}

Claiming an unlockable reward #

You can claim an unlockable reward.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
var reward = unlockablesSystem.ClaimAsync("<instanceId>");

Debug.Log("Collected reward:");

foreach (var currencyKvp in reward.Currencies)
{
    Debug.Log($"{currencyKvp.Key}: {currencyKvp.Value}");
}

foreach (var consumableKvp in reward.Consumables)
{
    Debug.Log($"{consumableKvp.Key}: {consumableKvp.Value}");
}

foreach (var collectable in reward.Collectables)
{
    Debug.Log(collectable);
}

Purchasing a slot #

You can purchase an additional unlockable slot.

1
await unlockablesSystem.PurchaseSlotAsync();

Purchasing an unlock #

You can purchase an unlock of a slot.

1
await unlockablesSystem.PurchaseUnlockAsync("<instanceId>");

Begin unlocking a slot #

You can begin unlocking a slot.

1
await unlockablesSystem.UnlockStartAsync("<instanceId>");

Creating an unlockable #

You can create an unlockable.

1
await unlockablesSystem.CreateAsync();

Inspecting the overflow slot #

You can inspect the overflow slot.

1
Debug.Log($"{unlockablesSystem.Overflow.Name} - {unlockablesSystem.Overflow.Description}");