本文将介绍如何配置Minecraft Spigot插件开发环境的NMS环境
NMS(net.minecraft.server)是Minecraft原版服务器的代码,可以让开发者更自由地使用原版的API,而非仅限于Spigot提供的API。但自由的代价是需要开发者为每个mc版本单独编写对应的代码,因为NMS的api在不同版本之间可能完全不同。
如果你需要手动管理游戏的发包(packets),实体(entities)等等spigot未提供或不完整的api时,使用NMS是不可避免的。
使用NMS意味着你需要将Mojang的服务器代码添加到项目依赖中(而这会产生版权风险)
过去的方案是使用Spigot的BuildTool,本地构建minecraft-server包,但本文将使用paper开发的工具:paperweight-userdev
此工具可以提供具有Mojang命名的api包
This is the only supported way of accessing server internals, as redistributing the server JAR is against the Minecraft EULA and general license assumption. Even if you manually depended on the patched server, you would be hindering other people working on your project and would be missing deployed API javadocs/sources in your IDE.
注意:本文仅针对 Grdle Kotlin DSL
添加gradle plugin
id("io.papermc.paperweight.userdev") version "2.0.0-beta.19"
值得注意的是,你需要先将gradle的版本升级到最新,若有兼容问题,则可以使用旧版的插件(如1.7.2)
添加对应版本的DevBundle
paperweight.paperDevBundle("1.21.8-R0.1-SNAPSHOT")刷新项目,等待构建完成,此时即可使用NMS api

完整的build.gradle.kts文件
plugins {
java
id("xyz.jpenilla.run-paper") version "2.3.1"
id("io.papermc.paperweight.userdev") version "2.0.0-beta.19"
}
group = "top.skidder"
version = "1.0-SNAPSHOT"
repositories {
gradlePluginPortal()
maven("https://repo.papermc.io/repository/maven-public/")
mavenCentral()
maven {
name = "spigotmc-repo"
url = uri("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
}
}
dependencies {
// Use Paperweight dev bundle instead of compileOnly
paperweight.paperDevBundle("1.21.8-R0.1-SNAPSHOT")
}
java {
val targetJavaVersion = 22
toolchain {
languageVersion.set(JavaLanguageVersion.of(targetJavaVersion))
}
sourceCompatibility = JavaVersion.toVersion(targetJavaVersion)
targetCompatibility = JavaVersion.toVersion(targetJavaVersion)
}
tasks.withType<JavaCompile>().configureEach {
options.encoding = "UTF-8"
val targetJavaVersion = 22
if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible) {
options.release.set(targetJavaVersion)
}
}
tasks.processResources {
val props = mapOf("version" to project.version)
inputs.properties(props)
filteringCharset = "UTF-8"
filesMatching("plugin.yml") {
expand(props)
}
}
tasks.runServer {
minecraftVersion("1.21.8")
}