Wednesday, December 26, 2018

Anti-cheat Javascript for browser/HTML5 game


I'm planning on venturing on making a single player action rpg in js/html5, and I'd like to prevent cheating. I don't need 100% protection, since it's not going to be a multiplayer game, but I want some level of protection.


So what strategies you suggest beyond minify and obfuscation?


I wouldn't bother to make some server side simple checking, but I don't want to go the Diablo 3 path keeping all my game state changes on the server side.


Since it's going to be a rpg of sorts I came up with the idea of making a stats inspector that checks abrupt changes in their values, but I'm not sure how it consistent and trusty it can be.


What about variables and functions escopes? Working on smaller escopes whenever possible is safer, but it's worth the effort?


Is there anyway for the javascript to self inspect it's text, like in a checksum?


There are browser specific solutions? I wouldn't bother to restrain it for Chrome only in the early builds.



Answer




The short answer is you can't do it. Anything that runs client side, especially from source, can be modified to defeat your tactics trivially. If you put in place a client side checker to look for abrupt changes, a user can just disable the checker.


The good news is that, generally, there is very little cheating on single-player games. The only major exception being for games that have large "youtube highscore" communities like Line Rider, where players compete with each other over YouTube.


If you are aiming for that, or are just too stubborn to accept that people might cheat in the game, or are keeping high-scores yourself (which is a form of multiplayer) then what you must do is all of the calculations server-side. Yes, everything that matters. You can't even repeat the calculation client side to try to give the user the score and then 'verify' it with the server because the user can then just disable the check and disable any system that ensures there are checks.


I wish there was a better answer to this, but there isn't.


That said, there are things you can do to make it a little harder to cheat. They will not stop anyone serious from doing it and releasing a toolkit to cheat, but it will slow them down:



  • Minify and Obfuscate your JS, which absolutely will make the code harder to read. You can de-minify and sort-of de-obfuscate but you can never get back the right variable and function names, nor comments.

  • Bake in values with a different language. In this case you can use PHP or other server side languages to handle static setup variables. If the jump distance is always supposed to be 2 spaces, normally you'd define a jump distance for the player object. Don't, handle that with PHP so that the JS source ends up with 2s plastered all over the code in a million places. This has the happy additional side effect of being able to speed up your JS too.

  • With some practice, you'll get proficient with the mix and you can even custom-build your JS for each player. Which is another way to prevent cheating. If each player's code is different somehow, then it is harder to write a cheat that can be part of a toolkit.

  • Finally, you can checksum the source based on the player's identity. Say their IP address and/or username. You know what the player-specific version of the JS will be, you can bake in a checksum and require that it be the same on the other end. Easy to disable like any client-side JS, but once again makes it a little harder to make a toolkit.



So. As you see, it is probably not worth it to go this route. It is hard. Requires a lot of really silly coding practices to do, and is ultimately still relatively easy to defeat. You'll need to do all the calculations server-side to prevent cheating. Or let go, and accept that cheating will happen.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...