CustomToast is a PocketMine-MP virion for displaying compact, animated toast notifications in the top-right corner of Minecraft: Bedrock Edition.
It gives plugin authors one small PHP API while handling the less friendly parts internally: resource-pack registration, UI routing, UTF-8-safe payloads, the network text packet, and the optional vanilla toast sound.
This repository is the canonical documentation and source for the library. The companion CustomToastExample repository is only a runnable demonstration of the API.
- Four built-in styles: info, success, warning, and error.
- Rounded or square corners, configurable globally or per toast.
- All 29 current Minecraft Bedrock formatting-code colors, plus automatic and neutral helpers.
- Built-in image icons, no icon, or a fixed-width three-byte Unicode glyph.
- Title-only, message-only, or title-and-message layouts with bold titles.
- Vietnamese and other UTF-8 text is preserved safely.
- Minecraft's built-in vanilla toast sound can play with each notification.
- Multiple toasts can be queued by the Bedrock UI.
- Multiple plugins can safely share one server-side CustomToast runtime.
- The resource pack is compiled and registered automatically at server startup.
- No command syntax or plugin-specific behavior is forced on the library user.
- PocketMine-MP 5.x
- PHP 8.1 or newer
- PHP extensions
mbstringandzip - A Bedrock client that accepts the server resource pack
CustomToast contains both PHP source and resource-pack files. Your build must inject both folders into the final plugin PHAR.
With Pockgin CLI, add this pockgin.libs.yml to the plugin that uses CustomToast:
libs:
- id: customtoast
repo: NhanAZ-Libraries/CustomToast
version: ^1.0.0
target: src/NhanAZ/CustomToast
src_path: src/NhanAZ/CustomToast
- id: customtoast-resources
repo: NhanAZ-Libraries/CustomToast
version: ^1.0.0
target: resources/CustomToast
src_path: resources/CustomToastThen build the host plugin:
node /path/to/pockgin-cli/bin/pockgin.js build .The two entries are intentional. The first injects the PHP API; the second injects the client-side UI and images.
Keep the target namespace exactly as shown. Pockgin copies the library without namespace shading, so every consumer resolves the same NhanAZ\CustomToast classes and shares one runtime coordinator.
If you use a different build system, copy these two paths into the same locations in the host plugin before creating its PHAR:
CustomToast/src/NhanAZ/CustomToast -> YourPlugin/src/NhanAZ/CustomToast
CustomToast/resources/CustomToast -> YourPlugin/resources/CustomToast
Do not install this repository directly in the PocketMine-MP plugins folder. It is a library, not a standalone plugin. Use CustomToastExample if you want a ready-to-run demonstration.
Create one library instance in your plugin's onEnable() method:
use NhanAZ\CustomToast\CustomToast;
use NhanAZ\CustomToast\ToastColor;
use NhanAZ\CustomToast\ToastCornerStyle;
use NhanAZ\CustomToast\ToastType;
use pocketmine\plugin\PluginBase;
final class Main extends PluginBase{
private CustomToast $customToast;
protected function onEnable() : void{
$this->customToast = CustomToast::create($this);
}
protected function onDisable() : void{
$this->customToast->close();
}
}Send a message-only toast:
$this->customToast->send(
$player,
ToastType::INFO,
"You have a new friend request."
);Choose any Minecraft Bedrock color independently of the toast type:
$this->customToast->send(
$player,
ToastType::INFO,
"Your party is ready.",
"Party",
null,
ToastCornerStyle::ROUND,
ToastColor::LIGHT_BLUE
);Send a title and a message:
$this->customToast->send(
$player,
ToastType::WARNING,
"The server will restart in 5 minutes.",
"Warning",
null,
ToastCornerStyle::SQUARE
);Send a compact text-only toast without an icon:
$this->customToast->send(
player: $player,
type: ToastType::INFO,
message: "A plain notification without an icon.",
showIcon: false
);A title may also be used without a message or icon:
$this->customToast->send(
player: $player,
type: ToastType::INFO,
message: "",
title: "Maintenance complete",
showIcon: false
);Replace the image icon with a Unicode glyph supported by the client's active font:
$this->customToast->send(
player: $player,
type: ToastType::INFO,
message: "A Minecraft glyph is displayed in the icon slot.",
title: "Glyph notification",
glyph: ""
);Messages may contain any number of explicit line breaks. The toast background grows vertically to fit the rendered lines:
$this->customToast->send(
$player,
ToastType::SUCCESS,
"First reward\nSecond reward\n\nCome back tomorrow.",
"Daily rewards"
);Send a toast to everyone online:
$count = $this->customToast->broadcast(
ToastType::SUCCESS,
"The event is now open!",
"Event"
);CustomToast::create(
PluginBase $plugin,
bool $forceResourcePack = true,
int $maxMessageBytes = 256,
bool $playSound = true,
ToastCornerStyle $cornerStyle = ToastCornerStyle::ROUND,
ToastColor $color = ToastColor::AUTO,
bool $showIcon = true
): CustomToastpluginis the host plugin containing the injected library and resources.forceResourcePackdisconnects clients that refuse the pack when set totrue.maxMessageByteslimits the message field without cutting a UTF-8 character in half.playSoundis the default sound behavior for every toast.cornerStyleis the default background shape for every toast.coloris the default background color.AUTOchooses a color from the toast type.showIconselects whether to show the type icon by default. Iconless toasts automatically use compact left padding.
Create the service once, during startup, before players join. Registering a resource pack after a player has joined will not make that client download it automatically.
$customToast->send(
Player $player,
ToastType $type,
string $message,
?string $title = null,
?bool $playSound = null,
?ToastCornerStyle $cornerStyle = null,
?ToastColor $color = null,
?bool $showIcon = null,
?string $glyph = null
): voidPass null as the title for a message-only toast. Pass an empty message with a non-empty title for a title-only toast. The five optional final arguments override the default sound, corner, color, image-icon, and glyph settings for that one toast. Pass false as showIcon to remove the image and its reserved space. Pass one three-byte Unicode code point as glyph to replace the image while keeping icon spacing; a glyph takes priority over showIcon.
The title is limited to 96 UTF-8 bytes, remains a single line, and is automatically wrapped in §l and §r so it renders bold without leaking formatting into the message. Newline and tab characters in the title are converted to spaces. Message line breaks and formatting codes are preserved, including repeated line breaks that create an empty line. Tabs in the message are converted to spaces.
$customToast->broadcast(
ToastType $type,
string $message,
?string $title = null,
?bool $playSound = null,
?ToastCornerStyle $cornerStyle = null,
?ToastColor $color = null,
?bool $showIcon = null,
?string $glyph = null
): intThe return value is the number of online players that received the toast.
$customToast->close();Call close() from the host plugin's onDisable() method. It removes the generated pack from the runtime resource stack and deletes the temporary .mcpack. Calling it more than once is safe.
When several plugins use CustomToast, close() releases only that plugin's reference. The pack remains active until the final consumer closes.
Every plugin may inject the same CustomToast source and call CustomToast::create() independently:
protected function onEnable() : void{
$this->customToast = CustomToast::create($this);
}
protected function onDisable() : void{
$this->customToast?->close();
}The shared runtime applies these rules:
- The first consumer compiles and registers the resource pack.
- Later consumers reuse that registration instead of adding the same UUID again.
- If any active consumer sets
forceResourcePacktotrue, the pack remains required. - Closing one consumer does not interrupt the others.
- The final
close()restores the original required-pack setting, unregisters the pack, and removes the generated.mcpack.
All consumers should inject the same CustomToast release and the same presentation assets. The first plugin enabled by PocketMine-MP supplies the active pack file. If different plugins bundle different themes under the same pack UUID, startup order would decide which theme players receive.
ToastType::INFO;
ToastType::SUCCESS;
ToastType::WARNING;
ToastType::ERROR;For command parsers, ToastType::fromName() understands the full names and the short forms i, s, w, and e.
Each toast has three mutually exclusive icon modes:
- Omit
showIconandglyphto use the image associated with itsToastType. - Set
showIcon: falseto use compact text-only padding. - Pass
glyph: "…"to render exactly one three-byte Unicode code point in the image slot.
Glyph rendering depends on the Minecraft client's active fonts and resource packs. Minecraft Bedrock's default private-use glyphs U+E100 through U+E10D can be tested with . Custom resource-pack emojis should use a three-byte Basic Multilingual Plane code point, normally from a private-use range such as the E0, E1, or later glyph pages. The pack must provide the matching font/glyph_<page>.png spritesheet. ASCII characters, four-byte emoji, and multi-code-point emoji sequences are rejected so every glyph payload keeps the fixed byte width required by the client-safe JSON UI bindings.
ToastCornerStyle::ROUND;
ToastCornerStyle::SQUARE;Use the cornerStyle argument of create() to select a plugin default. Use the cornerStyle argument of send() or broadcast() to override it for one notification. ToastCornerStyle::fromName() accepts round, rounded, square, sharp, r, and s.
ToastColor::AUTO selects BLUE, GREEN, YELLOW, or RED for info, success, warning, or error respectively. ToastColor::NEUTRAL resolves to DARK_GRAY. Every other case maps one-to-one to a current Minecraft Bedrock formatting code:
| Case | Code | Hex | Case | Code | Hex |
|---|---|---|---|---|---|
BLACK |
§0 |
#000000 |
DARK_BLUE |
§1 |
#0000AA |
DARK_GREEN |
§2 |
#00AA00 |
DARK_AQUA |
§3 |
#00AAAA |
DARK_RED |
§4 |
#AA0000 |
DARK_PURPLE |
§5 |
#AA00AA |
GOLD |
§6 |
#FFAA00 |
GRAY |
§7 |
#AAAAAA |
DARK_GRAY |
§8 |
#555555 |
BLUE |
§9 |
#5555FF |
GREEN |
§a |
#55FF55 |
AQUA |
§b |
#55FFFF |
RED |
§c |
#FF5555 |
LIGHT_PURPLE |
§d |
#FF55FF |
YELLOW |
§e |
#FFFF55 |
WHITE |
§f |
#FFFFFF |
MINECOIN_GOLD |
§g |
#DDD605 |
MATERIAL_QUARTZ |
§h |
#E3D4D1 |
MATERIAL_IRON |
§i |
#CECACA |
MATERIAL_NETHERITE |
§j |
#443A3B |
MATERIAL_REDSTONE |
§m |
#971607 |
MATERIAL_COPPER |
§n |
#B4684D |
MATERIAL_GOLD |
§p |
#DEB12D |
MATERIAL_EMERALD |
§q |
#47A036 |
MATERIAL_DIAMOND |
§s |
#2CBAA8 |
MATERIAL_LAPIS |
§t |
#21497B |
MATERIAL_AMETHYST |
§u |
#9A5CC6 |
MATERIAL_RESIN |
§v |
#EB7114 |
LIGHT_BLUE |
§w |
#8BB3FF |
ToastColor::fromName() accepts enum-style names such as dark_blue, short formatting codes such as 1, and familiar aliases such as resin, diamond, party_blue, neutral, and auto. A leading § or & is accepted too.
At startup, CustomToast collects the injected resources/CustomToast directory, creates CustomToast.mcpack in the host plugin's data directory, and places that pack at the top of PocketMine-MP's resource-pack stack.
When send() is called, the library sends a system TextPacket containing a private marker, a one-character presentation code, corner and color fields, an optional fixed-width glyph, and the display text. The custom HUD consumes marked messages, hides them from normal chat, builds the matching texture path, selects an image, glyph, or compact text-only layout, and runs the enter/wait/exit animation. If sound is enabled, a PlaySoundPacket for Minecraft Bedrock's built-in random.toast event is sent immediately before the text packet. No custom audio file or sound definition is bundled.
The marker format is an implementation detail. Plugin code should always call the public API instead of assembling packets manually.
You may replace the files below while keeping their paths unchanged:
resources/CustomToast/textures/ui/custom_toast/background_round_<official_name>.png
resources/CustomToast/textures/ui/custom_toast/background_square_<official_name>.png
resources/CustomToast/textures/ui/custom_toast/icon_info.png
resources/CustomToast/textures/ui/custom_toast/icon_success.png
resources/CustomToast/textures/ui/custom_toast/icon_warning.png
resources/CustomToast/textures/ui/custom_toast/icon_error.png
There are 58 active background files: 29 official color names for each corner style. For example, background_round_green.png is rounded green and background_square_material_resin.png is square Resin. All are 12x12 nine-slice textures with a four-pixel slice. background_round.png and background_square.png are the neutral variants. During pack compilation, the readable names are mapped to compact internal aliases used by JSON UI. The notification sound comes from the Bedrock client through the built-in random.toast event, so visual themes do not need to ship or license an audio file.
See ASSETS.md before distributing the bundled presentation assets.
- Bedrock JSON UI files modify global HUD and chat controls. Another resource pack that replaces the same controls can override CustomToast or be overridden by it.
- CustomToast places its pack at highest priority to make its bindings reliable.
- Multiple plugins are supported when they inject the unchanged
NhanAZ\CustomToastnamespace. Namespace-shaded or independently renamed copies cannot share the runtime coordinator and are unsupported. - Keep every consumer on the same CustomToast release and resource-pack theme.
- A resource-pack-only change may be cached by the client. During design work, change the pack UUID or clear the client's cached server packs when necessary. Keep release versions at
1.0.0unless the project owner explicitly requests a version change.
The client did not load the CustomToast resource pack, or another pack replaced the chat/HUD bindings. Confirm that the player accepted the pack and test CustomToast at the top of the pack stack.
Only the PHP half of the virion was injected. Add the second Pockgin mapping for resources/CustomToast and rebuild the host plugin.
Keep source files and configuration files encoded as UTF-8. Do not convert the text through an ASCII-only command or database column. CustomToast truncates by UTF-8 byte boundaries and does not replace Vietnamese characters.
The library API accepts title and message as separate arguments. Converting a command-line \\n separator is the responsibility of the host plugin. The example plugin demonstrates a safe parser. The pipe character | has no special meaning and remains part of the message.
Use the current resource pack. Older builds allowed Bedrock JSON UI to interpret number-leading text as a numeric expression. The current binding forces the extracted payload back to a string, so both 1 reward and Reward 1 render normally.
The PHP source is licensed under LGPL-3.0-or-later. Presentation assets are handled separately; read ASSETS.md.