Violet

Mob

On this page

The Mob object represents a mob entity in the game world.

Functions

mob:is_valid() -> boolean

Validates the object exists in the game world. Always call this before using other methods.


mob:get_id() -> number | nil

Returns the mob template ID or nil if unavailable.

The template ID identifies the mob species (e.g. every Blue Snail shares the same template ID). To tell two mobs of the same species apart, use mob:get_unique_id().


mob:get_unique_id() -> number | nil

Returns the unique instance ID of this specific spawned mob, or nil if unavailable.

Unlike the template ID, the unique ID is assigned by the server when the mob spawns: every mob in the map has a different one, it stays the same for the mob's whole lifetime, and it is not reused when the mob dies. This makes it the right key for tracking a specific mob across ticks.

lua
-- Lock onto a single mob and keep following that exact instance
local target_uid = nil

local function find_target(map)
    for _, mob in ipairs(map:get_mobs()) do
        if mob and mob:is_valid() then
            local uid = mob:get_unique_id()
            if target_uid == nil then
                target_uid = uid
            end
            if uid == target_uid then
                return mob
            end
        end
    end
    target_uid = nil -- target died or despawned, pick a new one next tick
    return nil
end

mob:get_position() -> table | nil

Returns position as a table with x and y fields, or nil if unavailable.

lua
local pos = mob:get_position()
if pos then
    -- pos.x, pos.y
end

mob:get_name() -> string | nil

Returns the mob name or nil if unavailable.


mob:distance() -> number | nil

Returns the Euclidean distance from the local player to this mob, or nil if the mob or the player is unavailable.


mob:get_health_percent() -> number | nil

Returns the mob's remaining health as a whole number from 0 to 100, or nil if unavailable.

The client is never told a mob's real HP — the server broadcasts the HP bar, so a percentage is the finest reading that exists. Multi-body bosses that share one bar all report the shared bar.

lua
-- Burst only once the boss is below 30%
for _, mob in ipairs(map:get_mobs()) do
    if mob and mob:is_valid() and mob:is_boss() then
        local hp = mob:get_health_percent()
        if hp and hp <= 30 then
            core.log(mob:get_name() .. " is at " .. hp .. "%")
        end
    end
end

mob:get_health_gauge() -> number, number | nil

Returns the raw pair behind get_health_percent() — the broadcast bar value and what it counts up to — or nil if unavailable.

Reach for this only when whole percent is too coarse: against a boss whose gauge max is 1000 it gives you 0.1% resolution. A max of 0 means the mob has no subdivided bar and the value is already a 0100 percentage. Note this pair is the mob's own bar, so unlike get_health_percent() it does not follow a multi-body boss to the body that owns the shared bar.

lua
local value, max = mob:get_health_gauge()
local precise = (max and max > 0) and (value * 100 / max) or value

mob:get_rank() -> number | nil

Returns the mob's Elite Monster-system tier, or nil if unavailable.

RankMeaning
0not part of the Elite Monster system
1elite monster
2elite champion
3elite boss

Use this instead of is_elite() when you need to tell the tiers apart — is_elite() is true for all three.


mob:is_elite() -> boolean | nil

Returns true if the mob belongs to the Elite Monster system — an elite monster or an elite boss — or nil if unavailable.

This is true for every special mob alike: both a trivial elite (e.g. Killer Bee, Failed Subject) and a much stronger boss-type elite (e.g. Odium's Guard). Use mob:is_boss() to tell those apart.


mob:is_boss() -> boolean | nil

Returns true if the mob's template is flagged as a boss — a designated boss-type mob (field boss, mini-boss, or a boss-type elite) that shows the boss HP bar and runs boss mechanics — or nil if unavailable.

This is independent of mob:is_elite(); a mob can be both. On a normal farming map a trivial elite and a stronger boss-type elite are both is_elite(), but only the boss-type one is is_boss() — so this is what distinguishes the tougher target when the map isn't a dedicated boss fight (where map:get_bosses() returns nothing).

lua
-- Prefer a boss-type mob on the map, otherwise fall back to any elite
local function pick_target(map)
    local elite_fallback = nil
    for _, mob in ipairs(map:get_mobs()) do
        if mob and mob:is_valid() then
            if mob:is_boss() then
                return mob            -- strongest: field boss / boss-type elite
            elseif mob:is_elite() and not elite_fallback then
                elite_fallback = mob  -- weaker elite, keep as a backup
            end
        end
    end
    return elite_fallback
end

Example

lua
-- Find closest mob to player
local map = core.object_manager.get_current_map()

if map and map:is_valid() then
    local closest_mob = nil
    local closest_dist = math.huge

    for _, mob in ipairs(map:get_mobs()) do
        if mob and mob:is_valid() then
            local dist = mob:distance()
            if dist and dist < closest_dist then
                closest_dist = dist
                closest_mob = mob
            end
        end
    end

    if closest_mob then
        core.log("Closest: " .. (closest_mob:get_name() or "Unknown")
            .. " at " .. (closest_mob:get_health_percent() or "?") .. "%")
    end
end