The final post that concludes the series about game development is gonna be around the backend (server). It’s pretty big topic, but I figured I’d summarize it in one (probably) long post, so here it goes.
Back Me Up!
Wait, why do we wanna bother with a backend? Can’t we just build a game and ship it without any backend whatsoever? .. Sure you can, but you’re talking about a seriously slim chance of success, as slim as flappy bird!
Compared to most other games, flappy bird is one of the few which doesn’t rely on a backend. Angry birds, CoC, Candy Crush, .. You name it! If it has any of the features below, it needs some sort of backend support:
- Push notifications
- User profiles
- … etc
Now, if you really wanna be lean and mean, you should avoid developing a backend yourself. There are tons of services out there that provide you with basic features, which you may get away with if your game is simple enough. This list is far from exhaustive:
Personally, I’ve had my fair share of pain dealing with blackbox backends that leave you completely in the dark when it comes to how the server is managed. If you start growing or needing extra features .. Good luck with that! Sometimes you don’t need that, most likely (if your game is any good) you’ll want it.
I’ve gone through my share of pain and suffering with the backend, all the way from a Java based server, to a python based server on GAE, to a C++ based madness server, and finally … to Elixir-goodness.
I’ve pretty much settled with Elixir, since with relatively minimal effort, I’ve written a full-featured realtime backend. Fully tested, with unit tests and integration tests. Moreover, stress tested like mad by the authors of the phoenix framework.
Using Elixir for my game was perfect, since it finally allowed me to think about server from the clients perspective.
Once a client connects to a server, we spawn a process to track that user. When that process dies, that means the user is disconnected! SO SIMPLE!! Do you want to add a retry and wait for the user to connect back again? SURE! All your work is done within that process.
Once the user starts interacting with our backend, we send the user’s process id (pid) to workers which do stuff. For example, the matchmaker worker will take a bunch of user processes then match them against each other based on the relative rating for each player.
Besides the workers, we also have “stateful” processes, which hold a shared state between one or more user process. For example, we spawn a “room state” process, and add the user to it. Once another user process joins, we close that “room state” process, and spawn a “game state” process, add the players there, and now they can proceed playing the game!!! It’s is so eloquent I can’t help but keep admiring how superior it is compared to every other crappy (yet popular) framework out there. ehm Django. ehm Rails.
So, with that, really, it was a piece of cake to write an auth system, leaderboards, game system, “referee” worker, matchmaker, … etc. All that makes up my game city! It’s really more of a city at this point rather than a server.
With the features easily implemented, since Elixir is a productivity focused language, we also gain scalability for free. I can, at any point in time, break my backend workers into Elixir applications, push them to different servers, and have a decentralized Elixir backend, which I can easily then scale and upgrade in a super fine-grain way.
Phew! Enough with the Elixir fanboyism! Time to close off this topic and head home!
If you’re looking for a backend for your game, make sure you test a “vertical slice demo” on it. Trust me on this one. Don’t delay crucial features from the backend thinking that you’ll get back to it later .. That spells disaster.
If you can easily implement the “vertical slice” demo on the backend easily enough, then you’re doing it wrong indie chum. Unless you really wanna focus on the backend, like it is the core of your game, or you have some super weird requirement, just stick with a simple solution. Even a custom backend can still be simple enough to develop!