API Reference

Read and modify player skill data from your mod

Overview

MMO Skill Tree provides a Java API that lets other mods read and modify player skill data at runtime. The API is built around two main classes:

  • MMOSkillTreeAPI — Static methods for reading XP, levels, and modifying player skill data
  • SkillRegistry — Discover available skills, get display names, and query categories

All methods accept string-based skill IDs (e.g. "MINING", "HERBALISM") and work identically for both built-in and custom skills.

Setup

Add the API jar as a compileOnly dependency. MMO Skill Tree provides it at runtime.

// build.gradle
dependencies {
    compileOnly 'ziggfreed:mmoskilltree-api:1.0.0'
}

Import the classes you need:

import com.ziggfreed.mmoskilltree.api.MMOSkillTreeAPI;
import com.ziggfreed.mmoskilltree.data.SkillRegistry;

Accessing Player Data

Player data lives in Hytale's Entity Component System (ECS). You need a Store<EntityStore> and a Ref<EntityStore> to access it. These are available from the player entity in event handlers and command contexts.

// From a player reference
Ref<EntityStore> ref = player.getReference();
Store<EntityStore> store = ref.getStore();

// Now you can query skill data
int miningLevel = MMOSkillTreeAPI.getLevel(store, ref, "MINING");
long totalXp = MMOSkillTreeAPI.getTotalXp(store, ref);
Thread safety: Store operations must run on the world thread. If you're in an async context, use world.execute(() -> { ... }) to dispatch to the world thread before accessing the store.

Skill Discovery

Use SkillRegistry to discover what skills are available on the server, including any custom skills the server owner has defined.

Discovery Methods

MethodReturnsDescription
allSkillIds()List<String>All skill IDs (built-in + custom)
allSkillIdsByCategory(category)List<String>Skill IDs in a category ("GATHERING", "COMBAT", "CRAFTING", "MISC")
isKnownSkill(name)booleanCheck if a skill ID exists
isCustomSkill(name)booleanCheck if a skill is server-defined (not built-in)
hasCustomSkills()booleanWhether any custom skills are registered

Metadata Methods

MethodReturnsDescription
getDisplayName(skillId)StringHuman-readable name (e.g. "Mining", "Herbalism")
getCategoryName(skillId)StringCategory name: "GATHERING", "COMBAT", "CRAFTING", or "MISC"

Example: List All Skills

SkillRegistry registry = SkillRegistry.getInstance();

for (String skillId : registry.allSkillIds()) {
    String name = registry.getDisplayName(skillId);
    String category = registry.getCategoryName(skillId);
    System.out.println(category + " > " + name + " (" + skillId + ")");
}
// Output:
// GATHERING > Mining (MINING)
// GATHERING > Woodcutting (WOODCUTTING)
// COMBAT > Swords (SWORDS)
// MISC > Herbalism (HERBALISM)    <-- custom skill
// ...

Reading Skill Data

Single Skill Queries

MethodReturnsDescription
getLevel(store, ref, skillId)intPlayer's level in a skill (minimum 1)
getXp(store, ref, skillId)longPlayer's total XP in a skill
getLevelProgress(store, ref, skillId)doubleProgress to next level (0.0 to 1.0)

Aggregate Queries

MethodReturnsDescription
getTotalXp(store, ref)longSum of XP across all skills
getTotalLevel(store, ref)intCombined level (calculated from total XP)
getAllXpByName(store, ref)Map<String, Long>XP for every skill as a map
getAllLevelsByName(store, ref)Map<String, Integer>Levels for every skill as a map
hasSkillData(store, ref)booleanWhether the player has any skill data

Example: Check a Level Requirement

// Gate access to a dungeon based on combat level
int swordsLevel = MMOSkillTreeAPI.getLevel(store, ref, "SWORDS");
int defenseLevel = MMOSkillTreeAPI.getLevel(store, ref, "DEFENSE");

if (swordsLevel >= 30 && defenseLevel >= 20) {
    // Allow entry
} else {
    player.sendMessage("Requires Swords 30 and Defense 20");
}

Modifying Skill Data

These methods modify XP directly without triggering level-up notifications or XP gain messages. All return booleantrue on success, false if the player has no skill data or the operation is invalid.

