Note: this is in relation to android specifically, but the best answer might not be platform specific, hence the other tags.
Consider a game similar to angry birds: you have a bunch of levels. Each time you finish a level, the next level is available for play, but not before. How can I make it harder for players to hack my game files and unlock levels that shouldn’t be available? Assume that progression data is stored locally.
My thoughts:
On android, all app files are stored in a folder that the user can only access if they have root access (by default, they never do, but it’s usually very easy to get as long as you google a little). Right now, I am using an sqlite database that looks something like this:
LevelId = pk | UnlockStatus = int, 0 = locked, 1 = unlocked, 2 = completed with 1 star, ...
This is fine as long as the user doesn’t have root or is not at all familiar with where app files are stored. If they have root however, this file is very easy to edit.
As far as I can tell, angry birds stores its level data in a .lua file, at least according to its name. I can find no text file or db file that contains level info. Opening this .lua in a text editor displays nothing but gibberish. I haven’t tried a hex editor.
Using an sql table is very convenient. Is there an easy way to store the progression data in the sql table such that the user will have a harder time making sense of it? Ideally, it should also not be too time-consuming to implement. Being an offline game, I don’t care THAT much if the player hacks it or not, so I’m looking for the best quality – implementation time trade-off. Theoretical answers that yield a lot more implementation time for considerably more quality are also appreciated however.
You best bet would be saving data using some sort of encryption. In android, SQLite doesn’t offer encryption at database level. However, you may encrypt the values (records) in table and decrypt them after querying.
Another way could be saving your data as key/value pair in some sort of text file (example of .lua in angrybirds) in internal or external memory and perform encryption on the file contents. On the other hand, decrypt it at run-time and read your key/value pairs.
Tadaaa! problemo solved 🙂