The problem I needed to solve
An achievement should follow recorded game outcomes rather than a button tap. I separated progress from claiming so automatic completion would not become repeated reward delivery.
Implementation in this snapshot
AchievementService.GetProgress finds a definition and runs CalculateCurrentValue against its statistics metric. TryClaim checks validity, completion and unclaimed status, saving the ID only after a successful grant.
The design decision and its cost
Metrics such as wins in one game, total matches and spent coins have explicit sources. IDs are normalized, and rewards can have definitions separate from achievement targets.
Current boundaries
Local statistics determine input quality. If a match ending is recorded incorrectly, progress will also be wrong; this service does not independently prove anti-cheat protection or outcome correctness.
Review scenarios and contract meaning
The interface may seem to need only three states, but each needs a precise meaning: progress below the target, completion with a reward available, or a reward already claimed. Wins in one game, for example, must come from that game’s statistics rather than total matches. The service calculates the current value from the metric type and the interface can relate it to the target. This allows achievement definitions to change without every button implementing its own counting logic. I treat statistics as contract input and do not infer their validity from an attractive progress bar.
Saving the claimed identifier after success prevents an ordinary repeat request, but deferred coin distribution adds an important qualification. Success can mean presentation was accepted while the balance has not increased. An interruption in that gap can separate the claimed marker from actual coins. Presentation completion and a repeated claim are therefore different review scenarios. Renaming a definition’s identifier may also make it appear new to saved data. Identifier management, statistical validity and reward durability are three data concerns the interface cannot solve by itself.
Spending and winning metrics have different inputs: one comes from economy changes and the other from recorded match results. Incorrect progress is not always an AchievementService bug. Following the metric source before changing the interface prevents superficial fixes. New definitions also need targets, counting units and claim conditions that agree with recorded behavior.
What this stage taught me
For me, an achievement is a clear relationship between behavior, counting and rewards. The interface can distinguish progress, claimable and claimed states because the model preserves those meanings.




