examples: global quests usage in CozyCollector (list/claim/reportProgress), quests capability
CI / check (push) Successful in 6s
CI / publish (push) Has been skipped

This commit is contained in:
edmand46
2026-08-25 16:25:36 +03:00
parent 695a7210b1
commit b8e226722d
3 changed files with 86 additions and 0 deletions
@@ -7,6 +7,7 @@ using RudderSdk.Core;
using RudderSdk.Core.Models.Inventory;
using RudderSdk.Core.Models.Leaderboards;
using RudderSdk.Core.Models.Player;
using RudderSdk.Core.Models.Quests;
using RudderSdk.Core.Models.Storage;
using RudderSdk.Core.Models.Stores;
using RudderSdk.Unity;
@@ -249,6 +250,7 @@ namespace LiveOpsExamples
await RefreshProfileAsync();
await RefreshStoresAsync();
await RefreshInventoryAsync();
await RefreshQuestsAsync();
try
{
@@ -456,6 +458,11 @@ namespace LiveOpsExamples
try { await RefreshInventoryAsync(); }
catch (Exception exception) { Log(CozyCollectorConsts.CapabilityInventory, "Inventory refresh failed", exception.Message); }
// Purchase metrics (purchase.offer:* / purchase.item:*) are reported
// server-side by the purchase fan-out; re-list to pick up new progress.
try { await RefreshQuestsAsync(); }
catch (Exception exception) { Log(CozyCollectorConsts.CapabilityQuests, "Quest refresh failed", exception.Message); }
}
// ---------------------------------------------------------------
@@ -573,6 +580,63 @@ namespace LiveOpsExamples
return mapped;
}
// ---------------------------------------------------------------
// Global quests (distinct from scenario quest nodes / QuestSession)
// ---------------------------------------------------------------
private async Task RefreshQuestsAsync()
{
var quests = await Rudder.Client.Quests.ListAsync();
var activeCount = 0;
if (quests != null)
{
foreach (var quest in quests)
{
if (quest.Status == "claimed")
continue;
activeCount += 1;
Log(CozyCollectorConsts.CapabilityQuests, "Quest " + (quest.Status ?? "active"), QuestProgressSummary(quest));
if (quest.Status == "completed" && !string.IsNullOrEmpty(quest.Id))
await ClaimQuestAsync(quest);
}
}
Log(CozyCollectorConsts.CapabilityQuests, "Quests loaded", activeCount + " active");
}
private async Task ClaimQuestAsync(Quest quest)
{
var result = await Rudder.Client.Quests.ClaimAsync(quest.Id);
if (result == null || !result.Success)
{
Log(CozyCollectorConsts.CapabilityQuests, "Quest claim rejected", result?.Error);
return;
}
if (!result.AlreadyClaimed)
Toast("Quest complete", quest.Name ?? quest.Id, CozyToastTone.Success);
Log(CozyCollectorConsts.CapabilityQuests, "Quest claimed", quest.Name ?? quest.Id);
await RefreshWalletsAsync();
}
private static string QuestProgressSummary(Quest quest)
{
var name = quest.Name ?? quest.Id;
if (quest.Objectives == null || quest.Objectives.Count == 0)
return name;
var parts = new List<string>();
foreach (var objective in quest.Objectives)
{
parts.Add(objective.Metric + " " + objective.Current + "/" + objective.Target);
}
return name + " · " + string.Join(" · ", parts);
}
// ---------------------------------------------------------------
// Round flow
// ---------------------------------------------------------------
@@ -625,6 +689,23 @@ namespace LiveOpsExamples
{
Log(CozyCollectorConsts.CapabilityScenario, "Trigger failed", exception.Message);
}
try
{
var completedIds = await Rudder.Client.Quests.ReportProgressAsync(
CozyCollectorConsts.QuestMetricCollectibles,
collected);
Log(
CozyCollectorConsts.CapabilityQuests,
"Quest progress reported",
CozyCollectorConsts.QuestMetricCollectibles + " +" + collected +
(completedIds.Count > 0 ? " · completed " + completedIds.Count + " quest(s)" : string.Empty));
await RefreshQuestsAsync();
}
catch (Exception exception)
{
Log(CozyCollectorConsts.CapabilityQuests, "Quest progress failed", exception.Message);
}
}
public void PlayAgain()