Developer API¶
KoraQuest provides a runtime API and Bukkit quest lifecycle events.
Add KoraQuest as a dependency¶
Place the API JAR in your local project library and use it as a compile-only dependency. Do not bundle the KoraQuest API classes inside your plugin JAR.
plugin.yml:
For an optional integration:
Check availability¶
import dev.ipseucz.koraquest.api.KoraQuestAPI;
if (!KoraQuestAPI.isAvailable()) {
getLogger().warning("KoraQuest API is not available.");
return;
}
Query quests and progress¶
import dev.ipseucz.koraquest.api.KoraQuestAPI;
import dev.ipseucz.koraquest.model.QuestDefinition;
KoraQuestAPI.getQuest("daily_break_stone").ifPresent(quest -> {
getLogger().info("Quest cycle: " + quest.cycle());
getLogger().info("Required: " + quest.required());
});
int progress = KoraQuestAPI.getProgress(player.getUniqueId(), "daily_break_stone");
String status = KoraQuestAPI.getStatus(player.getUniqueId(), "daily_break_stone");
Available query methods:
Optional<QuestDefinition> getQuest(String id);
Collection<QuestDefinition> getActiveQuests(UUID uuid);
Collection<QuestDefinition> getActiveQuests(UUID uuid, String cycle);
int getProgress(UUID uuid, String questId);
int getProgress(UUID uuid, String cycle, String questId);
String getStatus(UUID uuid, String questId);
Mutate player quests¶
boolean accepted = KoraQuestAPI.acceptQuest(player, "daily_break_stone");
boolean cancelled = KoraQuestAPI.cancelQuest(player, "daily_break_stone");
boolean completed = KoraQuestAPI.completeQuest(player, "daily_break_stone");
boolean rerolled = KoraQuestAPI.rerollQuest(player, "daily_break_stone");
Warning
Player mutation methods must run on the player's owning thread when the server uses Folia.
Progress objectives¶
Progress one specific quest:
Progress every matching objective:
import dev.ipseucz.koraquest.model.ObjectiveType;
KoraQuestAPI.progress(player, ObjectiveType.CUSTOM, "MY_EVENT", 1);
KoraQuestAPI.progressCustom(player, "MY_EVENT", 1);
Custom objective providers¶
KoraQuestAPI.registerObjectiveProvider("myplugin", (player, target, amount) -> {
KoraQuestAPI.progress(player, ObjectiveType.CUSTOM, target, amount);
});
Dispatch to the provider:
Remove the provider on plugin shutdown:
Custom reward providers¶
KoraQuestAPI.registerRewardProvider("tokens", (player, quest, value) -> {
int amount = Integer.parseInt(value);
// Add tokens with your plugin API.
return true;
});
The provider returns true only when delivery succeeds. Returning false keeps the reward claim available for retry.
Bukkit events¶
KoraQuest includes these lifecycle events:
QuestAcceptEvent
QuestCancelEvent
QuestProgressEvent
QuestReadyEvent
QuestCompleteEvent
QuestRewardEvent
QuestCycleResetEvent
QuestRerollEvent
Example listener:
import dev.ipseucz.koraquest.event.QuestCompleteEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public final class QuestListener implements Listener {
@EventHandler
public void onQuestComplete(QuestCompleteEvent event) {
getLogger().info(event.getPlayer().getName()
+ " completed " + event.getQuest().id());
}
}
Register the listener normally through Bukkit/Paper.
Threading guidance¶
- Query already-loaded data without blocking the main thread.
- Run player mutations on the correct entity thread.
- Do not access Bukkit entities from asynchronous database callbacks.
- Return
falsefrom a reward provider when the external reward service is unavailable. - Unregister providers in
onDisable().