We are developing the server for a massively multiplayer online game with a client-server architecture. The game design seeks to create an immersive play experience by enabling thousands of players to connect simultaneously to the same virtual world.
- The game design depends on having many players online at the same time.
- Client-server communication requires TCP for reliable, persistent connections.
- The game server uses a distributed deployment architecture.
- The project’s business plan seeks to optimize hardware and operating expenses.
- The project’s operating plan seeks to minimize downtime by building redundancy and failover into the architecture.
- The project’s plan for handling high load calls for evenly distributing client connections across several connection servers.
- Design of the game client calls for reliable access to game servers with minimal interruption in service and no user intervention.
Implement in the game client a mechanism for randomly choosing a connection server from a list of available options.
The implementation should:
- Use a random seed with a high chance of being unique on each game client to ensure even distribution. Because the set of servers to choose from is small, this doesn’t have to be too advanced. A hash of the client’s computer name might be enough. Avoid using time-based seeds, though, These can cause clients to clump together on the same connection server during sudden spikes in the client login rate.
- Provide a way to easily update the list of connection servers when changes occur. For game clients that use a custom patching solution, the server list can be hard-coded updated via the normal patching process. Or, the client could fetch the list via an HTTP request to a content delivery network (CDN). Avoid storing the data in a local file to limit meddling by inquisitive players.
- Add failover logic that selects another address when a connection server doesn’t respond. For the best player experience, try all servers in the list before notifying the player of an outage.
- Optionally include both DNS names and IP addresses in the server list. This can cut service interruptions if a player’s DNS provider stops working.
Client connections to our MMO game are evenly distributed across all connection servers. This ensures consistent connection performance for all clients. It also minimizes the average number of clients at risk of an outage if a connection server crashes.
When handling high-load scenarios in a distributed server environment, it’s common to turn to server-based load balancing solutions.
One option is to use a hardware load balancing device (HLD). This is a specialized network device that uses advanced rules and performance metrics to route traffic to back-end servers. While effective, they’re generally expensive and come with expensive support and admin costs.
Another server-side option is to manipulate DNS to randomly select an address from set of connection servers. This can work, but doesn’t handle failures too well. If a connection server goes down, its address will have to be removed from the rotation before DNS will stop resolving to its address.
In contrast, the client-side load balancing option is both inexpensive and reliable. It’s very easy to implement and test, saving development time. It also requires very little operations support compared to server-side solutions.