API Reference
Technical reference for plugin developers and advanced users. Includes the public API for external plugin integration.
Public API
External plugins can interact with the Quest System through a stable public API.
Getting the API Instance
import com.kyuubisoft.quests.api.QuestAPI;
// Get API instance
QuestAPI api = QuestAPI.getInstance();
if (api == null) {
// Quest plugin not loaded
return;
}
// Or with availability check
if (QuestAPI.isAvailable()) {
QuestAPI api = QuestAPI.getInstance();
// ...
}
Quest Query Methods
| Method | Description |
|---|---|
getActiveQuests(UUID) | Map of active quest IDs to QuestProgress |
getCompletedQuests(UUID) | Set of completed quest IDs |
hasActiveQuest(UUID, String) | Check if quest is active |
hasCompletedQuest(UUID, String) | Check if quest is completed |
getQuestProgress(UUID, String) | Get QuestProgress for a quest |
getQuestDefinition(String) | Get quest definition by ID |
getAllQuestIds() | List of all available quest IDs |
getQuestsByType(String) | Get quests by type (daily/weekly/story/side/hub) |
Daily/Weekly Methods
| Method | Description |
|---|---|
getCurrentDailyQuests(UUID) | Current daily quest IDs for player |
getCurrentWeeklyQuests(UUID) | Current weekly quest IDs for player |
getTimeUntilDailyReset() | Duration until next daily reset |
getTimeUntilWeeklyReset() | Duration until next weekly reset |
Streak Methods
| Method | Description |
|---|---|
getCurrentStreak(UUID) | Player's current completion streak |
getLongestStreak(UUID) | Player's longest streak ever |
Modification Methods
| Method | Description |
|---|---|
startQuest(Player, String) | Start a quest (returns success) |
abandonQuest(Player, String) | Abandon an active quest |
updateProgress(Player, String, String, int) | Update objective progress (questId, objectiveId, amount) |
processTrigger(Player, String, String, int) | Process trigger for all active quests (type, target, amount) |
Quest Token Methods
| Method | Description |
|---|---|
getQuestTokens(UUID) | Get token balance |
addQuestTokens(UUID, int) | Add tokens |
spendQuestTokens(UUID, int) | Spend tokens (returns false if insufficient) |
Event Listeners
| Method | Description |
|---|---|
onQuestStarted(BiConsumer<Player, String>) | Listen for quest start events |
onQuestCompleted(BiConsumer<Player, String>) | Listen for quest completion events |
onQuestAbandoned(BiConsumer<Player, String>) | Listen for quest abandon events |
removeStartListener(BiConsumer) | Remove start listener |
removeCompleteListener(BiConsumer) | Remove complete listener |
removeAbandonListener(BiConsumer) | Remove abandon listener |
Facts Database Methods
| Method | Description |
|---|---|
getPlayerFact(UUID, String) | Get a story fact value |
setPlayerFact(UUID, String, Object) | Set a story fact value |
checkFactConditions(UUID, List<String>) | Check fact conditions |
Usage Examples
Check Quest Status
QuestAPI api = QuestAPI.getInstance();
// Does the player have an active quest?
if (api.hasActiveQuest(player.getUUID(), "merchant_delivery")) {
player.sendMessage("You still have a delivery to complete!");
}
// Check completion
if (api.hasCompletedQuest(player.getUUID(), "main_story_01")) {
player.sendMessage("Chapter 1 complete!");
}
// Show progress
QuestProgress progress = api.getQuestProgress(player.getUUID(), "kill_spiders");
if (progress != null) {
player.sendMessage("Quest progress: " + progress.getCurrentProgress() + "/" + progress.getRequiredProgress());
}
React to Quest Completions
QuestAPI api = QuestAPI.getInstance();
api.onQuestCompleted((player, questId) -> {
// Firework effect or similar
spawnFirework(player.getLocation());
// Logging
LOGGER.info(player.getDisplayName() + " completed quest " + questId + "!");
// Chain into next quest
if (questId.equals("main_story_01")) {
api.startQuest(player, "main_story_02");
}
});
api.onQuestAbandoned((player, questId) -> {
LOGGER.info(player.getDisplayName() + " abandoned quest " + questId);
});
Start a Quest Programmatically
QuestAPI api = QuestAPI.getInstance();
// Start quest on special event
if (specialEventTriggered) {
boolean started = api.startQuest(player, "special_event_quest");
if (started) {
player.sendMessage("New quest started!");
} else {
// Player already has quest, quest doesn't exist, or prerequisites not met
player.sendMessage("Could not start quest.");
}
}
// Update progress manually
api.updateProgress(player, "gather_resources", "collect_wood", 5);
// Process a trigger across all active quests
api.processTrigger(player, "kills", "Spider", 1);
Quest Tokens as Currency
QuestAPI api = QuestAPI.getInstance();
// Check balance
int tokens = api.getQuestTokens(player.getUUID());
player.sendMessage("Quest Tokens: " + tokens);
// Spend tokens for a reward
if (api.spendQuestTokens(player.getUUID(), 50)) {
grantReward(player);
} else {
player.sendMessage("Not enough tokens! Need 50, have " + tokens);
}
// Grant bonus tokens
api.addQuestTokens(player.getUUID(), 25);
Access the Facts Database
QuestAPI api = QuestAPI.getInstance();
// Set a story fact
api.setPlayerFact(player.getUUID(), "rescued_villager", true);
api.setPlayerFact(player.getUUID(), "chosen_faction", "rebels");
// Read a fact
Object faction = api.getPlayerFact(player.getUUID(), "chosen_faction");
if ("rebels".equals(faction)) {
player.sendMessage("The rebels welcome you back!");
}
// Check multiple conditions at once
List<String> conditions = List.of("rescued_villager=true", "chosen_faction=rebels");
if (api.checkFactConditions(player.getUUID(), conditions)) {
// All conditions met - unlock special dialogue
api.startQuest(player, "rebel_secret_mission");
}
Thread Safety
- The API is thread-safe using
CopyOnWriteArrayListfor listeners - All query methods can be called from any thread
- Modification methods should ideally be called from the main thread
- Facts database access is synchronized
QuestAPI
The QuestAPI provides cross-mod integration for the quest system. Other mods can listen for quest events and query quest data.
Event Listeners
Register callbacks that fire when quest state changes:
| Method | Parameters | Description |
|---|---|---|
onQuestStarted(listener) | BiConsumer<Player, String> | Fires when a player starts a quest |
onQuestCompleted(listener) | BiConsumer<Player, String> | Fires when a player completes a quest |
onQuestAbandoned(listener) | BiConsumer<Player, String> | Fires when a player abandons a quest |
QuestAPI.onQuestCompleted((player, questId) -> {
logger.info(player.getDisplayName() + " completed " + questId);
});
Query Methods
| Method | Returns | Description |
|---|---|---|
getAllQuestIds() | Set<String> | All registered quest IDs |
getQuestsByType(type) | List<QuestDefinition> | Quests filtered by type (story, daily, weekly, side) |
Facts API
Facts are per-player key-value pairs used for story state tracking:
| Method | Returns | Description |
|---|---|---|
getPlayerFact(player, key) | String | Get a fact value for a player |
setPlayerFact(player, key, value) | void | Set a fact value |
checkFactConditions(player, conditions) | boolean | Check if all fact conditions are met |
File Paths
Plugin Data
plugins/KyuubiQuests/
├── config.json - Main configuration
├── configs/ - Standard configs
│ ├── quests.json
│ ├── story_quests.json
│ └── test_quests.json
├── quest_npc_profiles/ - NPC personality profiles
│ ├── arcanist_yuki.json
│ ├── cook_mira.json
│ ├── hunter_riven.json
│ └── ...
├── localization/ - Language files
│ ├── en-US.json
│ └── de-DE.json
└── playerdata/ - Player quest data
└── <uuid>.json
Resource Files
Server/Languages/
├── en-US/
│ └── quests.lang
└── de-DE/
└── quests.lang
Common/UI/Custom/Pages/QuestBook/
└── QuestBook.ui
Java Package Structure
com.kyuubisoft.quests/
├── QuestPlugin.java - Main plugin class
├── api/
│ └── QuestAPI.java - Public API for external plugins
├── commands/
│ ├── QuestCommand.java - /ksquest command
│ ├── QuestAdminCommand.java - /ksquestadmin command
│ └── QuestSettingsCommand.java - /ksquestsettings command
├── config/
│ ├── QuestConfig.java - Config model
│ └── QuestDefinition.java - Quest definition model
├── data/
│ ├── PlayerQuestData.java - Player quest data
│ └── QuestProgress.java - Quest progress tracking
├── hud/
│ └── QuestTrackerHud.java - Quest tracker HUD overlay
├── service/
│ └── QuestService.java - Core quest logic
└── ui/
└── QuestBookPage.java - Quest book UI page
Localization Keys
Quest Keys
quests.name.<id> - Quest display name
quests.desc.<id> - Quest description
quests.objective.<id>.<obj> - Objective display text
quests.dialog.<npc>.<key> - NPC dialog text
UI Keys
quests.ui.book_title - Quest book window title
quests.ui.active - "Active" tab
quests.ui.completed - "Completed" tab
quests.ui.available - "Available" tab
quests.ui.daily - "Daily" label
quests.ui.weekly - "Weekly" label
quests.ui.story - "Story" label
quests.ui.side - "Side" label
quests.ui.progress - "Progress" label
quests.ui.abandon - "Abandon" button
quests.ui.accept - "Accept" button
quests.ui.rewards - "Rewards" label
quests.ui.objectives - "Objectives" label
quests.ui.streak - "Streak" label
quests.ui.tokens - "Tokens" label
Command Keys
quests.cmd.start.success - Quest start success message
quests.cmd.start.already - Already active message
quests.cmd.abandon.success - Abandon success message
quests.cmd.abandon.not_active - Not active message
quests.cmd.complete.success - Admin complete success message
quests.cmd.reset.success - Admin reset success message