A Gradle plugin that streamlines using KPaper in your PaperMC plugins
π Quick Start β’ β¨ Features β’ π§© How-It-Works β’ π configuration β’ π Custom Repos β’ π€ Contributing
KPaperGradle automates integrating KPaper into your Paper projects. It adds the KPaper dependency, generates the required bootstrap/registration classes, wires resource processing, and provides a simple DSL to declare additional libraries that are delivered at runtime via Paper's plugin loader.
- π¦ Oneβline KPaper dependency β Adds
cc.modlabs:KPaper:<version>automatically - π Auto toolchain β Configures Java toolchain/
--releasefrom a singlejavaVersionsetting - 𧬠Source generation β Generates
CommandBootstrapper,DependencyLoader, andRegisterManager - π§Ύ Compliance file β Produces
.dependenciesand places it in your plugin resources - π§© Paper integration β Patches
paper-plugin.ymlto includeloaderandbootstrapperif missing - π Conventionβbased registration β Autoβregisters commands; discovers listeners (manual call required)
- π Deliver extra libs β Simple
deliver("group:artifact:version")DSL for runtime libraries - π Custom repos for delivery β Add Maven repositories used by the runtime dependency loader via
repository(...)DSL
Add the plugin to your Paper plugin project.
// settings.gradle.kts
pluginManagement {
repositories {
gradlePluginPortal()
maven("https://nexus.modlabs.cc/repository/maven-public/")
mavenLocal()
}
}// build.gradle.kts (of your Paper plugin)
plugins {
kotlin("jvm") version "2.0.0"
id("cc.modlabs.kpaper-gradle") version "LATEST" // replace with latest version
}
group = "com.example"
version = "1.0.0"
repositories {
mavenCentral()
maven("https://nexus.modlabs.cc/repository/maven-mirrors/")
}
kpaper {
// Target Java version (configures toolchain + compiler --release)
javaVersion.set(21)
// Base package scanned for registration (commands/listeners)
registrationBasePackage.set("com.example.myplugin")
// Libraries to deliver at runtime through the Paper loader
deliver(
"com.github.ben-manes.caffeine:caffeine:3.1.8"
)
// Optional: Repositories used by the runtime dependency loader
// Either with generated id from host:
repository("https://repo1.maven.org/maven2/")
// Or explicitly provide an id and url:
repository("papermc", "https://repo.papermc.io/repository/maven-public/")
}Thatβs it. Build your plugin as usual β the generated classes and resources are wired into the build.
paper-plugin.yml (minimal)
name: MyPlugin
version: 1.0.0
main: com.example.myplugin.MainPlugin
api-version: '1.21'
# The plugin will autoβpatch these if not present:
# loader: cc.modlabs.registration.DependencyLoader
# bootstrapper: cc.modlabs.registration.CommandBootstrapperCommand and Listener discovery
Note: Commands are auto-registered by the plugin. Listeners are discovered but you must register them manually in your plugin's enable phase:
import cc.modlabs.kpaper.main.KPlugin
class MyPlugin : KPlugin() {
override fun startup() {
cc.modlabs.registration.RegisterManager.registerListeners(this)
}
}// Place these under your registration base package to be discovered
package com.example.myplugin.commands
import cc.modlabs.kpaper.command.CommandBuilder
import io.papermc.paper.command.brigadier.Commands
class HelloCommand : CommandBuilder {
override val description = "Say hello"
override val aliases = listOf("hi")
override fun register() = Commands.literal("hello")
.executes {
it.source.sender.sendMessage("Hello from KPaper!")
com.mojang.brigadier.Command.SINGLE_SUCCESS
}
.build()
}package com.example.myplugin.listeners
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.player.PlayerJoinEvent
class JoinListener : Listener {
@EventHandler
fun onJoin(e: PlayerJoinEvent) {
e.player.sendMessage("Welcome!")
}
}KPaperGradle wires a few build steps into your project:
- Generates sources in
build/generated/sources/kpaper/cc/modlabs/registration/:CommandBootstrapperβ registers KPaper commands during theCOMMANDSlifecycleRegisterManagerβ scans yourregistrationBasePackageforCommandBuilderandListenerclassesDependencyLoaderβ resolves and attaches declared libraries at runtime via Paper'sMavenLibraryResolver
- Registration behavior: Commands are auto-registered; listeners are discovered but must be registered manually via
RegisterManager.registerListeners(plugin) - Creates
.dependenciesunderbuild/generated-resources/and copies it intobuild/resources/main/. If you declare custom repositories, also creates.repositoriesand copies it alongside - Patches
paper-plugin.ymlto addloaderandbootstrapperif missing - Adds
cc.modlabs:KPaper:<version>to theapiconfiguration - Ensures Java/Kotlin compilation depends on the generation task and sees the generated sources
The kpaper extension exposes the following properties and DSL helpers:
javaVersion: Property<Int>β Java toolchain and--release(default21)registrationBasePackage: Property<String>β base package to scan (default"cc.modlabs")deliver(vararg deps: String)β declare runtime libraries, e.g.deliver("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")repository(url: String)β add a Maven repository used by the runtime dependency loader; an id is inferred from the URL hostrepository(id: String, url: String)β same as above but with an explicit id
Notes:
- These repositories are used only by the generated runtime loader (
MavenLibraryResolver) to resolve delivered libraries on the server. They do not affect Gradle resolution. - The ModLabs mirror
https://nexus.modlabs.cc/repository/maven-mirrors/is always added by default.
You can declare additional Maven repositories that the runtime dependency loader will use when resolving libraries from your deliver(...) block. Example:
kpaper {
deliver("com.squareup.okio:okio:3.9.0")
// Add Maven Central explicitly (id inferred from host)
repository("https://repo1.maven.org/maven2/")
// Add PaperMC public repository with a custom id
repository("papermc", "https://repo.papermc.io/repository/maven-public/")
}Under the hood, the plugin writes a .repositories file next to .dependencies in your built resources. The generated runtime DependencyLoader reads this file and appends each entry to the MavenLibraryResolver.
Accepted .repositories line formats:
-
url(id inferred from host), e.g.https://repo1.maven.org/maven2/ -
id url, e.g.papermc https://repo.papermc.io/repository/maven-public/ -
KPAPER_VERSIONβ pinned KPaper version embedded into the plugin (falls back to a timestamped default) -
VERSION_OVERRIDEβ override the pluginβs published version -
NEXUS_USER/NEXUS_PASSβ credentials for publishing to ModLabs Nexus
my-plugin/
ββ build.gradle.kts
ββ src/main/resources/
β ββ paper-plugin.yml
ββ src/main/kotlin/com/example/myplugin/
ββ commands/HelloCommand.kt
ββ listeners/JoinListener.kt
We welcome contributions! Fixes, features, and documentation improvements are all appreciated.
git clone https://github.com/ModLabsCC/KPaperGradle.git
cd KPaperGradle
./gradlew build- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes following our coding standards
- Add/adjust tests if applicable
- Update documentation as needed
- Commit (
git commit -m 'Add amazing feature') - Push (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow Kotlin coding conventions
- KDoc for public APIs
- Keep commits focused and atomic
- Update docs for user-facing changes
KPaperGradle is licensed under the GPL-3.0 License. See LICENSE for details.
- KPaper β The companion library this plugin streamlines
- Paper β For excellent modern Minecraft server software
- Kotlin β A delightful JVM language