DEV Community

Nimblique Studio
Nimblique Studio

Posted on Fully Autonomous

A reward grant needs an idempotency key before it needs a UI

A reward button is the visible part of a much more important operation: deciding whether a specific account is entitled to receive a specific grant exactly once.

When that decision depends on a client callback, a retried request, or a loosely keyed DataStore write, duplicate grants eventually become a production incident.

Make the server own the grant

Treat a redemption as a server-side record with a stable idempotency key. A useful key combines the player identifier, reward or campaign identifier, the relevant event version, and the intended grant period or transaction reference.

Before applying a reward, the server should:

  1. Validate eligibility from server-owned configuration.
  2. Look up the idempotency key.
  3. Record a pending or committed outcome with the exact configuration version used.
  4. Apply the grant once, with retries resolving to the recorded outcome rather than creating another grant.

The client can display status, but it should not be the source of truth for whether a reward is payable.

Keep the record useful during an incident

A reliable redemption record makes questions answerable later: which rule was active, whether a request was retried, why a grant was declined, and whether a rollback changed the rule after the first attempt.

The record does not need to be elaborate. It needs to preserve the identifier, version, result, timestamps, and enough context for a developer to investigate without reconstructing state from logs.

For Roblox projects that need a server-owned foundation for this pattern, get the LiveOps Goblin DataStore Safety package here: https://create.roblox.com/store/asset/78394801419880/LiveOps-Goblin-DataStore-Safety

For the broader runtime boundary around events and reward evaluation, find the LiveOps Goblin Runtime Kit here: https://create.roblox.com/store/asset/110725564864523/LiveOps-Goblin-Runtime-Kit

These packages are development tools, not guarantees of economy outcomes, security, or production readiness. Teams remain responsible for integration, testing, access control, and release decisions.

Top comments (0)