How to Make a Custom Mob

A custom mob is a vanilla base entity wrapped with your own stats, equipment, effects, drops, and spawning, all defined in one config file. EcoMobs reads each file in the mobs/ folder and registers a mob you can spawn, drop loot from, and hook effects onto. This page covers building one from scratch, naming it, every part of its config, and the placeholders you can use inside it.

Quick start

  1. Open plugins/EcoMobs/mobs/ and copy _example.yml, renaming it to your mob's ID, e.g. necrotic_soldier.yml. The file name (without .yml) is the mob ID.

  2. Set the base mob and stat modifiers, and pick a category (this controls natural spawning).

  3. Set the display-name, then fill in the parts you want: equipment, effects, drops, boss-bar, and spawn.

  4. Run /ecomobs reload to load the mob.

  5. Run /ecomobs spawn necrotic_soldier and confirm the mob appears in the world with the name and stats you set.

Naming and IDs

The mob's file name without .yml is its ID. This is what you pass to commands, effects, the Entity Lookup System, and the Item Lookup System.

The structure of a mob

A mob config is a set of named parts, each controlling one aspect of the mob.

PartWhat it controls
Mob infoThe base entity, stat modifiers, category, display name, and lifespan
EquipmentThe items the mob wears in each slot
IntegrationsHooks into other plugins (LevelledMobs, ModelEngine, etc.)
Custom AIThe mob's targeting and behaviour goals
EffectsEffects and conditions that fire on mob actions
Damage stagesOptional phases the fight moves through, drained by damage, by hits, or by anything you can count
DefenceMounting and per-cause damage modifiers
DropsExperience and item drops on death
Boss barThe on-screen health bar
SpawnSpawn totems and craftable spawn eggs

Here is a complete mob with every part in place:

# === Mob info: the base entity and identity ===
mob: zombie attack-damage:90 movement-speed:1.5 follow-range:16 health:1200 # Base entity plus stat modifiers; see the Entity Lookup System
category: common # The category ID; controls natural spawning (required)
display-name: "&cNecrotic Soldier &7| &c%health%♥ &7| &e%time%" # Supports the internal placeholders below
lifespan: 120 # Seconds before the mob despawns; set to -1 to disable

# === Damage stages: optional, splits the fight into phases ===
damage-stages:
  1:
    mode: health # This stage absorbs damage
    health: 600 # The damage it absorbs before it ends
    start-effects: [ ] # Effects run when the stage begins
    end-effects: [ ] # Effects run when the stage ends
  2:
    mode: hits # This stage takes a fixed number of hits, whatever the weapon
    required-hits: 20 # The hits it takes before it ends
    player-only: true # If false, fire, lava, and other mobs also cost hits
    start-effects: [ ]
    end-effects: [ ]
  3:
    mode: trigger # This stage is drained by anything you can count, not by damage
    required-count: 30 # The count it takes before it ends
    radius: 32 # How far from the mob a player has to be for their count to land
    count-methods: # What counts; the same counters EcoJobs and EcoSkills use
      - trigger: mine_block
        value: 1
        filters:
          blocks:
            - coal_ore
    start-effects: [ ]
    end-effects: [ ]

# === Equipment: what the mob wears ===
equipment:
  hand: diamond_sword sharpness:2 # Remove any slots you don't want to fill
  off-hand: shield
  head: ""
  chest: ""
  legs: ""
  feet: ""

# === Integrations: hooks into other plugins ===
integrations:
  levelled-mobs:
    can-level: true # Allow LevelledMobs to level this mob
  model-engine:
    id: "" # ModelEngine model ID; leave blank for none
  better-model:
    id: "" # BetterModel model ID; leave blank for none
  libs-disguises:
    id: "" # LibsDisguises disguise ID; leave blank for none

# === Custom AI: how the mob behaves ===
custom-ai:
  clear: false # If true, custom AI replaces the vanilla entity AI
  target-goals: [ ] # How the mob decides who to attack
  entity-goals: [ ] # How the mob moves and behaves

# === Effects: actions that fire on mob triggers ===
effects:
  permanent-effects: [ ] # Always active; run as the entity
  spawn: [ ] # On spawn; run as the entity
  despawn: [ ] # On despawn; run as the entity
  interact: [ ] # On player interact; run as the player
  melee-attack: [ ] # On player melee attack; run as the player
  ranged-attack: [ ] # On player ranged attack; run as the player
  any-attack: [ ] # On any player attack; run as the player
  take-damage: [ ] # When the mob takes damage; run as the entity
  damage-player: [ ] # When the mob damages a player; run as the player
  kill-player: [ ] # When the mob kills a player; run as the player
  death: [ ] # When the mob dies; run as the entity
  kill: [ ] # When a player kills the mob; run as the player

