Form Library for PocketMine (Minecraft PE)
LibForm is a PHP library that simplifies the creation of Minecraft forms in PocketMine. It offers two approaches:
-
Class-based
Extend abstract classes to define form structure, elements, and behavior. Passingtrueas the third constructor argument automatically sends the form to the player. -
Dynamic (Fluent Interface)
Build forms on-the-fly using method chaining. Ideal for quick, concise form creation without defining separate classes.
Supported form types:
- List Form (LongForm)
- Modal Form
- Custom Form
Add LibForm to your project with Composer:
composer require imperazim/libformThen include classes under the imperazim\form namespace.
A scrollable list of buttons, optionally with custom textures or icons.
-
Extend
LongForm -
Override three methods:
title(): returns aTitleobject.content(): returns aContentobject.buttons(): returns aButtonCollection. EachButtoncan have a texture and a callback viaButtonResponse.
-
Instantiate with
trueto automatically send to the player.
use imperazim\form\long\LongForm;
use imperazim\form\long\elements\Button;
use imperazim\form\long\elements\ButtonTexture;
use imperazim\form\long\elements\ButtonCollection;
use imperazim\form\long\response\ButtonResponse;
use imperazim\form\base\Title;
use imperazim\form\base\Content;
class MyListForm extends LongForm {
protected function title(Player $player, FormData $formData): Title {
return new Title('Main Menu');
}
protected function content(Player $player, FormData $formData): Content {
return new Content('Select an option:');
}
protected function buttons(Player $player, FormData $formData): ButtonCollection {
return ButtonCollection::fromArray([
new Button(
'Option 1',
new ButtonTexture('textures/ui/icon_recipe', ButtonTexture::PATH),
new ButtonResponse(function(Player $player): FormResult {
$player->sendMessage("You clicked Option 1!");
return FormResult::CLOSE;
})
),
new Button(
'Option 2',
null,
new ButtonResponse(function(Player $player): FormResult {
$player->sendMessage("Option 2 selected.");
return FormResult::CLOSE;
})
),
]);
}
}
// Instantiation sends the form immediately:
new MyListForm($player, $formData, true);-
Call
DynamicLongForm::create($title). -
Chain methods:
setContent($text)addButton($text, $texturePathOrNull, $callback)sendTo($player)
use imperazim\form\long\DynamicLongForm;
DynamicLongForm::create("Quick Menu")
->setContent("What do you want to do?")
->addButton(
"Status",
'textures/blocks/diamond_block',
function(Player $player): FormResult {
$player->sendMessage("Status chosen!");
return FormResult::CLOSE;
}
)
->addButton(
"Settings",
null,
function(Player $player): FormResult {
$player->sendMessage("Opening settings...");
return FormResult::CLOSE;
}
)
->sendTo($player);A two-button confirmation dialog (confirm/cancel).
-
Extend
ModalForm. -
Override four methods:
title(): returns aTitle.content(): returns aContent.button1(): typicallyModalButton::confirm($text).button2(): typicallyModalButton::cancel($text).
-
Implement
onConfirm()to handle the “confirm” action. Optionally overrideonCancel()for custom “cancel” behavior. -
Instantiate with
trueto send immediately.
use imperazim\form\modal\ModalForm;
use imperazim\form\modal\elements\ModalButton;
use imperazim\form\base\Title;
use imperazim\form\base\Content;
class ConfirmationForm extends ModalForm {
protected function title(Player $player, FormData $formData): Title {
return new Title('Confirmation');
}
protected function content(Player $player, FormData $formData): Content {
return new Content('Are you sure you want to delete this item?');
}
protected function button1(Player $player, FormData $formData): ModalButton {
return ModalButton::confirm('Yes');
}
protected function button2(Player $player, FormData $formData): ModalButton {
return ModalButton::cancel('No');
}
protected function onConfirm(Player $player, FormData $formData): FormResult {
$player->sendMessage('Item deleted!');
return FormResult::CLOSE;
}
// Optionally:
// protected function onCancel(Player $player, FormData $formData): FormResult { ... }
}
// Sends the form automatically:
new ConfirmationForm($player, $formData, true);-
Call
DynamicModalForm::create($title). -
Chain methods:
setContent($text)setButton1($text, $callback)setButton2($text, $callback)sendTo($player)
use imperazim\form\modal\DynamicModalForm;
DynamicModalForm::create("Save Changes")
->setContent("Do you want to save your changes?")
->setButton1("Save", function(Player $player, ModalResponse $response): FormResult {
$player->sendMessage('Changes saved!');
return FormResult::CLOSE;
})
->setButton2("Cancel", function(Player $player, ModalResponse $response): FormResult {
$player->sendMessage('Operation canceled.');
return FormResult::CLOSE;
})
->sendTo($player);A flexible form with multiple input elements (text fields, toggles, sliders, dropdowns, etc.).
-
Extend
CustomForm. -
Override two methods:
title(): returns aTitle.elements(): returns anElementCollectionbuilt from individual element objects (Label,Input,Toggle,Slider,Dropdown,StepSlider).
-
Implement
onSubmit()to process submitted values viaCustomResponse. -
Instantiate with
trueto send immediately.
use imperazim\form\custom\CustomForm;
use imperazim\form\custom\elements\ElementCollection;
use imperazim\form\custom\elements\Input;
use imperazim\form\custom\elements\Toggle;
use imperazim\form\custom\elements\Slider;
use imperazim\form\custom\elements\Dropdown;
use imperazim\form\custom\elements\Option;
use imperazim\form\custom\response\CustomResponse;
use imperazim\form\base\Title;
class SettingsForm extends CustomForm {
protected function title(Player $player, FormData $formData): Title {
return new Title('General Settings');
}
protected function elements(Player $player, FormData $formData): ElementCollection {
return ElementCollection::fromArray([
new Input('username', 'Username:', 'Type your name', $player->getName()),
new Toggle('notifications', 'Enable notifications?', true),
new Slider('volume', 'Sound Volume', 0, 100, 1, 50),
new Dropdown('language', 'Language', [
new Option('en', 'English'),
new Option('es', 'Spanish'),
new Option('pt', 'Portuguese')
], 'en')
]);
}
protected function onSubmit(Player $player, CustomResponse $response): FormResult {
$username = $response->getInput('username');
$volume = $response->getSlider('volume');
$languageId = $response->getSelectedOption('language')->getId();
$player->sendMessage("Settings saved: $username, Volume $volume, Language $languageId");
return FormResult::CLOSE;
}
}
// Sends the form automatically:
new SettingsForm($player, $formData, true);-
Call
DynamicCustomForm::create($title). -
Chain methods:
addElement($elementObject)for each element.setOnSubmit($callback)to handle submission.sendTo($player)to display.
use imperazim\form\custom\DynamicCustomForm;
use imperazim\form\custom\elements\Input;
use imperazim\form\custom\elements\Toggle;
DynamicCustomForm::create("Player Profile")
->addElement(new Input('nickname', 'Nickname:', 'Enter your nickname...', $player->getName()))
->addElement(new Toggle('pvp', 'Enable PvP?', false))
->setOnSubmit(function(Player $player, CustomResponse $response): FormResult {
$nick = $response->getInput('nickname');
$pvpStatus = $response->getToggle('pvp') ? 'enabled' : 'disabled';
$player->sendMessage("Nickname: $nick | PvP: $pvpStatus");
return FormResult::CLOSE;
})
->sendTo($player);| Element | Description | Example Creation |
|---|---|---|
| Label | Informational, non-interactive text | new Label('Welcome!') |
| Input | Text input field | new Input('id', 'Label', 'Placeholder', 'Default value') |
| Toggle | On/off switch | new Toggle('id', 'Enable feature?', true) |
| Slider | Numeric range selector | new Slider('id', 'Volume', 0, 100, 5, 50) |
| Dropdown | Single-select option list | new Dropdown('id', 'Choose a color', [new Option('r','Red')], 'r') |
| StepSlider | Visual step selector | new StepSlider('id', 'Difficulty', [new Option('easy','Easy')], 'easy') |
Use FormData to share data between forms:
use imperazim\form\FormData;
// Create FormData with initial values:
$formData = new FormData([
'playerName' => $player->getName(),
'score' => 1000,
]); // Instantiate FormData and optional, the parameter accepts arrays!
// Retrieve values in any form:
$playerName = $formData->get('playerName'); // string
$score = $formData->get('score'); // int
or
$playerName = $formData['playerName']; // string
$score = $formData['score']; // int After a form interaction, return one of:
- FormResult::CLOSE — close the form for the player.
- FormResult::KEEP — keep the form open (e.g., for validation, re-prompt).
protected function onSubmit(Player $player, CustomResponse $response): FormResult {
// If "name" is empty, show an error and keep the form open:
if ($response->getInput('name') === '') {
$player->sendMessage("The 'name' field cannot be empty!");
return FormResult::KEEP;
}
// Otherwise, close the form:
return FormResult::CLOSE;
}This example registers a /testform command to open different types of forms:
namespace your\plugin\namespace;
use pocketmine\plugin\PluginBase;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\player\Player;
use imperazim\form\FormData;
use imperazim\form\long\DynamicLongForm;
use imperazim\form\modal\DynamicModalForm;
use imperazim\form\custom\DynamicCustomForm;
class Main extends PluginBase {
public function onEnable(): void {
$this->getServer()->getCommandMap()->register('testform', new FormCommand());
}
}
class FormCommand extends Command {
public function __construct() {
parent::__construct("testform", "Test command for forms", "/testform <type>");
}
public function execute(CommandSender $sender, string $label, array $args): void {
if (!$sender instanceof Player) {
$sender->sendMessage("This command can only be used by a player.");
return;
}
$type = $args[0] ?? '';
switch (strtolower($type)) {
case 'long':
// Class-based ListForm (auto-sent)
new MyListForm($sender, new FormData(), true);
break;
case 'long_dynamic':
// Dynamic ListForm
DynamicLongForm::create("Quick Menu")
->setContent("Choose:")
->addButton("Option A", null, fn(Player $p) => FormResult::CLOSE)
->sendTo($sender);
break;
case 'custom':
// Class-based CustomForm (auto-sent)
new SettingsForm($sender, new FormData(), true);
break;
case 'modal_dynamic':
// Dynamic ModalForm
DynamicModalForm::create("Confirmation")
->setContent("Do you wish to continue?")
->setButton1("Yes", fn(Player $p, $r) => FormResult::CLOSE)
->setButton2("No", fn(Player $p, $r) => FormResult::CLOSE)
->sendTo($sender);
break;
default:
$sender->sendMessage("Usage: /testform <long|long_dynamic|custom|modal_dynamic>");
}
}
}