Language

EliteEnchants

EliteEnchants

ModrinthSpigotMC

Create your own custom enchantments defined via JSON. The goal was to provide a solid amount of power and possibility. This is the first edition! It comes with some example custom enchants.

31 downloads 1 followers updated 22d ago
latest v1.0.0a Modrinth
Paper 1.21 – 26.1.2 EquipmentGame-mechanicsMagic

Splashv1

EliteEnchants

⚠ Alpha Release — Core systems are functional and stable. APIs and JSON schemas may change between versions. Test thoroughly before deploying on a live server.

EliteEnchants is a fully data-driven custom enchantment engine for Paper servers. Every enchant is defined entirely in a JSON file — no recompilation, no source edits, no restarts required to create new behavior. The engine evaluates a Trigger → Condition → Action pipeline at runtime, with a custom expression parser for dynamic numeric formulas and support for hooking into any Bukkit/Paper event.


Requirements

| Requirement | Version |
|---|---|
| Server software | Paper 1.21+ |
| Java | 21+ |


How It Works

Each enchant is a single JSON file placed in plugins/EliteEnchants/enchants/. On load (or /ee reload), the engine parses every file and registers its triggers dynamically — no hardcoded listeners required.

The runtime pipeline for every player action looks like this:

Player Action / Event
        ↓
Trigger Dispatcher
        ↓
Condition Evaluation  (short-circuits on first failure)
        ↓
Expression Resolution (level, damage, health, random, ...)
        ↓
Action Execution

Enchant data is stored on items using the PersistentDataContainer (PDC) API, making it fully persistent across server restarts and compatible with vanilla item handling.


Getting Started

1. Install

Drop the .jar into your plugins/ folder and start the server. Six example enchants are written automatically to plugins/EliteEnchants/enchants/ on first launch.

2. Apply an Enchant to an Item

Use /ee book <id> <level> to receive an enchant book, then drag and drop it onto any compatible item in your inventory. The book is consumed on application.

3. Create Your Own Enchant

Create a new .json file in plugins/EliteEnchants/enchants/ and run /ee reload. No server restart needed.


Commands

| Command | Description | Permission |
|---|---|---|
| /ee book <id> <level> | Give yourself an enchant book | (default: op) |
| /ee list | List all loaded enchants | — |
| /ee info <id> | Show details for a specific enchant | — |
| /ee reload | Hot-reload all enchant JSON files | eliteenchants.admin |
| /ee strip | Remove all custom enchants from held item | — |

All subcommands support tab completion, including enchant IDs and valid level ranges.


Enchant File Structure

A minimal enchant file looks like this:

{
  "id": "LIFESTEAL",
  "display_name": "<red>Lifesteal",
  "description": ["Heal on hit. Chance and heal amount scale with level."],
  "max_level": 5,
  "applicable_to": ["SWORD", "AXE"],
  "conflicts_with": [],
  "triggers": [
    {
      "event": "ON_HIT",
      "cooldown": 0.5,
      "conditions": [
        { "type": "CHANCE", "value": "0.15 + (level * 0.1)" },
        { "type": "TARGET_IS", "value": "LIVING" }
      ],
      "actions": [
        { "type": "HEAL",           "target": "HOLDER", "amount": "level * 1.5" },
        { "type": "SEND_ACTION_BAR","target": "HOLDER", "message": "<red>❤ Lifesteal!" }
      ]
    }
  ]
}

display_name and message fields support full MiniMessage formatting (<red>, <bold>, <gradient:...>, etc.).


Expression Engine

Any numeric field in conditions or actions accepts a full math expression. Expressions are evaluated at runtime with per-context variable injection.

Example:

{ "type": "ADD_DAMAGE", "amount": "level * (1.0 - holder_health_pct) * 5" }

Available Variables

| Variable | Description |
|---|---|
| level | Current enchant level |
| damage | Damage value in the triggering event |
| holder_health | Holder's current HP |
| holder_max_health | Holder's maximum HP |
| holder_health_pct | Holder's HP as a fraction (0.0–1.0) |
| target_health | Target's current HP |
| target_max_health | Target's maximum HP |
| target_health_pct | Target's HP as a fraction (0.0–1.0) |
| distance | Distance between holder and target |
| random | Random decimal (0.0–1.0) |

Supported Operators

+   -   *   /   %   ^
<   >   <=  >=  ==  !=
&&  ||  !

Built-In Functions

min() max() abs() floor() ceil() round() sqrt() pow() log() sin() cos() clamp() lerp() random()


Triggers

Standard Triggers

| Trigger | Description |
|---|---|
| ON_HIT | Holder damages an entity |
| ON_TAKE_DAMAGE | Holder receives damage |
| ON_KILL | Holder kills an entity |
| ON_MINE | Holder breaks a block |
| ON_SNEAK | Holder begins sneaking |
| ON_SHOOT | Holder launches a projectile |
| ON_ARROW_LAND | Projectile hits a target |
| ON_RIGHT_CLICK | Holder right-clicks |
| TICK | Fires every server tick (use cooldown to gate frequency) |

Dynamic Event Triggers

Any Bukkit/Paper event can be registered at runtime using reflection-safe MethodHandle dispatch. Define the event class and the methods that resolve the holder and target:

{
  "eventClass": "org.bukkit.event.player.PlayerInteractEntityEvent",
  "holderMethod": "getPlayer",
  "targetMethod": "getRightClicked"
}

This opens the door to entity interaction enchants, projectile logic, inventory triggers, movement systems, and anything else the Bukkit API exposes — without touching Java.


Conditions

All conditions in a trigger must pass before any actions execute. Evaluation short-circuits on the first failure.

