Editorial illustration: Achievements from statistics to claiming rewards

Achievements from statistics to claiming rewards

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.

Explore Dalo

Latest devlogs

Editorial illustration: Pasur launch and telemetry in the shared structure

Pasur launch and telemetry in the shared structure

Adding Pasur needs both a correct mode handoff and valid public telemetry.

Read article
Editorial illustration: Presenting selection and captures in Pasur

Presenting selection and captures in Pasur

Pasur motion should explain which hand card was played and which table cards were captured.

Read article
Editorial illustration: Pasur bot decisions from capture options

Pasur bot decisions from capture options

My teammate’s Pasur bot chooses among legal options without inspecting hidden opposing cards.

Read article
Dalo