Skip to content

Introduction#

BentoBox relies on Addons to provide new features or new Gamemodes. This tutorial will guide you through the process of creating your first addon.

Creating an Addon is often easier and quicker than creating a addon from scratch, because BentoBox provides wrappers and key API features. Addons also have direct access to the other addons' API, unlike plugins, due to the visibility principle of Java Classloaders. Moreover, they have access to BentoBox's Config API and Database API.

In order to comfortably follow this tutorial, you should have previous experience in addon development. The addon development process is indeed very similar to the latter, and we will consider throughout this tutorial that you understand the key Java concepts, for the sake of concision.

Prepare the project#

Using the pre-made Addon template#

The template currently does not exist.

Manually creating the project#

Import BentoBox as a dependency#

BentoBox holds all the API you will need to create and register your addon. Therefore, you should add it as a dependency of your project.

BentoBox uses Maven and our Maven repository is kindly provided by CodeMC. However, you can also use Gradle to grab BentoBox.

Maven#

Add the following to your pom.xml file.

<repositories>
  <repository>
    <id>codemc-repo</id>
    <url>https://repo.codemc.org/repository/maven-public/</url>
  </repository>
</repositories>

<dependencies>
  <dependency>
    <groupId>world.bentobox</groupId>
    <artifactId>bentobox</artifactId>
    <version>PUT-VERSION-HERE</version>
    <scope>provided</scope>
  </dependency>
</dependencies>

Gradle#

Add the following to your build.gradle file.

repositories {
  maven { url "https://repo.codemc.org/repository/maven-public/" }
}

dependencies {
  compileOnly 'world.bentobox:bentobox:PUT-VERSION-HERE'
}

If you have any issues, please have a look at Gradle's documentation about declaring dependencies.

Setup the project architecture#

Create the main Addon class#

The main class of an Addon works similarly as to one of a addon. It most notably handles the code that runs when laoding, enabling, reloading and disabling the addon.

The main class extends Addon.

Example:

import world.bentobox.bentobox.api.addons.Addon;

public class MyAddon extends Addon {

}

Tip

When naming your main class, consider the following: We recommend you to keep its name as close to the addon's name as possible. You can also append "Addon" to the class name to further disambiguate its purpose.

Genuine examples: Greenhouses, Chat, Biomes.

Mandatory methods#

Like Bukkit plugins, Addons must override a few methods in order to be properly enabled.

As such, your main Addon class should look like the following:

import world.bentobox.bentobox.api.addons.Addon;

public class MyAddon extends Addon {
    @Override
    public void onEnable() {}

    @Override
    public void onDisable() {}
}

onEnable()#

This method is called after #onLoad().

onDisable()#

This method is called when the Addon is being disabled, which usually occurs when the server is being shutdown.

Optional methods#

Additional methods can be overridden if needs be.

import world.bentobox.bentobox.api.addons.Addon;

public class MyAddon extends Addon {
    @Override
    public void onLoad() {}

    @Override
    public void onEnable() {}

    @Override
    public void onReload() {}

    @Override
    public void onDisable() {}
}

onLoad()#

The code in the onLoad() method is run when the Addon is loaded and before onEnable(). It is a good place to load configs and set up commands if this addon is a game mode:

    @Override
    public void onLoad() {
        // Save the default config from config.yml
        saveDefaultConfig();
        // Load settings from config.yml. This will check if there are any issues with it too.
        loadSettings();
        // Register game mode commands
        playerCommand = new DefaultPlayerCommand(this)

        {
            @Override
            public void setup()
            {
                super.setup();
                new IslandAboutCommand(this);
            }
        };
        adminCommand = new DefaultAdminCommand(this) {};
    }

onReload()#

The code in this method is run when (or if) the admin reloads Addons using the bbox reload command.

Create the addon.yml#

The addon.yml is required to describe your addon to BentoBox. It is almost identical to plugin.yml used by Bukkit. Here is a minimal example:

