What's the best way to save scores per level in android?

| | August 10, 2015

I’m in the middle of programming a tile based puzzle game, then i realized i don’t have any good ways to save data. For the moment i’m using these long combined strings for sharedpreferences and i’m very sure SharedPreferences isn’t designed to keep all my per level scores.

I’ve got 63 levels, spread into 7 difficulties, and all scores(stars granted) is saved like this:

prefs.edit().putInt("achievedstars"+current_difficulty+"_"+current_level, stars_granted).commit();

This means i am saving 63 of those strings as for only the stars granted for the levels. I also want to save “best amount of moves”, “time used”, and possibly more.

The game is not going to have a leaderboard, or communicate with others devices (although it may allow posting scores to FaceBook, twitter etc.)

Another thing that might be useful to mention is that the file should not be accessible(or atleast not readable enough for people to cheat)

What would you suggest as the best way of saving stats like this from android applications?

One Response to “What's the best way to save scores per level in android?”

  1. You have multiple choices:

    Shared preferences file is the one you are now using. It’s usable and nice key-value store, but should be used only for settings type data. Maybe for username, time played, etc. Nothing too complicated.

    Saving files in Android’s file system is better choice for your problem. How ever, you wanted to secure the file, so that user can’t modify it.

    Using databases managed by SQLite is bit heavy solution for this kind of stuff, but once setup, is easy to use and harder for everyday cheaters get theirs hands on the data. However, i think this is bit overkill for that kind of data.


    You could use file system to store XML data or plain text with some format you can figure out yourself. You could for example, store line by line, so that first is key and next line is value or you could write key and value same line, with some separator, like “|”. It’s really up to you.

    If you go with file system and you are only worried that if user manually locates the file and then edits it, you could do few things that give some security for the file.

    First, base64 encode the file data. This makes reading and writing file by hand a tedious job. Notice, this is quite standard so user with knowledge and will, can still find out what’s going on with your file. However, this works for most of users.

    // Make unreadable
    byte[] data = text.getBytes("UTF-8");
    String base64 = Base64.encodeToString(data, Base64.DEFAULT);
    
    // Make readable again
    byte[] data = Base64.decode(base64, Base64.DEFAULT);
    String text = new String(data, "UTF-8");
    

    Second, hash your file and store that hash to userprefs. When you load the file data, hash it and compare to the hash stored in userprefs. If they are not equal, user has changed something from it. Check this SO answer for how to hash data with SHA1.
    http://stackoverflow.com/questions/5980658/how-to-sha1-hash-a-string-in-android

    Please notice, while these add “security”, it’s not cheat proof still, but it’s a start.

Leave a Reply