Skip to content

Latest commit

 

History

History
480 lines (362 loc) · 14.9 KB

File metadata and controls

480 lines (362 loc) · 14.9 KB

Spigot plugin

kdoc( javadoc): SpigotPlugin.kt

The Spigot plugin provides the following features:

  • Generate 'plugin.yml' with the main detected automatically

  • Debug feature: task debugProjectName, idea Run Configuration DebugProjectName/RunProjectName

  • Shortcuts for dependency and repository.

Table of contents

Requirements

The plugin requires Gradle 9.0+, the latest version is recommended.

To update your gradle wrapper:

gradlew wrapper --gradle-version 9.2.1 --distribution-type all

Usage

Full Example Here

Using Version Catalog (Recommended)

settings.gradle.kts

dependencyResolutionManagement {
    repositories {
        mavenCentral()
    }
    versionCatalogs {
        create("spigots") {
            from("io.typst:spigot-catalog:1.0.0")
        }
        create("commons") {
            from("io.typst:common-catalog:1.1.0")
        }
    }
}

build.gradle.kts

plugins {
    java
    alias(spigots.plugins.spigot)
    alias(commons.plugins.ideaExt) // optional, for debug Run Configurations
}

repositories {
    mavenCentral()
    spigotRepos {
        papermc()
    }
}

dependencies {
    compileOnly(spigots.paper.api)
}
Groovy (settings.gradle)
dependencyResolutionManagement {
    repositories {
        mavenCentral()
    }
    versionCatalogs {
        create('spigots') {
            from('io.typst:spigot-catalog:1.0.0')
        }
        create('commons') {
            from('io.typst:common-catalog:1.1.0')
        }
    }
}
Groovy (build.gradle)
plugins {
    id 'java'
    alias papers.plugins.spigot
    alias commons.plugins.ideaExt // optional
}

repositories {
    mavenCentral()
    spigotRepos {
        papermc()
    }
}

dependencies {
    compileOnly papers.paper.api
}

Without Version Catalog

Groovy DSL

plugins {
    id 'io.typst.spigradle.spigot' version '4.0.2'
    id 'org.jetbrains.gradle.plugin.idea-ext' version '1.3' // optional
}

Kotlin DSL

plugins {
    id("io.typst.spigradle.spigot") version "4.0.2"
    id("org.jetbrains.gradle.plugin.idea-ext") version "1.3" // optional
}

Description file generation

The plugin.yml file will be generated by task generateSpigotPluginDescription based on the configuration of spigot, included into output jars automatically.

Basically the properties 'main', 'name' and 'version' defaults to auto-detected main, project.name, project.version respectively. So if we create a simple plugin that just needs those properties, we don't need any configuration. Only pay attention to your unique implementation.

You can configure all properties of plugin.yml in spigot {} block.

Main class detection

The plugin automatically detects your main plugin class using bytecode analysis (ASM). It scans compiled .class files to find classes that extend JavaPlugin.

How it works:

  • Scans compiled bytecode (not source code) for faster and more reliable detection
  • Finds non-abstract, public classes extending org.bukkit.plugin.java.JavaPlugin
  • Supports complex inheritance hierarchies
  • Incremental: only scans changed files for faster builds
  • Automatically sets the main property in plugin.yml

Manual override: If you need to manually specify the main class:

spigot {
    main.set("com.example.MyCustomMain")
}

For more details, see the Main Class Detection section.

Configuration

spigot extension - SpigotExtension

The description of your plugin for a plugin.yml.

The 'main' property will be set to the class auto-detected

About the plugin.yml, See plugin-yml wiki

Groovy Example
spigot {
    authors = ['Me']
    depend = ['ProtocolLib', 'Vault']
    softDepend = ['WorldEdit']
    apiVersion = '1.15'
    load = "STARTUP"
    libraries = ['my:lib:1.0.0', 'my:lib2:1.0.0']
    commands {
        register('give') {
            aliases = ['giv', 'i']
            description = 'Give command.'
            permission = 'test.foo'
            permissionMessage = 'You do not have the permission!'
            usage = '/<command> [item] [amount]'
        }
    }
    permissions {
        register('test.foo') {
            description = 'Allows foo command'
            defaults = 'true'
        }
        register('test.*') {
            description = 'Wildcard permission'
            defaults = 'op'
            children = ['test.foo': true]
        }
    }
}
Kotlin Example
spigot {
    authors = listOf("Me")
    depend = listOf("ProtocolLib")
    softDepend = listOf("WorldEdit")
    apiVersion = "1.15"
    load = "STARTUP"
    commands {
        register("give") {
            aliases = listOf("i")
            description = "Give command."
            permission = "test.foo"
            permissionMessage = "You do not have permission!"
            usage = "/<command> [test|stop]"
        }
    }
    permissions {
        register("test.foo") {
            description = "Allows foo command"
            defaults = "true"
        }
        register("test.*") {
            description = "Wildcard permission"
            defaults = "op"
            children = mapOf("test.foo" to true)
        }
    }
}

Without type-safe accessors:

configure<SpigotExtension> {
    authors = listOf("Me")
    // ...
}

debugSpigot extension - DebugExtension

Note: debugSpigot is a configuration extension, NOT a task. The actual task is named debugProjectName ( e.g., debugMyPlugin).

To see the platform defaults, see the dokka(javadoc) of SpigotBasePlugin

Available properties:

Property Type Default Description
version Property<String> - Paper/Minecraft version to download (e.g., "1.21.8")
eula Property<Boolean> false Auto-accept Minecraft EULA
jvmDebugPort Property<Int> 5005 Port for remote JVM debugging
downloadSoftDepend Property<Boolean> false Also download softDepends plugins
jvmArgs ListProperty<String> platform defaults JVM arguments (e.g., -Xmx2G)
programArgs ListProperty<String> platform defaults Server program arguments (e.g., nogui)
javaVersion Property<JavaLanguageVersion> project toolchain Java version for the server
javaHome Property<Directory> resolved from javaVersion Java installation directory

