Integration API
Build optional mod integrations with MMO Skill Tree
Overview
MMO Skill Tree supports optional integrations with other Hytale mods. External mods can provide adapters that hook into MMO Skill Tree's systems (e.g., awarding Fishing XP when a fishing mod fires a catch event) without either mod hard-depending on the other.
The integration system has two layers:
- Built-in adapters - MMO Skill Tree ships with adapters for supported mods. Each adapter uses reflection to detect whether the target mod is installed and self-activates at startup. No server config required.
- Config overrides - Server owners can optionally disable or re-prioritize adapters via
integrations.json.
Compatible Mods
MMO Skill Tree ships with built-in support across 7 integration domains, backed by 8 registered adapters (FISHING is served by two adapters, and Perfect Utils backs both STUN and AGGRO):
| Mod | Domain | What it does |
|---|---|---|
| HyFishing / Angler's Almanac | FISHING | Awards FISHING XP and fires CATCH_FISH quest progress when a player lands a fish; two adapters cover HyFishing (TheRedlotus) and Angler's Almanac (dev.rm20). |
| Perfect Parries | PARRIES | Detection-only: confirms Perfect Parries (narwhals) is present so parry-based skill-tree reward types become available; the parry mod queries the MMO API for bonus values. |
| HyCitizens | CITIZENS | Subscribes to HyCitizens (com.electro) citizen-interact events and forwards NPC interactions to the quest system as TALK_TO_NPC progress. |
| SimpleEnchantments | ENCHANTING | Listens for SimpleEnchantments (org.herolias) item-enchanted events and awards ENCHANTING XP scaled by enchantment level. |
| Perfect Utils | STUN | Outbound bridge to Perfect Utils' (narwhals) StunMobAPI so MMO abilities can apply stun/stagger, wake targets, and query stunned state. |
| Perfect Utils | AGGRO | Outbound bridge to Perfect Utils' (narwhals) AggroAPI so MMO abilities can drop, suppress, taunt, or clear mob aggro and query its remaining duration. |
| Alec's Tamework | TAMING | Subscribes to Alec's Tamework (com.alechilles.alecstamework) CompanionXpAwardedEvent and credits the built-in TAMING skill with flat XP plus feed/harvest/breed/combat objective progress. |
Most integrations need no configuration - just install both mods and the integration activates automatically. Check [Integrations] in your server log to confirm it's active.
Hyronix NPC Dialog is not an auto-detected integration. To open the NPC quest UI from an NPC dialog, add mmoquestui <player> <npc_id> as a command in your NPC Dialog config at mods/Hyronix_NPC Dialog/. This lets players interact with an NPC to browse and accept quests tied to that npcViewId.
For Mod Authors
To integrate your mod with MMO Skill Tree, add the API jar as a compile-only dependency and implement the appropriate interface. Your adapter is discovered automatically at server startup.
Step 1: Add the API Dependency
The API is published as a separate, lightweight jar (mmoskilltree-api) versioned independently from the main plugin. Add it as compileOnly so it's available at compile time but not bundled into your jar - MMO Skill Tree provides it at runtime.
// build.gradle
dependencies {
compileOnly 'ziggfreed:mmoskilltree-api:1.5.0'
}The API jar contains only interfaces and annotations - no plugin logic, no transitive dependencies beyond JSR-305 nullability annotations.
Step 2: Implement the Domain Interface
Each integration domain has a specific interface. Currently available:
| Domain | Interface | Methods |
|---|---|---|
| Fishing | FishingIntegration | onFishCaught(), isFishItem(), getFishDisplayName() |
| Parries | ParriesIntegration | Marker interface - presence activates parry rewards in skill trees. Bonuses queried via MMOSkillTreeAPI. |
| Citizens | CitizensIntegration | Enables TALK_TO_NPC quest objectives. Adapter listens for NPC interaction events. |
| Enchanting | EnchantingIntegration | Fires when a player enchants an item. Adapter awards ENCHANTING XP via the event bus. |
| Stun | StunIntegration | Outbound bridge to Perfect Utils' StunMobAPI so MMO abilities can apply stun/stagger, wake targets, and query stunned state. |
| Aggro | AggroIntegration | Outbound bridge to Perfect Utils' AggroAPI so MMO abilities can drop, suppress, taunt, or clear mob aggro. |
| Taming | TamingIntegration | Listens for Alec's Tamework companion-XP events and credits the built-in TAMING skill plus objective progress. |
Implement the interface and annotate your class with @IntegrationMeta to declare your domain and priority:
import com.ziggfreed.mmoskilltree.integration.IntegrationDomain;
import com.ziggfreed.mmoskilltree.integration.IntegrationMeta;
import com.ziggfreed.mmoskilltree.integration.fishing.FishingIntegration;
@IntegrationMeta(
domain = IntegrationDomain.FISHING,
priority = 10
)
public class YourFishingAdapter implements FishingIntegration {
@Override
public String getModName() {
return "Your Fishing Mod";
}
@Override
public boolean initialize() {
// Set up reflection handles, verify your mod's API is available
// Return false to gracefully skip this adapter
return true;
}
@Override
public void shutdown() {
// Clean up resources
}
@Override
public void onFishCaught(String playerName, String fishIdentifier, int rarity) {
// Called by MMO Skill Tree when it detects a fish catch
}
@Override
public boolean isFishItem(String itemIdentifier) {
// Return true if your mod recognizes this as a fish
return false;
}
@Override
public String getFishDisplayName(String fishIdentifier) {
// Return a human-readable name for the fish, or null
return null;
}
}@IntegrationMeta Fields
| Field | Type | Default | Description |
|---|---|---|---|
domain | IntegrationDomain | (required) | Which integration category this adapter belongs to |
priority | int | 100 | Lower values are tried first. If two mods integrate the same domain, the lower-priority adapter wins. |
Step 3: Submit Your Adapter
Built-in adapters are registered explicitly inside MMO Skill Tree (Hytale mod classloaders don't support Java ServiceLoader discovery). To add your adapter:
- Build your adapter following the patterns above
- Open a pull request or reach out on Discord to have it included in the next release
Once registered, MMO Skill Tree calls your adapter's initialize() at startup. If your mod isn't installed, initialize() returns false (via a failed Class.forName()) and the adapter is silently skipped. No server owner configuration needed.
Step 4: Reflection Pattern for External API Calls
Your adapter should never directly import classes from the mod it integrates with. Instead, use reflection to access the external mod's API. This ensures your adapter compiles even if the target mod isn't present at build time.
// WRONG - breaks if the mod isn't on the classpath
import com.example.fishmod.FishAPI;
// RIGHT - reflection-safe
public class MyAdapter implements FishingIntegration {
private static final String API_CLASS = "com.example.fishmod.FishAPI";
private Method isFishMethod;
private Object apiInstance;
@Override
public boolean initialize() {
try {
Class<?> api = Class.forName(API_CLASS);
apiInstance = api.getMethod("getInstance").invoke(null);
isFishMethod = api.getMethod("isFish", String.class);
return true;
} catch (Exception e) {
return false; // Gracefully skip
}
}
@Override
public boolean isFishItem(String id) {
try {
return (Boolean) isFishMethod.invoke(apiInstance, id);
} catch (Exception e) {
return false;
}
}
}Selection Behavior
When multiple adapters are discovered for the same domain (e.g., two fishing mod integrations), MMO Skill Tree selects one using this process:
- All discovered adapters are grouped by domain
- Within each domain, adapters are sorted by effective priority (lowest first)
- Each adapter is tried in order:
- If disabled in config → skip
- If
initialize()returns false or throws → skip (target mod not installed) - First adapter that passes all checks becomes active
- If no adapter succeeds, the domain uses a no-op implementation (safe, does nothing)
Config Overrides (Server Owners)
By default, all discovered adapters are enabled and use their annotation-declared priority. Server owners can override this in mods/mmoskilltree/integrations.json:
{
"schemaVersion": 1,
"overrides": {
"com.example.MyFishingAdapter": {
"enabled": false
},
"com.other.BetterFishingAdapter": {
"priority": 1
}
}
}Override keys are the fully qualified class name of the adapter. Available fields:
| Field | Type | Default | Effect |
|---|---|---|---|
enabled | boolean | true | Set to false to prevent this adapter from activating |
priority | integer | (from annotation) | Override the priority. Lower values are tried first. |
If the file doesn't exist, an empty one is generated on first startup. Server owners never need to edit it unless they want to disable or re-order integrations.
Startup Logging
MMO Skill Tree logs the full integration resolution process at startup. Look for lines prefixed with [Integrations] in the server log:
[INFO] [Integrations] Discovered 8 adapter(s) (explicit registry)
[INFO] [Integrations] Fishing: activated HyFishing via ...HyFishingAdapter
[INFO] [Integrations] Parries: activated PerfectParries via ...PerfectParriesAdapter
[INFO] [Integrations] Citizens: activated HyCitizens via ...HyCitizensAdapter
[INFO] [Integrations] SimpleEnchantments adapter initialized - event bus handlers registered
[INFO] [Integrations] === Integration Resolution Summary ===
[INFO] [Integrations] Fishing: ACTIVE - HyFishing | ...
[INFO] [Integrations] Parries: ACTIVE - PerfectParries | ...
[INFO] [Integrations] Citizens: ACTIVE - HyCitizens | ...
[INFO] [Integrations] Enchanting: ACTIVE - SimpleEnchantments | ...
[INFO] [Integrations] Stun: ACTIVE - PerfectUtils | ...
[INFO] [Integrations] Aggro: ACTIVE - PerfectUtils | ...
[INFO] [Integrations] Taming: ACTIVE - AlecsTamework | ...
[INFO] [Integrations] ========================================API Reference
All classes are in the com.ziggfreed.mmoskilltree.integration package.
| Class | Type | Description |
|---|---|---|
OptionalIntegration | Interface | Base interface. Defines getModName(), initialize(), shutdown(). |
FishingIntegration | Interface | Extends OptionalIntegration. Adds fishing-specific hooks. |
IntegrationMeta | Annotation | Declares domain, priority, and target plugin identity on adapter classes. |
IntegrationDomain | Enum | Integration categories: FISHING, PARRIES, CITIZENS, ENCHANTING, STUN, AGGRO, TAMING. |
PluginId | Class | Identifies a plugin by manifest Group + Name. |
IntegrationCandidate | Class | Data holder for a candidate integration's metadata. |
NoOpFishingIntegration | Class | Default no-op. Returned when no fishing mod is active. |
ParriesIntegration | Interface | Extends OptionalIntegration. Marker interface for parry mod adapters. |
NoOpParriesIntegration | Class | Default no-op. Returned when no parry mod is active. |
CitizensIntegration | Interface | Extends OptionalIntegration. Enables NPC interaction quest objectives. |
NoOpCitizensIntegration | Class | Default no-op. Returned when no citizens mod is active. |
EnchantingIntegration | Interface | Extends OptionalIntegration. Awards ENCHANTING XP on enchant events. |
NoOpEnchantingIntegration | Class | Default no-op. Returned when no enchanting mod is active. |
StunIntegration | Interface | Extends OptionalIntegration. Outbound bridge to Perfect Utils' StunMobAPI. |
NoOpStunIntegration | Class | Default no-op. Returned when no stun-capable mod is active. |
AggroIntegration | Interface | Extends OptionalIntegration. Outbound bridge to Perfect Utils' AggroAPI. |
NoOpAggroIntegration | Class | Default no-op. Returned when no aggro-capable mod is active. |
TamingIntegration | Interface | Extends OptionalIntegration. Listens for Alec's Tamework companion-XP events. No no-op counterpart in the source. |
Quick Start Checklist
| Step | What to do |
|---|---|
| 1 | Add compileOnly 'ziggfreed:mmoskilltree-api:1.5.0' to your build |
| 2 | Implement the domain interface (e.g., FishingIntegration) |
| 3 | Annotate with @IntegrationMeta (domain, priority) |
| 4 | Use reflection for all calls to external mod APIs (no direct imports) |
| 5 | Submit your adapter via PR or Discord for inclusion in the next release |