Overview
PocketMine-MP is built on a single-threaded tick-based architecture that manages worlds, entities, players, and network operations. The server runs at a target rate of 20 ticks per second (TPS), processing game logic synchronously while offloading heavy operations to async workers.Core Components
Server Class
TheServer class (pocketmine\Server) is the central hub that manages all server operations.
Server.php:183
The server maintains a constant 50ms tick cycle (1000ms / 20 ticks). Between ticks, the server sleeps using a
SleeperHandler that can be woken up by network packets or other events.Key Managers
PluginManager
PluginManager
Manages plugin loading, enabling, disabling, and event registration.
WorldManager
WorldManager
Handles world loading, unloading, chunk management, and world ticking.
Network
Network
Manages network interfaces (RakLib), packet broadcasting, and compression.
CommandMap
CommandMap
Routes commands to their handlers and manages command registration.
Threading Model
Main Thread
The main thread runs the tick loop which processes:- Network packets - Incoming player actions
- World ticking - Block updates, entity movement, chunk loading
- Entity updates - Player movement, mob AI
- Scheduled tasks - Plugin tasks registered via scheduler
- Event calls - Synchronous event handlers
Async Workers
TheAsyncPool manages worker threads for CPU-intensive operations:
- Chunk generation - World terrain generation
- Chunk I/O - Loading/saving chunks from/to disk
- Packet compression - Batch packet compression (ZLIB)
- Player authentication - JWT verification for Xbox Live
Tick Cycle
Each tick processes operations in a specific order:Tick Counter
The server maintains a tick counter starting from 0:TPS Monitoring
Singleton Pattern
TheServer instance is globally accessible:
While the singleton pattern provides convenience, plugins should prefer dependency injection through their constructor where possible.
Memory Management
TheMemoryManager monitors and controls memory usage:
Auto-GC Triggers
- Low memory threshold reached
- Every 30 minutes (configurable)
- Manual trigger via command
Component Lifecycle
Example: Accessing Components
Best Practices
Do
- Use async tasks for heavy operations
- Cache frequently accessed data
- Batch operations when possible
- Monitor TPS impact of your code
Don't
- Block the main thread
- Access thread-unsafe objects from workers
- Create excessive scheduled tasks
- Perform I/O on the main thread