# === Defence: incoming damage handling ===
defence:
  can-mount: true # If the mob can enter boats, minecarts, etc.
  damage-modifiers: # Multiply incoming damage by cause
    hot_floor: 1
    fire_tick: 1
    lava: 1
    suffocation: 1
    drowning: 1
    entity_explosion: 1
    block_explosion: 1

# === Drops: rewards on death ===
drops:
  experience: 30 # Experience dropped on death
  items:
    - chance: 100 # Percent chance for this group to drop
      items:
        - diamond_sword unbreaking:1 name:"Example Sword"

# === Boss bar: on-screen health bar ===
boss-bar:
  enabled: true # If the mob shows a boss bar
  color: white # blue, green, pink, purple, red, white, yellow
  style: progress # progress, notched_20, notched_12, notched_10, notched_6
  radius: 120 # Distance from the mob where the bar is visible

# === Spawn: totems and eggs ===
spawn:
  totem:
    enabled: false # If a 3-block totem can summon the mob
    top: netherite_block
    middle: iron_block
    bottom: magma_block
    conditions: [ ] # Conditions for the totem to work
  egg:
    enabled: true # If the mob has a spawn egg
    conditions: [ ] # Conditions for the egg to work; not-met-lines show on the egg
    item: evoker_spawn_egg unbreaking:1 hide_enchants # The spawn egg item
    name: "&cNecrotic Soldier&f Spawn Egg"
    lore:
      - ""
      - "&8&oPlace on the ground to"
      - "&8&osummon a &cNecrotic Soldier"
    craftable: true # If the spawn egg can be crafted
    recipe-permission: "ecomobs.craft.necrotic_soldier" # Optional; permission required to craft the egg
    shapeless: false # Optional; whether the recipe is shapeless, defaults to false
    recipe:
      - iron_block
      - netherite_block
      - iron_block
      - air
      - ecoitems:boss_core ? nether_star
      - air
      - iron_block
      - netherite_block
      - iron_block

Mob info

The top-level fields define what the mob is and how it identifies itself.

mob: zombie attack-damage:90 movement-speed:1.5 follow-range:16 health:1200 # Base entity plus stat modifiers
category: common # The category ID; controls natural spawning
display-name: "&cNecrotic Soldier &7| &c%health%♥ &7| &e%time%" # Supports the internal placeholders below
lifespan: 120 # Seconds before the mob despawns; set to -1 to disable

The mob line is a base entity with stat modifiers, read through the Entity Lookup System.

Equipment

If the base entity supports equipment, set an item per slot.

equipment:
  hand: diamond_sword sharpness:2 # Remove any slot you don't want to fill
  off-hand: shield
  head: ""
  chest: ""
  legs: ""
  feet: ""

Integrations

Hook the mob into other plugins you run. Remove the blocks for plugins you don't use.

integrations:
  levelled-mobs:
    can-level: true # Allow LevelledMobs to level this mob
  model-engine:
    id: "" # ModelEngine model ID
  better-model:
    id: "" # BetterModel model ID
  libs-disguises:
    id: "" # LibsDisguises disguise ID

Custom AI

Replace or extend the mob's behaviour with custom goals.

custom-ai:
  clear: false # If true, custom AI replaces the vanilla entity AI
  target-goals: [ ] # How the mob decides who to attack
  entity-goals: [ ] # How the mob moves and behaves

See the Custom Entity AI docs for the full list of goals.

Effects

Each key is a trigger; the effects you list under it fire when that trigger happens. Some run from the perspective of the entity, others from the player, marked per line.

effects:
  permanent-effects: [ ] # Always active; run as the entity
  spawn: [ ] # On spawn; run as the entity
  interact: [ ] # On player interact; run as the player
  melee-attack: [ ] # On player melee attack; run as the player
  take-damage: [ ] # When the mob takes damage; run as the entity
  death: [ ] # When the mob dies; run as the entity
  kill: [ ] # When a player kills the mob; run as the player

Display-name placeholders and the top-damager placeholders (%top_damager_<place>_name%, %top_damager_<place>_damage%, %top_damager_<place>_display%) work inside effects.

Damage stages

Optional. Splits the fight into ordered phases. Each stage is drained by one of three modes, and can run effects when it begins and ends. Leave the section out entirely for a normal mob that simply loses health.

