1
\$\begingroup\$

I have a mobile game with achievements on android, so the achievements are using Google Play Services.

For a couple of reasons, I must track the progress on the achievements locally (or so I think) because:

  • If the user is not connected to the internet
  • Some achievements have complex "step" that the simple increment system provided by the Google Play Service (number of steps, current step) cannot track.

When the game starts, the local copy data on the achievements is synced with what is on Google's server. Either

  • both are the same, do nothing
  • the local copy has more progress than what is shown on Google's: so update Google data (that happens if you play offline)
  • the copy on Google's server show more progress than locally: so update the local data (that happens if you play on a different device)

Clearly, there's a way to abuse the system here. Given two players with different achievement progress (Player_A (lots of achievements), Player_B (few achievements)) they can do the following:

  • Using Player_B's device, Player_B signs out of his account
  • Player_A signs in (the current active Google Account is now Player_A)
  • Start the game
  • All of Player_A's achievements are synced locally (they had more progress than the previous local version of Player_B)
  • Player_A signs out and Player_B signs in
  • Re-start the game: the local copy will show as more advanced than Player_B achievements, therefore they will get updated.

How do people deal with this problem? Not care? Key the local achievement progress to the logged in player (which causes some problems)? Not to track anything related to the achievements locally (but how to deal/detect being offline?)

\$\endgroup\$
2
\$\begingroup\$

This is a classical "local cache invalidation" problem, the very common case in which you really need to invalidate the cache when the user changes (so that, for example, when I access my home banking I don't see a chart about how much money the previous user has).

The usual solution is to include the player name in some form (a hash, a user_id...) in the cached data (your local achievements) and then when the player starts the game you check the active username vs. the username whose ID was stored in the cache: if they're different, you download all data from Google Play Services anew.

Obviously, doing this will delete any progress made by the previous user, so you could add a warning to allow the player to stop the transfer and log in again with the username that was in use when the existing cache was last saved so that he can sync it.

A more complex and maybe satisfying option, especially if you really can't save those complex achievement steps on Google, is to keep a local copy of all users' "caches" (at this point I'd call them something like "custom user achievement stats dataset"): every new user will create a new dataset, all of them stored on your device so you can always keep those data you can't save on Google... with bonus points for allowing an easy path to port the game on other mobile OSes.

\$\endgroup\$
  • \$\begingroup\$ I was considering keying the local data to the userId indeed, thanks for detailed information. \$\endgroup\$ – ADB Oct 1 '16 at 3:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.