Server Setup
Set up a local Paper server for plugin development and testing
You need a running Paper server to test your plugin. This guide walks through creating a local development environment from scratch.
Download Paper
Paper is a fork of Spigot with better performance and a richer API. Unify is built for Paper (and its forks like Purpur and Pufferfish).
- Go to papermc.io/downloads
- Download the latest build for your target version
- Create a folder for your server (e.g.,
~/mc-dev-server) - Move the downloaded
.jarinto that folder and rename it topaper.jar
First Launch
Create a startup script in your server folder:
@echo off
java -Xms1G -Xmx2G -jar paper.jar nogui
pausejava -Xms1G -Xmx2G -jar paper.jar nogui#!/bin/bash
java -Xms1G -Xmx2G -jar paper.jar noguiMake it executable: chmod +x start.sh
Run the script. The first launch will:
- Generate
eula.txt— open it and seteula=true - Create the world and config files
- Exit after EULA acceptance
Run it again. You should see the server start and the console prompt appear.
Install Unify
- Build Unify locally (see Getting Started)
- Copy
Unify.jarfromUnify/build/libs/into your server'splugins/folder - Restart the server
Verify it loaded:
[Server thread/INFO]: [Unify] Enabling Unify v1.0-SNAPSHOTPlugin Development Workflow
The fastest way to iterate is to build your plugin in IntelliJ and copy the jar to the server. Here's a smooth workflow:
1. IntelliJ Run Configuration
Create a shell script that builds and copies your plugin:
#!/bin/bash
SERVER_DIR="$HOME/mc-dev-server"
PLUGIN_NAME="MyPlugin"
# Build
./gradlew shadowJar
# Copy to server
cp "build/libs/${PLUGIN_NAME}.jar" "$SERVER_DIR/plugins/"
echo "Deployed to $SERVER_DIR/plugins/"In IntelliJ, go to Run → Edit Configurations → + → Shell Script and point it
at deploy.sh.
2. Hot Reload with PlugManX
Instead of restarting the server every time, use PlugManX to reload your plugin in-place:
/plugman reload MyPluginOr from your plugin's deploy script:
# After copying the jar, reload via RCON or server console
screen -S mc -p 0 -X stuff "plugman reload MyPlugin\n"⚠️ PlugManX is for development only. Always do full restarts in production.
3. Gradle Task (Recommended)
Add a deploy task to build.gradle.kts:
tasks.register<Copy>("deploy") {
dependsOn("shadowJar")
from(layout.buildDirectory.file("libs/MyPlugin.jar"))
into(file(System.getenv("MC_SERVER_DIR") ?: "../mc-dev-server/plugins"))
doLast {
println("Deployed to server plugins/")
}
}Set MC_SERVER_DIR in your environment, then run:
./gradlew deployServer File Layout
Your dev server should look like this:
mc-dev-server/
├── paper.jar
├── start.sh
├── eula.txt
├── server.properties
├── plugins/
│ ├── Unify.jar ← Unify library
│ ├── MyPlugin.jar ← Your plugin (copied on build)
│ └── PlugManX.jar ← Optional: hot reload
├── world/
├── world_nether/
└── world_the_end/Useful server.properties Settings
# Dev-friendly settings
online-mode=false # Allow offline-mode testing
gamemode=creative
force-gamemode=true
motd=\u00A7bDev Server
max-players=10
spawn-protection=0
allow-flight=trueJoining Your Server
From the Minecraft client:
- Add server →
localhost(or127.0.0.1) - If
online-mode=false, you can join with any username
Use a second Minecraft instance (different launcher profile) to test multiplayer features like visibility, nametags, and scoreboards.
IntelliJ Debugger (Advanced)
You can attach IntelliJ's debugger to a running Paper server for breakpoints and variable inspection:
- Start the server with JDWP enabled:
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 \
-Xms1G -Xmx2G -jar paper.jar nogui- In IntelliJ: Run → Attach to Process → select the Paper JVM
Or create a Remote JVM Debug run configuration with host localhost and
port 5005.
Common Issues
| Issue | Cause | Fix |
|---|---|---|
UnsupportedClassVersionError | Java version mismatch | Use Java 21 for modern, Java 8 for legacy |
NoClassDefFoundError: me.jordanfails.unify.* | Unify.jar not in plugins/ | Copy Unify.jar alongside your plugin |
| Plugin loads but commands don't work | ACF not registered | Call CommandHandler.registerCommands() in onEnable |
| Menu opens but items are missing | Button methods return null | Check getName() and getMaterial() aren't returning null |
| Changes not showing after reload | Old jar cached | Stop server, delete old jar, start fresh |
Next Steps
- Your First Plugin — Build a complete plugin from scratch
- Getting Started — Add Unify to an existing project
- Core Features — Quick overview of all utilities