Building a High Score Web Service (Considerations)
As part of this new game, I’m planning on having a global high score system where players from anywhere can post their initials and have them displayed across all game instances, and on the game website. Technically, doing that is pretty straight forward. You have some code running on a web server that receives and processes HTTP requests, and depending on what the service does, it’ll stash data in a database or maybe produce an image or whatever, and return some response to the requester. Simple in concept, but to build and architect a service that can scale and handle abuse, is nuanced and not at all simple.
I’m not going to get into architecture or scaling here, because at the end of the day, how I solve that is really based on the resources I have available and my personal framework or scripting language preferences for the back end. And that stuff is ideology and whatever I use there will be someone with a man-bun telling me I should use the latest new Google framework. Meh! The actual web service I am building is very, very simple and a regular LAMP stack will work just fine for my requirements. So that stuff aside, this leaves security and abuse. How do I stop some malicious asshole from spamming the service, trying to break it for the lulz, or maybe, more innocently trying to cheat the high score system?
There is no simple answer or solution to this, certainly not with the resources I have available. Even if my service requires strong authentication, where the user is registered, and uses a token, etc., the nature of a web service is its availability and ease to hit with requests. Any script-kiddie could write a script to send requests at a high frequency. Anyone could sniff the request being sent by the game and figure out how to form their own requests and spam or cheat the service. Shit, they can just send any old stream of garbage to the service, and it would need to handle it. So there’s no way to stop someone from spamming your service, but you can mitigate some of this by using mature and readily available software packages that most hosting providers have available. Something like Fail2ban, that scans logs looking for unusual and potentially malicious activity and bans IPs. This is already installed and working on my web server, but has a potential issue for a game related web service, where people may be behind proxies used by multiple people, meaning if there’s one bad actor who decided to get themselves banned, all people on that proxy will also get banned. Not ideal! If there’s no way to stop spamming, how do we stop the spamming from breaking or bringing the service to its knees? A server IP ban at the firewall (Fail2ban), will stop any blocked traffic from ever reaching and hitting the service, so that will be in place. My hosting service have their own rules and layers of protection on their networks and can help mitigate persistent attacks if needed. Basically this is too big a problem for me to solve well given my resources, so I’ll have to make do as best I can.
Then there’s cheating and just people trying to break shit. That is guaranteed to happen, as there are a lot of twats out there, so it’s important to make sure the web service is as bulletproof as possible. It must be able to handle with grace, any data that’s thrown at it. This just comes down to best practices and carefully scrubbing and cleaning any data the service will ultimately use. Requests must be authenticated to make sure they are coming from the actual game rather than a stand alone script. Tracking abusive or cheater IPs in another database and soft banning them. A possible option here, to take the validation load off the main DB, would be to hide the actual service behind another layer that uses a NoSQL DB to stash requests while some code chews on it in the background, and sorts the good from the bad, eventually sending good data to the actual service to be stashed as a purely internal, hidden operation. This approach could also provide a simple mechanism for metering traffic allowed into the service.
Tracking and catching cheats is more of an algorithm problem than anything else. The first thing would be to define what cheating or suspicious activity would look like. Knowing the rules of the game, it’s fairly easy to come up with a set of criteria that describes a valid high score. Is it impossibly high? Is it impossibly high for the length of time played or the wave/level reached? Are there too many requests from the same IP or user in a short period of time? Etc. Etc. There are all sorts of ways to break the problem down, and simply requires some thoughtful consideration and careful implementation.
Another thing that can be done to deter the casual or wannabe hacker, is to obfuscate the request to the web service, with encryption or misdirection, and protect it from manipulation with a checksum. This just makes it harder and more time consuming for someone to figure out, and because most griefers are lazy little oiks, they won’t bother. I don’t think this game or web service will be worth expending real energy on to hack.. LOL, who am I kidding!? When has that ever stopped someone from trying to break shit just because.
So there you have it. There’s a lot about web services that needs to be considered. If I was building this in a corporate or studio environment, I would definitely be more meticulous and “enterprise” in my approach, especially with the additional resources that would be available. I’m a one man band, building a silly little twin stick shooter on zero budget, so it’ll be as good as I can manage. Additionally, none of this is written in stone. I may just shit-can the global high scores idea completely if it proves too hard/risky, and I can’t come up with something reasonable, or it fails hard in test.
Of course if I was smart, there’s always a service like PlayFab where ALL that unpleasant crap is just done and handled for you. This is a very real option, provided you can justify the expense. As a small, one-man-band, hobbyist game developer, without a budget or any real hope the game will make any significant money, committing to a recurring expense is a tough pill to swallow. Also, because I’m a bit weird, I like to program stuff like this. I even used to do it for money at one time.
Anyway, I got super bored over the weekend working on this stuff, so have basically pushed the remaining tasks on the high score system (namely the in game GUI stuff), to the “back lot”. I got a big chunk of it out the way, and I’m looking forward to some fun coding next week making game pickups.
Category: Dev Blog, Game Dev, Indie Games, Programming