name: Bank
main: world.bentobox.bank.Bank
version: 1.0.0
api-version: 1.15.4
authors: tastybento
The above tags are mandatory and must be included in every addon.yml.

addon.yml Attributes
Attribute Required Description Example Notes
name yes The name of your addon. name: MyAddon
  • Alphanumeric characters and underscores (a-z,A-Z,0-9, _)
  • Used to determine the name of the addon's data folder. Data folders are placed in the ./addons/ directory by default.
  • It is good practice to name your jar the same as this, for example 'Bank.jar'
version yes The version of this addon. version: 1.3.1
  • Version is an arbitrary string, however the most common format is MajorRelease.MinorRelease.Build (eg: 1.4.1).
  • Typically you will increment this every time you release a new feature or bug fix.
  • Displayed when a user types /bbox version
description no Person friendly description of the functionality your addon provides. description: This addon is so boxy.
  • The description can have multiple lines.
  • Displayed when a user types /version addonName
authors yes Allows you to list one or multiple authors, if it is a collaborative project. If you list more than one then use a YAML string list format. This is actually a mandatory item. authors: - BONNe - tastybento
or
authors: tastybento
  • You can list one author or multiple authors.
main yes Points to the class that extends Addon or Pladdon main: world.bentobox.acidisland.AcidIsland
  • Note that this must contain the full namespace including the class file itself.
  • If your namespace is world.bentobox.addon , and your class file is called Myaddon then this must be world.bentobox.addon.Myaddon
depend no A list of addons that your addon requires to load. depend: Oneaddon, Anotheraddon
  • The value is comma delimited
  • Use the "name" attribute of the required addon in order to specify the dependency.
  • If any addon listed here is not found your addon will fail to load.
  • If multiple addons list each other as a depend, so that there are no addons without an unloadable dependency, all will fail to load.
softdepend no A list of addons that your addon may require but are not mandatory. softdepend: AcidIsland, BSkyBlock, SkyGrid, CaveBock, AOneBlock
  • The value is comma delimited.
  • Use the "name" attribute of the desired addon in order to specify the dependancy.
  • Your addon will load after any plugins listed here.
  • Circular soft dependencies are loaded arbitrarily.
permissions no Permissions that the addon wishes to register. Each node represents a permission to register. Each permission can have additional attributes.
permissions:    
  '[gamemode].intopten':
    description: Player is in the top ten.
    default: true
  '[gamemode].island.level':
    description: Player can use level command
    default: true
  '[gamemode].island.top':
    description: Player can use top ten command
    default: true
  • Permission registration is optional, can also be done from code
  • Permission registration allows you to set descriptions, defaults, and child parent relationships
  • Permission names can include the [gamemode] tag to enable the permission to apply to all the loaded game modes on the server.

Pladdons#

Pladdons are a combination of a Bukkit Plugin and Addon. The main benefit of a Pladdon is that it is loaded with the Bukkit Server class loader and so data within it can be accessed directly by Plugins. If you are writing a utility Addon, for example, a Level addon, then other Plugin writers may want to access the data it generates in code via an API. The simplest way to do this is to make a Pladdon and they can call methods in your code directly. If you do not want plugins to access data in your addon, then keep it as an Addon.

Making the Addon a Pladdon#

To do this, make a class with the recommended name of MyAddonPladdon.java, where MyAddon is the same name as your Addon and extend Pladdon. Instead of creating a plugin.yml the components are declared using Annotations. The annotations should be as below. The ApiVersion may be updated to the latest server version if you require it.

@Plugin(name="Pladdon", version="1.0")
@ApiVersion(ApiVersion.Target.v1_16)
@Dependency(value = "BentoBox")
public class LevelPladdon extends Pladdon {
    @Override
    public Addon getAddon() {
        return new Level();
    }
}

The only method that should be defined is the getAddon() method that must return an instance of your Addon.

Once this is done, the Addon will be loaded just like a plugin and will be able to be accessed via other plugins.


Last update: January 2, 2023 18:57:44