Home - PEMapModder/PocketMine-Plugin-Tutorials GitHub Wiki

Welcome to PEMapModder's PocketMine Plugin Tutorials - Wiki.

Volume 1

This is a place for public contribution. Everyone can edit this wiki, but please keep in mind while editing that the wiki should be purely informative and neutral.

Introduction

This tutorial, unlike some other tutorials, goes on a test-then-explain basis. Because understand everything about PocketMine plugins require a deep knowledge in coding, this tutorial attempts to explain everything and make everything sensible, but sometimes I'll simply say Put it into your code, I won't explain. At these points, it would be because you don't have enough foundation knowledge. I'll explain once you have enough knowledge to understand.

Another characteristic of this tutorial is that it encourages critical thinking. When you learn about something new, you are encouraged to think of questions about it, or to challenge the tutorial's accuracy by finding out possible contradictions. Thinking about these questions can help you learn and clear your mind. In the short term, it strengthens your memory and helps build a stronger framework. In the long term, it trains your thinking skills, and critical thinking is actually quite useful in real life.

Requirements

This tutorial is written for "general public", which means that it is expected to be read by everyone. However, there are some very basic things that you need to understand:

  • How to run a basic PocketMine server that is joinable
  • How to install plugins in PocketMine
  • Basic knowledge in computers, such as the definition of files

Introduction to Coding

So let me explain what coding is. What comes up into your mind when I talk about "coding"? A programmer with a computer showing a black screen like that of a PocketMine console? A lot of meaningless characters and symbols?

Let's get the correct idea for "coding", at least in terms of PocketMine plugins. Here, we are going to write PHP code, which is a language fairly easy to learn. Coding is a very logical and human-readable process. For evidence, let's take a look at this example line of code:

$player->sendMessage("Hello world!");

The above line means to sendMessage (send a message) to a player $player (we will look into variables later), with a message Hello world!.

So you can see, as long as you don't have phobia to monospace (the font type usually used for coding, which is also the font type used on PocketMine consoles), coding can actually be very easy and a lot of fun. It is just like working with redstone in Minecraft; you can make a simple lever-to-open-door setup, while you can also make a complicated Minecraft "calculator" or mob arenas. The only difference is that we don't have that much graphics, but words and symbols instead, in coding. However, obviously coding is much more powerful. :grinning:

The PHP official documentation said somewhere,

... is very dangerous because it allows execution of arbitrary PHP code. 

Being able to write and execute code gives you unlimited power. It brings you to the top of the world. After finally finishing a piece of software after a long time of trial and error, it would feel like you have flown through the stars, and now you are there, actualizing your dream. Are you ready for that?

Creating plugin.yml

Now let's create our first plugin. I call it MyPlugin.

