Progression #

Read more about the Progression system in Hiro here.

Initializing the progression system #

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

1
2
var progressionSystem = new ProgressionSystem(logger, nakamaSystem);
systems.Add(progressionSystem);

Subscribing to changes in the progression system #

You can listen for changes in the progression 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<ProgressionSystem>.Create(progressionSystem, system => {
  Instance.Logger.Info($"System updated.");

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

Refreshing the progression system #

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

1
await progressionSystem.RefreshAsync();

Get progressions for the user #

You can get all progressions for the current user including their current status and a dependency tree containing any unmet preconditions.

 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
var progressions = await progressionSystem.GetProgressionsAsync();

foreach (var kvp in progressions)
{
    Debug.Log($"Progression {kvp.Key}");
    Debug.Log($"Is Unlocked? {kvp.Value.Unlocked}");
    
    if (!kvp.Value.Unlocked)
    {
        Debug.Log("Unmet preconditions:");
        PrintUnmetPreconditions(kvp.Value.UnmetPreconditions)
    }
}

void PrintUnmetPreconditions(IProgressionPreconditionBlock block)
{
    Debug.Log($"Block Operator: {block.Operator}");

    if (block.Direct != null)
    {
        Debug.Log("Direct");
        Debug.Log($"Progressions: {string.Join(", ", block.Direct.Progressions)}");
        Debug.Log($"Achievements: {string.Join(", ", block.Direct.Achievements)}");
        Debug.Log($"Counts: {string.Join(", ", Counts.Select(kv => $"{kv.Key}: {kv.Value}"))}");
        Debug.Log($"ItemsMin: {string.Join(", ", ItemsMin.Select(kv => $"{kv.Key}: {kv.Value}"))}");
        Debug.Log($"ItemsMax: {string.Join(", ", ItemsMax.Select(kv => $"{kv.Key}: {kv.Value}"))}");
        Debug.Log($"StatsMin: {string.Join(", ", StatsMin.Select(kv => $"{kv.Key}: {kv.Value}"))}");
        Debug.Log($"StatsMax: {string.Join(", ", StatsMax.Select(kv => $"{kv.Key}: {kv.Value}"))}");
        Debug.Log($"EnergyMin: {string.Join(", ", EnergyMin.Select(kv => $"{kv.Key}: {kv.Value}"))}");
        Debug.Log($"EnergyMax: {string.Join(", ", EnergyMax.Select(kv => $"{kv.Key}: {kv.Value}"))}");
        Debug.Log($"CurrencyMin: {string.Join(", ", CurrencyMin.Select(kv => $"{kv.Key}: {kv.Value}"))}");
        Debug.Log($"CurrencyMax: {string.Join(", ", CurrencyMax.Select(kv => $"{kv.Key}: {kv.Value}"))}");
    }

    if (block.Nested)
    {
        Debug.Log("Nested");
        PrintUnmetPreconditions(block.Nested);
    }
}

Update the counters of a progression #

You can update one or more counters towards a progression for the user.

1
2
3
4
5
var progressions = await progressionSystem.UpdateProgressionAsync("<progressionId>", new Dictionary<string, long>
{
    { "rank", 2 },
    { "xp", 5 }
});

Purchase a progression #

You can purchase the unlock of a specified progression for the user.

1
var progressions = await progressionSystem.PurchaseProgressionAsync("<progressionId>");