Paper Plugin Guide
File mode0

Going further

Where to go next

Official docs, communities and a ladder of project ideas to keep growing.

Beginner17 min read

You can now write, build, test and share a plugin. This last page of the guide shows you where the real answers live, how to read the official reference pages (the Javadocs), how to learn from other people's plugins, and which project to build next.

Where you are

You learned the Java you need, how a plugin starts, how to react to events, run commands, show text and menus, save data, schedule tasks and share your work. Nobody remembers all of that. Working developers look things up all day. The skill that matters now is knowing where to look and how to read what you find.

Use the progress button on each page of this guide to mark what you have finished. It remembers your progress in this browser only, so it works without an account. If a page felt shaky, go back to it after you build something with it; a second visit with a real project in your head goes much faster.

Official places to look

These are the sources the Paper developers and library authors keep up to date. When something here disagrees with a forum post from three years ago, trust this.

WhereWhat you find there
docs.papermc.ioThe Paper documentation. The developer section covers plugin setup, events, commands, the scheduler, data storage and much more, written by the Paper team.
jd.papermc.ioThe Javadocs: the complete list of every class and method in the Paper API. The next section teaches you to read it.
docs.advntr.devThe Adventure and MiniMessage documentation: text, colors, click events, titles, boss bars and sounds.
github.com/Mojang/brigadierBrigadier, the command library Minecraft itself uses. Read its README after Commands, part 2.
dev.javaOracle's own Java learning site, with tutorials and the Java API documentation. Good when a Java idea, not a Paper idea, confuses you.
docs.gradle.orgThe Gradle documentation, for when your build file does something you do not understand.
PaperMC DiscordThe community server of the Paper project, with help channels for plugin developers. The PaperMC forums, linked from papermc.io, are the slower, searchable version.
github.com/PaperMCThe source code of Paper itself. When docs are unclear, the source code is the truth.

Inside this guide, the API map, the Paper cheat sheet, the error reference and the Event Finder are shortcuts for the questions you will ask most.

Asking for help well

People in help channels are volunteers. You get better answers, faster, when you make their job easy. Say which Paper and Java version you use, say what you wanted and what happened instead, paste the exact error text (as text, not a photo) and the code it points to, and say what you already tried. If the code is long, put it on a paste site and share the link. Never share passwords, tokens or your server's IP in public.

How to read the Javadocs

Javadoc is a standard format for documentation that is written inside Java code and turned into web pages. Every class in the Paper API has a page. Open the one for Paper 26.3 at jd.papermc.io/paper/26.3/, type a class name in the search box at the top, and press Enter. For example, search for Player. The page is long, so it helps to know its layout:

The parts of a Javadoc page A sketch of a Javadoc page for the Player interface with the class name at the top, a method summary table in the middle and method details below. Callouts explain each part. Interface Player Method Summary int getPing() void sendRichMessage(String) ...hundreds more rows Method Details: getPing() Gets the player's estimated ping. Returns: player ping Which type and what it extends Scan the list type, name, inputs Read the rules null? async? returns?
Every Javadoc page has the same three parts: the heading, a summary table, and the detail section.
  • The heading says what the type is (Interface, Class, Enum) and lists what it extends. The superinterface list is important: a Player is also a HumanEntity, a LivingEntity and an Entity, and it can do everything those can do.
  • The Method Summary is a table: return type on the left, method name and inputs on the right, then one line of description. Scan it like a menu.
  • Methods inherited from... boxes list methods that this type gets from a parent type. Each box has one parent type and a row of method links.
  • The Method Details hold the full text for each method: what it does, what each input means, and what it returns.

Reading one method

Here is how to read one entry. This is getPing from the Player page:

From the Javadoc of Player
1int getPing()
  1. The return type. This method gives back a whole number. A void here would mean it gives back nothing.
  2. The method name. Methods are called with a dot: player.getPing().
  3. The inputs. Empty parentheses mean it needs no input. A method like sendRichMessage(String) needs one piece of text.

The description under it says: "Gets the player's estimated ping in milliseconds", and that the value should not be used for anti-cheat. That second sentence is the sort of detail you only get by reading the full entry. Always scan the details for these words:

  • Returns / @return: what you get back, and sometimes that it can be null.
  • @Nullable: the result may be empty, so check before you use it.
  • Deprecated: the page tells you what replaces it.
  • Throws: the kinds of errors it may cause.
  • Must be called from the main thread, or similar notes about threads and the scheduler.

Now turn what you read into code. This small plugin adds a /ping command. Everything it needs came from the entry above.

PingCommand.javaCompiles on Paper 26.3Compile Lab
Where this file livesnext-steps-javadocsrcmainjavacomexamplenextstepsjavadocPingCommand.java