damage-stages:
  1:
    mode: health # Absorbs damage
    health: 600 # The damage this stage absorbs before it ends
    start-effects: [ ]
    end-effects: [ ]
  2:
    mode: hits # Takes a fixed number of hits, whatever the weapon
    required-hits: 20 # The hits this stage takes before it ends
    player-only: true # If false, fire, lava, and other mobs also cost hits
    start-effects: [ ]
    end-effects: [ ]
  3:
    mode: trigger # Drained by anything you can count, not by damage
    required-count: 30 # The count this stage takes before it ends
    radius: 32 # How far from the mob a player has to be for their count to land
    count-methods:
      - trigger: mine_block
        value: 1
        filters:
          blocks:
            - coal_ore
    start-effects: [ ]
    end-effects: [ ]

A hits stage is the reason this exists: with required-hits: 20, the stage takes exactly twenty hits whether the attacker punches barehanded or swings a maxed netherite sword.

The keys order the stages. Any key that is not a number is ignored, and gaps are fine — 1, 5, 10 runs in that order.

The mob's health, set in the mob lookup string, becomes a display mirror of overall stage progress. The boss bar drains once across the whole fight, with each stage taking an equal share of it, and healing the mob cannot buy it extra progress.

KeyModeMeaning
modeallhealth, hits, or trigger
healthhealthThe damage the stage absorbs. Must be greater than 0
required-hitshitsThe hits the stage takes. Must be at least 1
player-onlyhitsIf true, only player damage costs a hit
required-counttriggerThe count the stage takes. Must be greater than 0
radiustriggerHow far the stage reaches from the player who earned a count, in blocks. Defaults to 32
count-methodstriggerWhat counts toward the stage. At least one is required
start-effectsallEffects run when the stage begins
end-effectsallEffects run when the stage ends

Modes

health — a pool of damage. Every point of damage from any source drains it, whoever or whatever dealt it.

hits — a fixed number of hits, whatever the weapon. Each hit costs exactly one, so the stage lasts the same number of swings no matter how hard they land. With player-only: true only player damage counts, and everything else is cancelled outright; with player-only: false fire, lava, and other mobs each cost a hit too.

trigger — drained by anything libreforge can count, rather than by damage. The mob is untouchable for the length of the stage: hits still flinch it, knock it back, and fire its take-damage effects, but they move the stage not at all. It ends when its count-methods have delivered required-count.

Trigger stages and count-methods

count-methods is a list of libreforge counters, the same system EcoJobs and EcoSkills use for their own progress. Each entry names a trigger, and optionally filters, conditions, and either a value or a multiplier:

damage-stages:
  1:
    mode: trigger
    required-count: 500
    radius: 48
    count-methods:
      # Every soul sand mined near the boss counts for one
      - trigger: mine_block
        value: 1
        filters:
          blocks:
            - soul_sand
          player_placed: false
      # Every wither skeleton killed near the boss counts for twenty-five
      - trigger: kill
        value: 25
        filters:
          entities:
            - wither_skeleton
    start-effects:
      - id: send_message
        args:
          message: "&8The Hollow King is shielded! Feed the altar to break it."

See Configuring an Effect for the full trigger, filter, and condition lists.

A count is earned by a player, so the stage has to decide which mob it belongs to. Every mob of that type within radius blocks of the player, and currently in that stage, receives it. Two players fighting the same boss both feed it; a boss on the other side of the world is untouched. Set radius deliberately: too large and unrelated activity drains the fight, too small and players have to stand on top of the mob.

Counts also place the player on the mob's top-damager board, so %top_damager_1_name% names whoever fed the altar hardest, not only whoever hit the boss hardest. They are credited raw, in whatever the counter counted — a value: 25 count adds 25. That is the same convention a hits stage uses, where one hit credits one, so a mob mixing modes ranks players on a mix of units. Keep the value of a stage's count methods roughly in scale with the damage the mob's health stages take if you want one board to read sensibly across the whole fight.

Stage 1's start-effects run when the mob spawns. Every other transition runs the finished stage's end-effects and then the next stage's start-effects, and the last stage's end-effects run as the mob dies.

Stage effects run as the mob, with the mob as the victim and the player whose hit ended the stage as the player — no player on spawn. Use mutators and the aoe effect to retarget, for example to announce a phase to everyone fighting:

start-effects:
  - id: aoe
    args:
      shape: circle
      radius: 30
      effects:
        - id: send_message
          mutators:
            - id: victim_as_player
          args:
            message: "&cStage 2 begins!"

Defence

Control mounting and scale incoming damage per cause.

defence:
  can-mount: true # If the mob can enter boats, minecarts, etc.
  damage-modifiers: # Multiply incoming damage by cause
    fire_tick: 1
    lava: 1
    entity_explosion: 1

Damage modifiers

Each key is a damage cause, and each value multiplies the damage the mob takes from that cause. 1 is vanilla damage, 0.5 is half, 2 is double, and 0 makes the mob immune to it. Any cause you leave out stays at 1, so you only need to list the ones you want to change.

