Skip to main content
Use plugin-agones-minestom when your gamemode or lobby runs on Minestom and should report Agones state from player activity. In runtime-based servers, Agones is a provider-backed Grounds module selected by module ID. Once started, the module syncs Agones state from Minestom player events: the first player switches the gameserver to Allocated, and the last player leaving switches it back to Ready.
plugin-agones-minestom 0.6.0 and newer exposes a GroundsModuleProvider with ID grounds.agones.

Requirements

Your Minestom pod must run with an Agones sidecar exposing the SDK on http://localhost:9358. The Grounds Minestom image path configures this through the Agones-managed workload. Your runtime application must use grounds-minestom-runtime and include the Agones Minestom module on the runtime classpath.

Add the dependency

The module is published to the groundsgg GitHub Packages Maven registry as gg.grounds:plugin-agones-minestom.
build.gradle.kts
repositories {
    maven {
        url = uri("https://maven.pkg.github.com/groundsgg/plugin-agones")
        credentials {
            username = providers.gradleProperty("github.user").get()
            password = providers.gradleProperty("github.token").get()
        }
    }
}

dependencies {
    runtimeOnly("gg.grounds:plugin-agones-minestom:0.6.0")
}
GitHub Packages requires authentication even for public artifacts. Configure github.user and github.token in ~/.gradle/gradle.properties or through environment variables.

Select the provider

Call discoverProviders() and select grounds.agones in your runtime composition.
import gg.grounds.runtime.core.GroundsServer

fun main() {
    GroundsServer.builder()
        .discoverProviders()
        .useProvider("grounds.agones")
        .start()
}
The runtime discovers the provider through META-INF/services, validates it, creates the module, and owns the lifecycle calls:
  1. install(ctx) registers the player listeners.
  2. start() reconciles the initial Agones state and starts the fallback loop.
  3. stop() removes listeners, cancels the fallback task, and releases coroutine resources.
Discovery does not activate every provider on the classpath. The runtime starts Agones only when you explicitly call useProvider("grounds.agones").

Manifest example

Keep the release module source in grounds.yaml so teammates and CI use the same default.
grounds.yaml
name: minigame-agones
type: minestom-server
baseImage: minestom
build:
  task: :examples:minigame-agones:distTar
  artifact: examples/minigame-agones/build/distributions/*.tar
modules:
  - id: plugin-agones
    variant: minestom
    source: github:groundsgg/plugin-agones@v0.6.0:plugin-agones-minestom.jar
modules lets the CLI replace plugin-agones with a local repository during development. Your Gradle dependencies still define the actual runtime classpath.

State sync semantics

EventResulting Agones state
PlayerSpawnEvent when the server had no other playersAllocated
PlayerSpawnEvent with existing playersNo change
PlayerDisconnectEvent that leaves the server emptyReady
Fallback tick every 10 secondsReconciled from current player count
The disconnect path schedules its check on the next Minestom tick so that the connection manager’s player list is already updated when the check runs.
All state transitions go through AgonesHelper, which first fetches the gameserver state from the sidecar and only sends Allocate or Ready when it differs. Repeat calls are no-ops.

Label your GameServer

The Minestom module only handles state sync. For the Velocity proxy to discover your Minestom gameserver, you still need to follow the discovery contract:
  • deploy into the games namespace
  • add grounds/server-type: <lobby|game|match> to the GameServer resource metadata
  • listen on port 25565 in the pod

Low-level direct usage

Use direct lifecycle calls only when you are embedding the Agones module without grounds-minestom-runtime. Runtime-based servers should select the provider instead.
GroundsPluginAgones still exposes direct enable() and disable() calls for non-runtime embeds.
import gg.grounds.GroundsPluginAgones
import net.minestom.server.MinecraftServer

fun main() {
    val server = MinecraftServer.init()

    val agones = GroundsPluginAgones()
    agones.enable()

    Runtime.getRuntime().addShutdownHook(Thread { agones.disable() })

    server.start("0.0.0.0", 25565)
}
When you use grounds-minestom-runtime, do not call enable() yourself. The runtime calls install, start, and stop through the selected provider.

Failure modes

Grounds module provider grounds.agones was requested but not discovered means the runtime selected the provider ID, but plugin-agones-minestom was not on the runtime classpath or did not expose the provider service file. Use plugin-agones-minestom 0.6.0 or newer and rebuild the distribution.
Errors from the sidecar are logged at error level through the class logger. The fallback loop keeps retrying every 10 seconds, so a short sidecar outage is recovered automatically without any action from your gamemode.
If your deployment has no Agones sidecar, every sidecar call fails. The module continues to run, but cannot influence Agones state. In that setup, do not select grounds.agones to keep logs clean.

Next steps