Documentation Index
Fetch the complete documentation index at: https://mintlify.com/BG-Software-LLC/SuperiorSkyblock2/llms.txt
Use this file to discover all available pages before exploring further.
Creating Custom Modules
Plugin modules are similar to plugins but designed specifically for SuperiorSkyblock2. They offer hot-reload capabilities and automatic listener/command management without server restarts.
Module Structure
Create a class that extends PluginModule:
import com.bgsoftware.superiorskyblock.api.SuperiorSkyblock;
import com.bgsoftware.superiorskyblock.api.modules.PluginModule;
import com.bgsoftware.superiorskyblock.api.modules.ModuleLoadTime;
import com.bgsoftware.superiorskyblock.api.commands.SuperiorCommand;
import org.bukkit.event.Listener;
public class MyCustomModule extends PluginModule {
public MyCustomModule() {
super("MyCustomModule", "YourName");
}
@Override
public void onEnable(SuperiorSkyblock plugin) {
// Module initialization logic
getLogger().info("MyCustomModule has been enabled!");
}
@Override
public void onReload(SuperiorSkyblock plugin) {
// Handle module reload
getLogger().info("MyCustomModule has been reloaded!");
}
@Override
public void onDisable(SuperiorSkyblock plugin) {
// Cleanup logic
getLogger().info("MyCustomModule has been disabled!");
}
@Override
public Listener[] getModuleListeners(SuperiorSkyblock plugin) {
// Return your listeners (auto-registered)
return new Listener[] { new MyListener() };
}
@Override
public SuperiorCommand[] getSuperiorCommands(SuperiorSkyblock plugin) {
// Return player commands
return null;
}
@Override
public SuperiorCommand[] getSuperiorAdminCommands(SuperiorSkyblock plugin) {
// Return admin commands
return null;
}
}
Lifecycle Methods
onEnable
Called when the module is enabled. Initialize your module resources here.@Override
public void onEnable(SuperiorSkyblock plugin) {
saveResource("config.yml");
// Load configuration
// Initialize managers
}
loadData
Called after the plugin’s data is loaded. Load player/island data here.@Override
public void loadData(SuperiorSkyblock plugin) {
// Load module data from database
File dataFile = new File(getDataStoreFolder(), "data.yml");
// Load your data
}
onReload
Called when the module is reloaded via commands.@Override
public void onReload(SuperiorSkyblock plugin) {
// Reload configuration
// Reset cached data
}
onDisable
Called when the module is disabled. Clean up resources.@Override
public void onDisable(SuperiorSkyblock plugin) {
// Save data
// Close connections
// Unregister resources
}
Module Load Time
Control when your module loads by overriding getLoadTime():
@Override
public ModuleLoadTime getLoadTime() {
return ModuleLoadTime.AFTER_HANDLERS_LOADING;
}
Available Load Times
| Load Time | Description |
|---|
PLUGIN_INITIALIZE | Loaded before plugin initialization. Listen to PluginInitializeEvent |
BEFORE_WORLD_CREATION | Loaded before island worlds are created |
NORMAL | Default load time. Worlds loaded but managers not yet ready |
AFTER_MODULE_DATA_LOAD | Loaded after loadData() is called |
AFTER_HANDLERS_LOADING | Loaded after all plugin managers are ready |
Most modules should use AFTER_HANDLERS_LOADING to ensure all plugin managers are available.
Resource Management
Modules have dedicated folders for organization:
// Module folder: plugins/SuperiorSkyblock2/modules/{module-name}/
File moduleFolder = getModuleFolder();
// Data storage: plugins/SuperiorSkyblock2/datastore/modules/{module-name}/
File dataFolder = getDataStoreFolder();
// Module JAR file
File jarFile = getModuleFile();
// Save embedded resources
saveResource("config.yml");
// Get resource as InputStream
InputStream resource = getResource("data.json");
Complete Example
public class RewardsModule extends PluginModule {
private RewardsConfig config;
private RewardsManager manager;
public RewardsModule() {
super("RewardsModule", "Author");
}
@Override
public ModuleLoadTime getLoadTime() {
return ModuleLoadTime.AFTER_HANDLERS_LOADING;
}
@Override
public void onEnable(SuperiorSkyblock plugin) {
// Save default config
saveResource("config.yml");
// Load configuration
File configFile = new File(getModuleFolder(), "config.yml");
this.config = new RewardsConfig(configFile);
// Initialize manager
this.manager = new RewardsManager(plugin, config);
getLogger().info("RewardsModule enabled successfully!");
}
@Override
public void loadData(SuperiorSkyblock plugin) {
// Load reward data from database
manager.loadRewardData(getDataStoreFolder());
}
@Override
public void onReload(SuperiorSkyblock plugin) {
config.reload();
manager.reload();
}
@Override
public void onDisable(SuperiorSkyblock plugin) {
manager.saveData();
manager.shutdown();
}
@Override
public Listener[] getModuleListeners(SuperiorSkyblock plugin) {
return new Listener[] {
new IslandRewardListener(manager),
new PlayerRewardListener(manager)
};
}
@Override
public SuperiorCommand[] getSuperiorCommands(SuperiorSkyblock plugin) {
return new SuperiorCommand[] {
new RewardsCommand(manager)
};
}
@Override
public SuperiorCommand[] getSuperiorAdminCommands(SuperiorSkyblock plugin) {
return new SuperiorCommand[] {
new RewardsAdminCommand(manager)
};
}
public RewardsManager getManager() {
return manager;
}
}
Never call initModule(), initModuleLoader(), or disableModule() manually. These are managed by SuperiorSkyblock2.
Building and Deployment
Package your module
Build your module as a JAR file with all dependencies.<!-- Maven example -->
<build>
<finalName>MyCustomModule</finalName>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Deploy to modules folder
Place your JAR in plugins/SuperiorSkyblock2/modules/
Load the module
Use /is admin modules to manage modules without restarting the server.
Best Practices
- Use
getLogger() instead of creating your own logger
- Store configuration in
getModuleFolder()
- Store persistent data in
getDataStoreFolder()
- Return
null from listener/command methods if you have none
- Use
AFTER_HANDLERS_LOADING unless you need earlier access
- Always clean up resources in
onDisable()
- Handle
onReload() properly to support runtime configuration changes