I recently needed to set up a leaderboard service for our first game, Washed Up! (coming soon, join our mailing list to stay informed). I ended up deploying the open source server Nakama on Google Compute Engine, and I learned a bunch of things along the way, which I figured could well be helpful for others.
This is going to be a short series of posts since there’s quite a lot to cover. My plan right now is to cover:
- Why Nakama? (this post)
- Getting a basic service running
- Securing the service, adding resilience and backups (future)
- Using the service from Unity (future, if there’s interest)
Please do reach out on Twitter if you’re finding the series useful, since it’s a fair investment of time; I’ll gauge how much time to put into the subsequent posts based on how useful/interesting it seems to be to others.
I was attracted to Nakama because it is open source, and I like my critical infrastructure being open source, especially as this will probably span multiple games. It’s also written in Go, which I like a lot, and if you’re going the open source route, it really should be something you feel happy to hack on if needed.
I tested it locally on Windows Subsystem for Linux at first, and found it pleasant to use. Importantly, I also found the developers to be extremely responsive in their chat room when I needed to clarify something. I’ve already submitted a few pull requests back to the project and it feels like a good place to be.
But of course, running Nakama was just one option among many to implement leaderboards in a game; others included:
- Using distribution platform services (Steam, Game Center etc)
- Using a commercial 3rd-party solution (e.g. GameSparks)
- Writing my own simple server
I’ll quickly cover why I didn’t choose those other routes, so you can evaluate whether the conclusion makes sense for you too.
Why not Steam et al?
The main downside of depending on Steam and related services for leaderboards is that you are dependent on that service. I know, obvious. But the ramifications are:
- You can only deploy on platforms that have those services available; forget direct distribution, Itch.io etc
- Each of the platforms is its own little island of players
If you’re a “big dog” in games this won’t necessarily matter; each island of players will be large enough, and Steam only is probably a good fit for you. As a small unknown outfit though, alternative distribution can be attractive, even if you end up doing Steam as well, perhaps later in the process (as we intend to). And if you suspect that your player base will be small, maximising participation across all distribution platforms is compelling.
So for us, a more unified solution was desirable.
Why not GameSparks, GameOn etc?
One way to get around platform issues is to use a commercial SaaS option such as GameSparks or Amazon’s GameOn. I personally decided against it, because my needs are quite simple, and I’m not making games with an ongoing F2P or subscription component, so revenue per user over time is a downward scale. This is important because all of these systems are priced according to monthly active users. It doesn’t matter how many of the services you use, or how heavily you hammer them, if a unique user touches the service once in a month, that’s counted.
Now, they all have free tiers and they tend to look quite generous. 100k free with GameSparks, 35k with GameOn - but, unsurprisingly, the cost ratchets up after that; at GameSparks every $10pm buys you 500 MAU, and on GameOn 3,333 MAU. If every new player is worth potential ongoing revenue to you, that’s fine. But for cheap games, free games, pirated games, that’s not necessarily a beneficial curve.
I’m under no illusions about how many players I can realistically expect on our first game, but when I consider that the dependency will effectively exist forever, and I’m likely to want to use a service for multiple games (for sanity), and that at some point we might get a user spike (I can dream, right? 😉) and that spike is more likely from from heavily discounted / pirated copies (numbers like 95% are bandied around on PC), it starts to look less attractive.
I really don’t want to ever have to think of a spike in player numbers on one of our (eventual) back catalogue as being a negative thing. Gaining players on your free/cheap back catalogue is one of the great ways of building an audience as an indie, and I want that to be nothing but positive. Of course, even when running your own service that’s additional load you have to cater for, but since I imagine our needs are going to remain fairly modest, I feel more confident we can accommodate them on a better cost curve than the per-MAU pricing model.
There’s also the fact that you’re dependent on that SaaS supplier once you’ve shipped. They could change the pricing and there’s very little you can do about it; your game is shipped and switching provider at that point is a huge pain point, because even if you ship an update to switch, that’s not going to propagate cleanly to everyone at the same time, which for a social service is a problem. So that’s a risk. This is a sector with a lot going on; PlayFab got acquired by Microsoft recently, GameOn just launched, who knows what might happen in the next year or so.
Perhaps you don’t agree, and the free tier and MAU ramp looks fine to you, and you can live with the risk of dependence on a service. Cool! You’ll have an easier ride with the SaaS options. My own view is that in risk management the decisions you make that are hard or impossible to change later are the most important to hedge for, and what service you depend on is one of those. For my usage, more control and more fixed, predictable costs is a better fit. YMMV.
One advantage with Nakama is that if I do ever end up scaling up to a much larger operation and don’t want the hassle of running my own server any more, HeroicLabs offer a service to do it for me. The benefit of an open source solution is that I have the choice.
Why not write my own server?
I almost went down this route; writing a simple server in Go backed by a simple little database.
But since Nakama has done this already, is written in the language I would have picked, and has already solved a lot of the problems (including integration with platforms like Steam for user auth & friends etc if you happen to be running in that environment), it seemed crazy to re-invent the wheel.
Why Google Compute Engine?
You can run Nakama in any number of other environments; your own server, a VPS like Linode, another cloud provider like AWS, Azure, whatever. I decided to try to GCE because:
- Nakama already had some scripts for doing that, although it turned out they were out of date and missing a bunch of things, hence this blog series
- I’d never used it before, so it offered an interesting learning experience
- Google give you $300 credit for 12 months to try it out, plus a free micro tier VM every year, so it’s effectively free for a while
I have a little experience with AWS (this website is running on it), and I’ve run my own servers before (such as ogre3d.org). So far my experience with Google Cloud Platform (of which Google Compute Engine is the VM component) has been very positive. It feels a little more approachable than AWS; the product catalogue is less intimidating and the names are more intuitive, and the tutorials that automatically come up when you start using a feature are genuinely helpful.
GCE really just behaves like any other Virtual Private Server; the cost is based on how long the server is running, not how often it is used. On the downside this means there’s a minimum price you pay regardless, but on the plus side there’s less variance in the cost if you experience a spike in demand. The main benefit of GCE over a more basic VPS is that it comes with a bunch of other surrounding services you can bolt on as needed; I’ll be covering the use of a load balancer to act as an SSL front-end in a later post, for example.
This always-on approach might surprise you when thinking about ‘cloud’ providers, which you tend to associate with more ‘on-demand’ pricing. The ‘on-demand’ configurations are usually for higher-level service abstractions (for Google this is App Engine) which combine pre-configured frameworks e.g. Node, PHP etc which are shared between apps and which bill on per-use. At the other end there are the really low level ‘Cloud Functions’ which are also on-demand. Nakama is a custom, stand-alone service you really just need a server to run, hence Google Compute Engine (or another VPS) is its natural home.
To play devil’s advocate to my own blog series, Google Compute Engine may not be the best deployment option long-term for many smaller use cases. It’s a bit more expensive at the lower end than just running another VPS like Linode, but the advantage is that you can make use of a lot of other services that more easily bolt on later, like load balancing.
If you don’t end up needing those, you’re probably better with a regular VPS. I’ve gone with GCE for now because it works, and I have some sunk time in it, and I’ve effectively got it for a year for free, so moving to something else would only be more expensive. In 12 months I can consider whether I need the additional services that are available, and if not I could move it to a cheaper option. The good news is things work exactly the same way on any VPS, so beyond the usual migration effort anyone’s done when moving servers, it’s fairly straightforward. When you control the server, you can do that - again the sort of choice that not available if you go for the shrink-wrapped SaaS options.
Stay tuned for part 2, where I’ll actually start giving you the technical details of how to set up Nakama on Google Compute Engine.