BG-Software
Search…
Missions
Using missions, you can give your players tasks to do on your server. In this documentation, you will understand how to edit them to your own style!

How do missions work?

First of all, it's important to understand how missions work. Missions are instructions that given to external jars (similar to plugins). The jars handle the events and actions that player do, and by following the instructions that are given to them, they know how to reward the players or islands. SuperiorSkyblock provides default jars that know how to handle a large range of actions, such as block breaking, island actions, enchanting, collection of items and crafting of items.

Default mission jars

Here you can find information about every default mission jar.
BlocksMissions This jar knows to handle break of blocks by players. You can track break of blocks using this one. The jar has some custom instructions that can be given to it: required-blocks: A list of blocks that are needed to be broken. only-natural-blocks: Whether or not the mission will work only on natural blocks. blocks-placement: Whether or not the mission should listen to block placements. blocks-replace: Whether or not the mission should check if the block was placed before.
CraftingMissions This jar knows to handle crafting of items. You can track crafting of items using this one. The jar needs one instruction so it can work: craftings: A list of items that are needed to be crafted.
EnchantingMissions This jar knows to handle enchanting of items. You can track enchanting of items using this one. The jar needs one instruction so it can work: required-enchants: A list of enchants that needs to be applied on items.
IslandMissions This jar knows to handle actions that are done in islands. You can track them using this one. The jar has some custom instructions that can be given to it: events: A list of events that needs to be listened to. You can add the suffix "-target" to tell the plugin to check only when the player is the target of the action. success-check: A check that will be run on the event. Coding knowledge is required to use this section.
ItemsMissions This jar knows to handle collected items by players. You can track collected items using this one. The jar needs one instruction so it can work: required-items: A list of items that are needed to be collected.
KillsMissions This jar knows to handle killing of entities. You can track killed entities using this one. The jar has some custom instructions that can be given to it: required-entities: A list of entities that are needed to be killed. reset-after-finish: Whether or not the killing counter should get reset after completing the mission.

Create your first mission

Here you'll understand how to create your own mission. All the missions have the follow the same concept, but in this tutorial I chose to customize my own lumberjack mission!
I first start with setting basic information (name & mission type):
1
lumberjack:
2
mission-file: BlocksMissions # I am using the BlocksMissions jar as it knows how to handle block breaking.
Copied!
After that, I start giving it some more advanced settings. I want my players to only gain progress from natural blocks spawning, I want the mission to be reset upon disbanding of an island, and I want them to be able to use the mission if they are above island level of 250.
1
lumberjack:
2
mission-file: BlocksMissions
3
4
only-natural-blocks: true # Make sure only natural blocks are counted.
5
disband-reset: true # Resetting the mission upon island disband.
6
required-checks: # Handles custom checks, such as minimum level requirement.
7
- '%superior_island_level% > 250'
Copied!
Now, I will configure three important things:
    1.
    The blocks that will be tracked (I am using 1.16 blocks).
    2.
    Rewards for the mission
    3.
    The icon of the mission that will be displayed in /is missions.