The package com.example.nextstepsjavadoc is the folder path com/example/nextstepsjavadoc inside src/main/java: every dot in the package name is one folder. IntelliJ creates these folders for you when you make a new package.

  • next-steps-javadoc/
    • src/main/
      • java/com/example/nextstepsjavadoc/Package com.example.nextstepsjavadoc
        • PingCommand.javayou are hereCommand (BasicCommand)
        • PingPlugin.javaMain class: Paper starts here (named as main in plugin.yml)
      • resources/Files copied into the jar as they are
        • plugin.ymlTells Paper the plugin's name, version and main class
    • build.gradle.ktsThe build recipe: Paper 26.3 API, Java 25, how the jar is made
    • gradle.propertiesVersion numbers used by the build
    • gradlew.batRuns Gradle on Windows without installing it
    • settings.gradle.ktsThe project's name

Gray files come with the project template; you rarely edit them. Open the whole project in the Compile Lab, or download it from the project page.

1package com.example.nextstepsjavadoc;2 3import io.papermc.paper.command.brigadier.BasicCommand;4import io.papermc.paper.command.brigadier.CommandSourceStack;5import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;6import org.bukkit.entity.Player;7 8public final class PingCommand implements BasicCommand {9 10    @Override11    public void execute(CommandSourceStack source, String[] args) {12        if (!(source.getSender() instanceof Player player)) {13            source.getSender().sendRichMessage("<red>Only players have a ping.");14            return;15        }16        int milliseconds = player.getPing();17        player.sendRichMessage("<gray>Your ping is <green><ms> ms",18            Placeholder.unparsed("ms", String.valueOf(milliseconds)));19    }20}
  1. Only players have a ping, so we check what kind of sender ran the command. The console does not.
  2. The method we found in the Javadoc. It returns an int, so we store it in an int variable.
  3. The placeholder in MiniMessage wants text, so this turns the number into text.
PingPlugin.javaCompiles on Paper 26.3Compile Lab
Where this file livesnext-steps-javadocsrcmainjavacomexamplenextstepsjavadocPingPlugin.java

The package com.example.nextstepsjavadoc is the folder path com/example/nextstepsjavadoc inside src/main/java: every dot in the package name is one folder. IntelliJ creates these folders for you when you make a new package.

  • next-steps-javadoc/
    • src/main/
      • java/com/example/nextstepsjavadoc/Package com.example.nextstepsjavadoc
        • PingCommand.javaCommand (BasicCommand)
        • PingPlugin.javayou are hereMain class: Paper starts here (named as main in plugin.yml)
      • resources/Files copied into the jar as they are
        • plugin.ymlTells Paper the plugin's name, version and main class
    • build.gradle.ktsThe build recipe: Paper 26.3 API, Java 25, how the jar is made
    • gradle.propertiesVersion numbers used by the build
    • gradlew.batRuns Gradle on Windows without installing it
    • settings.gradle.ktsThe project's name

Gray files come with the project template; you rarely edit them. Open the whole project in the Compile Lab, or download it from the project page.

1package com.example.nextstepsjavadoc;2 3import java.util.List;4import org.bukkit.plugin.java.JavaPlugin;5 6public final class PingPlugin extends JavaPlugin {7 8    @Override9    public void onEnable() {10        registerCommand("ping", "Shows your connection delay", List.of(), new PingCommand());11    }12}
  1. Registers /ping when the plugin starts.
Your ping is 34 ms

Reading other people's plugins

Reading real code is the fastest way to move from "I can follow a tutorial" to "I can build things". Thousands of Paper plugins are open source on GitHub. On GitHub, search for paper plugin or open a plugin's page on Hangar or Modrinth and follow its source link. Pick a small, recent plugin with a few hundred lines and a README. Check three things first:

  • Is it recent? Look at the date of the last commit. Old projects teach old habits, and you will meet the red flags from Using AI assistants well.
  • Does it say it supports your Paper version? Look at api-version in plugin.yml.
  • What is the license? You may read any public code. You may copy it only if the license allows it, and you must follow its rules. When in doubt, learn how it works and write your own version. See licenses.

Then read it in the same order Paper does:

  1. plugin.yml or paper-plugin.yml

    The name, the main class, dependencies, and the permissions and commands that are declared there.

  2. The main class and onEnable

    Everything the plugin sets up appears here: listeners, commands, config, scheduled tasks. It is the table of contents of the plugin.

  3. One listener or command at a time

    Pick one feature and follow it. Ask the three questions: what triggers this, what does it check, and what does it change?

  4. Run it

    Clone the repo (FileNewProject from Version Control... in IntelliJ), build it and put it on your test server. Seeing the feature work makes the code much clearer. Then change something small and see what breaks.

Do not worry if you only understand half of it. Look up every class or method you do not know in the Javadocs, and keep a list of new ideas to try in your own plugin.

A ladder of project ideas

You learn most by building things you would like to use on your own server. Start with an easy rung, finish it, then climb. Each rung asks you to learn only one or two new ideas.