Keys are the lowercase name of a Spigot EntityDamageEvent.DamageCause value — FIRE_TICK is written fire_tick. The full list is on the DamageCause javadoc, and every value on it works here, not only the ones in the example file.

The ones worth reaching for:

CauseDamage from
entity_attackA melee hit from a player or mob
entity_sweep_attackA sword sweep hitting the mob as a secondary target
projectileArrows, tridents, snowballs, and other thrown or fired projectiles
magicPotions of Harming, Instant Damage arrows, evoker fangs
entity_explosionCreepers, ghast fireballs, end crystals, other mobs
block_explosionTNT and beds
fireStanding in fire
fire_tickBurning, once alight
lavaStanding in lava
hot_floorMagma blocks
fallFalling
drowningBeing underwater without air
suffocationBeing inside a solid block
lightningA lightning strike
thornsThe Thorns enchantment on whoever the mob hit
voidFalling out of the world
customDamage another plugin dealt with no vanilla cause

A boss that should ignore its own arena hazards is a few lines:

defence:
  can-mount: false
  damage-modifiers:
    fire: 0 # Immune to its own fire
    fire_tick: 0
    lava: 0
    hot_floor: 0
    projectile: 0.25 # Bows barely scratch it - melee or nothing
    magic: 2 # But splash potions hurt twice as much

Drops

Set the experience and item drops awarded on death. Group several items under one chance to roll them together.

drops:
  experience: 30 # Experience dropped on death
  items:
    - chance: 100 # Percent chance for this group to drop
      items:
        - diamond_sword unbreaking:1 name:"Example Sword"

Boss bar

Give the mob an on-screen health bar visible within a radius.

boss-bar:
  enabled: true # If the mob shows a boss bar
  color: white # blue, green, pink, purple, red, white, yellow
  style: progress # progress, notched_20, notched_12, notched_10, notched_6
  radius: 120 # Distance from the mob where the bar is visible

Spawn

Let players summon the mob with a 3-block totem, a spawn egg, or both.

spawn:
  totem:
    enabled: false # If a 3-block totem can summon the mob
    top: netherite_block
    middle: iron_block
    bottom: magma_block
    conditions: [ ] # Conditions for the totem to work
  egg:
    enabled: true # If the mob has a spawn egg
    conditions: [ ] # Conditions for the egg; not-met-lines show on the egg
    item: evoker_spawn_egg unbreaking:1 hide_enchants # The spawn egg item
    name: "&cNecrotic Soldier&f Spawn Egg"
    craftable: true # If the spawn egg can be crafted
    recipe-permission: "ecomobs.craft.necrotic_soldier" # Optional; permission to craft the egg
    shapeless: false # Optional; whether the recipe is shapeless, defaults to false
    recipe: # 9 slots for shaped, any order for shapeless
      - iron_block
      - netherite_block
      - iron_block
      - air
      - ecoitems:boss_core ? nether_star
      - air
      - iron_block
      - netherite_block
      - iron_block

Internal placeholders

These placeholders work in the display-name and in effects on this mob.

PlaceholderValue
%health%The current health of the mob
%max_health%The max health of the mob
%health_percent%The percentage of health the mob has
%stage%The current damage stage, 1-based (0 on a mob with no stages)
%max_stages%The number of damage stages (0 on a mob with no stages)
%stage_percent%The percentage of the current stage completed
%hits%The hits left in the current stage (0 outside a hits stage)
%max_hits%The hits the current stage takes (0 outside a hits stage)
%hits_percent%The percentage of the current stage's hits left (100 outside a hits stage)
%count%The count left in the current stage (0 outside a trigger stage)
%max_count%The count the current stage takes (0 outside a trigger stage)
%count_percent%The percentage of the current stage's count left (100 outside a trigger stage)
%time%The time left before the mob despawns (minutes:seconds)
%top_damager_<place>_name%The name of the top damager in that place (empty if nobody placed there)
%top_damager_<place>_damage%The contribution of the top damager in that place (0 if nobody placed there). A staged mob ranks players in whatever each stage counts: damage in health, one per hit in hits, and the count itself in trigger
%top_damager_<place>_display%The display name of the top damager in that place (empty if nobody placed there)

The number of places is set by top-damager-places in config.yml, and defaults to 10.


Where to go next

  • Default configs: browse the shipped examples here, and community configs on lrcdb.

  • Spawning: How to Make Mob Categories to control where and how mobs appear.

  • Commands: Commands and Permissions for spawning and giving mobs.

  • Effects: Configuring an Effect to bring the effects section to life.