First of all, at anywhere you like on your device, create an empty directory (folder, in case you don't understand) called MyPlugin. For the sake of convenience, I'll assume the directory is /plugins/MyPlugin. However, it would be convenient for testing if you create it in the plugins folder of your test server instead.

This MyPlugin directory will contain all the files required in a plugin, namely plugin.yml, src (source code) and resources.

The basic information of the plugin, including the plugin name, version and author (your name!), are specified in a file called plugin.yml. Here is an example:

name: MyPlugin
version: 1.0.0
author: YourName
api: 2.1.0
main: yourname\myplugin\MyPlugin

The first three lines are obvious, but I guess the last two lines need a bit explanation.

api is the PocketMine API version the plugin is compatible with. You don't need to understand this at the moment; simply copy that line. Basically it means whether the plugin can run on the current version PocketMine is running, but it is not related to the release code like 1.5.

main is the fully qualified name of your main class. Yes I know, you understand every word but you don't understand what I mean. That will be explained in the next section.

So, create a file called plugin.yml in /plugins/MyPlugin and copy the above things into it. For Windows users, I recommend using a program called Notepad++ to edit YAML files (and PHP files in the future, too).

Small trick: create a new file in Notepad++, copy the contents into it and click Save as. Browse to /plugins/MyPlugin and put plugin.yml as the file name, then hit enter.

First PHP File

Steady, calm down. It's not that scary.

Now, create the following directories:

/plugins/MyPlugin/src/
/plugins/MyPlugin/src/yourname/
/plugins/MyPlugin/src/yourname/myplugin/

Now, create an empty file at /plugins/MyPlugin/src/yourname/myplugin/, called MyPlugin.php. Found it familiar? Yes, it is the main: attribute in the plugin.yml mentioned above. Now let's talk about what all these mean.

In order to organize code better, PHP allows us to group our code using classes. The real concept of classes is fairly complicated, but for the moment, just assume it as the way to group code together.

The name of a class can be the combination of {A-Z a-z 0-9 _}, but it must not start with a number. It is the common practice of many developers that classes be named using the "camel hump" style, and the first character is always capital, like this:

Written in English class name
Hello world HelloWorld
my plugin MyPlugin
My first PM plugin MyFirstPMPlugin
Anti 3P Anti3P
500 internal server error _500InternalServerError or InternalServerError500

There is no strict rule about this, but if you name your class like my_plugin, people may not realize that it is a class. This confuses people when they are trying to help you.

Back to our plugin, we are going to name our main class something that describes it. So what is the best name? The plugin name, of course. The best thing about it is that it is unique. Each server run (technical term: PHP runtime) only loads one class with the same name. Having a unique class name is therefore important.

Hold on. This is a lie. What is that thing before the main class name?

It is called namespace. Starting in PHP 5.3.0, it is possible to group class names using namespaces.

The whole thing about namespaces and classes is like a filesystem. Namespaces are directories, and classes are files. In the same directory there cannot be two files or directories with the same name. However, if you put the files at different directories, there will be no conflict as long as you tell people which directory you are getting the file from. Vice versa for namespaces. Therefore, I was lying. A point to note is that the directory separator for files is / (fine, I know it is / or \ in Windows), but in PHP, the parts in namespaces are always separated by \, regardless of the operating system.

And the fact is, not only is it like a filesystem, but it is also based on a filesystem. You must put your PHP files in the correct path according to its full name (a.k.a. fully qualified name, i.e. namespace \ class name), with the namespace separator (\) changed to the directory separator, inside the source (src) folder. For example:

yourplugin\myplugin\MyPlugin => src/yourplugin/myplugin/MyPlugin.php

In the next section, we are going to fill the contents of MyPlugin.php.

Your First Class

The complete concept of a class is a fairly abstract and sophisticated idea, so we are assuming it as a group of code; and as mentioned above, within one file.

Now let's copy all these into your first class:

<?php
namespace yourname\myplugin;
use pocketmine\plugin\PluginBase;
class MyPlugin extends PluginBase{
}

Let's see how clever you are. Try guessing the meaning of each line and each word. Any idea?

<?php

This is the prefix for every PHP file. This identifies that this file is a PHP script. It must be the first line of every PHP file. This is the rule; just remember it because it means nothing else in PocketMine PHP files.

namespace statement

Yes, this is the namespace of the class. It's obvious. This line tells that all the things in the file are going to be in the specified namespace.

Don't forget the trailing (at the end) ; (semicolon). The semicolon is one of the most frequently seen symbols in PHP. It marks the end of a statement. Without the semicolon, PHP will think that the next line belongs to the same statement as well.

Now close your eyes and think of any questions.

The question I'm expecting you to ask is:

What is the meaning of having new lines if they are separated by semicolons?

The answer is simple. No meaning.

Most programmers, in order to make the code neater, put different statements on different lines. For example, one line to teleport the player, then another line to send a message to a player. It would look messy if you do a bunch of things on the same line, because this is coding, not story writing.

There is another reason. Well maybe it's not a reason; it's a result. It is the question of the hen and the egg (which came first?). But it's a reason for you to separate code into lines. When coding, it's almost impossible to avoid making errors. When an error happened, PHP would tell you which line the error comes from. But it won't tell you which statement. Therefore, you have to separate code into different lines.

To summarize, the format of a namespace declaration is:

namespace your\name\space\here;

Note that namespace declarations must be the first line of code (<?php isn't code). There are exceptions, but again, you don't need to learn about that for making standard PocketMine plugins. (There is another way, but PocketMine Forums does not accept plugins to do that)

use statements

Remember when I talked about the importance of namespaces? There is a question that you should have asked.

Why can't we use something else like _ instead of the annoying nonstandard \ and all those namespace declarations?

It is because of the use statements. With the use statements added in PHP 5.3, it is possible to abbreviate a long full class name (such as yourname\myplugin\MyPlugin) into its short class name: MyPlugin. So the format is:

use the\long\name\space\ClassName;

And in the code below, you can just say ClassName instead of the long full name.

So did you notice how the use statement was used in the above example?

use pocketmine\plugin\PluginBase;

And in the code below, we could write PluginBase directly, instead of the full name pocketmine\plugin\PluginBase.

If the class you want to use is in the same namespace as your current code, you don't need to use it.

Note that if you don't want to use use but want to type a full path, and that you are in a namespace, you need to put a \ before the full name, or else PHP will think that the class you are using is in your namespace.

Also, use statements MUST be directly below the namespace declaration, and above any other code.

class declaration

As I have previously mentioned, code is grouped using classes. To start our actual code, we have to declare our first class.

class YourClassName{
}

As you can guess, the {} (curly braces) is used to contain the code of the class. So our main class should be declared as:

class MyPlugin{
}

Wait, don't be too excited. Look again. The code in the above example has something else: extends PluginBase. What is it?

For the main class of your plugin, you must make it extend the pocketmine\plugin\PluginBase class. What does "extend" mean? You will understand later; right now it is far too early to learn.

To avoid having to type the full class name, which makes the code look messy, we have useed it in the line above.

=== Now, we have finished our first PHP class. Actually, this IS a plugin that can be loaded. In the next chapter, we are going to see your plugin being loaded.

Running the plugin (Finally!)

As I have recommended, create the plugin at the place where all of your plugins are run at (/plugins). Good, have you done that? Now, download the plugin DevTools, which is available here.

Now, you might be asking Why do I need this "DevTools" plugin?. This is because DevTools is able to compile your current plugin/code into a .PHAR file, which is basically a plugin file for PocketMine. It also will run your code right now in a raw format, without compilation.

You will need to install the plugin to this directory: /plugins

Good, have you done that? Now, save all of the files using your current IDE (Integrated Development Enviroment), and run your server. If your server is currently already running, please stop the server and relaunch. It should show up as: alt text

Trouble loading your plugin? Ask a human on Freenode IRC channel #pocketmine.

These are the basic structure of your plugin. Every plugin goes through these steps. In the next volume, we are going to study three fundamental components of a plugin, namely commands, event handlers and scheduled tasks.

Next (Volume 2)