Skip to content

API and Integration

EmakiLevel exposes a static facade, EmakiLevelApi. Third-party plugins should depend on emaki-level-api; the installed EmakiLevel plugin installs the bridge during enable and removes it on disable.

Dependency

Maven:

xml
<dependency>
  <groupId>emaki.jiuwu.craft</groupId>
  <artifactId>emaki-level-api</artifactId>
  <version>1.4.0</version>
  <scope>provided</scope>
</dependency>

Gradle:

kotlin
dependencies {
    compileOnly("emaki.jiuwu.craft:emaki-level-api:1.4.0")
}

Server runtime jars:

text
EmakiCoreLib-*.jar
EmakiLevel-1.4.0.jar

Do not put emaki-level-api-*.jar into plugins/. The runtime plugin jar already contains its own API.

Getting the API

Use the static facade directly:

java
if (EmakiLevelApi.available()) {
    int level = EmakiLevelApi.getLevel(player.getUniqueId(), "main");
    double exp = EmakiLevelApi.getExp(player.getUniqueId(), "main");
}

If you prefer a helper, check availability first:

java
if (!EmakiLevelApiProvider.available()) {
    return;
}

EmakiLevelApiProvider.requireAvailable();
LevelOperationResult result = EmakiLevelApi.addExp(player.getUniqueId(), "main", 50.0, "quest_reward");

Recommended paper-plugin.yml optional dependency:

yaml
dependencies:
  server:
    EmakiLevel:
      load: BEFORE
      required: false
      join-classpath: true

If your plugin cannot run without EmakiLevel, set required to true.

EmakiLevelApi methods

MethodDescription
available()Whether the API is installed.
type(String typeId)Query one level type.
types()Get all loaded level types.
getPlayerData(UUID uuid)Get a player level data view.
getLevel(UUID uuid, String typeId)Get the current level.
getExp(UUID uuid, String typeId)Get current-level exp.
getTotalExp(UUID uuid, String typeId)Get total exp.
getRequiredExp(UUID uuid, String typeId, int targetLevel)Get required exp for a target level.
addExp(UUID uuid, String typeId, double amount, String reason)Add exp and trigger auto-upgrade.
removeExp(UUID uuid, String typeId, double amount, String reason)Remove current-level exp without downgrading.
setExp(UUID uuid, String typeId, double amount, String reason)Set current-level exp.
addLevel(UUID uuid, String typeId, int amount, String reason)Add levels and reset current-level exp.
removeLevel(UUID uuid, String typeId, int amount, String reason)Remove levels and reset current-level exp.
setLevel(UUID uuid, String typeId, int level, String reason)Set level and reset current-level exp.
levelUp(UUID uuid, String typeId, LevelUpCause cause)Try to level up once with requirements, costs, and rewards.

Use stable reason ids such as quest_reward, dungeon_clear, or daily_task. The reason is exposed to the level action variable %reason%.

Data views

LevelTypeView reads the display information, bounds, upgrade mode, and attributes for a level type.

PlayerLevelView summarizes all level types for one player.

PlayerLevelEntryView contains level, exp, totalExp, requiredExp, and progress for one type.

LevelOperationResult contains whether the operation succeeded, the failure reason, the operation type, type id, the before/after level and exp, and extra data.

Always check success():

java
LevelOperationResult result = EmakiLevelApi.addExp(player.getUniqueId(), "combat", 25.0, "arena_win");
if (!result.success()) {
    plugin.getLogger().warning("Failed to add level exp: " + result.reason());
    return;
}

Common failure reasons include player_not_found, type_not_found, type_disabled, invalid_amount, upgrade_disabled, manual_upgrade_disabled, max_level, not_enough_exp, not_enough_money, not_enough_material, and invalid_requirement.

CoreLib Action

EmakiLevel registers CoreLib actions so other modules, scripts, or integrations can modify level data.

Action ids

CoreLib actions registered by EmakiLevel let other modules, scripts, or third-party integrations modify level data. Current action IDs use only canonical names; historical aliases are no longer registered. See CoreLib Actions for the full action page.

OperationAction ID
Add expemakileveladdexp
Set expemakilevelsetexp
Remove expemakilevelremoveexp
Add levelemakileveladdlevel
Set levelemakilevelsetlevel
Remove levelemakilevelremovelevel
Reset level typeemakilevelreset
Manual level-upemakilevellevelup

Parameters

ParameterRequiredDefaultDescription
typeYesprimary_typeLevel type id.
amountYes0Exp or level amount. Level operations are rounded to integers.
targetNoContext playerOnline player name or UUID. Falls back to ActionContext.player().
reasonNoactionOperation reason.
auto_upgradeNotrueOnly matters for exp addition; whether this operation can trigger auto-upgrade.
silentNofalseSilent flag passed to the level service.

Examples

yaml
actions:
  - 'emakileveladdexp type="cooking" amount="25" reason="recipe_success"'
yaml
actions:
  - 'emakileveladdexp target="Steve" type="main" amount="100" reason="admin_reward"'
yaml
actions:
  - 'emakileveladdexp type="mining" amount="500" auto_upgrade="false" reason="event_reward"'
yaml
actions:
  - 'emakilevelsetlevel target="Steve" type="combat" amount="30" reason="migration"'

A successful action returns type, old_level, new_level, old_exp, new_exp, and amount. Failed actions return a CoreLib failure result with an EmakiLevel reason id.

MythicMobs drop integration

MythicMobs intangible drops do not need a developer API:

yaml
Drops:
  - emakilevel_exp{type=main;amount=120}
  - elv_exp{type=combat;amount=80;reason=mythic_drop}

See MythicMobs integration for details.

Do not depend on implementation classes

Third-party plugins should not reference DefaultEmakiLevelApi, PlayerLevelService, PlayerLevelDataStore, LevelTypeLoader, RequirementLoader, SourceRuleLoader, LevelOperationAction, or any class under emaki.jiuwu.craft.level.service, loader, listener, or bridge. The stable public entry point is only emaki.jiuwu.craft.level.api.*.