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.
- Development plugins can share one server-side CustomToast runtime through the DevTools shared virion loader.
- 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.
NhanAZ-Plugins/DevTools can discover CustomToast as a virion, shade its PHP namespace into the host plugin, and retain its resource pack under the protected virion resource directory. Add this to the host plugin's devtools.yml:
virions:
- name: CustomToast
version: ^1.0.0Check out this repository at an exact commit into virions/CustomToast, then run NhanAZ-Plugins/DevTools@v0.1.0. The complete tested implementation is the companion CustomToastExample workflow.
For folder-plugin development, use this server layout:
server/
|- plugins/
| `- YourPlugin/
|- virions/
| `- CustomToast/
| |- virion.yml
| |- src/
| `- resources/CustomToast/
`- DevTools.phar
DevTools loads one shared development copy of the PHP classes. CustomToast reads the resource pack directly from its virion source folder. No source or resource copying is required.
Production builds are standalone. DevTools shades CustomToast into a private namespace and stores its assets below the protected virion resource directory. A single DevTools-built CustomToast consumer is supported, including CustomToastExample. Do not run multiple independently shaded CustomToast consumers on the same server: they cannot share the static runtime coordinator and would compete for the same resource-pack UUID.
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.
Multiple folder plugins may use the same CustomToast source from the server's virions/CustomToast directory 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 development consumers use the same CustomToast source and presentation assets loaded by DevTools. The first plugin enabled by PocketMine-MP supplies the active pack file. This shared development runtime does not apply across separately shaded production PHARs.
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 folder plugins are supported when DevTools loads one shared development virion. One private DevTools-shaded production consumer is supported, but separately shaded PHARs cannot share the runtime coordinator.
- 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.
For development, confirm the source exists at virions/CustomToast/resources/CustomToast. For production, rebuild the host plugin with the declared CustomToast virion through DevTools and confirm the PHAR verifier reports the resource pack.
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.