1
lumberjack:
2
mission-file: BlocksMissions
3
4
only-natural-blocks: true
5
disband-reset: true
6
required-checks:
7
- '%superior_island_level% > 250'
8
9
# The blocks that will be tracked.
10
required-blocks:
11
# A section of blocks. All the blocks in a section will be counted together.
12
'1':
13
# All the blocks of this section.
14
types:
15
- 'OAK_LOG'
16
- 'SPRUCE_LOG'
17
- 'BIRCH_LOG'
18
- 'JUNGLE_LOG'
19
- 'ACACIA_LOG'
20
- 'DARK_OAK_LOG'
21
# The total amount of all the blocks of the section (5 stacks).
22
amount: 320
23
24
# The rewards of the mission.
25
rewards:
26
items:
27
'1': # Random section name, doesn't really matter.
28
type: OAK_SAPLING # The item's type
29
amount: 16 # The item's amount.
30
commands: # Commands that will be executed upon completion.
31
- 'is admin msg %player% &e&lMission | &7Successfully finished the mission Lumberjack!'
32
33
# Settings related to the icon in the missions menu.
34
icons:
35
# The icon that will be displayed when the player cannot complete the mission for any reason.
36
not-completed:
37
type: PAPER
38
name: '&aLumberjack'
39
lore:
40
- '&7Cut 320 logs.'
41
- ''
42
- '&6Required Materials:'
43
- '&8 - &7x320 Logs'
44
- ''
45
- '&6Rewards:'
46
- '&8 - &7x16 Oak Saplings'
47
- ''
48
- '&6Cut Logs: &7{1}/320'
49
- '&6Progress: &7{0}%'
50
- '&c&l ✘ &7Not Completed'
51
# The icon that will be displayed when the player can complete the mission.
52
can-complete:
53
type: PAPER
54
name: '&aLumberjack'
55
lore:
56
- '&7Cut 320 logs.'
57
- ''
58
- '&6Required Materials:'
59
- '&8 - &7x320 Logs'
60
- ''
61
- '&6Rewards:'
62
- '&8 - &7x16 Oak Saplings'
63
- ''
64
- '&6Cut Logs: &7320/320'
65
- '&6Progress: &7100%'
66
- '&a&l ✔ &7Click to redeem your reward.'
67
enchants:
68
DURABILITY: 1
69
flags:
70
- HIDE_ENCHANTS
71
# The icon that will be displayed when the player has already completed the mission.
72
completed:
73
type: MAP
74
name: '&aLumberjack'
75
lore:
76
- '&7Cut 320 logs.'
77
- ''
78
- '&6Cut Logs: &7320/320'
79
- '&6Progress: &7100%'
80
- '&a&l ✔ &7Already Claimed.'
Copied!
As you might have noticed, I used some built-in placeholders, such as {0} and {1}. {0} - Used as a percentage placeholder. {1} - Used as a placeholder for the amount of tracked blocks. {value_<block>} - Used as a placeholder for the amount of a specific tracked block. {percentage_<block>} - Used as a percentage placeholder for a specific block.
That's it! The mission is now setup and ready to be used. There are more settings that can be applied to all the missions: required-missions: A list of missions that must be completed before completion of the mission. required-checks: A list of checks which depend on placeholders that needs to be checked before completion of the mission. only-show-if-required-completed: Whether or not the mission should only be shown in menus when the required missions & checks are completed. island: Whether or not the mission should be an islands mission (mission that is synced with all island members). auto-reward: Whether or not the plugin should reward the players without them doing it in the missions menu. disband-reset: Whether or not the mission should be reset when disbanding the island (used for player-missions). leave-reset: Whether or not the mission should be reset when leaving an island (used for player-missions). reset-amount: The amount of times a mission can be completed. rewards.items: A list of items that will be given to players when they complete the mission. rewards.commands: A list of commands that will be executed when players complete the mission. icons.not-completed: The item that will be shown in the menu when the mission is not completed. icons.can-complete: The item that will be shown in the menu when the mission can be completed. icons.completed: The item that will be shown in the menu when the mission is completed.

Create your own mission jar

