How To Code a Minecraft Plugin
After many years of waiting, today I can officially announce that Minecraft Plugin Development has come to replit! With this tutorial you will understand all you need to know on how to create the basic boilerplate for a standard Java edition plugin for the Spigot API.
This guide is geared towards creating a plugin on repl.it but will also work for IDEs such as Intelij IDEA and Eclipse (I recommend Intelij out of the two)
For any assistance feel free to leave a reply or join my Discord server discord.gg/zfgVqZv
Background Information
Minecraft Java plugin development can be done for a variety of different APIs such as CraftBukkit, Spigot, PaperMC, Bungeecord, etc.
A Minecraft plugin is essentially a library built on these APIs that will allow you to interact with the API to create custom gamemodes, administration utilities, and much more!
Plugins are typically cross compatible with the main APIs but if you use methods specific to PaperMC it will not run as intended on CraftBukkit or Spigot servers, so be careful if cross-compatibility is a concern for you.
In this tutorial we will be building our plugin on the Spigot API using Maven as our build tool (Gradle is not available on repl.it as far as i’m aware).
Getting Started
Maven
Create a new Java repl and then go to the terminal/console.
Type the following commands in this order:
rm *
mvn archetype:generate
After that, you should begin to see Maven (a java build tool) spit messages in console. Leave it for a minute until it asks you to start inputting information for your project.
The first message you see should be along the lines of
Choose a number or apply filter (...):
For this, choose the latest version, for example if I was given this:
1: 1.0-alpha-1
2: 1.0-alpha-2
3: 1.0-alpha-3
4: 1.0-alpha-4
5: 1.0
6: 1.2
7: 1.3
8: 1.4
I would enter 8
into the console.
After this you will see a message asking you to input your groupID
. For this, if you have a domain then enter tld.yourdomain
, for example I own the domain astolfo.tech so I would enter tech.astolfo
. If you don’t have a domain then use me.yourname
.
After this it will ask you for your artifactID, this is basically the name of your project. So, just enter what you’d like to call your plugin without any spaces or special characters. Example: tutorialplugin
Once you’ve entered your artifactID it will ask for your plugin version, just put 1.0-SNAPSHOT
to start with. It doesn’t really matter what goes here but in the end it will be the prefix of your compiled jarfile.
Once that’s done it will ask for what you’d like the package to be named. In this case enter your groupID+artifactID, for example: tech.astolfo.tutorialplugin
or tld.yourdomain.plugin
When that’s over it will ask you to confirm, enter Y
, and then you should see this:
Pre-plugin Setup
You should see a folder in your files with the name of your artifactID, click it and open the pom.xml
file.
Delete what’s currently in your pom.xml and paste the following:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>REPLACE WITH YOUR GROUPID</groupId>
<artifactId>REPLACE THIS WITH YOUR ARTIFACT ID</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>REPLACE THIS WITH YOUR PLUGIN NAME</name>
<description>REPLACE THIS WITH A DESCRIPTION OF YOUR PLUGIN</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<url>https://astolfo.tech</url>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.8.8-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
Make sure to replace the values i’ve marked with your own values or your plugin will fail to compile!
Once you’ve modified the pom.xml file, navigate to src/main
and create a folder called resources
and then go inside that folder and create a file called plugin.yml
We will setup this file later!
After that go to src/main/java/groupID/artifactID
and delete App.java
.
Create a new file called YourPluginName.java
and inside of it paste the following:
package YOUR-GROUP-ID.YOUR-ARTIFACT-ID;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
public class YourPluginName extends JavaPlugin {
@Override
public void onEnable() {
}
@Override
public void onDisable() {
}
}
Replace the value for package
on line 1 and the name of the class to the appropriate values.
After this, go back to your plugin.yml file and paste the following:
name: NAME_OF_PLUGIN
version: ${project.version}
main: YOUR-GROUP-ID.YOUR-ARTIFACT-ID.YourPluginName
prefix: CONSOLEPREFIX
authors: [YOURNAME]
description: REPLACE THIS WITH A DESCRIPTION THAT WILL BE SHOWN WHEN PLAYERS DO /about <YourPlugin>
website: YOUR WEBSITE
Here’s an example of a working plugin.yml file:
name: TutorialPlugin
version: ${project.version}
main: tech.astolfo.tutorialplugin.TutorialPlugin
prefix: AstolfoTutorial
authors: [AstolfoDev]
description: An example plugin for my replit tutorial!
website: https://astolfo.tech
Setting Up Your Repl
Now that we’ve sorted all that out, create a .replit
file in your project root and paste in the following:
language="Java"
run="cd YOURARTIFACTID && mvn clean install"
Remember! Replace the marked value with your own
This will automatically compile your code whenever you click the run button!
Creating a Command
Now that we’ve sorted out all the basics, let’s begin creating our first command!
To start, go to your plugin.yml
file and add this to the bottom of the file:
commands:
COMMANDNAME:
usage: /<command>
Replace COMMANDNAME with what you want the player to type in game, for example a command called tutorial
will be run when you type /tutorial
in game. For a full list of command properties read this documentation
After that navigate to src/main/java/groupID/artifactID
and create a new folder called classes
and inside that folder create a folder called commands
.
Inside the commands folder create a new file called YourCommandName.java
Inside that file paste in the following boilerplate:
package YOUR-GROUP-ID.YOUR-ARTIFACT-ID.classes.commands;
import org.bukkit.*;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class YourCommandName implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
return true;
}
}
In this command I will show you how to send a basic message to the player. For more information on various that can be called on the player interface consult this documentation.
Inside our onCommand method (above the return true) we will define the Player as the command executor. To do this we will create a new Player variable called "p" by casting the "sender" variable like this.Player p = (Player) sender;
Next, to send the message we need to use the Player#sendMessage()
method like this: p.sendMessage("OwO");
.
Our code should look like this now:
package tech.astolfo.tutorialplugin.classes.commands;
import org.bukkit.*;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class YourCommandName implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
Player p = (Player) sender;
p.sendMessage("OwO");
return true;
}
}
If your code looks like mine then that means you’re on the right track!
Now, how do we let the plugin know we want this class to be responsible for the command we created in our plugin.yml?
Simple! Head over to your plugin’s main class (YourPluginName.java) and import the class for your command by writing
import YOUR-GROUP-ID.YOUR-ARTIFACT-ID.classes.commands.YourCommandName;
After that, add the following line inside the onEnable()
method
getCommand("COMMANDNAME").setExecutor(new YourCommandName());
And that’s all there is to it! You can run the repl and use your compiled jarfile (located in src/target
on your server to test it out!
Creating a Listener
Commands are great and all but what if you want to do an action when an event occurs? (Ex. When a player hits an entity) Well, that’s where listeners come into play!
Go to your classes folder and create a folder called "listeners" and inside it create a new file called YourListenerName.java
.
Inside this file paste in the following boilerplate:
package YOUR-GROUP-ID.YOUR-ARTIFACT-ID.classes.listeners;
import org.bukkit.*;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.*;
public class YourListenerName implements Listener {
}
}
Remember! Replace the marked values with your own
Let’s create a new event handler which will prevent players from dropping items. To do this, create a new method with the player drop event as a parameter like this:
@EventHandler
public void noDropItems(PlayerDropItemEvent e) {
}
WARNING! Ensure you remember to put @EventHandler above the method or it will not work!
Inside our new method let’s get the player who dropped the item using the e#getPlayer()
method and send him a message like this
Player p = e.getPlayer();
p.sendMessage("No littering!");
Now, let’s cancel the event so the player can’t drop the item using the e#setCancelled()
method.
Our method should look like this now.
@EventHandler
public void noDropItems(PlayerDropItemEvent e) {
Player p = e.getPlayer();
p.sendMessage("No littering!");
e.setCancalled(true);
}
If this is the case, we can move onto actually registering the listener.
Navigate to your main class again, import your listener class and inside your onEnable()
method add a new line with the following:
getServer().getPluginManager().registerEvents(new YourListenerName(), this);
That’s all there is to creating a listener. More events can be found on the Spigot API documentation
Compiling your Plugin
Now that we’ve finished, press the run button and it should compile your plugin and put the .jar file for you to download in src/target
.
If the build fails and throws an error, either check my working repl project repl.it/@agent9002/Tutorial-Plugin and see what you’ve done differently. Or, if you’re too confused then feel free to contact me.
Need Tech Support?
If you need any assistance feel free to leave a reply or join my Discord server discord.gg/zfgVqZv
its not working for me
Could you give a bit more detail please? @gentechnolgy
Great tutorial! But how do I get my plugin into Minecraft??
Drag and drop the compiled jarfile into the "plugins" folder @CarlosRosiles
for the commands folder, do we create files actually called YourCommandName.java, or do we call it something else. Also, i tried to name it /help or something, and you cannot have a file with / in the name. ty btw for all of the help
You can name it Help.java
or whatever you'd like as long as it's written with ASCII symbols, and no worries feel free to ask me whatever you'd like. @CoolBro4811
No problem ;3 @CoolBro4811
heyyyyyyyyyy how do you find the two ID folders. i got nothing. stuff keeps saying GO TO ARTIFACTID or smthn i dont have anything like that. :CCCCCCCCCCCCCCCCC
its the 2 values you configured when setting up maven @CoolBro4811
@AstOwOlfo wtf is maven can i get a screenshot lol
@AstOwOlfo ooh im stupid i named the groupID and artifactID
wow im so dumb xD ty for the help
where is the project root folder? im not sure xD this like my 3rd time with java not including lessons
@CoolBro4811 wait u can ping urself xDDDDDDDDDDDDDD
@CoolBro4811 also just noticed @AstOwOlfo that in ur profile thingy when u hover over ur name it doesnt say u code java
HMMMMMMM
@CoolBro4811 Nvm i figured it out from looking at urs
doesnt show java cause repl hates me @CoolBro4811
I have no idea how this works. Hover on my username. So to make it actually working minecraft, you would need some way to show the results right?
To make it actually have effects, you would need some way to show the results, right? And about "I have no idea how this works.Hover on my username", look at who I am and what I code with. @agent9002
You can use getLogger#info
or a standard System.out.println();
to debug in console @anonymous360c
this is sick!
Cheers mate, I appreciate it. Hope it helps you out ;) @ChezCoder
Can you help me? When I enter the first two lines and run it, this is what it says:
javac -classpath .:/run_dir/junit-4.12.jar:target/dependency/
- -d . Main.java
Main.java:1: error: class, interface or enum expected
rm *
^
1 error
compiler exit status 1
I do not know why. makes me think they know what I'm doing. I'm also new here.
dont run it in console, run it in "shell" @LeviSikes
@agent9002 could you tell me how to find it in "shell"?
@agent9002 , I hope you have a lot of patience. I do not have that, I think.
@LeviSikes I mean the Shell tab
@LeviSikes I mean the shell tab
in that case, create a bash repl and do it inside there @LeviSikes
@agent9002 can you show me how?
oh wait what, no i misread your question. if you read my tutorial it explains this, you need to create a .replit file and put the details i wrote @LeviSikes
How do I go about adding the libraries I want to the repl?
add them to your maven dependencies in the pom.xml file @Ricky_J_Aquino
Having an issue where I am unable to run it. I went through the tutorial but I seem to be missing something.
https://repl.it/@Ricky_J_Aquino/plugin#factionfocus/
did you create the .replit file like I wrote in the tutorial? @Ricky_J_Aquino
Yeah, it's there.
@agent9002
EDIT: I just realized I didn't have it in the root, that's my bad.
alright perfect, im glad thats sorted @Ricky_J_Aquino
create a new bash repl instead of a java repl and it should work @Ricky_J_Aquino
Ok, will try that.
@agent9002
EDIT: It worked, thanks.
no problem, have fun @Ricky_J_Aquino
wait this includes spigot and BUKKIT? (intense confusion)
spigot is a fork of bukkit, so yeah. @Benramin
Me and my friend are making are own server and this really helped!
btw, this is java right? or am I just stupid.
glad to hear it! hope your server goes well.
yes, this is java ;D @Benramin
itz no problem @agent9002
Oh yeah minecraft, forgot about that game. Haven't played since 2012. I guess I outgrew it.
not a bad idea to get back into it, hypixel has peaked and the community is more alive than ever. @Wuru
Don't have the time. I have my own custom operating system to program and manage. @agent9002
(That one kid waiting for pocket edition)
me playing minecraft java: "yes! netherite!" i fall score:0
😡 😡 😡 😡 😡 😡 RAAAAAGGGGGGEEE!!!!!
very sad, no way to prevent this :( @Leroy01010
lol :( @agent9002
Did this really take years? If it did wow.
Oh no, what I meant by that was that there wasn't really a plugin dev community on here or any tutorials relating to it. @AbhayBhat
@agent9002, oh ok.
Sorry to disappoint lmao @AbhayBhat
@agent9002, love this tutorial by the way... I feel like ur really godly at java and can get a job soon..
aww thank u so much, really appreciate it. i'm honestly nothing special, started java ~a month ago. i saw your java tutorial series and liked it a lot, ur kind of my hero lol. @AbhayBhat
@agent9002, WAHT THE ****, but, ur better than me... How else would you know what maen and this cool stuff is...
well idk about better, u've clearly got much more experience. i guess i just practiced a bunch. java is also really nice to work with soooo ;P @AbhayBhat
btw u got discord? @AbhayBhat
@agent9002, no but i might lol. My dad wudnt let me. But i showed him how all my frens got discord, so he said he might let me. Ill make sure to tell u if I do get it :)
ight sounds lit ;D @AbhayBhat
I edited it
oh nice gg @AbhayBhat
@AbhayBhat (You do realize that everyone can see your username and tag)
@Muffinlavania, idrc, ill just edit it
WARNING: All illegal access operations will be denied in a future release
what does this mean :o
oh ok
sorry bout that! @FluidGaming
I want to make a game for my institution
I’m not really a python developer so you’re probably better off asking someone who has experience making games with py. @FluidGaming
Yo @agent9002 would you mind helping me to make a game for institution using python???
Sorry, could you explain that a bit clearer for me? What exactly is this project? @FluidGaming
WOW! But nxt time can u make a python plugin
Bro, python would be WAY too slow. @FluidGaming
Java is the industry standard for Minecraft plugins, if you have any interest in doing them then I recommend you just learn Java because attempting to do it in Python is not only going to result in a plugin with worse performance but it’s also going to be a lot harder to make since you’ll be going in blind. If you can find a good plugin API for Python though, I wouldn’t mind helping you. @FluidGaming
@FluidGaming Explain again how Python would work in Minecraft?
It would work. There's cores for c++ and js. Unlike the client, you can use server cores with diff langs. @AtriDey
@agent9002 I dissagree. Despite it being one of the easiest and most popular languages in the world, it is still too slow, as it does not use a compiler and it being dynamically typed. There is a reason the original version of Minecraft is not written in Java. I mean, if he made a C# or C++ plugin, then it would be at a good speed.
Definitely not, the server also has to use a client based in Java. So if you're writing this in C#/C++ it would have to translate the Java code to C#/C++ and vice versa which is just going to be slow. This is why projects that attempt to do this with different languages typically fail to support a large amount of players and lack a large number of the in-game events. Good speed isn't something that would be achieved here. With efficient coding constructs you shouldn't run into any issues with speed with MC Plugin Development. @viraatvv
@agent9002 Not really. Java programmers can easily switch to C# and C++.
What are you on about? The actual server client from Mojang is written in Java, it's not a matter of plugin developers being incompetent, the actual client is based on Java. Think of it as asking a mod developer to rewrite the entire base game of Minecraft in C#/++ with Java server compatibility. And even then, there's already so many existing frameworks and libraries made in Java for CraftBukkit and it's forks, it would just be too much of a hassle. It's not an "easy switch". @viraatvv
cool post ;)
thanks @lilykhan :3
waiting for bedrock edition.
haha maybe @TheForArkLD
I actually made something similar to a mod a few months ago for bedrock, i might make a post lol
addons i’m guessing? @ironblockhd
No, i made a post about it now
@TheForArkLD Wait, you can mod that thing? Do you have to pay those Minecoin things or something?
Minecoins are for the addons/cosmetics on the marketplace. Self-made plugins/mods/skins/etc. are free @AtriDey
Nice!
Thank you for comment! Hope this was helpful. @HahaYes
@agent9002 maybe amasad will like this. He really likes these posts
:o pog @HahaYes
@HahaYes, Yeah, but I am to scared to @ him lol. I don't wanna get in trouble
look on his twitter, he has like 200 notifications i don't think you will get into trouble lol
@ironblockhd well I guess it would be rude not to invite the main man @amasad
@agent9002 duuuude this is sick! @Scoder12 can we load the plugin into your minecraft server?
It would be huge if you can code and run the plugin all on repl.it
@amasad if you're talking about his recent post on repl share then that would definitely work as it uses PaperMC as it's jarfile (good choice @Scoder12 ;3). The problem though, is that it's running on a 1.16.1 version (the poor performance version), but with server config optimisations this could turn out real nicely.
@agent9002 I'd be happy to include any changes you have in mind, I'm don't know anything about server optimization. I would appreciate if you could help integrate my server setup with your plugin tutorial!
Sounds great, i’ll contact you on Discord about this. @Scoder12
@agent9002 lol why are you commenting on my section of the wall.
@HahaYes Same cycles AGAIN. EDIT: I lost one.
@CodeLongAndPros WHAT AGAIN
@CodeLongAndPros T SERIES VS PEWDIEPIE ALL OVER AGAIN
@HahaYes Oh no.
What the heck is going on and why are you talking about pewdipie @everyoneherewhohascommentedontheoriginalcomment