MethodDescription
addXp(store, ref, skillId, amount)Add XP (respects per-skill max level cap)
removeXp(store, ref, skillId, amount)Remove XP (fails if insufficient XP)
setXp(store, ref, skillId, amount)Set XP to an exact value
Note: addXp enforces the per-skill max level cap configured in the server settings. If a player is already at max level, the call returns false. If the amount would exceed the cap, it's automatically clamped.

Example: Award XP for a Custom Event

// Award 500 Mining XP when player completes a mining challenge
boolean success = MMOSkillTreeAPI.addXp(store, ref, "MINING", 500);
if (success) {
    player.sendMessage("You earned 500 Mining XP!");
}

Utility Methods

These static helpers don't require player data — they work with the server's leveling formula.

MethodReturnsDescription
calculateLevelFromXp(xp)intWhat level a given XP amount corresponds to
getXpRequiredForLevel(level)longXP required to reach a specific level
// How much XP to reach level 50?
long xpNeeded = MMOSkillTreeAPI.getXpRequiredForLevel(50);
// ~446,000 XP with default settings

// What level is 1,000,000 XP?
int level = MMOSkillTreeAPI.calculateLevelFromXp(1_000_000);

Parry Bonuses

If the Perfect Parries integration is active, these methods return the player's accumulated parry bonuses based on their claimed skill tree rewards and currently held weapon.

MethodReturnsDescription
getParryCounterattackBonus(store, ref)doubleCounterattack damage bonus (e.g. 0.05 = 5%)
getParryReflectBonus(store, ref)doubleReflect damage bonus
getParryStaminaDrainBonus(store, ref)doubleStamina drain bonus on parry
getParryStunDamageBonus(store, ref)doubleStun damage bonus on parry

These methods automatically resolve the player's held weapon to the correct combat skill and sum matching parry rewards. Returns 0.0 if the integration is not active or the player has no parry rewards.

Direct Component Access

For advanced use cases, you can access the underlying SkillComponent directly. This gives you access to all player data including rewards, settings, and boost tokens.

MethodReturnsDescription
getSkillComponent(store, ref)SkillComponentGet existing component (null if none)
getOrCreateSkillComponent(store, cmdBuf, ref)SkillComponentGet or create component (requires CommandBuffer)
SkillComponent skills = MMOSkillTreeAPI.getSkillComponent(store, ref);
if (skills != null) {
    // Read settings
    boolean showsXpGains = skills.getShowXpGains();
    String language = skills.getLanguage();

    // Read specific skill data using ByName methods
    long miningXp = skills.getXpByName("MINING");
    int miningLevel = skills.getLevelByName("MINING");
}

Full Example

Here's a complete example that discovers all skills on the server, reads a player's data, and awards bonus XP:

import com.ziggfreed.mmoskilltree.api.MMOSkillTreeAPI;
import com.ziggfreed.mmoskilltree.data.SkillRegistry;

// Discover available skills
SkillRegistry registry = SkillRegistry.getInstance();
List<String> gatheringSkills = registry.allSkillIdsByCategory("GATHERING");

// Read player data
Ref<EntityStore> ref = player.getReference();
Store<EntityStore> store = ref.getStore();

for (String skillId : gatheringSkills) {
    int level = MMOSkillTreeAPI.getLevel(store, ref, skillId);
    String name = registry.getDisplayName(skillId);
    player.sendMessage(name + ": Level " + level);
}

// Award 1000 XP to the player's highest gathering skill
String bestSkill = null;
int bestLevel = 0;
for (String skillId : gatheringSkills) {
    int level = MMOSkillTreeAPI.getLevel(store, ref, skillId);
    if (level > bestLevel) {
        bestLevel = level;
        bestSkill = skillId;
    }
}

if (bestSkill != null) {
    MMOSkillTreeAPI.addXp(store, ref, bestSkill, 1000);
    String name = registry.getDisplayName(bestSkill);
    player.sendMessage("Awarded 1000 " + name + " XP!");
}

Class Reference

ClassPackageDescription
MMOSkillTreeAPIcom.ziggfreed.mmoskilltree.apiStatic methods for all skill data operations
SkillRegistrycom.ziggfreed.mmoskilltree.dataSkill discovery, metadata, and category queries
SkillComponentcom.ziggfreed.mmoskilltree.dataECS component holding all player skill data