Scaling a game or any service for that matter can be a daunting. However it's important to be ready to handle a case where a large number of people want to start using your service. My biggest fear is being unable to provide my services should thousands of users join at once.
Idle pixel currently has 3000+ active players. The servers are very much capable of handling this load, but what happens if 10,000 new players decide to join overnight? Awesome!, I would say, but at the same time, I'd probably think ohoh!, I have some work to do - and fast.
Before diving into my thought process of scaling this project, I want to talk about different types of idle games. Most idle games
are singleplayer. This means that the game most likely runs on code that is executed from the user's computer (html/javascript). There really isn't any problem
with scaling in this case. Having 10 active players vs 10,000 active players won't have much of an impact, as each user is running the game code on their machine.
Idle pixel works with a game server. Most of the game logic is executed on this server for which I must rent. The more players that use this server, the more CPU and memory I need
to keep the game running smooth. The difference here is the server needs to do all calculations and operations for every user connected to the game. So the more players online,
the more resources are used.
So what's the plan? What if thousands and thousands of players find out about the game and want to play at the same time? We need to be well prepared to handle the load. I'll be discussing two methods of scaling, and I've tested them both. These two methods of scaling are called vertical scaling, and scaling horizontally. If you know a bit about the software world, this may be a familiar topic. However, if you're new to this and want to learn about scaling a game, keep on reading.
Scaling vertically: This method of scaling is probably the easiest one. However it can get pretty expensive. The idea behind this is to simply upgrade the main game server as your player count increases. Oh, we have 1000 players online? No problem! I'll just upgrade the server to have more CPU power. Problem solved! This can work in the short term, but eventually as your player base grows, so does your server power. As you probably already know, upgrading a server to have more CPU/RAM becomes expodentially more expensive. This method is much eaiser to maintain; you just keep upgrading the main server to support the number of players. More players = stronger server.
Vertically scaling is awesome because every player is on the same server. Idle pixel has a chat room, and since everyone is on the same server, it's easy to send messages between players. Same thing with trading items. Just look up if the player is online on the server, and make the trade. That's it! Easy!
Testing: Right now, the game server currently has 4GB of RAM and 2 CPUs. I was able to handle about 4000 players online until it started to lag. I then upgraded to 16GB of RAM and 8 CPUs for which the game was able to handle 10,000 players. I then did the ultimate test with a massive server containg 192 GB of RAM with 72 CPUs! This server could handle 50,000 players without any issues, however - it was costing me well over 30,000$ a year. That is where vertically scaling becomes a problem. The bigger the server, the more expesnive it gets. Therefore I did not take this path.
OK, so vertically scaling is nice because we can just throw money at the server when the time comes. However, it becomes very expensive, and using the other method of scaling is much cheaper - but much more complex to handle. Let's talk about the method I'll be using now: Scaling horizontally.Scaling Horizontally: This method of scaling can be very difficult to manage if you are not prepared. The idea here is to have multiple smaller servers running side by side to serve the player base. When a user wants to connect to the game, they must choose which server they wish to connect to. (This can be done automatically, depending on your code).
You can then set a limit of players allowed on a server at once. If game server 1 is full, simply connect to game server 2. This method is cheap because you're not spending money on upgrading a main server, but simply renting out smaller servers which run in parallel. See the image below:
Horizontally scaling is really nice. If your player base increases, you add more servers. If they player base decreases, you remove servers. This seems like the obvious choice for running services with a high number of users, but it does bring on some challenges. Let's start with chat. Server 1 and Server 2 can't chat with each other. The only way to accomplish this is to have a seperate server deticated to chatting. This means every chat command must be fowarded to this server and then broadcasted to all servers. It's possible to achieve this, but it can be harder to maintain. Now what about trading? What if a player on server 1 wants to trade with a player on server 2? Now we need an exchange/trading server. What happens if a player is logged into server 1 and then logs into server 2 from another computer? You need a login server to deal with this. Horizontally scaling is cheaper, but much more complicated.
Final thoughts: Creating a game that scales to thousands of players is not easy. I went with the horizontal scaling approach. Keep in mind that there are still some choke points with this. Every server talks to the database, which in itself is also a server. What if this server becomes overloaded? There are ways to deal with database servers to have replica's (slave/master databases) but I won't get into this topic.
Good luck on your projects, and I hope this small read was helpful. I am now at peace knowing that if thousands of players join overnight, I'll be ready to spin up new servers to serve these players accordingly.
Thanks
SMITTY