12 min read

 In this article by Cody M. Sommer, the author of the book, Building Minecraft Server Modifications – Second Edition, we will be introduced to the Bukkit API and learn what it allows you to accomplish through programming plugins for a Spigot server. By the end of the article, you will most likely have numerous ideas for plugins that you will eventually be able to create yourself. This article will cover the following topics in detail:

  • Understanding the purpose of an API
  • Finding the documentation of the Bukkit API
  • Navigating through JavaDocs to find specific information
  • Reading and understanding the documentation
  • Exploring and learning the aspects of the Bukkit API

(For more resources related to this topic, see here.)

Introduction to APIs

API is an acronym for Application Programming Interface. An API helps control how various software components are used. Spigot includes the Minecraft code in a form that is easy for developers to utilize when creating plugins. Spigot has a lot of code that we need not access in order to create plugins. It also includes code that we should not tamper with, as it may cause the server to become unstable. Bukkit provides us with the interfaces that we can use to properly modify the game while restricting access to other portions of the code. An interface is essentially a shell of a class. It includes methods, but the methods are empty. The Spigot server contains classes for each interface. The classes implement the interfaces and fill each method with the appropriate code.

To explain this better, let’s imagine the Bukkit API as a menu to a pizza shop. The menu contains different types of pizza, such as pepperoni, Hawaiian, and meat lovers. These menu items represent the interfaces within the API, with each interface having a method named makePizza(). At this point, these pizzas cannot be eaten, because they are merely a concept. They are just items on a menu. But let’s say that a pizza shop named All You Need is Pizza decides to open up and they use this menu, or API. This pizza shop can represent CraftBukkit. The pizza shop creates recipes for each item on the menu. This is equivalent to writing code for each makePizza() method within the three interfaces. Thus, these recipes are the classes that implement the interfaces. However, these classes are still just a concept. It is not until the makePizza() method is called that you have an instance of that class. This instance, or object, will be the tangible pizza that you can actually eat. Now, imagine that there is another pizza shop named Crazy Little Thing Called Pizza, which opens across the street from All You Need is Pizza. This new pizza shop will represent Spigot. Crazy Little Thing Called Pizza uses the exact same menu, or API, as All You Need is Pizza. However, its recipes, or implementations of the methods, may be different.

Using this same analogy, we can see the benefit of the API. As a customer, I can take a look at the menu and assemble an order. For example, I want to order a pepperoni pizza and a meat lovers pizza. Since I created my order based on the menu and both pizza shops implemented the same menu, either restaurant is able to fulfill my order. Likewise, a developer creates a plugin based on the Bukkit API. Both CraftBukkit and Spigot utilize the Bukkit API. Therefore, they will both support the plugin. The following diagram explains this relation between pizza and code:

Basically, Bukkit acts as a bridge between a plugin and the Spigot server. The Spigot team adds new classes, methods, and so on to the API as new features develop in Minecraft, but the preexisting code rarely changes. This ensures that Bukkit plugins will still function correctly months, or even years, from now even though new versions of Minecraft/Spigot are released. For example, if Minecraft were to change how an entity’s health is handled, we will not see any difference.

The Spigot jar will account for this change by filling the getHeath method with the updated code. Then, when the plugin calls the getHealth method, it will function exactly as it had before the update. The addition of new Minecraft features, such as new items, is another example of how great the Bukkit API is. Let’s say that we’ve created a plugin that gives food an expiration date. To check whether an item is food, we’ll use the isEdible method. Minecraft continues to create new items. If one of these new items is Pumpkin Bread, Spigot will flag that type of item as edible and will therefore be given an expiration date by our plugin. A year from now, new food items will still be given expiration dates without us needing to change any of our code.

The Bukkit API documentation

Documentation of the Bukkit API can be found at hub.spigotmc.org/javadocs/bukkit/. The Spigot API is a superset of the Bukkit API, which means that it contains all the classes, interfaces, and so on that are present in the Bukkit API as well as some additional classes that are unique to the Spigot project. If you want your plugin to support Spigot and CraftBukkit servers, then you will want to develop by using the Bukkit API. If you choose to only support Spigot servers, then you can develop against the Spigot API. However, using the Spigot API will yield the same results.

Navigating through the Bukkit API documentation

We can go through the Bukkit API documentation to get a general idea of what we can modify on a Spigot server. Server-side plugins are different from client-side mods in that we are limited with what we are able to modify in the game using server-side plugins. For example, we cannot create a new type of block, but we can make lava blocks rain from the sky. We cannot make zombies look and sound like dinosaurs, but we can put a zombie on a leash, change its name to Fido, and have it not burn in the daylight. For the most part, you cannot change the visual aspect of the game, but you can change how it functions. This ensures that everyone who connects to the server with a standard Minecraft client will have the same experience.

For some more examples on what we can do, let’s have a look at the various pages of the API’s documentation:

You will see that the classes and interfaces within the API are selectable in the lower left section of the JavaDocs. Selecting a package in the upper left narrows the choices in the section below it. Each type, such as a class or interface, is organized into a package. These packages help group similar classes together. For example, Cow, Player, and Zombie are all types of entities and thus can be found in the org.bukkit.entity package. So, if I were to say that the World interface can be found at org.bukkit.World, then you will know that you can find World within the org.bukkit package. Knowing this will help you find the classes or interfaces that you are looking for. You can always use Ctrl + F to search for a specific word on the webpage. This can help in finding a specific class in a long list.

