IntelliJ survival guide
The handful of IntelliJ features that make writing plugins much easier.
IntelliJ IDEA has hundreds of features, but you only need about a dozen to write plugins comfortably. This page teaches those: finding your way around the window, letting IntelliJ finish your code, fixing red errors with one key, reading Paper's own documentation, and running your test server. Learn these and the editor starts doing half the typing for you.
A tour of the window
Open any plugin project (, then pick the project's folder, the one that contains build.gradle.kts). The first time, IntelliJ may ask whether you trust the project; choose Trust Project, because Gradle needs to run to set it up. Wait for the progress bar at the bottom right to finish.
These are the parts you will use, and the keys that open them. Each tool window opens and closes with the same shortcut, and you can also click its icon on the window's edge.
| Part | Where | Open with | What it is for |
|---|---|---|---|
| Project tree | Left | Alt+1 | All the folders and files of your project. Double-click a file to open it. |
| Editor | Middle | Esc jumps back to it | Where you write code. Each open file gets a tab at the top. |
| Run toolbar | Top right | Shift+F10 runs | Pick a run configuration (Run Paper Server, Build Plugin Jar) and press Run, Debug or Stop. |
| Run window | Bottom | Alt+4 | The output of what you ran: for your test server, its console. |
| Gradle window | Right (elephant icon) | click the icon | Every Gradle task, and the button to reload the project. |
| Terminal | Bottom | Alt+F12 | A PowerShell terminal, already in your project folder. |
| Problems | Bottom | Alt+6 | A list of every error and warning in the open file and the project. |
For the rest of this page, open the practice project: download it, unzip it, and open the folder in IntelliJ. It is a small plugin with one listener, so you can try every shortcut on real plugin code. Here is the listener you will work on:
Where this file livesintellij-tips-practicesrcmainjavacomexampleintellijtipspracticeGiftListener.java
The package com.example.intellijtipspractice is the folder path com/example/intellijtipspractice 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.
- intellij-tips-practice/
- src/main/
- java/com/example/intellijtipspractice/Package com.example.intellijtipspractice
- GiftListener.javayou are hereListener: reacts to events
- PracticePlugin.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
- java/com/example/intellijtipspractice/Package com.example.intellijtipspractice
- 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
- src/main/
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.intellijtipspractice;2 3import org.bukkit.entity.Player;4import org.bukkit.event.EventHandler;5import org.bukkit.event.Listener;6import org.bukkit.event.player.PlayerJoinEvent;7 8public final class GiftListener implements Listener {9 10 @EventHandler11 public void onJoin(PlayerJoinEvent event) {12 Player player = event.getPlayer();13 player.sendRichMessage("<green>Welcome! <gray>A gift is waiting for you.");14 }15}- An import tells Java which library a name such as
Playercomes from. IntelliJ writes these lines for you, as you will see below. - This class listens for events.
- Runs when a player joins. You will add to this method in this page's exercise.
- Sends a colored chat message to the player.
Autocomplete: let IntelliJ type for you
Autocomplete (IntelliJ calls it code completion) is the feature you will use most. As you type, IntelliJ shows a list of everything that fits at that spot. Pick an entry with the arrow keys and press Enter or Tab, and IntelliJ writes the full name, correctly spelled.
Type a dot to discover what something can do
This is the trick that makes the Paper API learnable. In onJoin, start a new line under the sendRichMessage line and type player. (with the dot). IntelliJ lists everything a Player can do: getHealth, setGameMode, teleport, giveExpLevels, hundreds of methods (the named actions an object can do). Keep typing to filter the list: player.give shows only the methods with "give" in them.
Each entry shows the method's name, the values it needs in brackets, and on the right what it gives back. You do not need to memorize the Paper API. You need to know which object to ask (the player, the event, the server), then type a dot and read.
- Ctrl+Space opens the list on purpose, for example when you closed it or want suggestions before typing anything.
- Ctrl+P, with the cursor inside a method's brackets, shows which values (parameters) that method expects, and highlights the one you are typing now.
- Ctrl+Q on a selected entry shows its documentation, so you can read what a method does before you pick it.
Autocomplete works for event names too. Type PlayerJoin in a method's brackets and IntelliJ offers PlayerJoinEvent, and when you pick it, it also adds the import line at the top of the file for you.
Red squiggles and Alt+Enter
IntelliJ checks your code while you type. When something is wrong, it underlines it:
- Red: an error. The plugin will not compile until you fix it.
- Yellow or gray: a warning or a suggestion. The code compiles, but something could be better, such as a variable you never use.
- Strikethrough (a line through a name): the method or class is deprecated, meaning there is a newer way and the old one may disappear. In Paper 26.3 you will see this on old tutorial code such as
ChatColor. Use the modern way that this guide teaches.
Hover the underlined code to read the problem in a tooltip, or press F2 to jump to the next error in the file.
The magic key: Alt+Enter
Put the cursor on anything underlined and press Alt+Enter. IntelliJ shows a short list of quick fixes and, most of the time, the first one is exactly what you need. The three you will use constantly:
| The problem | What Alt+Enter offers |
|---|---|
A class name is red because it is not imported, like Sound | Import class. It adds the import line at the top. If several classes have that name, it asks which one. |
You called a method that does not exist yet, like sendWelcome(player) | Create method. It writes an empty method with the right parameter for you to fill in. |
| A value has the wrong type, like a decimal number where a whole number is needed | Cast or change the variable's type. Read the options; the right fix depends on what you meant. |
Here is the most common red error of all. This code uses Sound without importing it:
1player.giveExpLevels(5);2player.playSound(player, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1.0f, 1.0f);IntelliJ underlines Sound in red right away. If you build anyway, the compiler stops with this message:
> Task :compileJava FAILEDC:\Users\jacec\IdeaProjects\intellij-tips-practice\src\main\java\com\example\intellijtipspractice\GiftListener.java:15: error: cannot find symbol player.playSound(player, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1.0f, 1.0f); ^ symbol: variable Sound location: class GiftListener1 errorFAILURE: Build failed with an exception."Cannot find symbol" means "I do not know this name". Either it is misspelled or it is not imported. Press Alt+Enter on Sound, choose Import class, and pick org.bukkit.Sound.
Navigation: read the API like a book
The best documentation for Paper is Paper's own code, and IntelliJ lets you jump straight into it.
| Keys | What it does | When to use it |
|---|---|---|
| Ctrl+click (or Ctrl+B) | Go to where a name is defined. On sendRichMessage it opens the Paper source file with that method and its description. | "What exactly does this method do, and what else is next to it?" |
| Ctrl+Q | Quick documentation in a popup, without leaving your file. Hovering a name for a moment shows the same. | "What does this method return? Can it be null?" |
| Ctrl+Alt+Left | Go back to where you were before you jumped. | After a Ctrl+click adventure. |
| Shift Shift (press twice) | Search Everywhere: find any class, file, setting or action by name. | "Open PlayerJoinEvent." "Where is plugin.yml?" |
| Ctrl+Shift+F | Find in Files: search for text in every file of the project. | "Where do I send the message that contains 'gift'?" |
| Ctrl+E | Recent files. | Jumping between the two or three files you are working on. |
| Ctrl+F12 | File structure: a list of the methods in the current file. | Big classes with many event handlers. |
When you Ctrl+click a Paper class, IntelliJ may first show a "decompiled" version, rebuilt from the compiled bytecode without any descriptions. If you see a banner at the top with Download Sources, click it: IntelliJ fetches the real Paper source code, with every description (called Javadoc) that the Paper developers wrote. Those descriptions are often the best explanation of a method anywhere.
Refactoring and tidying
Refactoring means changing how code is organized without changing what it does: renaming things, moving them, cleaning them up. IntelliJ does it safely, everywhere at once.
| Keys | What it does |
|---|---|
| Shift+F6 | Rename a variable, method, class or file, and update every place that uses it. Never rename by hand: you will miss one. |
| Ctrl+Alt+L | Reformat code: fixes indentation and spacing in the whole file. Press it whenever code looks messy. |
| Ctrl+Alt+O | Optimize imports: removes imports you no longer use and sorts the rest. |
| Ctrl+O | Override methods: lists methods you can add from the parent class. In your main class, this is how you add onDisable without typing it. |
| Ctrl+D / Ctrl+Y | Duplicate the current line / delete the current line. Handy for adding a second sendRichMessage line. |
| Ctrl+Z / Ctrl+Shift+Z | Undo / redo. IntelliJ remembers a lot of history, so experiment freely. |
Gradle inside IntelliJ
IntelliJ reads your Gradle files to learn where the Paper API is and which Java to use. When you change a build file (build.gradle.kts, settings.gradle.kts or gradle.properties), IntelliJ does not reread it on its own. A small floating button with the Gradle elephant appears in the editor: click it, or press Ctrl+Shift+O, to load the Gradle changes.
The Gradle tool window (the elephant icon on the right) lists every task the project knows. The two you care about are Tasks > build > build (builds the jar) and Tasks > Run Paper > runServer (starts the test server). Double-click a task to run it. The reload button at the top of this window (two circling arrows) does the same as Ctrl+Shift+O.
When Gradle sync goes wrong
If every Paper name is suddenly red (JavaPlugin, Player, everything), IntelliJ has lost track of the Paper API. Work through these in order, and stop as soon as it is fixed:
- Reload the Gradle project (Ctrl+Shift+O, or the reload button in the Gradle window) and read the Build window at the bottom. A real error there, such as a typo in
build.gradle.ktsor no internet connection, is the actual cause. - Check you opened the right folder: the one with
build.gradle.ktsin it, not its parent. - Check the Gradle JVM: , and set Gradle JVM to your Java 25.
- As a last resort: , tick nothing extra, and click Invalidate and Restart. IntelliJ throws away its memory of the project and rebuilds it. It takes a while, which is why it is the last step, not the first.
Run configurations: run and debug your server
A run configuration is a saved "what to run" choice. The guide's projects (and the paper-templates on Jace's PC) come with two, in the drop-down at the top right of the window:
- Run Paper Server runs the Gradle task
runServer. It downloads Paper 26.3 the first time, builds your plugin, and starts a real server in the project'srunfolder with your plugin already installed. Join it from Minecraft 26.3 atlocalhost. - Build Plugin Jar runs the Gradle task
build. The jar lands inbuild\libs, ready to copy to another server.
Next to the drop-down are three buttons: the green arrow Run (Shift+F10), the bug Debug (Shift+F9) and the red square Stop (Ctrl+F2).
While the server runs, the Run window at the bottom is its console. You can type server commands there (without the slash), such as op Steve or plugins, and press Enter.
Debug starts the same server, but lets you pause your plugin at any line. Click in the gray margin left of a line number to set a red dot, a breakpoint, then join the server. When that line is about to run, the server pauses and IntelliJ shows every variable's value at that moment. It is the best way to understand why code does something unexpected. Debugging like a pro teaches it step by step.
Shortcut cheat sheet
All shortcuts are for Windows with IntelliJ's default keymap. If you forget one, press Ctrl+Shift+A (Find Action) and type what you want to do, such as Reload All Gradle Projects or Invalidate Caches; the shortcut is shown next to each result.
| Keys | Action |
|---|---|
| Ctrl+Space | Autocomplete |
| Ctrl+P | Show the parameters a method expects |
| Alt+Enter | Quick fix (import, create method, fix types) |
| F2 | Jump to the next error |
| Ctrl+click / Ctrl+B | Go to definition (read the API source) |
| Ctrl+Q | Quick documentation |
| Ctrl+Alt+Left | Go back |
| Shift Shift | Search Everywhere |
| Ctrl+Shift+F | Find in Files |
| Ctrl+E | Recent files |
| Ctrl+F12 | File structure |
| Shift+F6 | Rename everywhere |
| Ctrl+Alt+L | Reformat code |
| Ctrl+Alt+O | Optimize imports |
| Ctrl+O | Override methods (add onDisable) |
| Ctrl+D / Ctrl+Y | Duplicate line / delete line |
| Ctrl+Shift+O | Load Gradle changes |
| Shift+F10 / Shift+F9 | Run / Debug the selected run configuration |
| Ctrl+F2 | Stop |
| Alt+1 / Alt+4 / Alt+6 / Alt+F12 | Project tree / Run window / Problems / Terminal |
| Ctrl+Alt+S | Settings |
| Ctrl+Shift+A | Find Action (search for any command) |
Common beginner traps
Editing files outside src/main
Your plugin is made only from what is inside src/main. Two other folders look tempting but are generated:
buildis Gradle's output. Anything you change there is overwritten by the next build.runis the test server. Itspluginsfolder holds a copy of your plugin's files. If your plugin saves aconfig.yml, the server's copy lives inrun\plugins\YourPlugin\config.yml. Editing the one insrc/main/resourceslater does not change that copy, because a plugin only writes its default config when none exists yet. Delete the server's copy to get the new default.
Wrong JDK selected
If IntelliJ complains about the Java version ("release version 25 not supported", or modern Java code underlined in red although it builds fine with Gradle), check two settings:
- : SDK should be a Java 25 JDK (IntelliJ calls a JDK an SDK, software development kit). If 25 is not in the list, choose Add SDK > JDK and pick the Temurin 25 folder.
- : Gradle JVM should be Java 25 too.
Files not saved
IntelliJ saves automatically: when you run something, switch to another program, or after a short pause. So you rarely need Ctrl+S. The trap is the other direction: if you edit a project file in another program (Notepad, File Explorer), IntelliJ may still show the old version for a moment. Edit project files in IntelliJ only, and if you did change something outside, use .
plugin.yml in the wrong folder
The server only finds plugin.yml if it ends up at the top of the jar, and it only gets there from src/main/resources:
- intellij-tips-practice/
- plugin.ymlWRONG: the project folder itself is not packed into the jar
- src/
- main/
- java/
- com/example/intellijtipspractice/
- plugin.ymlWRONG: this folder is for Java code only
- PracticePlugin.java
- GiftListener.java
- com/example/intellijtipspractice/
- resources/
- plugin.ymlRIGHT: everything here is copied to the top of the jar
- java/
- main/
With plugin.yml anywhere else, the server refuses to load the jar with an error that it does not contain a plugin.yml. To be sure, right-click src/main/resources in the project tree and create the file there with .
Opening the wrong folder
If you open a folder that contains several projects (for example all of paper-templates, or your whole IdeaProjects), IntelliJ does not find a build.gradle.kts at the top, so nothing gets set up and all the code stays red. Close it with and open the single project folder instead.
A gift on join, typed with autocomplete
In the practice project's GiftListener, make joining players receive 5 experience levels, hear the experience orb sound, and see a gold message "You received 5 experience levels!". The rule: type as little as possible. Use autocomplete for every name, and Alt+Enter for the import. Then run Run Paper Server, join at localhost and check it.
Hint 1
Start a new line under the sendRichMessage line and type player.give. Which method gives levels, not raw experience points?
Hint 2
For the sound, type player.playS and pick the version of playSound that takes an entity (the player), a Sound and two numbers. Press Ctrl+P inside the brackets to see what each value means. Then type Sound.ENTITY_EXP for the sound.
Hint 3
The two numbers are the volume and the pitch. 1.0f means normal for both; the f marks a decimal number of the type float.
Show the solution
Three new lines in onJoin and one new import, which Alt+Enter adds for you:
Where this file livesintellij-tips-exercisesrcmainjavacomexampleintellijtipsexerciseGiftListener.java
The package com.example.intellijtipsexercise is the folder path com/example/intellijtipsexercise 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.
- intellij-tips-exercise/
- src/main/
- java/com/example/intellijtipsexercise/Package com.example.intellijtipsexercise
- GiftListener.javayou are hereListener: reacts to events
- PracticePlugin.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
- java/com/example/intellijtipsexercise/Package com.example.intellijtipsexercise
- 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
- src/main/
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.intellijtipsexercise;2 3import org.bukkit.Sound;4import org.bukkit.entity.Player;5import org.bukkit.event.EventHandler;6import org.bukkit.event.Listener;7import org.bukkit.event.player.PlayerJoinEvent;8 9public final class GiftListener implements Listener {10 11 @EventHandler12 public void onJoin(PlayerJoinEvent event) {13 Player player = event.getPlayer();14 player.sendRichMessage("<green>Welcome! <gray>A gift is waiting for you.");15 player.giveExpLevels(5);16 player.playSound(player, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1.0f, 1.0f);17 player.sendRichMessage("<gold>You received 5 experience levels!");18 }19}- Added by Alt+Enter, Import class. Make sure it is
org.bukkit.Sound. - Adds 5 whole levels to the green bar.
giveExpwould add 5 experience points instead, which is barely visible. - Plays the sound at the player's position: who or where, which sound, volume, pitch.
- The confirmation message, in gold.
Welcome! A gift is waiting for you.
You received 5 experience levels!
Notice how much of that you did not have to know in advance. You knew the object (player), typed a dot, and let IntelliJ show you the rest. That is how experienced developers work with the Paper API every day.
Ctrl+click detective
In GiftListener, hold Ctrl and click sendRichMessage. Which file opens? Read the description above the method: what format does it say the message uses? Then press Ctrl+Alt+Left to come back.
Hint
The file's name is shown in the editor tab. If you see a "Download Sources" banner, click it first to see the descriptions.
Show the solution
It opens CommandSender.java, and the description says the message uses the MiniMessage format, with a link to the MiniMessage docs. That tells you two useful things:
sendRichMessagebelongs toCommandSender, which means anything that can send commands has it: players and the server console alike. APlayeris a kind ofCommandSender, which is whyplayer.sendRichMessageworks. You will learn how one type can be a "kind of" another in Inheritance and interfaces.- The tags like
<green>are MiniMessage, explained in MiniMessage: easy formatted text.
You just answered a question by reading the API itself. Whenever you wonder "where does this come from?", Ctrl+click it.
Recap
- Know the window: project tree (Alt+1), editor, run toolbar, Run window (Alt+4), Gradle window, terminal (Alt+F12), Problems (Alt+6).
- Type an object and a dot to see everything it can do; Ctrl+Space and Ctrl+P help further.
- Red means error. Alt+Enter fixes most of them, especially missing imports; check you picked the right package.
- Ctrl+click opens the Paper source and its descriptions; Ctrl+Q shows them in a popup.
- Rename with Shift+F6 (then check
plugin.yml), tidy with Ctrl+Alt+L and Ctrl+Alt+O. - Load Gradle changes after editing build files; Invalidate Caches is the last resort.
- Run Paper Server starts a test server with your plugin; stop it by typing
stop. Debug lets you pause at breakpoints. - Only edit files in
src/main, keepplugin.ymlinsrc/main/resources, and use Java 25 as the project SDK and Gradle JVM.
Quick quiz
You want to know what a
Playercan do, but you do not know any method names. What is the fastest way?Typing a dot after an object lists everything it can do, with parameters and return types. Keep typing to filter, and press Ctrl+Q on an entry to read its description.The word
Soundis red, and the build says "cannot find symbol". What is the most likely fix?"Cannot find symbol" on a class name almost always means a missing import (or a typo). Alt+Enter adds the import. Invalidate Caches is a last resort for when every Paper name is red, not one.You added a library to
build.gradle.kts, but IntelliJ still underlines its classes in red. What did you forget?IntelliJ only rereads build files when you load the Gradle changes. Until then, it does not know the new library exists. Saving is automatic in IntelliJ.You renamed your main class with Shift+F6. What should you check right after?
Rename updates all Java code, butplugin.ymlis a text file. If itsmain:line still has the old name, the server cannot find your plugin's main class.What is the safest way to stop the test server started with Run Paper Server?
Thestopcommand saves the worlds and calls every plugin'sonDisable, exactly like a real server shutdown. The red Stop button can end the process abruptly, without a clean shutdown; keep it for a stuck server.
Next steps
- Your first plugin, step by step: use everything from this page to write and run your first plugin.
- Anatomy of a plugin project: what every file in the project tree is for.