| Condition | Description |
|---|---|
| CHANCE | Probabilistic check — e.g. "0.05 * level" |
| HEALTH_ABOVE / HEALTH_BELOW | Holder HP threshold |
| HEALTH_PERCENT_ABOVE / HEALTH_PERCENT_BELOW | Holder HP as fraction |
| TARGET_HEALTH_ABOVE / TARGET_HEALTH_BELOW | Target HP threshold |
| IS_SNEAKING / IS_SPRINTING / IS_FLYING | Movement state |
| IS_ON_GROUND / IS_ON_FIRE / IS_FROZEN | Physical state |
| TARGET_IS / TARGET_NOT | Entity category (LIVING, UNDEAD, CREATURE, etc.) |
| DAMAGE_ABOVE / DAMAGE_BELOW / DAMAGE_CAUSE | Damage event filtering |
| BIOME_IS / WORLD_IS / TIME_IS / WEATHER_IS | Environmental checks |
| HAS_EFFECT / TARGET_HAS_EFFECT | Potion effect checks |
| EXPR / EXPRESSION | Arbitrary boolean expression |


Actions

| Action | Description |
|---|---|
| HEAL | Restore HP to target |
| DAMAGE | Deal damage to target |
| ADD_DAMAGE | Add flat bonus to current event damage |
| MULTIPLY_DAMAGE | Multiply current event damage by a factor |
| SET_HEALTH | Set target HP to a specific value |
| SET_ON_FIRE / EXTINGUISH | Ignite or extinguish target |
| FREEZE / UNFREEZE | Apply or remove powder snow freeze |
| APPLY_POTION / REMOVE_POTION / CLEAR_POTIONS | Manage potion effects |
| PLAY_SOUND | Play a sound at the target's location |
| SPAWN_PARTICLE | Spawn a particle effect |
| SEND_MESSAGE / SEND_ACTION_BAR / SEND_TITLE | Send text to the holder |
| STRIKE_LIGHTNING / STRIKE_LIGHTNING_EFFECT | Real or visual lightning |
| TELEPORT / TELEPORT_BEHIND | Teleport an entity |
| LAUNCH / KNOCKBACK / PULL | Apply velocity |
| EXPLOSION | Create an explosion |
| BREAK_BLOCK | Break blocks in a radius |
| SPAWN_MOB | Spawn an entity |
| GIVE_EXP / RESTORE_HUNGER / RESTORE_SATURATION | Player resource management |
| CANCEL_EVENT | Cancel the triggering Bukkit event |
| RUN_COMMAND | Execute a console or player command |

Dynamic Action Registry (Java API)

Addons and soft-dependencies can register entirely custom actions at runtime without modifying the plugin:

actionRegistry.put("SPAWN_EGG", (def, ctx) -> {
    if (ctx.target instanceof Creature creature) {
        ItemStack egg = new ItemStack(
            Material.valueOf(creature.getType().name() + "_SPAWN_EGG")
        );
        ctx.holder.getWorld().dropItemNaturally(ctx.holder.getLocation(), egg);
    }
});

Included Example Enchants

Six fully-configured enchants are written to disk on first launch as ready-to-use references:

| ID | Slot | Description |
|---|---|---|
| LIFESTEAL | Sword, Axe | Heals on hit; chance and amount scale with level |
| LIGHTNING | Sword, Axe, Trident | Chance to strike lightning; adds bonus damage and slowness |
| BERSERKER | Sword, Axe | Bonus damage scales with missing health percentage |
| FEATHERFALL_ELITE | Boots | Reduces fall damage by 25% per level; eliminated at max level |
| EXCAVATOR | Pickaxe, Shovel | Area block-break while sneaking; radius scales with level |
| FROSTBITE | Sword, Axe | Freezes and slows on hit; conflicts with LIGHTNING |


Performance Notes

The engine is designed with throughput in mind:

  • Cached MethodHandles — dynamic event resolution avoids repeated reflection lookups
  • Cooldown gating — per-trigger, per-player cooldowns are checked before any evaluation
  • Short-circuit conditions — the condition chain aborts on the first failure; expensive checks should go last
  • Filtered dispatch — only enchants relevant to the triggered event and the holder's equipped items are evaluated

Advanced Example

{
  "id": "VOIDSTEP",
  "display_name": "<dark_purple>Voidstep",
  "description": ["Teleport behind your target on hit."],
  "max_level": 3,
  "applicable_to": ["SWORD"],
  "conflicts_with": [],
  "triggers": [
    {
      "event": "ON_HIT",
      "cooldown": 4.0,
      "conditions": [
        { "type": "CHANCE", "value": "0.08 * level" },
        { "type": "TARGET_IS", "value": "LIVING" }
      ],
      "actions": [
        { "type": "TELEPORT_BEHIND", "target": "TARGET" },
        { "type": "PLAY_SOUND", "target": "HOLDER", "sound": "ENTITY_ENDERMAN_TELEPORT" },
        { "type": "SPAWN_PARTICLE", "location": "TARGET", "particle": "PORTAL", "count": "20", "spread": "0.5" }
      ]
    }
  ]
}

Versions

Alpha
1.0.0a
paper · 1.21, 1.21.1, 1.21.2 · 22d ago
## Hotfix A. ### **CHANGED:** ``` EntityType type = EntityType.valueOf(param(action, "type", "ZOMBIE").toUpperCase()); ``` ###…
29
Alpha
1.0.0
paper · 1.21, 1.21.1, 1.21.2 · 23d ago
Initial Alpha Release.
2

Comments 0

No comments yet. Be the first to share your thoughts.

Download EliteEnchants

SpigotMC

Files are served directly from the original source. Modgrid does not host or modify them.