Paper Plugin Guide
File mode0

Tools

plugin.yml Builder

Fill in a form and get a valid plugin.yml with permissions and dependencies.

BeginnerTool

Every Paper plugin needs a small settings file that tells the server its name, its version and where its main class is. Fill in this form and you get that file, written correctly, with a check that tells you when something would stop Paper from loading your plugin.

What is plugin.yml, in one minute

When the server starts, it opens every jar in the plugins folder and looks for one file inside: plugin.yml. That file is like the label on a box. It does not contain any code. It tells Paper what the plugin is called, which version it is, which class to start (the main class), and which Minecraft version it was written for. Without it, Paper ignores the jar.

The file is written in YAML: one key: value pair per line, and indentation with spaces to group things. YAML is picky. One tab instead of spaces, or a colon in the wrong place, and the server cannot read the file. That is why a form helps: it writes the punctuation for you.

What happens when the server starts and stops Steps in order: the server starts, reads the plugins folder, reads plugin.yml, creates the main class, calls onLoad, loads worlds, calls onEnable, then runs until the server stops and calls onDisable. 1. Server starts Paper boots 2. Reads the plugins folder 3. Reads plugin.yml 4. Creates your main class 5. onLoad() very early 6. Worlds load Paper loads them 7. onEnable() your setup code 8. Running 20 ticks a second 9. Server stops /stop or crash 10. onDisable() your cleanup Boxes with code names are the methods you write in your main class. Paper calls them for you. Read left to right, then continue on the next row
Paper opens each jar, reads plugin.yml, then starts the main class it names.

The plugin.yml Builder

Work through the sections from the top. The file on the right (or below, on a phone) updates with every key you press. Messages marked Fix would stop Paper from loading the plugin. Messages marked Tip are things that work but are better changed. Your answers are remembered in this browser.

The builder is loading. If this message stays, JavaScript is turned off in your browser.

The fields, in plain English

  • name (required): what the plugin is called. Letters, numbers, dots, dashes and underscores. Other plugins use this name when they say they need yours.
  • version (required): your own version number, like 1.0.0. It is written in quotes so YAML does not turn 1.0 into a decimal number.
  • main (required): the full name of your main class. The builder makes it from the package and class name you type, so the two cannot drift apart. See the next section.
  • api-version: the Minecraft version you wrote the plugin for. Write '26.3' in quotes. If it is missing, Paper treats your plugin as ancient and runs a slow compatibility layer. If it is newer than the server, Paper refuses to load it.
  • description, authors, website, prefix: information for people. Nothing breaks if you leave them out.
  • load: POSTWORLD (the default) starts your plugin after the worlds are loaded. STARTUP starts it before, which only matters for plugins that create worlds.
  • depend and softdepend: other plugins you need or can use. depend means "do not load me without them". softdepend means "start them first if they exist, but load me either way".
  • loadbefore: the opposite of softdepend. It asks Paper to load another plugin after yours.
  • libraries: libraries Paper downloads from Maven Central before starting your plugin.
  • permissions and commands: covered in their own sections below.

The main class must match your files

This is the mistake that costs beginners the most time. The line main: com.example.myplugin.MyPlugin is a promise about three things in your project, and all three must agree:

  • my-plugin/
    • src/
      • main/
        • java/
          • com/
            • example/
              • myplugin/
                • MyPlugin.javaThe file. Its folders spell the package, its name is the class
        • resources/
          • plugin.ymlContains: main: com.example.myplugin.MyPlugin
  1. The folders com/example/myplugin match the package com.example.myplugin.
  2. The first line of the Java file says package com.example.myplugin;.
  3. The class inside is named MyPlugin and extends JavaPlugin.

Change one of them and the console shows ClassNotFoundException or Cannot find main class. The builder shows the path and a starter class under the YAML so you can compare. Read about renaming safely in Anatomy of a plugin project.

Permissions and commands

