Overview
Modules are the official extension system for SuperiorSkyblock2. Unlike regular Bukkit plugins, modules are loaded and managed by SuperiorSkyblock itself, providing tighter integration and hot-reload capabilities.
Why Use Modules?
Hot Reload Enable, disable, and reload modules without restarting the server.
Managed Lifecycle SuperiorSkyblock handles listener and command registration automatically.
Integrated API Direct access to SuperiorSkyblock’s internal systems and data.
Organized Structure Dedicated folders for module code and data storage.
Module vs Plugin
Loaded by SuperiorSkyblock
Can be reloaded without server restart
Automatic listener/command management
Direct API access
Managed through /is admin modules
Loaded by server
Require full server restart
Manual listener/command registration
API access via dependency
Managed through server plugin system
Creating a Module
Basic Structure
import com.bgsoftware.superiorskyblock.api.SuperiorSkyblock;
import com.bgsoftware.superiorskyblock.api.modules.PluginModule;
import com.bgsoftware.superiorskyblock.api.commands.SuperiorCommand;
import org.bukkit.event.Listener;
public class MyModule extends PluginModule {
public MyModule () {
super ( "MyModule" , "AuthorName" );
}
@ Override
public void onEnable ( SuperiorSkyblock plugin ) {
// Module initialization
getLogger (). info ( "Module enabled!" );
}
@ Override
public void onReload ( SuperiorSkyblock plugin ) {
// Reload configuration/data
getLogger (). info ( "Module reloaded!" );
}
@ Override
public void onDisable ( SuperiorSkyblock plugin ) {
// Cleanup resources
getLogger (). info ( "Module disabled!" );
}
@ Override
public Listener [] getModuleListeners ( SuperiorSkyblock plugin ) {
// Return event listeners
return new Listener [] {
new MyListener ()
};
}
@ Override
public SuperiorCommand [] getSuperiorCommands ( SuperiorSkyblock plugin ) {
// Return player commands
return new SuperiorCommand [] {
new MyCommand ()
};
}
@ Override
public SuperiorCommand [] getSuperiorAdminCommands ( SuperiorSkyblock plugin ) {
// Return admin commands
return null ; // or return admin commands
}
}
Module Properties
Module Info
Module State
Resources
// Get module name
String getName ();
// Get module author
String getAuthor ();
Module Lifecycle
Load Stages
Modules can specify when they should be loaded:
@ Override
public ModuleLoadTime getLoadTime () {
return ModuleLoadTime . NORMAL ;
}
BEFORE_WORLD_CREATION
Loaded before worlds are created. Use if you need to override the WorldsProvider.
NORMAL
Default loading stage. Most modules should use this.
AFTER_HANDLERS_LOADING
Loaded after all plugin handlers are ready. Use if interacting with handlers in onEnable().
Lifecycle Methods
onEnable
onReload
onDisable
loadData
onPluginInit
@ Override
public void onEnable ( SuperiorSkyblock plugin) {
// Module initialization
// Register custom handlers
// Load configuration
// Initialize data structures
}
Called when the module is loaded/enabled. @ Override
public void onReload ( SuperiorSkyblock plugin) {
// Reload configuration files
// Refresh cached data
// Re-initialize changed systems
}
Called when /is admin reload is executed. @ Override
public void onDisable ( SuperiorSkyblock plugin) {
// Save data
// Cancel tasks
// Close connections
// Clean up resources
}
Called when the module is disabled. @ Override
public void loadData ( SuperiorSkyblock plugin) {
// Load player-specific data
// Load island-specific data
// Initialize database connections
}
Called after plugin data is loaded (similar to PluginInitializedEvent). @ Override
protected void onPluginInit ( SuperiorSkyblock plugin) {
// First-time initialization only
// Create configuration files
// Set up defaults
}
Called once when the module is first initialized.
Event Listeners
Modules return event listeners that are automatically managed:
@ Override
public Listener [] getModuleListeners ( SuperiorSkyblock plugin) {
return new Listener [] {
new IslandListener ( this ),
new PlayerListener ( this ),
new CustomEventListener ( this )
};
}
Listeners are automatically registered when the module enables and unregistered when it disables.
Example Listener
public class IslandListener implements Listener {
private final MyModule module ;
public IslandListener ( MyModule module ) {
this . module = module;
}
@ EventHandler
public void onIslandCreate ( IslandCreateEvent event ) {
Island island = event . getIsland ();
SuperiorPlayer player = event . getPlayer ();
module . getLogger (). info (
player . getName () + " created island " + island . getUniqueId ()
);
}
}
Commands
Modules can provide both player and admin commands:
Player Commands
@ Override
public SuperiorCommand [] getSuperiorCommands ( SuperiorSkyblock plugin) {
return new SuperiorCommand [] {
new InfoCommand (),
new ListCommand ()
};
}
Admin Commands
@ Override
public SuperiorCommand [] getSuperiorAdminCommands ( SuperiorSkyblock plugin) {
return new SuperiorCommand [] {
new GiveCommand (),
new SetCommand ()
};
}
Return null if your module doesn’t provide commands of that type.
File Management
Module Folders
Module Folder
Data Store Folder
// plugins/SuperiorSkyblock2/modules/{module-name}/
File moduleFolder = getModuleFolder ();
// Store configuration files, resources
File config = new File (moduleFolder, "config.yml" );
Resource Management
// Save embedded resource from jar
saveResource ( "config.yml" );
saveResource ( "lang/en-US.yml" );
// Read resource from jar
InputStream stream = getResource ( "defaults.yml" );
Configuration Example
public class MyModule extends PluginModule {
private FileConfiguration config ;
@ Override
public void onEnable ( SuperiorSkyblock plugin ) {
// Save default config if not exists
File configFile = new File ( getModuleFolder (), "config.yml" );
if ( ! configFile . exists ()) {
saveResource ( "config.yml" );
}
// Load config
config = YamlConfiguration . loadConfiguration (configFile);
getLogger (). info ( "Loaded configuration!" );
}
@ Override
public void onReload ( SuperiorSkyblock plugin ) {
// Reload config
File configFile = new File ( getModuleFolder (), "config.yml" );
config = YamlConfiguration . loadConfiguration (configFile);
getLogger (). info ( "Reloaded configuration!" );
}
public FileConfiguration getConfig () {
return config;
}
}
Accessing SuperiorSkyblock API
Modules have direct access to the SuperiorSkyblock API:
@ Override
public void onEnable ( SuperiorSkyblock plugin) {
// Get managers
GridManager gridManager = plugin . getGrid ();
PlayersManager playersManager = plugin . getPlayers ();
// Access islands
for ( Island island : gridManager . getIslands ()) {
getLogger (). info ( "Island: " + island . getName ());
}
// Access players
for ( SuperiorPlayer player : playersManager . getAllPlayers ()) {
getLogger (). info ( "Player: " + player . getName ());
}
}
Module Logger
// Get module-specific logger
Logger logger = getLogger ();
logger . info ( "Information message" );
logger . warning ( "Warning message" );
logger . severe ( "Error message" );
Log messages are prefixed with [SuperiorSkyblock2] [ModuleName].
Advanced: Module Initialization
These methods are for advanced usage. SuperiorSkyblock calls them automatically.
// Initialize module (called by SuperiorSkyblock)
void initModule ( SuperiorSkyblock plugin, ModuleInitializeData context);
// Initialize loader settings
void initModuleLoader ( File moduleFile, ClassLoader classLoader);
// Disable module
void disableModule ();
Complete Module Example
public class RewardsModule extends PluginModule {
private FileConfiguration config ;
private Map < UUID , Integer > dailyRewards = new HashMap <>();
public RewardsModule () {
super ( "DailyRewards" , "YourName" );
}
@ Override
public void onEnable ( SuperiorSkyblock plugin ) {
// Load config
File configFile = new File ( getModuleFolder (), "config.yml" );
if ( ! configFile . exists ()) {
saveResource ( "config.yml" );
}
config = YamlConfiguration . loadConfiguration (configFile);
// Load data
loadRewardsData ();
// Start daily reset task
startResetTask (plugin);
getLogger (). info ( "Daily rewards module enabled!" );
}
@ Override
public void onReload ( SuperiorSkyblock plugin ) {
File configFile = new File ( getModuleFolder (), "config.yml" );
config = YamlConfiguration . loadConfiguration (configFile);
getLogger (). info ( "Configuration reloaded!" );
}
@ Override
public void onDisable ( SuperiorSkyblock plugin ) {
// Save data
saveRewardsData ();
getLogger (). info ( "Daily rewards module disabled!" );
}
@ Override
public void loadData ( SuperiorSkyblock plugin ) {
// Load player-specific reward data
loadRewardsData ();
}
@ Override
public Listener [] getModuleListeners ( SuperiorSkyblock plugin ) {
return new Listener [] {
new RewardListener ( this )
};
}
@ Override
public SuperiorCommand [] getSuperiorCommands ( SuperiorSkyblock plugin ) {
return new SuperiorCommand [] {
new DailyCommand ( this )
};
}
@ Override
public SuperiorCommand [] getSuperiorAdminCommands ( SuperiorSkyblock plugin ) {
return new SuperiorCommand [] {
new ResetCommand ( this )
};
}
private void loadRewardsData () {
File dataFile = new File ( getDataStoreFolder (), "rewards.yml" );
if ( dataFile . exists ()) {
FileConfiguration data = YamlConfiguration . loadConfiguration (dataFile);
for ( String key : data . getKeys ( false )) {
UUID uuid = UUID . fromString (key);
int count = data . getInt (key);
dailyRewards . put (uuid, count);
}
}
}
private void saveRewardsData () {
File dataFile = new File ( getDataStoreFolder (), "rewards.yml" );
FileConfiguration data = new YamlConfiguration ();
for ( Map . Entry < UUID , Integer > entry : dailyRewards . entrySet ()) {
data . set ( entry . getKey (). toString (), entry . getValue ());
}
try {
data . save (dataFile);
} catch ( IOException e ) {
getLogger (). severe ( "Failed to save rewards data!" );
}
}
private void startResetTask ( SuperiorSkyblock plugin ) {
// Reset daily rewards at midnight
// Implementation details...
}
public int getRewardCount ( UUID player ) {
return dailyRewards . getOrDefault (player, 0 );
}
public void incrementReward ( UUID player ) {
dailyRewards . put (player, getRewardCount (player) + 1 );
}
}
Module Commands Management
Commands are managed through /is admin modules:
/is admin modules list - List all modules
/is admin modules load <name> - Load a module
/is admin modules unload <name> - Unload a module
/is admin modules reload <name> - Reload a module
Best Practices
Save on Disable Always save data in onDisable() to prevent data loss.
Handle Reload Implement onReload() properly to support runtime changes.
Use Separate Data Folder Store databases in getDataStoreFolder(), not getModuleFolder().
Check Initialization Use isInitialized() before accessing module resources.
Return Null for No Commands If your module has no commands, return null instead of empty array.
Log Important Events Use getLogger() to log initialization, errors, and important events.
Packaging a Module
Create module.yml
name : MyModule
main : com.example.MyModule
version : 1.0.0
author : YourName
Build JAR file
Compile your module into a JAR with dependencies.
Place in modules folder
Put the JAR in plugins/SuperiorSkyblock2/modules/
Load module
Use /is admin modules load MyModule or restart server.
See Also
API Reference Complete API documentation
Events SuperiorSkyblock events
Commands Creating custom commands
Examples Module examples and templates