Skip to main content
The RPGMobs API allows other Hytale mods to react to RPG mob events, inspect mob state, and modify behavior at runtime. It ships as a separate RPGMobs-api artifact so your mod only depends on the lightweight API interfaces, not the full plugin.

Setup

Dependency

Add the API JAR as a compile-only dependency in your build.gradle:
dependencies {
    compileOnly files('libs/RPGMobs-API-1.0.0.jar')
}
Or if published to a Maven repository:
dependencies {
    compileOnly 'Frotty27:RPGMobs-api:1.0.0'
}
The -javadoc.jar and -sources.jar are available as additional downloads. Place all three in your libs/ folder for full IDE support (autocomplete, inline docs, click-to-source).

Mod Manifest

Declare RPGMobs as a dependency in your mod’s manifest.json so Hytale loads it before your mod:
{
  "Dependencies": {
    "Frotty27:RPGMobs": "*"
  }
}

Entry Point

All API access goes through the static RPGMobsAPI class:
import com.frotty27.rpgmobs.api.RPGMobsAPI;

// Register a listener
RPGMobsAPI.registerListener(myListener);

// Query mob state
RPGMobsAPI.query().getTier(entityRef);

// Unregister when your mod shuts down
RPGMobsAPI.unregisterListener(myListener);
If RPGMobs has not initialized yet, calling these methods throws RPGMobsNotInitializedException.

Event System

Implement IRPGMobsEventListener and override the events you care about. All handler methods have default no-op implementations, so you only need to override what you use.
import com.frotty27.rpgmobs.api.IRPGMobsEventListener;
import com.frotty27.rpgmobs.api.events.*;

public class MyEliteListener implements IRPGMobsEventListener {

    @Override
    public void onRPGMobSpawned(RPGMobsSpawnedEvent event) {
        int tier = event.getTier();
        // Cancel the spawn if needed
        // event.setCancelled(true);
    }

    @Override
    public void onRPGMobDrops(RPGMobsDropsEvent event) {
        // Add custom items to the drop list
        event.getDrops().add(myCustomItem);
    }

    @Override
    public void onRPGMobDamageDealt(RPGMobsDamageDealtEvent event) {
        // Reduce elite damage by 20%
        event.setMultiplier(event.getMultiplier() * 0.8f);
    }
}
Register it during your mod’s initialization:
RPGMobsAPI.registerListener(new MyEliteListener());

Available Events

EventFired whenCancellableMutable fields
RPGMobsSpawnedEventElite enters the worldYes
RPGMobsDeathEventElite diesNo
RPGMobsDropsEventLoot is about to spawnYesgetDrops() (live list)
RPGMobsDamageDealtEventElite deals outgoing damageYessetMultiplier(float)
RPGMobsDamageReceivedEventElite takes incoming damageNo
RPGMobsAbilityStartedEventAbility execution beginsYes
RPGMobsAbilityCompletedEventAbility finishes normallyNo
RPGMobsAbilityInterruptedEventAbility was interruptedNogetReason()
RPGMobsAggroEventElite targets an entityNotargetRef()
RPGMobsDeaggroEventElite loses its targetNo
RPGMobsScalingAppliedEventScaling parameters computedNoAll fields (read-only record)
RPGMobsReconcileEventConfig reconciliation passNo

Base Event Fields

Every event extends RPGMobsEvent which provides:
  • getEntityRef() — the RPG mob’s Ref<EntityStore>
  • getTier() — zero-based tier index (0 = Tier 1, 4 = Tier 5)
  • getRoleName() — the NPC role identifier (e.g. "Skeleton_Frost_Knight")

Cancelling Events

Events that implement ICancellable can be cancelled to prevent the action:
@Override
public void onRPGMobSpawned(RPGMobsSpawnedEvent event) {
    if (event.getTier() >= 4) {
        event.setCancelled(true); // Block Tier 5 spawns
    }
}
Cancellable events: RPGMobsSpawnedEvent, RPGMobsDropsEvent, RPGMobsDamageDealtEvent, RPGMobsAbilityStartedEvent.

Query API

The Query API provides read-only access to any RPG mob’s current state. Access it via RPGMobsAPI.query().
import com.frotty27.rpgmobs.api.query.IRPGMobsQueryAPI;

IRPGMobsQueryAPI query = RPGMobsAPI.query();

Identity

MethodReturnsDescription
isRPGMob(ref)booleanWhether the entity is an RPGMobs elite
getTier(ref)Optional<Integer>Zero-based tier index

Scaling

MethodReturnsDescription
getHealthMultiplier(ref)Optional<Float>Applied health multiplier
getDamageMultiplier(ref)Optional<Float>Applied damage multiplier
getModelScale(ref)Optional<Float>Visual size scale
isHealthFinalized(ref)booleanWhether health scaling has been verified

Progression