A permission is a name like myplugin.heal. Before Paper lets someone do a protected thing, it asks "does this player have that permission?". Listing permissions in plugin.yml makes them show up in permission plugins and lets you pick a default: everyone, nobody, only operators, or everyone except operators. A parent permission can have children; giving the parent gives all of the children. A wildcard like myplugin.* is just a parent whose children are all your other permissions. The builder's "Add a wildcard parent" button creates one for you. Learn how to check permissions in code in Permissions.

paper-plugin.yml

Paper has a second, newer file called paper-plugin.yml. Turn on that mode in the builder to see what changes. A Paper plugin can have a bootstrapper (code that runs before the server is ready) and a loader (code that builds the plugin's classpath, for example by downloading libraries). Instead of depend, softdepend and loadbefore it has one dependencies section where every plugin gets its own load, required and join-classpath setting. It has no commands section: Paper plugins register commands in code. You almost never need it for your first plugins. The full story is in Paper plugins: paper-plugin.yml, bootstrapper and loader.

Where the file goes

  1. Copy or download the file

    Press Download to get the file with the right name, or Copy and paste into a new file.

  2. Put it in src/main/resources

    In IntelliJ, right-click src/main/resources, choose New then File, and name it plugin.yml. Folders named resources are copied into the jar as they are. If you put the file next to your Java files it will not end up in the jar.

  3. Build and read the console

    Build the jar, put it in the server's plugins folder and start the server. A good start prints Enabling MyPlugin v1.0.0. If you see Could not load 'plugins/MyPlugin.jar', read the line under it: it names the exact key that is wrong.

Mistakes beginners make

  • Using a tab to indent. YAML only allows spaces. A tab gives found character '\t' that cannot start any token. The builder never writes tabs.
  • Forgetting quotes around numbers. api-version: 26.3 without quotes can be read as the number 26.3. Always write '26.3'.
  • A main class that does not match. See the section above. It is the most common reason a plugin "does nothing".
  • A command that does not exist in the YAML. If you call getCommand("heal").setExecutor(...) without a heal: entry, getCommand returns null and the plugin crashes on start.
  • Putting the file in the wrong folder. It must sit in src/main/resources, directly, not in a subfolder, so it ends up in the root of the jar.
  • A depend that is not installed. If you write depend: [Vault] and the server does not have Vault, your plugin refuses to load. Use softdepend when your plugin works without it.

Recap

  • plugin.yml is the label on the jar: name, version, main class and api-version are the essentials.
  • main must equal your package plus your class name, and the folders must match.
  • Use depend for plugins you cannot work without and softdepend for optional ones.
  • Declare permissions with defaults; a parent permission with children works as a wildcard.
  • Commands in plugin.yml are the classic way; Brigadier in code is the modern way.

Quick quiz

  1. Your main class is com.example.shop.ShopPlugin. Where does the file live?

  2. Your plugin works without Vault, but gets extra features if Vault is installed. Which line do you write?

  3. What does default: op on a permission mean?

  4. Why should api-version be written '26.3' with quotes?

Try it

Describe a plugin by hand

Imagine a plugin called CoinShop by you. It uses Vault if it is installed, has a /shop command, and the permission coinshop.use that everyone has by default. Use the builder to produce its plugin.yml. Then answer: which line makes it work without Vault, and where would the Java file live if the package is dev.yourname.coinshop and the class is CoinShopPlugin?

Hint
Pick the example "Uses another plugin (Vault)" as a starting point, then change the names. Look at the path shown under the YAML.
Show the solution

The line softdepend: [Vault] lets it load without Vault. The Java file is src/main/java/dev/yourname/coinshop/CoinShopPlugin.java and main is dev.yourname.coinshop.CoinShopPlugin. The permission has default: true, and the command shop names it with permission: coinshop.use.

Next steps

Read the whole story in plugin.yml explained, then build your first plugin and watch Paper read the file you just made. Need a delay in ticks for your first task? Try the Tick Calculator.