Progression: Achievements, Stats & Leaderboards

UCrimsonOnlineAchievementService

Wraps IOnlineAchievements. Queries achievement definitions and progress; writes per-stat progress; unlocks achievements.

FunctionDescription
QueryAchievements(LocalPlayerIndex, Delegate)Fetches achievement definitions + current progress from platform
GetCachedAchievements(LocalPlayerIndex)Returns TArray<FCrimsonAchievementProgress> from cache
WriteAchievementProgress(LocalPlayerIndex, AchievementId, ProgressPercent, Delegate)Writes progress (0–100). Platform unlocks at 100.
OnAchievementUnlockedDelegate: LocalPlayerIndex + AchievementId
Async node
UCrimsonAsyncAction_WriteAchievement — Blueprint async action. Pins: LocalPlayerIndex, AchievementId (FName), ProgressPercent (float 0–100), On Success, On Failure.

UCrimsonOnlineStatsService — global leaderboards

Wraps IOnlineLeaderboards. Reads and writes ranked global leaderboard entries.

FunctionDescription
ReadLeaderboardEntries(LocalPlayerIndex, LeaderboardName, RangeStart, RangeEnd, Delegate)Reads a range of globally ranked entries
ReadLeaderboardEntriesForFriends(LocalPlayerIndex, LeaderboardName, Delegate)Reads entries for the local player's friends
WriteLeaderboardEntry(LocalPlayerIndex, LeaderboardName, StatName, Value, Delegate)Submits a score; platform applies keepBest logic
GetCachedLeaderboard(LeaderboardName)Returns TArray<FCrimsonLeaderboardEntry> from cache

FCrimsonLeaderboardEntry

FieldTypeDescription
UniqueIdTSharedPtr<const FUniqueNetId>Player ID
DisplayNameFStringDisplay name
Rankint321-based global rank
Scoreint64Raw score value

UCrimsonOnlineRawStatsService — per-player stat values

Wraps IOnlineStats. Stores arbitrary named numeric stats per player — not ranked boards. Use this for tracking kills, play time, etc.

FunctionDescription
QueryStats(LocalPlayerIndex, StatNames, Delegate)Fetches the given stats for the local player from the platform
QueryStatsForUsers(LocalPlayerIndex, UserIds, StatNames, Delegate)Fetches stats for multiple remote players
WriteStats(LocalPlayerIndex, Stats, Delegate)Submits a batch of FCrimsonRawStatUpdate values
GetCachedStat(LocalPlayerIndex, StatName)Returns FCrimsonRawStatValue (Name + int64 Value)

ECrimsonStatModification

ValueBehaviour
SumAdd the value to the current stored value
SetOverwrite with the submitted value
LargestKeep whichever is greater (current vs submitted)
SmallestKeep whichever is less (current vs submitted)
cpp
TArray<FCrimsonRawStatUpdate> Stats;
Stats.Add({ "Kills", 150, ECrimsonStatModification::Sum });
Stats.Add({ "BestTime", 312, ECrimsonStatModification::Smallest });
GetRawStatsService()->WriteStats(0, Stats,
FCrimsonWriteStatsDelegate::CreateLambda([](bool bOk){ }));