In order to create your own missions jar, you must have knowledge in Java and the Spigot API. Mission jars are part of the SuperiorSkyblock's API, which can be found here. In this tutorial, I will make a chat-mission that counts the amount of times a player has written "Hello". First, I create a ChatMission object that extends the Mission object, and override all the methods.
1
public final class ChatMission extends Mission<Object> {
2
3
@Override
4
public void load(JavaPlugin plugin, ConfigurationSection section) throws MissionLoadException {
5
6
}
7
8
@Override
9
public double getProgress(SuperiorPlayer superiorPlayer) {
10
return 0;
11
}
12
13
@Override
14
public void onComplete(SuperiorPlayer superiorPlayer) {
15
16
}
17
18
@Override
19
public void onCompleteFail(SuperiorPlayer superiorPlayer) {
20
21
}
22
23
}
Copied!
As you can see, the Mission object needs an argument. This argument will be our data. The Mission object has a built-in system to organize all the data for us. In this tutorial, I can just use the Integer class. In more complicated missions, you might want to use your own custom object.
1
public final class ChatMission extends Mission<Integer> {
2
3
...
4
5
}
Copied!
Now, we need to start implementing the default methods. load() - That's your "constructor" of the mission. It has two parameters: the plugin's instance, and the configurationsection of the mission. If something was not done correctly, and you want to cancel the loading of the mission - throw MissionLoadException with your error as a message. getProgress() - Calculates the progress of the player. Must return a number between 0 and 1. onComplete() - A callback method that will be ran when a player completes a mission. onCompleteFail() - A callback method that will be ran when a player fails to complete a mission.
1
public final class ChatMission extends Mission<Integer> {
2
3
private int AMOUNT_OF_TIMES = 0;
4
private String CHAT_MESSAGE = "";
5
6
@Override
7
public void load(JavaPlugin plugin, ConfigurationSection section) throws MissionLoadException {
8
if(!section.contains("times"))
9
throw new MissionLoadException("Mission ChatMission must contain the \"times\" section!");
10
11
if(!section.contains("message"))
12
throw new MissionLoadException("Mission ChatMission must contain the \"message\" section!");
13
14
AMOUNT_OF_TIMES = section.getInt("times");
15
16
if(AMOUNT_OF_TIMES <= 0)
17
throw new MissionLoadException("times must be a positive value.");
18
19
CHAT_MESSAGE = section.getString("message").toLowerCase();
20
}
21
22
@Override
23
public double getProgress(SuperiorPlayer superiorPlayer) {
24
Integer count = get(superiorPlayer);
25
return count == null ? 0D : (double) count / AMOUNT_OF_TIMES;
26
}
27
28
@Override
29
public void onComplete(SuperiorPlayer superiorPlayer) {
30
// There's nothing special to do here, so I will just clear data from the user.
31
clearData(superiorPlayer);
32
}
33
34
@Override
35
public void onCompleteFail(SuperiorPlayer superiorPlayer) {
36
// Empty
37
}
38
39
}
Copied!
At this point, you can start listening to your events and alter the data when necessary. There's only one important thing to do, and it's to call the rewardMission() method. Furthermore, it's important to implement the saveProgress() and loadProgress() methods, so data will be saved on restarts.
The final product after adding a listener & registering it:
1
public final class ChatMission extends Mission<Integer> implements Listener {
2
3
private int AMOUNT_OF_TIMES = 0;
4
private String CHAT_MESSAGE = "";
5
6
@Override
7
public void load(JavaPlugin plugin, ConfigurationSection section) throws MissionLoadException {
8
if(!section.contains("times"))
9
throw new MissionLoadException("Mission ChatMission must contain the \"times\" section!");
10
11
if(!section.contains("message"))
12
throw new MissionLoadException("Mission ChatMission must contain the \"message\" section!");
13
14
AMOUNT_OF_TIMES = section.getInt("times");
15
16
if(AMOUNT_OF_TIMES <= 0)
17
throw new MissionLoadException("times must be a positive value.");
18
19
CHAT_MESSAGE = section.getString("message").toLowerCase();
20
21
Bukkit.getPluginManager().registerEvents(this, plugin);
22
}
23
24
@Override
25
public double getProgress(SuperiorPlayer superiorPlayer) {
26
Integer count = get(superiorPlayer);
27
return count == null ? 0D : (double) count / AMOUNT_OF_TIMES;
28
}
29
30
@Override
31
public void onComplete(SuperiorPlayer superiorPlayer) {
32
// There's nothing special to do here, so I will just clear data from the user.
33
clearData(superiorPlayer);
34
}
35
36
@Override
37
public void onCompleteFail(SuperiorPlayer superiorPlayer) {
38
// Empty
39
}
40
41
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
42
public void onPlayerChat(AsyncPlayerChatEvent e){
43
SuperiorPlayer superiorPlayer = SuperiorSkyblockAPI.getPlayer(e.getPlayer());;
44
45
// Checking if the tracked message is in the player's message.
46
if(!e.getMessage().toLowerCase().contains(CHAT_MESSAGE))
47
return;
48
49
// Making sure that the player can actually complete the mission, so we don't track data for no reason.
50
if(!SuperiorSkyblockAPI.getMissions().canCompleteNoProgress(superiorPlayer, this))
51
return;
52
53
// Increasing the counter by 1.
54
Integer currentCount = get(superiorPlayer);
55
insertData(superiorPlayer, currentCount == null ? 1 : currentCount + 1);
56
57
/* Calling the reward method with the following paramters:
58
mission - this instance.
59
superiorPlayer - our player.
60
boolean - should the plugin check for auto reward or not.
61
*/
62
SuperiorSkyblockAPI.getMissions().rewardMission(this, superiorPlayer, true);
63
}
64
65
}
Copied!
More complicated missions will require more data to be tracked and more listeners. Moreoever, I didn't implement the saveProgress() and loadProgress(), and didn't implement other useful methods that you might want to use. I recommend going through the Mission object before creating your own jar and see all the things it provides. If you want to see how the default mission jars are implemented, check out their github repository!
Last modified 1mo ago