project

Stop Wasting Time: How I Automated My Minecraft Server Setup with a Custom Gradle Plugin

If you've ever developed a plugin for a Minecraft server like PaperMC, you know the routine. For every new project, or even just to test a clean build, you have to go through a tedious setup process. That's why I created the Paper Setup Gradle Plugin, a tool that automates this entire workflow.

Cristopher Cousiño
Author
Thursday, July 10, 2025
Published
4 min read
Read time

If you've ever developed a plugin for a Minecraft server like PaperMC, you know the routine. For every new project, or even just to test a clean build, you have to:

  1. Navigate to the PaperMC website to find and download the right server JAR for your Minecraft version.
  2. Create a server directory and drop the JAR inside.
  3. Run it once, just for it to fail because you haven't agreed to the EULA.
  4. Open eula.txt and change false to true.
  5. Manually download all your core testing plugins like LuckPerms, WorldEdit, or ProtocolLib.
  6. Finally, write a shell script or IDE run configuration to launch the server with the correct JVM flags.

This process is tedious and time-consuming. As a developer, I want to write code, not wrestle with server setup. That's why I created the Paper Setup Gradle Plugin, a tool that automates this entire workflow.

The Solution: One Task to Rule Them All

My goal was simple: provide a single, configurable block in my build.gradle.kts file that defines my entire development server. After a bit of work, this is the result:

kotlin
plugins {
    id("io.github.gateopenerz.paper-server") version "1.0.2"
}

// Configure the entire server in one place!
paperServer {
    version.set("1.21.7") // Minecraft version
    jvmArgs.set("-Xms2G -Xmx4G") // Custom JVM flags
    serverDir.set("development-server") // Server location
    preLaunchTasks.set(listOf("build")) // Build your plugin first

    // Automatically download plugins from top sources
    plugins.set(listOf(
        "modrinth:LuckPerms",
        "hangar:ViaVersion:5.4.2-SNAPSHOT+784", // Specify a version
        "modrinth:WorldEdit"
    ))
    
    // Or add them from a direct URL
    pluginUrls.set(listOf(
        "https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/target/ProtocolLib.jar"
    ))
}

With this configuration, two new Gradle tasks become available:

  • ./gradlew setupPaperServer: This task downloads the specified Paper JAR, accepts the EULA, and fetches every single plugin listed from Modrinth, Hangar, or the direct URLs.
  • ./gradlew runPaperServer: This task automatically runs setupPaperServer first, then starts the PaperMC server with your custom JVM arguments.

How It Works Under the Hood

The magic happens through a combination of the Gradle API and external web APIs:

  1. Fetching Paper: The plugin hits the official PaperMC API to find the latest build number for the given Minecraft version and constructs the correct download URL.
  2. Plugin Discovery: For plugins like "modrinth:WorldEdit", it queries the Modrinth and Hangar REST APIs to search for the plugin by name. It then intelligently filters the results to find a version compatible with your server's Minecraft version.
  3. Automation: The setupPaperServer task checks if the files already exist to avoid re-downloading them on every run. It also writes eula=true to the eula.txt file.
  4. Execution: The runPaperServer task uses Gradle's JavaExec to launch the server JAR in a new process, applying all your configurations.

Conclusion

Creating this plugin was a fantastic learning experience in build automation and API integration with Kotlin. More importantly, it solved a real-world problem that has already saved me hours of setup time. By automating the boring stuff, I can spend more time focusing on what I enjoy: building and testing cool features for Minecraft.

RELATED

Continue Reading

Enjoyed this article?

Check out more of my thoughts and projects, or get in touch to discuss your next idea.