Project idea ladder Five rungs from easy to hard: messages and small rules, commands that save data, menus and items, mini games with timers, big plugins and databases. 1. Messages and small rules 2. Commands that save data 3. Menus and items 4. Mini games with timers 5. Big plugins and databases Start at the bottom. harder
Finish one rung before the next. A small plugin that works teaches more than a big one that does not.
RungIdeaChapters you need
1Welcome kit: join message, title and a first-join giftEvents, MiniMessage, Project: Welcome kit
1Chat tweaks: blocked words, colored namesProject: Chat, Priorities and canceling
2Heal and feed commands with cooldownsCommands, Cooldowns, Project: Heal and feed
2Homes: /sethome and /homeConfig files, Saving player data, Project: Homes
3A magic wand with spells and particlesItems, Effects, Project: Magic wand
3A shop menu players clickMenus, Project: Shop menu
4A live sidebar with statsScoreboards, Project: Scoreboard
4A parkour course with timers and checkpointsScheduler, Project: Parkour
5A mini game with lobby, teams and roundsCustom events, Organizing a bigger plugin, Threads and performance
5A plugin that works with other plugins, such as a currency or permissions pluginOther plugins, Permissions

Tips for any project:

  • Write the feature list first. Three to five lines, the way you would for the AI prompts on the AI page. Cut it in half.
  • Make one thing work, then commit. See Git and GitHub.
  • Test on a fresh server before you show anyone, and when it is good, publish it.
  • When you get stuck for more than 30 minutes, make the smallest example that shows the problem. Half the time you find the answer while making it. If not, you have the perfect question to ask.
  • Keep the guide's Practice Arena for short challenges when you do not have a project in mind.

Keep growing

  • Read the Paper release notes when a new Minecraft version comes out, so you know what changed before your plugin breaks.
  • Fix, then improve. Go back to your first plugin in a month. You will see a dozen things you would do better, and each fix is practice.
  • Help someone else. Answering a beginner's question in a help channel is the best test of your own understanding.
  • Stay curious about the next layer: data components, paper-plugin.yml and bootstrappers, Folia, and server internals, when you need them.
Try it

Find a method you have never used

Open the Paper Javadocs and find out how to set a player's food level to the maximum. Which method do you call? Write the one line of code. Hint: it is a method that the Player page shows only as an inherited link.

Hint 1

Search for Player. The summary table does not list food methods. Scroll to the boxes called "Methods inherited from..." and look at the interface that describes a human, which includes players.

Hint 2

The interface is HumanEntity. Open it and look for methods whose names include Food. A full food bar is 20.

Show the solution

The method is declared in HumanEntity, which Player extends, so you can call it directly on a player:

Fill the food bar
1player.setFoodLevel(20);

This is the main lesson: when a method is not on the class you are looking at, look at what the class extends.

Try it

Read a real plugin

Find a small, recent open source Paper plugin on GitHub, Hangar or Modrinth. Without copying anything, write down answers to these five questions:

  1. Which Paper version does its api-version say?
  2. What is its main class, and what does onEnable register?
  3. What is one event it listens to, and what does the handler do?
  4. Which commands does it add?
  5. What is one thing you would do differently after reading this guide?
Hint

Start with src/main/resources/plugin.yml. The main class is named on its main: line.

Show the solution

There is no single correct answer. A good answer names real files and classes from the plugin you picked. If you could answer questions 1 to 4, you can read plugins. Question 5 is where the learning starts: maybe the plugin uses a deprecated method, repeats code, or does web work on the main thread.

Try it

Choose your next project

Pick one rung from the ladder and write, in three lines, what the plugin will do. Then list the chapters you will reread before you start.

Show the solution

Example: "A homes plugin. Players run /sethome to save their position and /home to return. Homes survive a restart." Chapters to reread: Config files, Saving player data and Project: Homes. Short and clear is the point.

Recap

  • Keep docs.papermc.io, the Javadocs, the Adventure docs and dev.java at hand. Official sources beat old forum posts.
  • A Javadoc page has a heading, a summary table and detail entries. If a method is missing, look at what the type extends.
  • Press Ctrl+Q in IntelliJ for documentation and Ctrl+B for source.
  • Learn from other plugins by reading plugin.yml, then the main class, then one feature at a time. Respect the license.
  • Build up the project ladder one rung at a time, and ask questions with your versions, your code and the exact error.

Quick quiz

  1. You cannot find setFoodLevel in the method summary of the Player page. What is the most likely reason?

  2. In int getPing(), what does int tell you?

  3. You find a useful open source plugin with no license file. What are you allowed to do?

  4. Which file is the best place to start reading an unknown plugin?

  5. Which of these makes a request for help easier to answer?

You made it

That is the end of the guide, and the start of your own plugins. Open Project: Welcome kit if you want a guided build, or the Practice Arena for quick challenges, and begin the next idea on your list. Have fun, and keep your server's players in mind: the best plugin is the one somebody uses.