Introduction

This is the official documentation of OQ.MineBot [www.minecraftbot.com] plugin API.

Creating Project

1. Firstly you must create a new Class Library (.NET Framework):

Make sure you create a .NET Framework project, as .NET Standard (.NET Core) will not work.

2. It is recommended to change your Output path to your bot's plugin folder, so that you can immediately compile it and run the plugin:

3. After you coded your plugin and you are ready to test, you must build the plugin: (You must Reload your plugin tab after each build, in order to use the latest build version)

Installation

You can set-up the plugin API in a few different ways, however some are considered better practices and others are easier. There are 3 different methods listed below, ranked by best practice.

Watch our environment setup tutorial here.

  1. NuGet package

    1. Open NuGet package manager

    2. Install the OQ.MineBot.PluginBase package

    (When a bot update is released you must go into the package manager, select the OQ.MineBot.PluginBase package and click the Update button)

  2. Github clone

    1. Clone the MineBot API (https://github.com/OnlyQubes/OQ.MineBot.PluginBase.git) into a local folder.

    2. Add cloned project into your solution.

    3. Reference it in your plugin project.

    (When a bot update is released you must update the local repository with "git pull")

  3. Dll

    1. Download the latest dll from Github.

    2. Reference it in your plugin project.

    (When a bot update is released you must redownload the dll file and re-add the reference to the new one)

File Structure

Plugins are made up of two types of classes: IStartPlugin and ITask. A plugin must have one IStartPlugin class, which is generally named PluginCore, and can have many Task classes. Below you will find the explanation and purpose of each type. It is good practice to store the tasks in a separate folder like this:

PluginCore

The PluginCore class generally inherits from IStartPlugin and contains base plugin functions, such as OnLoad, OnEnable, OnDisable, OnStart, and OnStop. This class will also have the Plugin attribute, which will define the name, description, and version of the plugin.

The Plugin attribute defines the name, description, and version of the plugin. All plugins need to have this in order to be loaded. The attribute can be applied to the class in the following way:

[Plugin(1, "Example Plugin", "This is the description of the plugin.")]
public class PluginCore : IStartPlugin { /* PluginCore.cs code would go here */ }

The OnLoad method is called once the plugin is loaded/reloaded, which is usually when the bot is started. The method can optionally register the plugin's settings in the following way: (You can find a list of the setting types here)

public override void OnLoad(int version, int subversion, int buildversion) {
this.Setting.Add(new BoolSetting("Boolean setting", "Description goes here.", true));
this.Setting.Add(new StringSetting("String setting", "Description goes here.", "this is the default value"));
this.Setting.Add(new NumberSetting("Number setting", "Description goes here.", 10, 0, 20));
}

The OnStart method is called when the plugin is started on a bot (and will be called for each bot). It is usually used to register task classes, which are explained below. Generally the settings are passed into the tasks from this method through the task constructor (can be seen below in line 3). Tasks can be registered in the following way:

public override void OnStart() {
RegisterTask(new MyTask());
RegisterTask(new MyOtherTask(this.Setting.GetValue<string>("This is a number setting")));
}

Task

Task classes must inherit from ITask, which will require you to implement bool Exec(). The returned boolean will determine whether any of the listeners (explained below) will execute or not, where true will execute the appropriate listener and false will not execute it. Example:

public class MyTask : ITask, ITickListener {
public override bool Exec() {
// return true; // would always execute listeners when appropriate.
// return false; // would never execute listeners.
return !Context.Player.State.Eating; // only execute if not currently eating.
}
public async Task OnTick() {
// Code in here will be called each tick while the player is not eating.
// If the player is eating then this code will be skipped until it is done.
}
}

Task classes have access to the Context variables, these variable refer to the current bot and allow you to interact with the bot or it's environment. Context variables are: Context, State, World, Inventory, Actions (legacy), where Context is the main/parent class that allows you to access everything regarding this bot and the other variables are shortcuts to those variables.

You can then also optionally override async Task Start() and/or async Task Stop(). Start gets called after the Context (this.Context, this.Player, This.Inventory, etc) is initialized. Stop gets called when the plugin is stop for this (or all) bot(s).

Tasks can inherit from Listener classes (you can find all listener types here), which will hook the appropriate calls and will get executed if the Exec function returns true. The following code showcases the ITickListener, which is generally the most used listener:

public class MyTask : ITask, ITickListener {
public override bool Exec() {
// Execute listeners only if the player is dead.
return Context.Player.IsDead();
}
public async Task OnTick() {
// This will be executed for every tick that the player is dead (Exec returns true).
await Context.Player.Respawn();
}
}

The main idea behind tasks is that they allow you to separate complex tasks/jobs into different classes, which only run when needed.

Async Programming

...