Example:

debugSpigot {
    version = "1.21.8"
    eula = true
    jvmDebugPort = 5005
    downloadSoftDepend = true
    // Use append() (Gradle 8.7+) to preserve defaults:
    jvmArgs.append("-Xmx4G")
    programArgs.append("--world myworld")
}
debugSpigot {
    version = "1.21.8"
    eula = true
    jvmDebugPort = 5005
    downloadSoftDepend = true
    // Use append() (Gradle 8.7+) to preserve defaults:
    jvmArgs.append("-Xmx4G")
    programArgs.append("--world myworld")
}

Warning: Using add(), set(), or empty() on jvmArgs/programArgs will discard platform defaults. Use append() or appendAll() (Gradle 8.7+) to preserve defaults.

Use external dependencies

Declaring dependencies to libraries in plugin.yml is the recommended approach instead of shading jar.

You can use the compileOnlySpigot dependency configuration to declare as compileOnly and libraries in plugin.yml.

To see the dependency graph of compileOnlySpigot, execute the dependencies Gradle task and look at the spigotLibrariesClasspath section. also you can see the result plugin.yml in build/tmp/generateSpigotPluginDescription.

The spigotLibrariesClasspath configuration resolves only root level dependencies.

dependencies {
    compileOnlySpigot("org.ahocorasick:ahocorasick:0.6.3")
}

Tasks

All tasks supports UP-TO-DATE check.

detectSpigotEntrypoints - SubclassDetection

Finds the main class extends org.bukkit.plugin.java.JavaPlugin.

generateSpigotPluginDescription - YamlGenerate

Depends on: detectSpigotEntrypoints

Generates the description file 'plugin.yml'.

debugProjectName - Exec

Depends on: prepareProjectName

Runs a local Paper server with your plugin for debugging. This task orchestrates the complete debug workflow:

What it does:

  1. Downloads Paper server (via downloadPaper) - Fetches the specified Paper version from PaperMC API if not already cached
  2. Prepares plugin dependencies (via preparePluginDependencies) - Resolves plugins listed in depends/ softDepends:
  • First tries to copy from your project's compileClasspath
  • Falls back to downloading from SpigotMC (via Spiget API) if not found
  1. Copies your plugin JAR (via copyArtifactJar) - Copies the built plugin to the debug server's plugins folder
  2. Creates starter scripts (via createJavaDebugScript) - Generates platform-specific scripts:
  • starter.bat for Windows
  • starter for Unix/Linux/Mac
  1. Launches the server - Opens a new terminal window and runs the server

IntelliJ IDEA Run Configurations:

Spigradle automatically creates two run configurations (NOTE: These are only generated if the plugin org.jetbrains.gradle.plugin.idea-ext is applied):

  1. DebugProjectName - Remote JVM DebugRecommended
  • Type: Remote JVM Debug configuration
  • Purpose: Attaches debugger to an already-running server process
  • Recommended workflow:
    1. Run debugProjectName task via IntelliJ's terminal or "Run Gradle Task"
    2. Server starts in a new terminal window with remote debugging enabled on port 5005
    3. Click the "🐞 Debug" button on this configuration to attach the debugger
  • Advantages:
    • Keeps IntelliJ lightweight - server runs in separate terminal, not managed by IDE
    • Clean separation between server output and IDE
    • Better performance - IDE doesn't handle server I/O
  • When to use: Standard debugging workflow (recommended for regular use)
  1. RunProjectName - JarApplication
  • Type: JarApplication run configuration
  • Purpose: All-in-one server launch directly from IntelliJ
  • Usage:
    • Click the "▶ Run" button to start the server normally
    • Click the "🐞 Debug" button to start the server AND attach debugger in one step
  • Note: Makes IntelliJ heavier as it manages the server process directly; You need to click the Sync All Gradle Projects button in IDEA if you change the debugSpigot extension.
  • When to use: Only when you want absolute convenience and don't mind the performance impact

Directory structure:

  • Server directory: MY_PROJECT/.gradle/spigradle-debug/paper/
  • Global JAR cache: GRADLE_USER_HOME/spigradle-debug-jars/paper/VERSION/paper.jar
  • Plugin dependencies: MY_PROJECT/.gradle/spigradle-debug/paper/plugins/

Configuration:

See debugSpigot extension for configuration options like version, EULA acceptance, JVM arguments, and debug port.

Testing with MockBukkit

With Spigradle 1.3.0+, you can use the MockBukkit without any special code.

If you use less than 1.3.0, add it in build.gradle:

task copyPluginYaml(type: Copy, dependsOn: spigotPluginYaml) {
    from(new File(spigotPluginYaml.temporaryDir, 'plugin.yml'))
    into(sourceSets.test.output.resourcesDir)
}

tasks.test.dependsOn(copyPluginYaml)

Working with paperweight-userdev

Prerequisite: https://docs.papermc.io/paper/dev/userdev/

build.gradle.kts

plugins {
    // ...
    alias(spigots.plugins.paperweight.userdev)
}

dependencies {
    paperweight.paperDevBundle(spigots.versions.spigot.api) // this is a replacement for spigot-api/paper-api 
    // ...
}

tasks {
    assemble {
        dependsOn(reobfJar)
    }
}

debugSpigot {
    // ...
    jarFile = tasks.reobfJar.flatMap { it.outputJar } // For debug, to copy the reobfJar
}

Templates

spigot-plugin-template by @Silthus

BukkitJavaGradle by @portlek

See also