A SkyMine plugin for PocketMine-MP 5 (NetherGames fork) that treats tick time as a budget: mine refills are spread across ticks, player scans are batched, and lookups that run on every interaction are O(1) indexes instead of linear scans.
Inspired by the SkyMine mode of play.bitonetop.com.
This plugin is under active development. The core is implemented, statically clean (PHPStan level 9) and boots on a live 5.44 server, but in-game testing on a real Bedrock client is still in progress. Expect behavior changes and bug fixes; check the commit history before updating a production server.
| System | What it does |
|---|---|
mine/ |
Cuboid mines with weighted block lists, hologram countdowns, automatic timed refills via a per-tick block budget (MineFillTask), placement grief protection, drops-to-inventory rewards, full JSON persistence |
crate/ |
Animated shulker crates with configurable color, weighted rewards, NBT key items (consumed exactly once), read-only previews and spin windows, explosion protection, O(1) position index |
outpost/ |
Capturable zones with progress, cooldowns, owner gold payouts, holograms with settable label positions, JSON persistence |
slapper/ |
Clickable NPCs (your skin, messages, player/console: commands) plus clickable blocks bound to them; look-at-players on a 5s interval |
leaderboard/ |
Floating top-10 holograms for money, gold, mined, deaths, kills and team level/wins; hash-guarded re-renders (no flicker) |
team/ |
Teams with invites, kicks, disband, levels/XP, explicit-accept duels with arena rendezvous teleport and safe return, live-duel sidebar while fighting, JSON persistence |
warp/ |
Named server warps with create/move/delete, per-player teleport, missing-world-safe, JSON persistence |
label/ |
General multi-line floating labels (wiki/help/tutorials), full CRUD, JSON persistence |
lobby/ |
Hub + mid-lobby positions, mid-lobby scoreboard zone (pos1/pos2), map-wide lobby protection (non-staff cannot break/place/interact; crates, slapper blocks and mines keep working), join teleport modes, fall/void/hunger guards with ground-or-hub void rescue — all configurable |
shop/ |
Category shop with buy/sell/sell-all through the economy managers, confirmations |
quest/ |
Daily quests (mine/kill/earn) with progress bars, claim-once rewards, lazy daily reset, JSON persistence |
composer/ |
Material processor: virtual workbench, multiset recipe matching, plus an in-game admin UI to create/rename/edit/delete recipes (persisted to composer.recipes) |
tools/ |
Unbreakable, undroppable progression gear with block-break XP, level-gated enchant upgrades, material costs, upgrade UI |
trade/ |
Chest-style two-player trades: private sides, double-confirm, change invalidates confirmations, safe cancel/timeout/death/disconnect handling |
scorehud/ |
Sidebar with welcome, duel and stats screens, named-zone places with hysteresis switching, live refresh on economy/kill/death/PvP changes, delta-only line updates with title tracking, per-player toggle |
economy/ |
Dual JSON currency (money, gold) with vetoable change events |
miner/ |
Per-player mined (mines only)/deaths/kills/streak stats |
pvp/ |
Per-player PvP preference with projectile attribution, duel override |
lagmaker/ |
Item-entity stacking, per-player drop caps, TTL/all/off cleanup passes with 30/5/2/1s warnings — every pass tick-spread |
wand/ |
Position Wand: left-click sets pos1, sneak-click sets pos2, never breaks blocks; shared SelectionManager for all cuboid systems |
form/ |
Bundled FormAPI port (Simple/Custom/Modal) compatible with PM 5.44, plus the shared Ui toolkit (menu/confirm/input) every window is built from |
config/ |
Typed config.yml access plus the messages.* catalog: every player-facing chat string is configurable with built-in fallbacks |
event/ |
Public cancellable events for other plugins |
useless/ |
SpreadTask (tick-spread iteration), hologram particles, NumberFormatter, read-only inventories, fake-chest virtual windows (VirtualInventory + VirtualWindow, offset clear of the player), shared placement-transaction unpacking (BlockTransactions), canonical Positions/Items/Worlds/Arrays helpers (fromTuple, drain, removeIndex) |
One 50 ms tick, one 50,000-block mine refill before: setBlockAt x 50,000 in a single tick — the server freezes after: mines.blocks-per-tick (default 3,000) per tick — ~17 ticks, players lifted out first same pattern everywhere: sidebar passes, join hologram bursts and cleanup sweeps all run through SpreadTask
useless/SpreadTask— one-shot task that walks any list N entries per tick, then cancels itself. Used by the sidebar tick, every join-hologram burst, and the lag-cleaner queue builder. (One-shot matters: scheduling it as repeating would leak a task per tick — an earlier revision of this plugin did exactly that.)mine/MineFillTask— refill writes at mostmines.blocks-per-tickblocks per tick with arithmetically derived coordinates (no 50k position array allocated up front).- O(1) indexes — crates and slapper blocks are resolved by a
world:x:y:zhash, not by scanning every crate on every click. - Normalized collision boxes —
min/maxare precomputed once, so the per-tickisIn()check is six float comparisons (world-aware variant included, no extra cost when worlds already match). - Delta-only sidebar — unchanged scoreboard lines cost one string compare and zero packets.
- Single-timer clear warnings — the 30/5/2/1s item-clear countdowns ride on the same counter that triggers the clear; no extra tasks are scheduled.
- Snapshotted tuning — per-tick config reads are cached once per tick (LagMaker) or once per opening (crate animation pacing).
- Requires PocketMine-MP 5 — NetherGames fork (API 5.44) and PHP 8.1+ with the
yamlextension. - Copy this folder to
plugins/SkyMineZ/(folder plugin — no.pharbuild needed) and start the server. resources/config.ymlis copied toplugin_data/SkyMineZ/config.ymlon first run; edit it, then run/skymine reload.
Player commands (skyminez.use, granted to everyone):
| Command | Effect |
|---|---|
/skymine menu |
Main menu form (PvP/sidebar toggles, stats, warps, shop, quests, teams, composer, gear, hub, admin shortcuts) |
/skymine pvp [on|off] |
Toggle your PvP preference |
/skymine hud |
Toggle your sidebar |
/skymine stats [player] |
Mining stats, works for offline names too |
/hub / /lobby |
Teleport to the configured hub (falls back to mid-lobby) |
/warp [name] |
Teleport to a server warp (lists them with no argument) |
/team <menu|create|info|list|invite|accept|deny|leave> |
Teams, invitations and info |
/team duel challenge <team> / accept <id> / deny <id> |
Challenge and fight other teams (owners only) |
/quest |
Daily quests with progress bars and claim buttons |
/shop |
Category shop (buy/sell/sell-all with confirmations) |
/trade <player|accept|deny|cancel> |
Chest-style player trading |
/composer |
Material composer (pick a recipe, fill the workbench, close to craft) |
/tools |
Progression gear: attune the held item, spend XP/materials on upgrades |
Admin commands (skyminez.admin, op by default):
| Command | Effect |
|---|---|
/skymine money|gold <give|take|set|check> <player> [amount] |
Manage balances |
/skymine pos1 / /skymine pos2 |
Mark cuboid corners for /mine create and /outpost create |
/skymine wand |
Get the Position Wand (admin) |
/skymine lagmaker <status|toggle|cleanup <off|ttl|all>> |
Lag protection controls |
/skymine reload / /skymine save |
Reload config+data / flush every store |
/crate create|remove|move|list|givekey|open|color|menu|save |
Crates, keys and shulker color |
/crate reward <add|remove|list|weight|type> |
Reward entries with live chance display |
/mine create|remove|list|info|reset|setinterval|setlabel|clearblocks|menu |
Mines |
/mine block <add|remove|list> |
Weighted block list (/mine block add <mine> stone 60) |
/mine pos1|pos2 |
Same markers, mine-flavoured aliases |
/outpost create|remove|list|info|owner|reset|setlabel|menu |
Outposts (owner <name> <player|clear>) |
/slapper create|remove|list|move|menu |
NPCs with your skin |
/slapper msg|cmd <add|remove|clear|list> |
Messages and commands ({player} placeholder, console: prefix runs as console) |
/slapper block <add|remove|list> |
Clickable blocks bound to a slapper |
/lb create|remove|list|info|title|setpos|refresh|menu |
Leaderboards (/lb create top money Top Money) |
/hub set|setmid|setmidzone|unset|unsetmid|clearmidzone|info |
Lobby positions, mid-lobby scoreboard zone and map protection state |
/warp create|delete|move|list |
Warp management |
/label create|set|addline|delline|move|remove|list|info |
Floating text labels |
/team kick|disband |
Owner controls (plus everything in the player table) |
/team arena <seta|setb|clear|info> |
Duel rendezvous points; fighters teleport on accept, return afterwards |
/composer manage |
Create/rename/edit/delete composer recipes in game |
Typical first setup, in game:
/skymine pos1
/skymine pos2
/mine create coal
/mine block add coal coal_ore 40
/mine block add coal stone 60
/mine reset coal
/crate create vote
/crate givekey Steve vote 5
/outpost create mid
/lb create top money Top Balance
/slapper create guide
/hub set
/warp create spawn
/team arena seta
/team arena setb
Single-point create/move commands (/crate, /lb, /mine setlabel,
/outpost setlabel, /label, /slapper, /skymine pos1|pos2) resolve at
your eye (middle) position — just stand where you want it, no aiming at
blocks required. Cuboid systems (/mine create, /outpost create, /hub setmidzone) read
the shared pos1/pos2 selection instead: mark corners
with the subcommands above or with the Position Wand (left-click = pos1,
sneak-click = pos2, blocks are never broken). Teleports (/warp, /hub,
duel arenas) always target feet position, so you never land inside a block.
All tuning lives in config.yml: sidebar texts and timings (including the
duel board under scoreboard.duel, with {team}/{enemy}/{duel_time}
plus the usual stat placeholders), PvP defaults,
economy starting balances, crate animation pacing and key behavior, mine
refill budget and default interval, outpost capture/cooldown/gold values,
lobby positions/mid-zone/anti-damage, team/duel timings and arena spawns
(teams.arena-a/b, set in game with /team arena seta|setb), daily quests,
shop catalog, tool upgrade packages, composer recipes, trade timeouts, and the
lag-cleaner mode (off / ttl / all), TTL, interval and per-tick budget.
Every player-facing chat string lives under messages: (503 keys, {braces}
placeholders) — reword or translate without touching code. A missing or empty
entry falls back to the built-in default, so old configs keep working; the
legacy pvp.disabled-message key still wins when set.
Data files (plugin_data/SkyMineZ/*.json) are plain JSON and safe to inspect;
mines.json, crates.json, outposts.json, slappers.json,
leaderboards.json, teams.json, warps.json, labels.json, quests.json,
lobby.json, pvp.json, miner.json, money_economy.json and
gold_economy.json survive restarts including owners, timers and block lists.
- Bundled forms — every window is built from the shared
Uitoolkit (Ui::menu()/Ui::confirm()/Ui::input()), which sits on the bundled FormAPI port (SimpleForm/CustomForm/ModalForm) plus theonCompletion/ retry / blocking members PM 5.44 requires. - Events —
CrateOpenEvent,MineResetEvent,OutpostCaptureEvent,SlapperInteractEvent,MinerBlockMinedEvent,EconomyChangeEvent,ScoreHudUpdateEvent,PlayerPvPChangeEvent. Handlers are guarded by::hasHandlers()so events nobody listens to skip allocation entirely (MinerBlockMinedEventadditionally funnels throughEventDispatcher::dispatch()). - Scoreboard places —
ScoreHud::registerPlace($id, $box, $board)shows a board inside any cuboid (middle/lobby/duel); the mid-lobby zone and live duels are the built-in users.LobbyManager::isGuarded($world)is the matching query for map-wide lobby rules. - Static analysis —
composer stan(PHPStan level 9, clean). The PocketMine sources are server-provided; pointscanDirectoriesinphpstan.neon.distat your server checkout. - Verified on a live server — the plugin boots on 5.44.2+dev and every console-safe command path was executed against a real server during development.
MIT — see LICENSE. You are free to use, modify and redistribute this plugin, including on commercial servers, as long as the copyright notice stays intact.