Introduction
Lotus At A Glance
Lotus is a menu framework for Bukkit-based plugins. You describe a menu in terms of title, capacity, content, and button behavior, then Lotus handles the boring runtime work for you: opening inventories, tracking live views, dispatching clicks, repainting buttons, and building paginated screens.
If you are coming from raw Bukkit Inventory code, Lotus removes the three big pain points:
- slot math everywhere
- listener boilerplate everywhere
- state scattered across unrelated classes
Which module do you use?
Lotus is split into three modules:
| Module | Purpose | Use it directly? |
|---|---|---|
lotus-commons |
Shared core runtime and API | No |
lotus-paper |
Paper 1.21+ integration |
Yes, on Paper |
lotus-spigot |
Spigot 1.8.8 integration |
Yes, on Spigot |
You add exactly one platform module to your plugin: lotus-paper or lotus-spigot.
lotus-commons comes in automatically.
These docs are written against the current Lotus 2.x source API from the Lotus repository,
including the multi-module split and the platform-specific builders.
The Mental Model
You only need a few concepts to be productive:
Lotus<C>is the runtime you create once inonEnable().Menu<C>is the template that describes one screen.MenuView<C, M>is the live, per-player instance of that menu.Contentis the slot-to-button map inside a view.Buttonis the clickable or decorative thing placed in a slot.Pagination<T>is a reusable page definition that opens a fresh session per player.
The easiest way to think about Lotus is: a menu is a function of the current view state. When the state changes, Lotus can repaint what the player sees.
Quick Tour
Add the repository configuration that matches your build tool:
<repositories> <repository> <id>papermc-repo</id> <url>https://repo.papermc.io/repository/maven-public/</url> </repository> </repositories>}repositories { maven { url = 'https://repo.papermc.io/repository/maven-public/' } mavenCentral() }}repositories { maven("https://repo.papermc.io/repository/maven-public/") mavenCentral() }}
Then add the Paper artifact:
Minimal Paper setup:
public final class MyPlugin extends JavaPlugin {
private Lotus<Component> lotus;
@Override
public void onEnable() {
this.lotus = PaperLotus.create(this);
}
public void openWelcome(Player player) {
lotus.openMenu(player, new WelcomeMenu());
}
}
final class WelcomeMenu implements PaperMenu {
@Override
public Component title(MenuView<Component, ?> view) {
return Component.text("Welcome");
}
@Override
public Capacity capacity(MenuView<Component, ?> view) {
return Capacity.ofRows(3);
}
@Override
public Content content(MenuView<Component, ?> view) {
return Content.builder(view.capacity())
.fillBorder(Button.of(new ItemStack(Material.BLACK_STAINED_GLASS_PANE)))
.set(1, 4, Button.clickable(
new ItemStack(Material.PAPER),
(menuView, event) ->
menuView.viewer().sendMessage(Component.text("Hello from Lotus!"))
))
.build();
}
}
Add the repository configuration that matches your build tool:
<repositories> <repository> <id>spigotmc-repo</id> <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url> </repository> <repository> <id>sonatype-snapshots</id> <url>https://oss.sonatype.org/content/repositories/snapshots/</url> </repository> </repositories>}repositories { maven { url = 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' } maven { url = 'https://oss.sonatype.org/content/repositories/snapshots/' } mavenCentral() }}repositories { maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") maven("https://oss.sonatype.org/content/repositories/snapshots/") mavenCentral() }}
Then add the Spigot artifact:
Minimal Spigot setup:
public final class MyPlugin extends JavaPlugin {
private Lotus<String> lotus;
@Override
public void onEnable() {
this.lotus = SpigotLotus.create(this);
}
public void openWelcome(Player player) {
lotus.openMenu(player, new WelcomeMenu());
}
}
final class WelcomeMenu implements Menu<String> {
@Override
public String title(MenuView<String, ?> view) {
return ChatColor.GOLD + "Welcome";
}
@Override
public Capacity capacity(MenuView<String, ?> view) {
return Capacity.ofRows(3);
}
@Override
public Content content(MenuView<String, ?> view) {
return Content.builder(view.capacity())
.fillBorder(Button.of(new ItemStack(Material.STAINED_GLASS_PANE)))
.set(1, 4, Button.clickable(
new ItemStack(Material.PAPER),
(menuView, event) ->
menuView.viewer().sendMessage(ChatColor.YELLOW + "Hello from Lotus!")
))
.build();
}
}
On Paper, menu titles are Adventure Components. On Spigot, menu titles are plain
Strings, and Lotus uses that string as-is. If you want colors on Spigot, translate or build
the string yourself.
Read The Docs In This Order
- Getting Started to install the right artifact, shade it, and boot Lotus once.
- Your First Menu to build something that opens immediately.
- Capacity, Slots & Slot Masks to understand the grid model.
- Content and Slot Iterator to learn how Lotus stores buttons and how to place several objects in order.
- Menus to learn templates, live views, and handler hooks.
- Buttons to learn the six built-in button types.
- Pagination once you are ready for scrollable lists.