People get coins for completed tasks(for example completing a level) in my game. In addition, they can purchase coins(they need to pay for that with real money) in the app store. With these coins, people can purchase different items in the game.

Is it easy for somebody to manipulate the amount of coins when I store it as an integer variable in a text file on the device(iOS and Android phones and tablets)?

What is the best way in MonoGame/Xamarin to store the amount of coins so that nobody can manipulate it afterwards?

  • 2
    \$\begingroup\$ The only way to prevent it from being modified is to store the authoritative value on a device that you control, like a server. Have you looked into server validation of earning & transactions in your game? \$\endgroup\$ – DMGregory Aug 21 '18 at 12:02
  • \$\begingroup\$ No, I don't know how to do that and I have no server. Is it not possible to store it on the device? Because I don't want that you need an internet connection all the time when you play the game. It's just a small jump 'n' run game. \$\endgroup\$ – Joe Driver Aug 21 '18 at 12:31
  • 2
    \$\begingroup\$ If it's on the player's device, then it's in the player's control. You can make it easier or harder to cheat, but if your goal is "nobody can manipulate the amount" then you must have a trusted device (your server) verifying those transactions. Anything else can be hacked. \$\endgroup\$ – DMGregory Aug 21 '18 at 12:39
  • \$\begingroup\$ Is it difficult to modify a text file that is stored on the player's device? At the moment I use IsolatedStorage on MonoGame to store the amount of coins in a text file. It doesn't need to be 100% secure, but I don't want that everybody can easily modify the file. \$\endgroup\$ – Joe Driver Aug 21 '18 at 12:55

The only solution would be to have a validation server; that being said, you mentioned not wanting them to always have an internet connection and that being one of the reasons you did not want to implement this solution but I would like to remind you that to buy things on the app store the user will need to have an internet connection at that moment.

Because of that required connection, you dont need to have Always-OnLine checks if you use a "real-money" economy and a "game world" economy. You can always allow users to buy the "real-money" economy using the ingame currency but require them to have an internet connection. However, if you do allow such a thing then the user can still modify any internal values on their device without you being able to check any of it.

tl;dr Either you trust the user to not hack, or you need to perform online validation of anything relating to real money

  • \$\begingroup\$ How can I implement and use a validation server? Does it cost me money? Where can I find a tutorial? \$\endgroup\$ – Joe Driver Aug 21 '18 at 14:22
  • \$\begingroup\$ The short version is: 1) Connect to the remote server 2) send a signal to inform the server what action you want to perform 3) wait for the answer 4) act on the answer \$\endgroup\$ – TurtleKwitty Aug 21 '18 at 14:45
  • \$\begingroup\$ For connecting to the remote server its all about using sockets, there are a million different ways of doing it, a simple "program basic server <language> <os>" in Google will do the trick for that part \$\endgroup\$ – TurtleKwitty Aug 21 '18 at 14:48
  • \$\begingroup\$ as for the "signal" for a simple Learning project like wha tyou see mto describe i would suggest just sending an enum for the action to perform followed by the value they want to affect. for example an enum where 1 is buy coins someting like (1, 10) to buy ten coins \$\endgroup\$ – TurtleKwitty Aug 21 '18 at 14:50

What I do is store the data in an obscured and verifiable fashion in memory and on disk, only decoding it when necessary. As mentioned in the comments, this will not prevent alteration, but it will deter it.

For example, an obscured value could be a struct that stores the number twice, once normally and once altered by, for example, XOR-ing it with some key. Then any program trying to alter the value in-memory or on disk would find the first, and modify it. But the next time you try to access the value, some property fetcher would check to see if they match. If they don’t, just forcibly quit the application. That may be sufficient to deter most casual hacking. It would also help if you cryptographically sign your save data and verify that when loading.

However, you also have to worry about users modifying the app code, which would allow them to bypass any check. And if they can see the source decompiled, they can easily determine where your check is and either disable it or figure out how to change the value in the save data on disk. So you would also need to try to obscure your “currency“ class and methods, as well as your loading code so they are harder to find and modify. And if they do manage to modify the game, you can check whether it’s been modified on Android at least by ensuring the signature on the installed package is the one you expect it to be (again, in an obscured way). If not, then you can again force quit, or behave slightly differently so that casual hackers don’t notice anything immediately.

None of these will completely deter someone determined enough, but everything combined together has helped stop many of the problems with games I’ve worked on.


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.