Skip to main content

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:

ValueMatches
"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:

EventTrigger Type
BlockBreakEventblocks_mined
BlockPlaceEventblocks_placed
EntityDeathEventkills
PlayerCraftEventitems_crafted
PlayerMoveEventdistance_walked
PlayerChatEventchat_messages
ZoneEnterEventzones_discovered
PlayerEquipEventequip_item, full_armor_set
PlayerJoinEventweekend_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

MethodDescription
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

MethodDescription
getActiveTitle(Player)Active title ID (or null)
getUnlockedTitles(Player)Set of all unlocked titles

Modification Methods

MethodDescription
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

MethodDescription
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

MethodDescription
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 CopyOnWriteArrayList for listeners
  • All query methods can be called from any thread
  • Modification methods should ideally be called from the main thread