Skip to main content
This guide will walk you through creating your first PocketMine-MP plugin from scratch.

What is a Plugin?

Plugins are extensions that add custom functionality to your PocketMine-MP server. They can add new commands, listen to events, create custom game mechanics, and much more.

Prerequisites

  • Basic PHP knowledge
  • A PocketMine-MP server
  • A text editor or IDE (PHPStorm, VSCode, etc.)

Plugin Types

PocketMine-MP supports two types of plugins:
  1. Folder plugins - Full-featured plugins with proper structure (recommended)
  2. Script plugins - Single-file plugins for quick testing only
This guide focuses on folder plugins. Script plugins have limited features and are not recommended for production use.

Creating Your First Plugin

1

Create the plugin folder structure

Create a new folder in your server’s plugins directory:
plugins/
└── MyFirstPlugin/
    ├── plugin.yml
    └── src/
        └── MyNamespace/
            └── Main.php
2

Create plugin.yml manifest

The plugin.yml file describes your plugin to PocketMine-MP.
plugin.yml
name: MyFirstPlugin
version: 1.0.0
main: MyNamespace\Main
api: [5.0.0]

# Optional fields
author: YourName
description: My first PocketMine-MP plugin
website: https://example.com
The api field specifies which PocketMine-MP API versions your plugin supports. Use the API version of your server.
3

Create your main plugin class

Create src/MyNamespace/Main.php:
src/MyNamespace/Main.php
<?php

declare(strict_types=1);

namespace MyNamespace;

use pocketmine\plugin\PluginBase;

class Main extends PluginBase {
    
    protected function onEnable() : void {
        $this->getLogger()->info("MyFirstPlugin has been enabled!");
    }
    
    protected function onDisable() : void {
        $this->getLogger()->info("MyFirstPlugin has been disabled!");
    }
}
All plugin main classes must extend pocketmine\plugin\PluginBase (or implement pocketmine\plugin\Plugin).
4

Load the plugin

Place your plugin folder in the plugins directory and start/restart your server.You should see:
[INFO] Loading MyFirstPlugin v1.0.0
[INFO] Enabling MyFirstPlugin v1.0.0
[INFO] MyFirstPlugin has been enabled!

Plugin Lifecycle Methods

Your plugin has three lifecycle methods you can override:

onLoad()

Called when the plugin is loaded, before onEnable(). Use this for early initialization.
protected function onLoad() : void {
    $this->getLogger()->info("Plugin is loading...");
    // Initialize resources, register custom classes, etc.
}

onEnable()

Called when the plugin is enabled. This is where most initialization happens.
protected function onEnable() : void {
    // Register event listeners
    // Register commands
    // Load configuration
    // Schedule tasks
}
Do not access the Server instance or perform world operations in onLoad(). Use onEnable() instead.

onDisable()

Called when the plugin is disabled. Use this for cleanup.
protected function onDisable() : void {
    // Save data
    // Cancel tasks
    // Close database connections
}

Complete Example

Here’s a complete first plugin that announces when players join:
name: WelcomePlugin
version: 1.0.0
main: Welcome\Main
api: [5.0.0]
author: YourName
description: Welcomes players to the server

Common Methods

These methods are available in your plugin class (via PluginBase):
MethodDescriptionExample
getServer()Get the Server instance$this->getServer()->getOnlinePlayers()
getLogger()Get the plugin’s logger$this->getLogger()->info("Message")
getDataFolder()Get the plugin’s data folder$this->getDataFolder() . "data.json"
getConfig()Get the plugin’s config$this->getConfig()->get("setting")
getScheduler()Get the task scheduler$this->getScheduler()->scheduleTask($task)
saveResource()Save an embedded resource$this->saveResource("config.yml")

Next Steps

Plugin Structure

Learn about plugin.yml and folder organization

Event Handlers

Respond to game events

Commands

Create custom commands

Configuration

Manage plugin settings

Troubleshooting

Plugin not loading

  • Check plugin.yml syntax (use a YAML validator)
  • Ensure the main class exists and namespace matches
  • Verify file permissions
  • Check server logs for error messages

”Class not found” errors

  • Verify namespace matches folder structure
  • Check spelling of class names
  • Ensure declare(strict_types=1); is at the top of PHP files

Plugin loads but doesn’t work

  • Check for errors in server console
  • Use $this->getLogger()->debug() to add debug messages
  • Verify API version compatibility

Build docs developers (and LLMs) love