Quick answer: Anchor reward timing to the server clock, store the last-claim timestamp server-side, and detect when the device clock jumps relative to monotonic time.

Your daily reward checks the device date against the last claim. A player sets their clock forward a day, claims again, and repeats. The device clock is attacker-controlled, so move the timing decision to the server and watch for clock tampering on the client.

How to fix it

1. Decide eligibility on the server

Store the last-claim time on the backend and compute eligibility from the server clock. The client asks to claim; the server decides whether enough real time has passed.

2. Compare wall clock to a monotonic source

On the client, track elapsed time with a monotonic timer and compare it to wall-clock changes. A large forward jump in wall time with little monotonic elapsed time signals clock tampering.

3. Fail closed when offline

If the device is offline and you cannot reach the server, defer the reward rather than trusting the local clock, so an offline clock change cannot unlock anything.

Catching the ones you can't reproduce

The hardest version of this to fix is the one you can't reproduce — it only happens on a player's hardware, OS, driver, or save state, under conditions that simply aren't present on your machine. A report that says “it crashed” or “it froze” gives you nothing to act on, so the bug survives release after release while quietly costing you players.

Automatic error capture closes that gap. Each failure arrives with its full stack trace, the device and OS, the build number, and a breadcrumb trail of what the player did right before it broke, so even a failure you have never seen becomes a specific, reproducible issue. Fold identical failures into one signature ranked by how many players each hits, and your worklist sorts itself worst-first instead of arriving as a stream of vague complaints.

This is where a tool like Bugnet earns its place. Its SDK captures every mobile error automatically with the full stack trace plus device, OS, memory, build, and game-state context, folds duplicates into one grouped issue with an occurrence count, and ties each to the build it first appeared on — so you fix the problem that hurts the most players first and confirm it is gone when its signature disappears from the next release.

Most of the time the fix is small. Seeing the failure clearly is the part that actually costs you.