Common Problems
In the world of Minecraft servers, there are three common problems:
- Minecraft servers are hard to scale.
- It’s hard to recover a Minecraft server from a crash.
- CI/CD is non-existent for Minecraft servers.
When building Minematic, I ran into many limitations when trying to build a scaleable and redundant network. That’s why I decided to build Meteor.
What is Meteor?
Meteor is a load-balancer created for Minecraft servers that allows developers to scale their game networks across multiple servers. Meteor can start new game environments within 200ms
and recover from a server crash within 2s to 3s
without users disconnecting from the network.
Use Cases
Meteor is designed for a few specific use cases:
Round-Based Games
Round-based games such as Duels, SkyWars, or other classic Minecraft games are perfect for Meteor. Minecraft worlds do not need to be saved after every round so Meteor can scale these types of games.
Minigame Networks
Minigame networks can scale their round-based games and save money on servers with Meteor. Traditional minigame networks have servers for each separate game on the network, but with Meteor, multiple different types of games can be deployed within the same server through environments. Instead of creating and deleting servers every time a game has more demand than another, Meteor can scale based on the current demand for each game.
Traditional Network Architecture
Meteor Shared Network Architecture
No World Modification
My game Minematic falls under this category. Minematic consisted of many planets and space stations, with each area being immutable. Because of this, Meteor can separate each location as a different type of environment, which can be independently scaled based on demand.
Player count and server resources are relatively the same even if demand changes for different environments with Meteor.
Technical Overview
Environments
Minecraft servers have an incredibly annoying problem: they are slow. Starting a Minecraft server can take between 30 seconds to a few minutes. This is unacceptable, so I came up with a solution: environments.
Environments are lightweight Minecraft worlds using Advanced Slime Paper that can be rapidly created and destroyed on demand. Environments operate on a few principles:
- Environments are stored only in RAM.
- All actions and players are hidden from other environments.
- Environments must be replicable.
- Environments must be fault tolerant.
RAM-Based Storage
Environments are stored only in RAM because they need to be created and destroyed quickly. Environments accomplish this using RAM-based template worlds from Advanced Slime Paper. Other environment data is stored in a Kotlin object. The only data saved across each environment is player data handled by the game developer.
Hiding Actions and Players
Environments hide actions and players from other environments to create the illusion of a standalone server. This allows multiple games to run on a single server, with the player thinking they are on an isolated server. The environment server plugin hides packets sent by players from other environments automatically. This makes game development simple with Meteor.
Creating New Environments
Environments are created based on world templates using Advanced Slime Paper’s clone()
method. Templates are stored with each server and updated in the CI/CD pipeline. This allows for fast cloning with environment worlds loading within 70ms
and being active within 200ms
across the network.
Crash Recovery
Meteor can fully recover from a server crash within 2s to 3s
. In the event of a crash, players are automatically routed to a limbo server. Then, the Meteor Proxy uses a heartbeat message with Redis Pub/Sub to detect if an outage occurs, and it will automatically recreate the crashed environments on different servers. Players will only experience a loading screen for a few moments and then will be moved to the new environment in the exact location they were in last.
Load Balancer & Scaling
The most important aspect of scaling with Meteor is the load-balancer. Meteor uses a weight-based approach to distributing environments across a network. The proxy manages where players travel on the network by using Redis Pub/Sub to talk to environment servers. After determining the best server, the proxy sends a message to the identified server and asks it to create a new environment. After the environment is created, the proxy is notified and routes the player to the correct location on the network.
Weighted Distribution
Meteor uses a weight-based strategy to find the best server. Weight is determined based on total server player count, performance, and uptime. All attributes are calculated into a single number, and the server with the smallest number is chosen for the next deployment.
Network Architecture
Meteor networks are designed to leverage the power of environments. Instead of creating individual servers for each game, networks using Meteor consist of multiple environment servers and meteor proxies. This allows administrators to save money by consolidating the number of servers needed.
Fixed number of servers for every game.
Dynamic number of servers shared between each game.
Limbo Server
The limbo server acts as a fallback for all players without a destination. After a player joins the limbo server, its goal is to get the user routed out as quickly as possible. Players stay in the limbo server until their destination is available. The most common reasons a player goes to a limbo server are when an environment doesn’t exist when the user joins or when a server crashes.
Meteor Proxy Plugin
The Meteor proxy plugin serves as the orchestrator of a network. The proxy plugin is responsible for routing users, requesting the creation and deletion of environments, and detecting and recovering from crashes.
Environment Server Plugin
The environment plugin is responsible for creating, deleting, and managing environments on the server it runs on. The environment plugin also hides player actions and reports metrics to the proxy.
Pterodactyl CI/CD
Meteor uses GitSync, a tool I developed for Pterodactyl Panel that syncs game server deployments to a GitHub repository. Although not limited to Pterodactyl with GitSync, it allows for the deployment of development networks, the ability to sync all servers to the same version, and rolling updates with no downtime.