Skip to main content
The Main class analyzer ensures your plugin’s main class file exists at the expected location and is correctly implemented to work with PocketMine-MP.

What it checks

File location validation

The analyzer verifies the main class file exists at the expected path based on the namespace defined in plugin.yml:
  • Converts the fully-qualified class name to a file path
  • Expects files under the src/ directory
  • Follows PSR-4 autoloading conventions
Example:
# plugin.yml
main: MyPlugin\Main
Expected file location: src/MyPlugin/Main.php

Class definition validation

Once the file is found, the analyzer parses and validates:
  • A class definition exists in the file
  • The fully-qualified class name (FQCN) matches the plugin.yml declaration
  • The class is not abstract
  • The class properly extends or implements PocketMine-MP plugin interfaces

Plugin interface validation

Your main class must follow one of these patterns:

Extend PluginBase

The recommended approach for most plugins.
namespace MyPlugin;

use pocketmine\plugin\PluginBase;

class Main extends PluginBase {
    // Your plugin code
}

Implement Plugin interface

For advanced use cases requiring custom plugin base classes.
namespace MyPlugin;

use pocketmine\plugin\Plugin;

class Main implements Plugin {
    // Must implement all Plugin interface methods
}

Lifecycle method validation

The analyzer checks that plugin lifecycle methods follow proper visibility rules:
  • onLoad() - Should be public or protected
  • onEnable() - Should be public or protected
  • onDisable() - Should be public or protected
Lifecycle methods with private visibility will generate warnings.

Issues detected

Error severity issues

The file at the expected path doesn’t exist.
Error: Main class file not found at expected path: src/MyPlugin/Main.php
Fix: Create the main class file at the expected location or update the main field in plugin.yml.
The PHP file contains syntax errors.
Error: Failed to parse main class file: Syntax error, unexpected token "}"
Fix: Correct the PHP syntax errors in your main class file.
The file doesn’t contain a class definition.
Error: No class definition found in main class file
Fix: Ensure your main class file contains a class definition.
The class name or namespace doesn’t match plugin.yml.
Error: Main class FQCN mismatch. Expected: MyPlugin\Main, Found: MyPlugin\Core
Fix: Change the class name/namespace to match the main field in plugin.yml.
The main class is declared as abstract.
Error: Main class must not be abstract
Fix: Remove the abstract modifier from the main class.
The class doesn’t extend PluginBase or implement Plugin interface.
Error: Main class must implement pocketmine\plugin\Plugin interface or extend PluginBase
Fix: Extend pocketmine\plugin\PluginBase or implement pocketmine\plugin\Plugin.

Warning severity issues

  • Lifecycle methods (onLoad, onEnable, onDisable) should be public or protected

Code examples

Correct implementation

declare(strict_types=1);

namespace MyPlugin;

use pocketmine\plugin\PluginBase;

class Main extends PluginBase {
    
    protected function onEnable(): void {
        $this->getLogger()->info("Plugin enabled!");
    }
    
    protected function onDisable(): void {
        $this->getLogger()->info("Plugin disabled!");
    }
}

Common issues

// Bad: Abstract class cannot be instantiated
abstract class Main extends PluginBase {
    // Error: Main class must not be abstract
}

// Good: Remove abstract modifier
class Main extends PluginBase {
    // Correct
}

Path resolution

The analyzer resolves the main class path using PSR-4 conventions:
  1. Takes the FQCN from plugin.yml (e.g., MyPlugin\SubNamespace\Main)
  2. Converts backslashes to forward slashes: MyPlugin/SubNamespace/Main
  3. Adds .php extension: MyPlugin/SubNamespace/Main.php
  4. Prepends src/ directory: src/MyPlugin/SubNamespace/Main.php
The analyzer expects your source files to be in the src/ directory following PSR-4 autoloading standards.

Best practices

Use proper namespace structure

Organize your code with meaningful namespaces that match your directory structure.
// File: src/MyPlugin/Commands/MainCommand.php
namespace MyPlugin\Commands;

Keep lifecycle methods protected

Use protected visibility for onLoad(), onEnable(), and onDisable() methods.
protected function onEnable(): void {
    // Implementation
}

Always extend PluginBase

Unless you have specific requirements, extend PluginBase instead of implementing Plugin interface directly.
class Main extends PluginBase {
    // Provides helpful methods out of the box
}
The analyzer validates your main class at src/Analyzer/MainClassAnalyzer.php:16-44

Build docs developers (and LLMs) love