Let’s look at the World class and see what it has to offer. The classes are listed in the alphabetical order. So, we will find World near the end of the list within the org.bukkit package. When you click on the World class link, all of its methods will be displayed in the main column of the site under the Method Summary header, as shown in the following screenshot:

A World object is an entire world on your server. By default, a Minecraft server has multiple worlds, including the main world, nether world, and end world. Spigot even allows you to add additional worlds. The methods that are listed in the World class can be applied to the specific world object. For example, the Bukkit.getWorlds method will give you a list of all the worlds that are on the server; each one is unique. Therefore, if you call the getName method on the first world, it may return world while calling the same method on the second world may return world_nether.

Understanding the Java documentation

Let’s look at a method that is included in the World class to see what information it provides us. Click on the link to view the createExplosion(Location loc, float power, boolean setFire) method. You will be brought to the method description that is similar to the one shown in the following screenshot:

The screenshot explains each parameter and the return value for the method. This method requires that we pass three parameters to it, which is explained as follows:

  • Where the explosion should take place
  • How powerful the explosion should be
  • Whether the explosion should cause the surrounding blocks to ignite in flames

If the returned value is void, then the method will not send any information back to us. In this example, the method returns a boolean value. On reading the documentation, you will learn that the returned value is whether or not the explosion actually occurred. If another plugin prevented the explosion from happening, then the createExplosion method will return false.

Exploring the Bukkit API

Now that you are familiar with the Bukkit API documentation, I advise you to look through it on your own. You will find interesting methods; many of these methods will spark ideas for cool plugins that you may want to make. Note that there may be additional links to view more methods for an object. For example, a Player is a type of LivingEntity. Therefore, you can call a LivingEntity method on a Player object. This inheritance is shown after the method summary, as shown in the following screenshot:

If you are ever going to try and think up an idea for a plugin, browsing through the API documentation will surely give you some ideas. I suggest reading the class pages, listed as follows, as they will be the classes that you will frequently use in your future plugins:

Class

Package

Description

World

org.bukkit

A world on the server

Player

org.bukkit.entity

A person who is playing on the server

Entity

org.bukkit.entity

A player, mob, item, projectile, vehicle, and so on

Block

org.bukkit.block

A specific block in the world, such as a dirt block or a chest

Inventory

org.bukkit.inventory

The inventory of a player, chest, furnace, and so on

ItemStack

org.bukkit.inventory

An item that is in an inventory, which includes how many items are present

Location

org.bukkit

The location of an entity or a block

Material

org.bukkit

The type of a block or item, such as DIRT, STONE, or DIAMOND_SWORD.

Bukkit

org.bukkit

Contains many useful methods that can be called from anywhere in your code

Now that you understand how to read the Bukkit Java documentation, you can find answers to various questions that you may have. For example, what if you want to find out which methods you would call to get the Block that is at x:20 y:64 z:14 in the world that is named “world”?

First, you will need to retrieve the correct World object. The initial place that you may check is the Bukkit class, as listed in the previous table. You may check there because you can call these methods from anywhere in your code. Another option is to view the uses of the World class. This can be done by clicking on the Use link at the top of the World page. There, you can see all the methods that return a World object as well as methods that accept a World object as a parameter. To aid in searching through a page, remember that you can use Ctrl + F. Searching for name will lead you to the Bukkit.getWorld method, which takes the name of the world as a parameter and returns the actual World object.

Once you have the World object, you will want to find a method that will give you the Block at a specific location. You could navigate to the World page and use Ctrl + F to search for block, location, x, y, or z. If none of these help you find a useful method, then you can always view the uses of Block in a way that is similar to how we viewed the uses of World. Either way, you will find the World.getBlockAt method, which can be called on the World object that you discovered in the previous step.

The following are a few additional challenges to guide you while exploring the Bukkit API on your own and becoming familiar with it:

  • Which method will you call to check what time it is in a world?
  • Which methods will you call to send a message to the player whose name is Steve?
  • Which methods will you call to check whether the material of a block is flammable?
  • Which method will you call to check whether a player has diamonds in their inventory?
  • Which methods will you call to check whether a player is holding an item that is edible?

Summary

If you have any trouble figuring out any of the problems mentioned in the challenges or with any other portion of the Bukkit API, the following are a few of the many places where you can ask for help:

  • The Spigot forums (www.spigotmc.org/forums)
  • The official IRC channel for Spigot (www.spigotmc.org/pages/irc)
  • The Minecraft forums (www.minecraftforum.net)

You can also contact me directly or visit my website at www.codisimus.com. I am always interested in helping out a fellow developer.

You now have the knowledge required to begin programming your own Bukkit plugins. As we did in this article, we will have to refer to the documentation to find the required information. Being able to navigate and understand the API documentation will speed up the process of coding. If you are ever unsure of a section of the API, you now know how to find the information that you need.

Resources for Article:


Further resources on this subject:



Subscribe to the weekly Packt Hub newsletter. We'll send you the results of our AI Now Survey, featuring data and insights from across the tech landscape.

* indicates required

LEAVE A REPLY

Please enter your comment!
Please enter your name here