Enderbow: An easy first plugin

May 2, 2020
Enderbow: An easy first plugin
  • Introduction
    This guide is aimed at people who are just starting to learn the Bukkit/Spigot API and will attempt to guide them on best practices and learning how plugins work.
    It is primarily for people who already have a basic understanding of Java, if you are reading this without first learning the basics of Java, please first check out some tutorials on that.
    This guide also assumes that all readers are familiar with setting up their dependencies with a build tool or manually by updating the build path.
    If you already have an advanced or intermediate understanding of Java than this guide may be a little slow for you, however it should help to introduce you to plugin development.
    After the guide is reviewed on the forums, I intend to put it on the Wiki under PluginSnippets.
    The format is relatively simple, each section will be summarized briefly, then I will include the code which is fully commented. I would suggest that all readers challenge themselves by reading the code and comments, then attempt to recreate it and customize or change certain aspects. This will help to reinforce your understanding and ensure that you have not misinterpreted what is happening in the code.
    Github repository can be found here.

    Main (The class extending JavaPlugin)
    The main class in your plugin is where everything starts. You can think of it as the heart of your plugin. In this class we want to register any event listeners and take any actions that are required upon starting or stopping your plugin. In the case of this plugin we are going to create our internal Config object for storing variables that server owners can set, create a Logger object for logging important messages to the console, as well as a static instance of our plugin.
    You'll notice at first that several parts are underlined in red when you first create this, that is because we haven't yet created the other classes!
    Note: People are often concerned with statically accessing the plugin instance, please check this thread for more information
    Please visit this Github page to see the code

    This class will contain all of our utility methods. The purpose of this is to make all of these methods easily accessible from anywhere in our code and to improve readability and reuseability. We have declared the entire class as final so that we don't have to worry about anyone extending this class by accident.All methods and constant fields in this class are designed to be accessible anywhere and do not require an instance to function.
    Please visit this Github page to see the code

    Creating an internal config class is essential for efficient clean code. We will use this class to store all variables that can be set from the config.yml. The basic concept is that instead of constantly reading from the file, we read it once upon loading the plugin and then store the values. This is a more efficient method because reading from/writing to files is generally the slowest operation for a computer. Therefore we only read from the file on start up or when requested to by a player using the command to reload the config. We also include a method to save the internal config object and write to file, however we won't be using it in this plugin so its main use would be for other plugins that might access ours.
    I've also included the config.yml file that will be created by default so you can see how it is formatted.
    Please see these javadocs for more information on FileConfiguration and ConfigurationSection
    Note: We are currently storing all messages in the main config.yml, however it may be best to have a separate language file or implement a proper Localization pattern.
    Please visit this Github page to see the code

    Please visit this Github page to see the config.yml

    It is best practice to have each command in its own class implementing CommandExecutor. Each time that a player uses the enderbow command, the onCommand() method is activated. Therefore we will go through various steps to check that the CommandSender has permission to execute the command, as well as ensure that the end result can be run for this sender. We will also check if the sender has entered additional arguments and handle those cases.
    Please visit this Github page to see the code

    This is where the "magic" happens, in this class we will actually be shooting an ender pearl whenever the player shoots the bow we created in our createEnderBow() util method. This type of class implements Listener and therefore will "listen" for when an event is called then will run the code that we have specified. In this case we will first be checking if another plugin has cancelled the event, then go through and shoot the ender pearl if all conditions are met.
    Please visit this Github page to see the code

    Now that we have added all of the code required, the last step is to include a plugin.yml file in the root of the directory. This file will be accessed by the server when loading the plugin and will register our command as well as setup some basic information required for plugins.
    For a complete in depth on the plugin.yml, please see this wiki page.
    Please visit this Github page to see the plugin.yml

    Now the only thing left to do is compile the plugin and try it out!
    Please let me know what you thought of the tutorial or if you have any concerns.
    If you have a better way of doing something or want to point out any errors please feel free to do so in the comments below so I can update it.
    The plugin itself can be downloaded from here if anyone is just interested in the plugin itself.

    Original thread can be found here.
  • Loading...
  • Loading...