Creating a Multibot Module

This tutorial will guide you through the steps of making basic Multibot module. Multibot is the goto bot for zone staff members that host events. This is because it has a variety of modules and utilities that make it easier to host events. Utilities are tools that can be used in several different situations in tandem with each other whereas modules are typically full games that you would generally only load one at a time. Some examples of Multibot modules are hunt, zombies, and trivia.

Requirements

First, let's create a directory for our new module. For example, we'll create a directory called test under src/twcore/bots/multibot where the rest of the modules are. Inside of that directory we need to make a test.java file. The filename should be consistent with the name of the directory. Let's also create a test.cfg file in this directory, we'll discuss why later. One the first line of our test.java file we can declare our newly made package.

A Multibot module class extends the MultiModule class, so we will need to import that class. The MultiModule class also has several abstract functions which the module must implement. These include init(), cancel(), isUnloadable(), getModHelpMessage(), and requestEvents(ModuleEventRequester eventRequester). Because the requestEvents() function uses the ModuleEventRequester class we must also import it.


package twcore.bots.multibot.test;

import twcore.bots.MultiModule;
import twcore.core.util.ModuleEventRequester;

public class test extend MultiModule {

    public void init() {

    }

    public String[] getModHelpMesage() {
        return null;
    }

    public void requestEvents(ModuleEventRequester events) {

    }

    public boolean isUnloadable() {
        return true;
    }

    public void cancel() {

    }

}

The init() function is called when the module is loaded. getModHelpMessage() returns a String[] of help commands that will be displayed when help for the module is requested. The isUnloadable() function determines whether or not the module can presently be unloaded. Generally, this will be true since if a staff member is trying to unload the module they likely no what they are doing. The cancel() function is called when the module is unloaded.

Event Handling

Continuum consists of a large number of event packets. Every time a player moves, fires, grabs a flag, sends a message, or does a number of other actions, a packet is sent from the client to the server and then sent down to all the other clients. For a bot to be able to function in Continuum it must be able to create and interpret these packets. The requestEvents() function uses the passed parameter to designate that the module will listen for particular events. The most important and arguably mandatory event is the message event, which is automatically requested. Other events need to be specifically requested for modules with ModuleEventRequester's request() function.

For example:

    public void requestEvents(ModuleEventRequester events) {
    events.request(this, EventRequester.PLAYER_DEATH);
        events.request(this, EventRequester.PLAYER_LEFT);
        events.request(this, EventRequester.FREQUENCY_SHIP_CHANGE);
        events.request(this, EventRequester.PLAYER_ENTERED);
    }

Events are then handled by the appropriately named handleEvent() function. This function takes the paramater of the event type that it handles. The handleEvent(Message event) should look fairly similar for most modules. It will be triggered every time the bot receives a message packet. When a message is retrieved, it's important to figure out what the message is and who sent it. You also want to know what type of message it is. In Continuum there are several different types of messages including public messages, private messages, zone messages, arena messages, and so on. You also may want your module to have some commands, so you should check to see if the message is one of those commands.


    public void handleEvent(Message event) {
        String message = event.getMessage(); // Gets event message
        //This line may be ugly, but it's important. Sometimes (for some reason), Message packets with an 
        //ID but no messager are sent. This makes sure that doesn't cause problems
        String name = event.getMessager() == null ? m_botAction.getPlayerName(event.getPlayerID()) : event.getMessager();

        //If the message is a private message then check and see if it's a bot command.
        if (event.getMessageType() == Message.PRIVATE_MESSAGE)
                handleCommands(name, message);
    }

    public void handleCommands(String name, String msg) {
        msg = msg.toLowerCase(); //Fix case sensitivity

        //If the message starts with !mycommand then send whatever follows my command to a custom function
        if(msg.startsWith("!mycommand "))
             runMyCommand(name, msg.substring(11));
    }

Bot Actions

I just explained how the bot interprets events, so now I'll explain how it performs actions. As a result of extending the MultiModule class, the BotAction class is automatically passed to the module via the m_botAction variable. So, using the functions of BotAction, the bot can perform actions. For example, one function of the BotAction class is getOperatorList() which gets the OperatorList class. This can then be used to check what level of privileges a player has.


    public OperatorList opList;

    public void init() {
        opList = m_botAction.getOperatorList();
    }

    public void handleEvent(Message event) {
        String message = event.getMessage();
        String name = event.getMessager() == null ? m_botAction.getPlayerName(event.getPlayerID()) : event.getMessager();

        if (event.getMessageType() == Message.PRIVATE_MESSAGE && !opList.isBotExact(name)) //Disallow bots from sending commands
                handleCommands(name, message);
    }

Check the BotAction class to see the myriad of possibilities.

Formatting

On the whole, formatting in TWCore is inconsistent. However, we would like to beging forming some consistency about how things are ordered. For this reason, we ask that functions are sorted in a sensible order, such as the order they appear in the help file. The init() function should be the first function and the cancel() function should be the last. The other required functions should be just after the init() function. For more in depth questions, ask a developer!

For more information on building Multibot modules, click here.

Previous Tutorial | Next Tutorial