MethodReturnsDescription
getSpawnDistance(ref)Optional<Float>Distance from world origin at spawn
getDistanceHealthBonus(ref)Optional<Float>Bonus health from distance
getDistanceDamageBonus(ref)Optional<Float>Bonus damage from distance

Combat

MethodReturnsDescription
isInCombat(ref)booleanWhether the mob has an active target
getLastAggroTarget(ref)Optional<Ref<EntityStore>>Current or last aggro target
getLastAggroTick(ref)Optional<Long>Server tick of last aggro event

Summons

MethodReturnsDescription
getSummonedMinionCount(ref)Optional<Integer>Number of active summoned minions

Abilities

MethodReturnsDescription
getSupportedTriggerTypes()Set<String>All registered ability trigger type IDs
isTriggerTypeSupported(id)booleanWhether a specific trigger type is registered

Query Examples

Check if an entity is an elite and read its tier

IRPGMobsQueryAPI query = RPGMobsAPI.query();

if (query.isRPGMob(entityRef)) {
    int tier = query.getTier(entityRef).orElse(0);
    System.out.println("RPG mob detected — Tier " + (tier + 1));
}

Read scaling values for a HUD or tooltip

IRPGMobsQueryAPI query = RPGMobsAPI.query();

Optional<Float> health = query.getHealthMultiplier(entityRef);
Optional<Float> damage = query.getDamageMultiplier(entityRef);
Optional<Float> scale  = query.getModelScale(entityRef);

health.ifPresent(h -> System.out.println("Health multiplier: " + h + "x"));
damage.ifPresent(d -> System.out.println("Damage multiplier: " + d + "x"));
scale.ifPresent(s ->  System.out.println("Model scale: " + s + "x"));

Check combat state and current target

IRPGMobsQueryAPI query = RPGMobsAPI.query();

if (query.isInCombat(entityRef)) {
    query.getLastAggroTarget(entityRef).ifPresent(targetRef -> {
        System.out.println("Currently fighting a target");
    });
    query.getLastAggroTick(entityRef).ifPresent(tick -> {
        System.out.println("Aggro started at server tick " + tick);
    });
}

Read distance-based progression bonuses

IRPGMobsQueryAPI query = RPGMobsAPI.query();

query.getSpawnDistance(entityRef).ifPresent(distance -> {
    System.out.println("Spawned " + distance + "m from world origin");
});

Optional<Float> healthBonus = query.getDistanceHealthBonus(entityRef);
Optional<Float> damageBonus = query.getDistanceDamageBonus(entityRef);

if (healthBonus.isPresent() && damageBonus.isPresent()) {
    System.out.println("Distance bonuses — health: +" + healthBonus.get()
        + "x, damage: +" + damageBonus.get() + "x");
}

Monitor summoned minions

IRPGMobsQueryAPI query = RPGMobsAPI.query();

query.getSummonedMinionCount(entityRef).ifPresent(count -> {
    System.out.println("Active minions: " + count);
});

Ability Types

The AbilityType enum defines the built-in abilities:
EnumIDDescription
HEAL_LEAP"HEAL_LEAP"Jump to safety and self-heal
CHARGE_LEAP"CHARGE_LEAP"Leap toward target with area damage
SUMMON_UNDEAD"SUMMON_UNDEAD"Spawn undead reinforcements

Example: Full Integration

import com.frotty27.rpgmobs.api.RPGMobsAPI;
import com.frotty27.rpgmobs.api.IRPGMobsEventListener;
import com.frotty27.rpgmobs.api.events.*;

public class MyMod implements IRPGMobsEventListener {

    public void onEnable() {
        RPGMobsAPI.registerListener(this);
    }

    public void onDisable() {
        RPGMobsAPI.unregisterListener(this);
    }

    @Override
    public void onRPGMobSpawned(RPGMobsSpawnedEvent event) {
        // Log spawns for analytics
        System.out.println("Elite spawned: tier=" + event.getTier()
            + " role=" + event.getRoleName());
    }

    @Override
    public void onRPGMobDrops(RPGMobsDropsEvent event) {
        // Double drops for Tier 5 elites
        if (event.getTier() == 4) {
            var drops = event.getDrops();
            drops.addAll(new ArrayList<>(drops));
        }
    }

    @Override
    public void onRPGMobDamageDealt(RPGMobsDamageDealtEvent event) {
        // Check if mob is far from spawn using query API
        var distance = RPGMobsAPI.query()
            .getSpawnDistance(event.getEntityRef());

        if (distance.isPresent() && distance.get() > 5000f) {
            // Extra 10% damage for mobs far from spawn
            event.setMultiplier(event.getMultiplier() * 1.1f);
        }
    }
}

Thread Safety

Event callbacks are dispatched from the server’s main tick thread. Do not perform blocking I/O or long-running computations inside event handlers. If you need async processing, queue work to a separate thread and return immediately. The Query API reads component data from the entity store and should only be called from contexts where the store is accessible (event handlers, tick systems, or world.execute() callbacks).