API Reference
Technical reference for plugin developers and advanced users. Includes the public API for external plugin integration.
Achievement Definition Schema
interface Achievement {
// Required
id: string; // Unique identifier (snake_case)
category: Category; // Category classification
trigger: Trigger; // Unlock condition
// Optional
iconItem?: string; // Item ID for icon (default: "Ore_Gold")
hidden?: boolean; // Hide until unlocked (default: false)
difficulty?: Difficulty; // Difficulty tier (default: "normal")
requires?: string | string[]; // Prerequisite achievement ID(s)
showRequires?: boolean; // Show requirements when locked (default: true)
title?: Title; // Unlockable title reward
rewards?: Reward[]; // Item/command rewards
additionalInfo?: AdditionalInfo; // Custom info text
custom?: boolean; // Mark as custom achievement
}
type Category = "combat" | "progression" | "exploration" | "social" | "husbandry" | "secret";
type Difficulty = "easy" | "normal" | "hard" | "epic";
Trigger Types
BlocksMined / BlocksPlaced
interface BlockTrigger {
type: "blocks_mined" | "blocks_placed";
target: string; // Block ID, "any", or prefix (e.g., "Ore_")
count: number; // Required count
}
Target Matching:
"any"- Matches all blocks"Stone"- Exact match"Ore_"- Prefix match (matches Ore_Iron, Ore_Gold, etc.)
Kills
interface KillsTrigger {
type: "kills";
target: string; // Entity ID, "any", "any_mob", "any_player"
count: number;
}
Target Options:
| Value | Matches |
|---|---|
"any" | All entities |
"any_mob" | All non-player entities |
"any_player" | All players |
"Spider" | Exact entity type |
ItemsCrafted
interface CraftTrigger {
type: "items_crafted";
target: string; // Item ID or "any"
count: number;
}
ZonesDiscovered
interface ZoneTrigger {
type: "zones_discovered";
target: string; // Zone ID or "any"
count: number;
}
ChatMessages
interface ChatTrigger {
type: "chat_messages";
count: number;
}
PlaytimeMinutes
interface PlaytimeTrigger {
type: "playtime_minutes";
count: number; // Minutes
}
DistanceWalked
interface DistanceTrigger {
type: "distance_walked";
count: number; // Blocks
}
FullArmorSet
interface ArmorTrigger {
type: "full_armor_set";
target: ArmorMaterial;
}
type ArmorMaterial =
| "iron" | "copper" | "bronze" | "steel"
| "cobalt" | "mithril" | "thorium"
| "adamantite" | "onyxium" | "prisma";
EquipItem
interface EquipTrigger {
type: "equip_item";
target: string; // Item ID
}
Manual
interface ManualTrigger {
type: "manual";
}
AutoOnPrerequisites
interface AutoTrigger {
type: "auto_on_prerequisites";
}
WeekendLogin
interface WeekendLoginTrigger {
type: "weekend_login";
count: number; // Number of weekend logins required
}
Triggers when a player logs in on Saturday or Sunday. Useful for attendance-based achievements.
SkillLevel (MMO SkillTree)
interface SkillLevelTrigger {
type: "skill_level";
target: string; // Skill name (e.g., "mining", "fishing")
count: number; // Required skill level
}
TotalSkillLevel (MMO SkillTree)
interface TotalSkillLevelTrigger {
type: "total_skill_level";
count: number; // Combined level of all skills
}
RpgLevel (RPG Leveling)
interface RpgLevelTrigger {
type: "rpg_level";
target: string; // Level number as string
count: number; // Usually 1
}
RpgXp (RPG Leveling)
interface RpgXpTrigger {
type: "rpg_xp";
target: "any";
count: number; // Total XP required
}
Reward Types
Item Reward
interface ItemReward {
type: "item";
itemId: string; // Hytale item ID
amount: number; // Quantity (1-64)
}
Command Reward
interface CommandReward {
type: "command";
command: string; // Command to execute (use {player} placeholder)
executor: Executor; // Who runs the command
}
type Executor = "console" | "player";
Lootbag Reward
interface LootbagReward {
type: "lootbag";
lootbagId: string; // ID from lootbags.json
}
Title Definition
interface Title {
id: string; // Title identifier (for localization)
color?: string; // Hex color code (default: "#FFFFFF" white)
}
Additional Info
interface AdditionalInfo {
text: string; // Display text
color?: string; // Hex color code (default: "#AAAAAA" gray)
}
Configuration Schema
interface Config {
language: "en-US" | "de-DE";
loadDefaultAchievements: boolean;
display: {
displayMode: "nametag" | "chat" | "both";
titlePosition: "prefix" | "above" | "below";
nametagFormat: string;
chatFormat: string;
titleColor: string;
showRpgLevel: boolean;
rpgLevelFormat: string;
rpgLevelColor: string;
rpgLevelPosition: "before_name" | "after_name" | "after_title";
};
notifications: {
enabled: boolean;
displayMode: "chat" | "banner" | "both";
displayDurationMs: number;
showRewardsInBanner: boolean;
broadcastToChat: boolean;
broadcastFormat: string;
};
tracking: {
saveIntervalSeconds: number;
enableExploration: boolean;
enableCombat: boolean;
enableProgression: boolean;
enableSocial: boolean;
};
admin: {
cascadeRevoke: boolean;
cascadeRevokeWarning: boolean;
bypassPrerequisites: boolean;
};
export: {
enabled: boolean;
intervalSeconds: number;
exportGlobalStats: boolean;
exportLeaderboards: boolean;
exportRecentUnlocks: boolean;
leaderboardSize: number;
recentUnlocksSize: number;
includePlayerTotals: boolean;
};
groupPrefixes: {
[groupName: string]: {
prefix: string;
priority: number;
};
};
}
Localization Keys
Achievement Keys
achievements.name.<id> - Achievement display name
achievements.desc.<id> - Achievement description
achievements.title.<id> - Title display name
UI Keys
achievements.ui.gallery - Gallery window title
achievements.ui.search - Search placeholder
achievements.ui.all - "All" filter
achievements.ui.combat - "Combat" filter
achievements.ui.progression - "Progression" filter
achievements.ui.exploration - "Exploration" filter
achievements.ui.social - "Social" filter
achievements.ui.completed - "Completed" filter
achievements.ui.locked - "Locked" status
achievements.ui.unlocked - "Unlocked" status
achievements.ui.progress - "Progress" label
achievements.ui.requires - "Requires" label
achievements.ui.reward - "Reward" label
achievements.ui.title - "Title" label
achievements.ui.prev - "Previous" button
achievements.ui.next - "Next" button
achievements.ui.page - "Page" label
Command Keys
achievements.cmd.grant.success - Grant success message
achievements.cmd.grant.already - Already unlocked message
achievements.cmd.revoke.success - Revoke success message
achievements.cmd.revoke.not_unlocked - Not unlocked message
achievements.cmd.list.header - List header format
achievements.cmd.list.empty - Empty list message
Trigger Keys
achievements.trigger.blocks_mined - "Mine {0} blocks"
achievements.trigger.blocks_placed - "Place {0} blocks"
achievements.trigger.kills - "Kill {0} {1}"
achievements.trigger.items_crafted - "Craft {0} {1}"
achievements.trigger.playtime_minutes - "Play for {0} minutes"
achievements.trigger.distance_walked - "Walk {0} blocks"
achievements.trigger.chat_messages - "Send {0} chat messages"
achievements.trigger.zones_discovered - "Discover {0} zones"
File Paths
Plugin Data
plugins/KyuubiAchievements/
├── config.json - Main configuration
├── configs/ - Standard configs
│ ├── achievements.json
│ ├── mmo_achievements.json
│ └── rpg_leveling_achievements.json
├── custom/ - Custom configs (safe from updates)
│ └── custom_achievements.json
├── localization/ - Language files
│ ├── en-US.json
│ └── de-DE.json
├── playerdata/ - Player achievement data
│ └── <uuid>.json
└── export/ - Statistics export
├── global_stats.json
├── leaderboard.json
└── recent_unlocks.json
Resource Files
Server/Languages/
├── en-US/
│ └── achievements.lang
└── de-DE/
└── achievements.lang
Common/UI/Custom/Pages/Achievements/
├── AchievementGallery.ui
├── AchievementToast.ui
└── TitleSelection.ui
Java Package Structure
com.hytale.achievements/
├── AchievementPlugin.java - Main plugin class
├── api/
│ └── AchievementAPI.java - Public API for external plugins
├── commands/
│ ├── AchievementCommand.java - /achievements command
│ ├── TitleCommand.java - /titles command
│ └── AchievementAdminCommand.java
├── config/
│ ├── AchievementConfig.java - Config model
│ ├── AchievementDefinition.java
│ ├── Reward.java
│ └── AdditionalInfo.java
├── data/
│ └── PlayerAchievementData.java
├── display/
│ ├── TitleDisplayManager.java
│ ├── ToastManager.java
│ ├── AchievementToastHud.java
│ └── EmptyHud.java
├── export/
│ └── StatsExporter.java
├── integration/
│ ├── LuckPermsIntegration.java
│ └── MHUDIntegration.java
├── service/
│ └── AchievementService.java
├── tracking/
│ ├── BlockBreakTrackerSystem.java
│ ├── BlockPlaceTrackerSystem.java
│ ├── CombatTracker.java
│ ├── ExplorationTracker.java
│ ├── MovementTracker.java
│ └── SocialTracker.java
├── ui/
│ ├── AchievementGalleryPage.java
│ └── TitleSelectionPage.java
└── util/
└── AdventureConverter.java
Events
Achievement Events (Internal)
The plugin tracks these Hytale events:
| Event | Trigger Type |
|---|---|
BlockBreakEvent | blocks_mined |
BlockPlaceEvent | blocks_placed |
EntityDeathEvent | kills |
PlayerCraftEvent | items_crafted |
PlayerMoveEvent | distance_walked |
PlayerChatEvent | chat_messages |
ZoneEnterEvent | zones_discovered |
PlayerEquipEvent | equip_item, full_armor_set |
PlayerJoinEvent | weekend_login (checks day of week) |
Public API
External plugins can interact with the Achievement System through a stable public API.
Getting the API Instance
import com.hytale.achievements.api.AchievementAPI;
// Get API instance
AchievementAPI api = AchievementAPI.getInstance();
if (api == null) {
// Achievement plugin not loaded
return;
}
// Or with availability check
if (AchievementAPI.isAvailable()) {
AchievementAPI api = AchievementAPI.getInstance();
// ...
}
Achievement Query Methods
| Method | Description |
|---|---|
hasAchievement(Player, String) | Check if player has achievement |
hasAchievement(UUID, String) | Check by UUID |
getProgress(Player, String) | Current progress |
getRequiredProgress(String) | Required progress to unlock |
getUnlockedAchievements(Player) | Set of all unlocked IDs |
getUnlockedCount(Player) | Number of unlocked achievements |
getTotalAchievementCount() | Total number of achievements |
getUnlockTimestamp(Player, String) | Unix timestamp of unlock |
getAllAchievementIds() | List of all achievement IDs |
getAchievementsByCategory(String) | Achievements in a category |
achievementExists(String) | Check if achievement exists |
Title Query Methods
| Method | Description |
|---|---|
getActiveTitle(Player) | Active title ID (or null) |
getUnlockedTitles(Player) | Set of all unlocked titles |
Modification Methods
| Method | Description |
|---|---|
grantAchievement(Player, String) | Grant achievement (with rewards) |
revokeAchievement(Player, String) | Revoke achievement |
setProgress(Player, String, int) | Set progress directly |
incrementProgress(Player, String, int) | Increment progress (checks unlock) |
Event Listeners
| Method | Description |
|---|---|
onAchievementUnlock(BiConsumer<Player, String>) | Listener for unlock events |
removeUnlockListener(BiConsumer) | Remove unlock listener |
onProgressUpdate(BiConsumer<Player, String>) | Listener for progress updates |
removeProgressListener(BiConsumer) | Remove progress listener |
Statistics Methods
| Method | Description |
|---|---|
getTotalBlocksMined(Player) | Total blocks mined |
getTotalBlocksPlaced(Player) | Total blocks placed |
getTotalMobKills(Player) | Total mob kills |
getPlaytimeMinutes(Player) | Playtime in minutes |
Usage Examples
Check Achievement Status
AchievementAPI api = AchievementAPI.getInstance();
// Does the player have "monster_hunter_1"?
if (api.hasAchievement(player, "monster_hunter_1")) {
player.sendMessage("You are a monster hunter!");
}
// Show progress
int progress = api.getProgress(player, "blocks_mined_1000");
int required = api.getRequiredProgress("blocks_mined_1000");
player.sendMessage("Progress: " + progress + "/" + required);
React to Achievement Unlocks
AchievementAPI api = AchievementAPI.getInstance();
api.onAchievementUnlock((player, achievementId) -> {
// Firework effect or similar
spawnFirework(player.getLocation());
// Logging
LOGGER.info(player.getDisplayName() + " unlocked " + achievementId + "!");
});
Grant Achievement Programmatically
AchievementAPI api = AchievementAPI.getInstance();
// Grant achievement on special event
if (specialEventTriggered) {
boolean granted = api.grantAchievement(player, "special_event_2026");
if (granted) {
// Successfully granted
} else {
// Player already had it or achievement doesn't exist
}
}
Statistics for Leaderboard
AchievementAPI api = AchievementAPI.getInstance();
int blocksMinedTotal = api.getTotalBlocksMined(player);
int achievementCount = api.getUnlockedCount(player);
long playtimeMinutes = api.getPlaytimeMinutes(player);
// Use for leaderboard...
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