plugin-agones when you run the Grounds proxy in front of
Agones-managed gameservers. The plugin replaces the static velocity.toml server list with live
Kubernetes-driven discovery and routes joining players to a lobby.
Requirements
The plugin assumes the following environment:- the Velocity pod runs in the
gamesnamespace alongside its gameservers - the pod has read access to the Agones
gameservers.agones.devcustom resources (listverb) - an Agones sidecar runs next to the Velocity container and exposes the SDK on
http://localhost:9358
What the Plugin Provides
Once the plugin starts, it runs two responsibilities in parallel on the proxy:GameServerStateManagersyncs the proxy’s own Agones state (ReadyorAllocated) with the connected player countDiscoveryServicepolls Kubernetes every two seconds and keeps Velocity’s server registry in sync with the running gameservers
grounds/server-type label and cached for routing and the /agones command.
Gameserver Requirements
For a gameserver pod to appear in Velocity, it must satisfy the discovery contract:Deploy into the games namespace
The discovery query is scoped to the
games namespace. Gameservers outside that namespace are
ignored.Label the GameServer with a role
Set
grounds/server-type to lobby, game, or match on the GameServer resource metadata.
Unlabeled gameservers are skipped.Expose Minecraft on port 25565
The proxy registers the pod at
PodIP:25565. The plugin does not honor Agones allocated ports —
the gameserver must listen on the default Minecraft port inside the pod.If your gameserver follows all four steps, it appears in
/agones on the proxy within two seconds
of reaching a running state.Lobby Routing
The plugin treatsgrounds/server-type=lobby as the entry point for new connections.
| Event | Behavior |
|---|---|
| Player logs in and at least one lobby is running | Login succeeds and the proxy routes the player to a lobby |
| Player logs in and no lobby is running | Login is denied with a user-facing message |
PlayerChooseInitialServerEvent with no server | The plugin sets the first registered lobby as target |
“First registered lobby” is a deterministic but unordered pick from Velocity’s internal map. If you
need priority routing, plan to pair this with party-aware routing later.
The /agones Command
The plugin registers an operator command for inspecting the current proxy state.
| Attribute | Value |
|---|---|
| Permission | grounds.command.agones |
| Console | always allowed |
| Output scope | all registered proxy servers |
lobby (green), game (aqua), match (light purple), unknown (gray).
Example output:
State Sync on the Proxy
The proxy itself runs as an Agones gameserver, so the plugin also manages its own state:- the plugin calls
Allocatewhen the first player logs in - the plugin calls
Readywhen the last player disconnects - a 10 second fallback loop reconciles the state in case events are missed
Failure Modes
Kubernetes client fails to initialize
Kubernetes client fails to initialize
If the plugin cannot build a Kubernetes client at startup, discovery stays disabled for the
process lifetime. The plugin logs the reason and continues without registering servers. The proxy
accepts no logins until a lobby is discoverable again — which only happens after a restart with
a working Kubernetes configuration.
Agones sidecar unreachable
Agones sidecar unreachable
The proxy-side state sync logs the failure and keeps trying on its fallback loop. Discovery and
routing continue to work because they depend on the Kubernetes API, not on the sidecar.
Gameserver missing a PodIP
Gameserver missing a PodIP
Gameservers without a
PodIP entry in status.addresses are skipped and logged as
missing_pod_ip. This usually clears up on the next poll once Agones populates the status.Gameserver missing the server-type label
Gameserver missing the server-type label
Unlabeled gameservers are silently skipped. Check the
GameServer resource if you expect it to
appear and it does not.Next Steps
- Read Paper or Minestom to set up gameservers that the Velocity proxy will discover.
- Review Agones Integration for the shared discovery contract.