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:
- Navigate to the PaperMC website to find and download the right server JAR for your Minecraft version.
- Create a server directory and drop the JAR inside.
- Run it once, just for it to fail because you haven't agreed to the EULA.
- Open eula.txt and change false to true.
- Manually download all your core testing plugins like LuckPerms, WorldEdit, or ProtocolLib.
- 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:
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:
- 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.
- 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.
- 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.
- 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.