The official API documentation for building custom plugins.
Welcome to the SlothLite API! Building a configuration panel for your custom plugin is designed to be incredibly simple. You do not need to know how to write complex Java Swing layouts—our PluginPanel base class handles all the sizing, colors, fonts, and borders for you.
To create a plugin, you just need to follow three steps: Define the Descriptor, build the UI, and link your Variables.
Every plugin must start with the @PluginDescriptor annotation. This tells the SlothLite engine how to classify your plugin, where to put it in the UI, and how it should appear on the Plugin Hub.
import src.main.java.util.plugins.PluginDescriptor;
import src.main.java.util.PluginPanel;
@PluginDescriptor(
name = "My Custom Plugin",
description = "A brief description of what this does.",
cardKey = "MY_CUSTOM_PLUGIN", // A UNIQUE identifier for the UI engine
hasButton = false // Set to true ONLY if you want a dedicated icon on the sidebar
// iconPath = "/icons/my_icon.png" // Required if hasButton is true
)
public class MyCustomPlugin extends PluginPanel {
// ...
}
SlothLite UI is dynamic. Instead of trying to update individual buttons when a setting changes, we use a "Clear and Rebuild" architecture. Whenever your plugin panel is opened, or a sub-menu is toggled, you call rebuildPanel(). You must always start this method with this.removeAll();.
// 1. The Constructor
public MyCustomPlugin(GameCanvas canvas, client clientInstance) {
super(canvas, clientInstance);
rebuildPanel(); // Generate the UI when the class is loaded
}
// 2. The UI Builder
@Override
public void rebuildPanel() {
this.removeAll(); // CRITICAL: Clear old UI elements first!
// Add the standard Top Header & Main On/Off Switch
addHeader(isPluginEnabled(), "My Custom Plugin",
e -> closePanel(),
(isEnabled) -> onToggle(isEnabled)
);
// ... Add your buttons, toggles, and dropdowns here ...
this.revalidate();
this.repaint();
}
Inside your rebuildPanel() method, you can use our built-in helper methods to instantly generate styled controls. These methods take a Consumer (Lambda) to immediately apply the setting when the user changes it.
addToggle("Draw Overlays", Config.myToggleVar, (isEnabled) -> {
Config.myToggleVar = isEnabled;
});
addTextField("Target NPC", Config.myTargetNpc, (text) -> {
Config.myTargetNpc = text;
});
String[] options = {"Low", "Medium", "High"};
addDropdown("Detail Level", options, Config.myDropdownVar, (selectedIndex) -> {
Config.myDropdownVar = selectedIndex;
});
// Integer Scaler (e.g., Opacity 0 to 100)
addScaler("Opacity", Config.myOpacityVar, 0, 100, (newVal) -> {
Config.myOpacityVar = newVal;
});
// Double Scaler (e.g., Border thickness 0.1 to 5.0)
addDoubleScaler("Border Width", Config.myBorderVar, 0.1, 5.0, (newVal) -> {
Config.myBorderVar = newVal;
});
addColorPicker("Highlight Color", Config.myColorVar, (newColor) -> {
Config.myColorVar = newColor;
});
If you have a lot of settings, you can hide them behind a collapsible header.
// 1. Define a class variable to track the state
private boolean isMenuExpanded = false;
// ... inside rebuildPanel() ...
// 2. Add the sub-header
addSubHeader(isMenuExpanded, "Advanced Settings", e -> {
isMenuExpanded = !isMenuExpanded; // Flip the state
rebuildPanel(); // Refresh the UI to show/hide contents
}, null);
// 3. Wrap the hidden settings in an IF statement
if (isMenuExpanded) {
addToggle("Debug Mode", Config.myDebugVar, (isEnabled) -> Config.myDebugVar = isEnabled);
}
src.main.java.util.plugins package. The engine will auto-detect it on startup..class files into a .jar. Place the .jar on the VPS server and add its details to the hub.php registry. The client will automatically handle the download, injection, and UI building in real-time.