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.
Overview
Missions provide objectives for players and islands to complete, offering rewards and progression. The mission system supports both player-specific missions and island-wide missions with customizable requirements and tracking.
Mission Architecture
Missions in SuperiorSkyblock2 are built on an extensible abstract class:
public abstract class Mission < V > {
// V is the data type stored per player/island
}
The generic type V represents the data structure used to track progress for this mission.
Core Components
Mission Properties
// Mission identification
String getName ();
void setName ( String name);
// Category
MissionCategory getMissionCategory ();
void setMissionCategory ( MissionCategory category);
Mission Types
Player Missions
Track individual player progress:
mission . setIslandMission ( false );
// Progress is tracked per player
// Examples: Kill 100 zombies, mine 500 stone, craft 50 tools
Island Missions
Track collective island progress:
mission . setIslandMission ( true );
// Progress is tracked per island (via owner)
// Examples: Reach island level 100, have 10 members, place 1000 spawners
Player Mission Example
Island Mission Example
public class KillMobsMission extends Mission < Integer > {
private int requiredKills ;
@ Override
public void load ( JavaPlugin plugin , ConfigurationSection section ) {
requiredKills = section . getInt ( "required-kills" , 100 );
setIslandMission ( false ); // Player-specific
}
@ Override
public double getProgress ( SuperiorPlayer player ) {
Integer kills = get (player);
return kills == null ? 0.0 : Math . min ( 1.0 , ( double ) kills / requiredKills);
}
}
public class IslandLevelMission extends Mission < Void > {
private int requiredLevel ;
@ Override
public void load ( JavaPlugin plugin , ConfigurationSection section ) {
requiredLevel = section . getInt ( "required-level" , 100 );
setIslandMission ( true ); // Island-wide
}
@ Override
public double getProgress ( SuperiorPlayer player ) {
Island island = player . getIsland ();
if (island == null ) return 0.0 ;
BigDecimal level = island . getIslandLevel ();
return Math . min ( 1.0 , level . doubleValue () / requiredLevel);
}
}
Mission Lifecycle
Loading Missions
@ Override
public void load ( JavaPlugin plugin, ConfigurationSection section)
throws MissionLoadException {
// Load configuration
// Set up requirements
// Initialize data structures
// Register listeners if needed
}
Parse Configuration
Read mission parameters from the config section
Validate Data
Check for required fields and valid values
Initialize Tracking
Set up data structures for progress tracking
Register Listeners
Register Bukkit event listeners if needed
Unloading Missions
@ Override
public void unload () {
// Unregister listeners
// Clean up resources
// Note: Progress data is saved automatically
}
Do not save progress data in unload(). SuperiorSkyblock handles this automatically.
Progress Tracking
Progress Calculation
@ Override
public abstract double getProgress ( SuperiorPlayer player);
Return a value between 0.0 and 1.0:
0.0 = No progress
0.5 = 50% complete
1.0 = 100% complete (can complete)
Progress Value
@ Override
public int getProgressValue ( SuperiorPlayer player) {
// Return the actual progress number
// e.g., 47 out of 100 kills
return 47 ;
}
This is used for displaying progress to players.
Completion Check
public boolean canComplete ( SuperiorPlayer player) {
return getProgress (player) >= 1.0 ;
}
Data Management
Storing Mission Data
Insert Data
Get Data
Clear Data
// Store data for a player
public void insertData ( SuperiorPlayer player, V value) {
// Automatically handles player vs island missions
}
Data Key Resolution
@ Nullable
protected SuperiorPlayer getDataKey ( SuperiorPlayer player) {
if (islandMission) {
Island island = player . getIsland ();
return island == null ? null : island . getOwner ();
}
return player;
}
Island missions use the island owner as the data key, so all island members share progress.
Completion Handlers
On Complete
@ Override
public abstract void onComplete ( SuperiorPlayer player);
Called when a player successfully completes the mission:
@ Override
public void onComplete ( SuperiorPlayer player) {
// Give rewards
player . sendMessage ( "Mission completed!" );
// Execute commands
Bukkit . dispatchCommand ( Bukkit . getConsoleSender (),
"eco give " + player . getName () + " 1000" );
// Grant items
player . asPlayer (). getInventory (). addItem ( new ItemStack ( Material . DIAMOND , 10 ));
}
On Complete Fail
@ Override
public abstract void onCompleteFail ( SuperiorPlayer player);
Called when a player tries to complete but requirements aren’t met:
@ Override
public void onCompleteFail ( SuperiorPlayer player) {
double progress = getProgress (player) * 100 ;
player . sendMessage ( String . format ( "Mission only %.1f%% complete!" , progress));
}
Mission Categories
Missions are organized into categories:
public interface MissionCategory {
String getName ();
int getSlot (); // GUI slot
List < Mission < ? >> getMissions ();
}
Example Categories:
Farming Missions
Combat Missions
Building Missions
Economy Missions
Requirements System
Required Missions
Missions can depend on other missions:
@ Override
public void load ( JavaPlugin plugin, ConfigurationSection section) {
// Require these missions first
addRequiredMission ( "starter-mission" , "intermediate-mission" );
}
Required Checks
Placeholder-based requirements:
// Add checks with placeholder support
addRequiredCheck (
"%island_level% >= 50" ,
"%island_worth% >= 1000000"
);
Visibility Control
// Only show if required missions are completed
toggleOnlyShowIfRequiredCompleted ();
Progress Persistence
Save Progress
@ Override
public void saveProgress ( ConfigurationSection section) {
// Save mission data to config
for ( Map . Entry < SuperiorPlayer , V > entry : entrySet ()) {
section . set ( entry . getKey (). getUniqueId (). toString (),
serializeData ( entry . getValue ()));
}
}
Load Progress
@ Override
public void loadProgress ( ConfigurationSection section) {
// Load mission data from config
for ( String key : section . getKeys ( false )) {
UUID uuid = UUID . fromString (key);
SuperiorPlayer player = SuperiorSkyblockAPI . getPlayer (uuid);
V data = deserializeData ( section . get (key));
insertData (player, data);
}
}
Progress is automatically saved when missions reload or the plugin disables.
GUI Integration
@ Override
public void formatItem ( SuperiorPlayer player, ItemStack itemStack) {
// Called async before displaying in GUI
// Inject custom placeholders into item
ItemMeta meta = itemStack . getItemMeta ();
if (meta != null ) {
String name = meta . getDisplayName ();
name = name . replace ( "{progress}" ,
String . valueOf ( getProgressValue (player)));
meta . setDisplayName (name);
itemStack . setItemMeta (meta);
}
}
Data Transfer
Transfer on Island Ownership Change
@ Override
public void transferData ( SuperiorPlayer oldOwner, SuperiorPlayer newOwner) {
// Called when island leadership transfers
// Move mission progress to new owner
}
This is primarily for island missions when ownership changes.
Example: Complete Mission
Here’s a complete example of a mission implementation:
public class FarmingMission extends Mission < Integer > {
private int requiredHarvests ;
private Set < Material > validCrops ;
@ Override
public void load ( JavaPlugin plugin , ConfigurationSection section )
throws MissionLoadException {
// Load config
requiredHarvests = section . getInt ( "required-harvests" , 1000 );
List < String > crops = section . getStringList ( "valid-crops" );
validCrops = crops . stream ()
. map (Material :: valueOf)
. collect ( Collectors . toSet ());
if ( validCrops . isEmpty ()) {
throw new MissionLoadException ( "No valid crops specified" );
}
// Register listener
Bukkit . getPluginManager (). registerEvents ( new Listener () {
@ EventHandler
public void onHarvest ( BlockBreakEvent event ) {
if ( validCrops . contains ( event . getBlock (). getType ())) {
SuperiorPlayer player = SuperiorSkyblockAPI
. getPlayer ( event . getPlayer ());
incrementProgress (player);
}
}
}, plugin);
// Set up data clearing
setClearMethod (data -> {
// Cleanup when resetting progress
});
}
private void incrementProgress ( SuperiorPlayer player ) {
Integer current = getOrCreate (player, p -> 0 );
insertData (player, current + 1 );
if ( canComplete (player)) {
player . sendMessage ( "Farming mission ready to complete!" );
}
}
@ Override
public double getProgress ( SuperiorPlayer player ) {
Integer harvests = get (player);
if (harvests == null ) return 0.0 ;
return Math . min ( 1.0 , ( double ) harvests / requiredHarvests);
}
@ Override
public int getProgressValue ( SuperiorPlayer player ) {
Integer harvests = get (player);
return harvests == null ? 0 : harvests;
}
@ Override
public void onComplete ( SuperiorPlayer player ) {
// Give rewards
player . sendMessage ( "Farming mission completed!" );
Player bukkitPlayer = player . asPlayer ();
if (bukkitPlayer != null ) {
bukkitPlayer . getInventory (). addItem (
new ItemStack ( Material . DIAMOND_HOE , 1 )
);
}
// Execute reward commands from config
getMissionCategory (); // Access category if needed
}
@ Override
public void onCompleteFail ( SuperiorPlayer player ) {
int current = getProgressValue (player);
player . sendMessage ( String . format (
"Only %d/%d harvests complete!" ,
current, requiredHarvests
));
}
@ Override
public void formatItem ( SuperiorPlayer player , ItemStack item ) {
ItemMeta meta = item . getItemMeta ();
if (meta == null ) return ;
int current = getProgressValue (player);
double percent = getProgress (player) * 100 ;
List < String > lore = meta . getLore ();
if (lore != null ) {
lore = lore . stream ()
. map (line -> line
. replace ( "{current}" , String . valueOf (current))
. replace ( "{required}" , String . valueOf (requiredHarvests))
. replace ( "{percent}" , String . format ( "%.1f" , percent))
)
. collect ( Collectors . toList ());
meta . setLore (lore);
}
item . setItemMeta (meta);
}
}
Best Practices
Use Async-Safe Operations formatItem() is called async. Don’t access Bukkit API unsafely.
Validate Configuration Throw MissionLoadException if config is invalid.
Handle Null Data get() can return null for players with no progress.
Clean Up Listeners Unregister event listeners in unload().
IMissionsHolder Interface
Both SuperiorPlayer and Island implement this interface:
public interface IMissionsHolder {
void completeMission ( Mission < ? > mission );
void resetMission ( Mission < ? > mission );
Map < Mission < ? >, Integer > getCompletedMissions ();
int getAmountMissionCompleted ( Mission < ? > mission );
boolean hasCompletedMission ( Mission < ? > mission );
void resetAllMissions ();
}
See Also
Players Player mission tracking
Islands Island mission tracking
Configuration Configure missions
Events Mission completion events