Advanced

Advanced

This page collects the less-common but still important knobs in Lotus: runtime options, helpers, custom openers, and extension boundaries.

Lotus.Options

Runtime options are configured when you create the Lotus instance:

Lotus<Component> lotus = PaperLotus.create(this, builder -> builder
    .allowBottomInventoryClick(false)
    .dynamicButtonAction(false)
    .debug(true)
);
Option Default What it means
allowBottomInventoryClick true Allow clicks in the player's own inventory while a Lotus menu is open
dynamicButtonAction false Let Lotus internally move buttons during pickup/place inventory actions
debug false Enable [lotus] debug logging

Read them back with lotus.options().

ItemBuilder

Both platform modules ship an ItemBuilder tuned to the platform's text API.

{`

ItemStack sword = ItemBuilder.of(Material.DIAMOND_SWORD) .displayName(Component.text("Legendary Blade").color(NamedTextColor.AQUA)) .lore( Component.text("A very sharp blade").color(NamedTextColor.GRAY), Component.text("Tier: Legendary").color(NamedTextColor.GOLD) ) .amount(1) .unbreakable(true) .build(); }</CodeTabItem> <CodeTabItem value="spigot" label="Spigot 1.8.8" language="java">{

ItemStack sword = ItemBuilder.of(Material.DIAMOND_SWORD) .displayName("&bLegendary Blade") .lore("&7A very sharp blade", "&6Tier: Legendary") .amount(1) .unbreakable(true) .build(); `}

On Spigot, ItemBuilder translates & color codes for item names and lore.

Register Menus By Name

lotus.registerMenu(new ShopMenu());
lotus.openMenu(player, "shop");
lotus.registeredMenu("shop");

This is handy for command-driven or config-driven menus.

Inspect Open Views

lotus.viewOf(player);
lotus.openViews();

Common pattern:

for (MenuView<?, ?> view : lotus.openViews()) {
    if (view.menu() instanceof ShopMenu) {
        view.refresh();
    }
}

Custom ViewOpener

If you need a special open path for a specific InventoryType, register a custom opener.

{` lotus.registerOpener(InventoryType.HOPPER, (framework, view) -> { Inventory inventory = Bukkit.createInventory( view, InventoryType.HOPPER, Component.text("Quick Actions") );
view.content().forEach((slot, button) -> inventory.setItem(slot.index(), button.item()));
view.viewer().openInventory(inventory);
return inventory;

}); }</CodeTabItem> <CodeTabItem value="spigot" label="Spigot 1.8.8" language="java">{ lotus.registerOpener(InventoryType.HOPPER, (framework, view) -> { Inventory inventory = Bukkit.createInventory(view, InventoryType.HOPPER, "Quick Actions");

view.content().forEach((slot, button) -> inventory.setItem(slot.index(), button.item()));
view.viewer().openInventory(inventory);
return inventory;

}); `}

ViewOpener is part of the public spi package, so extending it is a supported customization path.

Pagination Sync Helpers

When a shared data source changes, you may want to refresh already-open pagination views without tracking every session yourself.

Use the pagination definition ID, which is the string passed to Pagination.builder("...").

{` PaperLotus.syncOpenPagination(lotus, "shop", player); PaperLotus.syncOpenPagination(lotus, "shop"); `} {` SpigotLotus.syncOpenPagination(lotus, "shop", player); SpigotLotus.syncOpenPagination(lotus, "shop"); `}

The one-player overload refreshes a specific player's currently open pagination if it matches the ID. The two-argument overload scans all open views managed by that Lotus runtime and refreshes the matching ones.

Error Handling

If a button throws a RuntimeException, Lotus catches it, logs the problem, and keeps the menu usable:

[lotus] button dispatch failed in menu <name>

You can also log your own messages through lotus.logger().

Public Surface vs Internal Surface

The stable extension points live in:

  • studio.mevera.lotus.api.*
  • studio.mevera.lotus.spi.*

Avoid importing internal.* classes. They are implementation details and are not the public compatibility surface.

High-Level Package Map

lotus-commons
  studio.mevera.lotus
    Lotus, LotusBuilder
    api.button
    api.content
    api.data
    api.item
    api.menu
    api.pagination
    api.slot
    spi

lotus-paper
  studio.mevera.lotus.paper
    PaperLotus
    ItemBuilder
    api.menu
    api.pagination

lotus-spigot
  studio.mevera.lotus.spigot
    SpigotLotus
    ItemBuilder
    api.pagination

That is the practical import surface most plugin authors work with.