Interface IAchievementService
Service interface for unlocking achievements, tracking their progress, and reading the player's achievement state.
Inherited Members
Namespace: Serenity.Achievements.Application.Interfaces.Services
Assembly: Serenity.Achievements.Application.dll
Syntax
public interface IAchievementService : IService, IFoundationSettings, IDisposable
Remarks
Reads are synchronous over an in-memory cache hydrated by LoadAsync(CancellationToken); writes are asynchronous because the configured backend may be a network or database call. Operations on an unknown achievement never throw: they log a warning and return an empty/no-op result, matching the framework's never-throw-in-runtime philosophy.
IDisposable so the composition root can stop in-flight detached work (an unlock's screenshot capture and platform push) at teardown, rather than letting it run against a service nothing reads any more. A disposed service turns every mutating call into a no-op, the same never-throw contract every other operation on this interface already carries.
Properties
IsLoaded
Whether LoadAsync(CancellationToken) has successfully hydrated the cache. False means every read answers "locked" because nothing has been read from the store yet, not because the player has earned nothing.
Declaration
bool IsLoaded { get; }
Property Value
| Type | Description |
|---|---|
| bool |
Methods
GetAll()
Every registered achievement definition, in display order.
Declaration
IReadOnlyList<AchievementDefinition> GetAll()
Returns
| Type | Description |
|---|---|
| IReadOnlyList<AchievementDefinition> |
GetMaximumPoints()
The points every registered achievement adds up to.
Declaration
int GetMaximumPoints()
Returns
| Type | Description |
|---|---|
| int |
GetTotalPoints()
The points the current player has actually earned.
Declaration
int GetTotalPoints()
Returns
| Type | Description |
|---|---|
| int |
GetUnlocked()
The registered definitions the current player has unlocked, in display order.
Declaration
IReadOnlyList<AchievementDefinition> GetUnlocked()
Returns
| Type | Description |
|---|---|
| IReadOnlyList<AchievementDefinition> |
GetVisible()
The registered definitions the UI may show, in display order: everything that is not hidden, plus every hidden achievement the player has already unlocked.
Declaration
IReadOnlyList<AchievementDefinition> GetVisible()
Returns
| Type | Description |
|---|---|
| IReadOnlyList<AchievementDefinition> |
IncrementProgressAsync(AchievementId, long, CancellationToken)
Adds a delta to the progress numerator of a progressive achievement.
Declaration
Task IncrementProgressAsync(AchievementId achievement, long delta, CancellationToken cancellationToken = default)
Parameters
| Type | Name | Description |
|---|---|---|
| AchievementId | achievement | The achievement to advance. |
| long | delta | The amount to add to the numerator. |
| CancellationToken | cancellationToken | Token used to cancel the operation. |
Returns
| Type | Description |
|---|---|
| Task |
IsUnlocked(AchievementId)
Whether an achievement is unlocked for the current player.
Declaration
bool IsUnlocked(AchievementId achievement)
Parameters
| Type | Name | Description |
|---|---|---|
| AchievementId | achievement | The achievement to test. |
Returns
| Type | Description |
|---|---|
| bool |
LoadAsync(CancellationToken)
Hydrates the in-memory cache from the store, reconciles it against the platform account, and retries any unlock that has not reached the platform yet.
Declaration
Task LoadAsync(CancellationToken cancellationToken = default)
Parameters
| Type | Name | Description |
|---|---|---|
| CancellationToken | cancellationToken | Token used to cancel the operation. |
Returns
| Type | Description |
|---|---|
| Task |
ResetAllAsync(CancellationToken)
Clears every unlock, progress row and screenshot for the current player. The platform account is only cleared when ClearPlatformOnReset is on. Intended for debugging and QA, not for shipped gameplay.
Declaration
Task ResetAllAsync(CancellationToken cancellationToken = default)
Parameters
| Type | Name | Description |
|---|---|---|
| CancellationToken | cancellationToken | Token used to cancel the operation. |
Returns
| Type | Description |
|---|---|
| Task |
RetryPlatformSyncAsync(CancellationToken)
Re-attempts everything LoadAsync(CancellationToken) does with the platform account: brings the session up if it is not up yet, reconciles both directions when the account can be read, and drains the offline queue.
Declaration
Task RetryPlatformSyncAsync(CancellationToken cancellationToken = default)
Parameters
| Type | Name | Description |
|---|---|---|
| CancellationToken | cancellationToken | Token used to cancel the operation. |
Returns
| Type | Description |
|---|---|
| Task |
Remarks
A storefront client that was closed at boot typically comes up minutes later, and
nothing else re-tries: without this the unlocks earned in between sit at
platform_synced = false until the next launch. The Unity runner added in a later
phase calls this on a backoff timer; game code rarely needs to.
Cheap and safe to call when the platform is still unavailable — it returns after the
failed initialize.
SaveConditionStateAsync(AchievementId, string, CancellationToken)
Stores the opaque state an unlock condition needs to resume counting after a relaunch, against the achievement's progress row.
Declaration
Task SaveConditionStateAsync(AchievementId achievement, string conditionState, CancellationToken cancellationToken = default)
Parameters
| Type | Name | Description |
|---|---|---|
| AchievementId | achievement | The achievement the state belongs to. |
| string | conditionState | The state produced by the condition tree. May be null. |
| CancellationToken | cancellationToken | Token used to cancel the operation. |
Returns
| Type | Description |
|---|---|
| Task |
Remarks
Separate from SetProgressAsync(AchievementId, long, CancellationToken) because the two answer different questions: the numerator is what the player is shown, the condition state is how the evaluator rebuilds its counters, and a boolean achievement has the second without ever having the first. Unknown and already-unlocked achievements are no-ops.
SetProgressAsync(AchievementId, long, CancellationToken)
Sets the progress numerator of a progressive achievement, clamped to its target.
Declaration
Task SetProgressAsync(AchievementId achievement, long current, CancellationToken cancellationToken = default)
Parameters
| Type | Name | Description |
|---|---|---|
| AchievementId | achievement | The achievement to advance. |
| long | current | The new numerator. |
| CancellationToken | cancellationToken | Token used to cancel the operation. |
Returns
| Type | Description |
|---|---|
| Task |
TryGetProgress(AchievementId, out AchievementProgress)
Attempts to read the tracked progress of an achievement.
Declaration
bool TryGetProgress(AchievementId achievement, out AchievementProgress progress)
Parameters
| Type | Name | Description |
|---|---|---|
| AchievementId | achievement | The achievement to look up. |
| AchievementProgress | progress | The tracked progress, when one exists. |
Returns
| Type | Description |
|---|---|
| bool | True when progress is tracked for the achievement; otherwise false. |
TryGetUnlockRecord(AchievementId, out AchievementUnlockRecord)
Attempts to read the unlock record of an achievement.
Declaration
bool TryGetUnlockRecord(AchievementId achievement, out AchievementUnlockRecord record)
Parameters
| Type | Name | Description |
|---|---|---|
| AchievementId | achievement | The achievement to look up. |
| AchievementUnlockRecord | record | The unlock record, when the achievement is unlocked. |
Returns
| Type | Description |
|---|---|
| bool | True when the achievement is unlocked; otherwise false. |
UnlockAsync(AchievementId, CancellationToken)
Unlocks an achievement. Already-unlocked and unknown achievements are no-ops.
Declaration
Task UnlockAsync(AchievementId achievement, CancellationToken cancellationToken = default)
Parameters
| Type | Name | Description |
|---|---|---|
| AchievementId | achievement | The achievement to unlock. |
| CancellationToken | cancellationToken | Token used to cancel the operation. |
Returns
| Type | Description |
|---|---|
| Task |
Events
Loaded
Raised after LoadAsync(CancellationToken) has hydrated the cache, so a screen already on display can show what the player actually owns.
Declaration
event Action Loaded
Event Type
| Type | Description |
|---|---|
| Action |
Remarks
The achievements module loads asynchronously while the game's first menu is already up, so a listing opened early would otherwise show every achievement as locked and never correct itself — reads are synchronous over a cache that simply was not populated yet. Only a successful load raises this; a store that could not be reached raises nothing, because nothing changed. Raised outside the mutation gate, so a handler is free to call back into the service, and every handler failure is contained.
StateReset
Raised after ResetAllAsync(CancellationToken) has cleared everything, so the parts of the system that hold derived state can drop theirs too.
Declaration
event Action StateReset
Event Type
| Type | Description |
|---|---|
| Action |
Remarks
The evaluator is the reason this exists: it drops an achievement's condition tree the moment the achievement unlocks, and its trees carry tallies of their own. Without a notification, a debug reset would clear the store and leave every already-unlocked achievement permanently unreachable for the rest of the session, with stale counters in the trees that remained. Raised outside the service's mutation gate, so a handler is free to call back into the service.