NPC Type

NPC

Represents a non-player character in Old School RuneScape.

Methods

id()

Get config/variant-resolved ID.

Returns: number - The NPC's unique ID

Example:

local chicken = npcs:find_first({name = "Chicken"})
if chicken then
    print("NPC ID:", chicken:id())
end

name()

Get NPC name.

Returns: string - The NPC's display name


x()

Get world X coordinate.

Returns: number - The X coordinate in the game world


y()

Get world Y coordinate.

Returns: number - The Y coordinate in the game world


floor()

Get floor/plane level.

Returns: number - The floor level (0-3)


tile()

Get position as a Tile object with x, y, and floor.

Returns: Tile or nil - The tile object representing the NPC's position

Example:

local goblin = npcs:find_first({name = "Goblin"})
if goblin then
    local tile = goblin:tile()
    print(string.format("Goblin at (%d, %d, %d)", tile.x, tile.y, tile.floor))
end

distance()

Get distance to local player in tiles. This is the preferred method over distance_to_player().

Returns: number - The distance in tiles

Example:

local banker = npcs:find_first({name = "Banker"})
if banker then
    local dist = banker:distance()
    print("Banker is", dist, "tiles away")
    
    if dist < 5 then
        banker:interact({action = "Bank"})
    end
end

distance_to_player() (deprecated)

Deprecated: Use distance() instead.

Get distance to local player in tiles.

Returns: number - The distance in tiles


local_x()

Get local X coordinate (relative to the region).

Returns: number - The local X coordinate


local_y()

Get local Y coordinate (relative to the region).

Returns: number - The local Y coordinate


render_height()

Get render height in pixels.

Returns: number - The render height


base_point()

Get base point on screen.

Returns: (number, number) - Tuple of (x, y) screen coordinates


next_point()

Get next point on screen (used for click prediction on moving NPCs).

Returns: (number, number) - Tuple of (x, y) screen coordinates


move_mouse_to()

Move the mouse to this NPC with human-like movement. Uses the NPC's clickable point.

Returns: boolean - true on success, false if the position is invalid or the move fails

Example:

local cow = npcs:nearest("Cow")
if cow and cow:move_mouse_to() then
    mouse:click()
end

track()

Start tracking this NPC: the mouse follows the NPC until the entity is invalid, another mouse action is performed, or you call mouse:stop_track().

Returns: void

Example:

local goblin = npcs:nearest("Goblin")
if goblin then
    goblin:track()
    sleep(2000)
    mouse:stop_track()
end

set_bounding_model(x1, x2, y1, y2, z1, z2)

Set custom bounding model dimensions for this NPC. Falls back to the default captured model if not set.

Parameters:

NameTypeDescription
x1numberMinimum X coordinate
x2numberMaximum X coordinate
y1numberMinimum Y coordinate
y2numberMaximum Y coordinate
z1numberMinimum Z coordinate
z2numberMaximum Z coordinate

Returns: void

Example:

local npc = npcs:find_first({name = "Goblin"})
if npc then
    -- Set custom bounding model dimensions
    npc:set_bounding_model(-50, 50, -100, 0, -50, 50)
end

remove_bounding_model()

Remove the custom bounding model, falling back to the default captured model.

Returns: void

Example:

local npc = npcs:find_first({name = "Goblin"})
if npc then
    -- Remove custom bounding model to use default
    npc:remove_bounding_model()
end

orientation()

Get orientation (direction the NPC is facing).

Returns: number - The orientation value


movement_animation_id()

Get movement animation ID.

Returns: number - The animation ID for movement


movement_animation_frame()

Get movement animation frame.

Returns: number - The current frame of the movement animation


movement_animation_cycle()

Get movement animation cycle.

Returns: number - The animation cycle counter


animation_id()

Get current animation ID.

Returns: number - The active animation ID (-1 if none)

Example:

local npc = npcs:find_first({name = "Guard"})
if npc then
    local anim = npc:animation_id()
    if anim ~= -1 then
        print("NPC is animating:", anim)
    end
end

animation_frame()

Get animation frame.

Returns: number - The current frame of the animation


animation_cycle()

Get animation cycle.

Returns: number - The animation cycle counter


animation_delay()

Get animation delay.

Returns: number - The delay before animation starts


idle_animation_id()

Get idle animation ID (the animation when standing still).

Returns: number - The idle animation ID


in_combat()

Check if NPC is in combat.

Returns: boolean - true if in combat, false otherwise

Example:

local monster = npcs:find_first({name = "Goblin"})
if monster and not monster:in_combat() then
    -- Safe to attack
    monster:interact({action = "Attack"})
end

is_interacting()

Check if NPC is interacting with something (returns boolean).

Returns: boolean - true if interacting with any actor, false otherwise

Example:

local npc = npcs:find_first({name = "Goblin"})
if npc and npc:is_interacting() then
    print("NPC is already in combat")
end

interacting()

Get the actor (Player or NPC) the NPC is interacting with.

Returns: LuaActor or nil - The actor being interacted with, or nil if not interacting

Example:

local npc = npcs:find_first({name = "Goblin"})
if npc then
    local target = npc:interacting()
    if target then
        if target:is_player() then
            local player = target:as_player()
            print("Goblin is attacking player:", player:name())
        elseif target:is_npc() then
            local other_npc = target:as_npc()
            print("Goblin is fighting:", other_npc:name())
        end
    end
end

interacted_by()

Get the actor (Player or NPC) that is interacting with this NPC.

Returns: LuaActor or nil - The actor that is interacting with this NPC, or nil if none

Example:

local npc = npcs:find_first({name = "Cow"})
if npc then
    local attacker = npc:interacted_by()
    if attacker then
        if attacker:is_player() then
            local player = attacker:as_player()
            if player:name() == players:local_player():name() then
                print("I am attacking this cow")
            else
                print("Another player is attacking this cow:", player:name())
            end
        end
    else
        -- No one is attacking, safe to attack
        npc:interact({action = "Attack"})
    end
end

click()

Human-like left click the NPC.

Returns: boolean - true if clicked successfully, false otherwise

Example:

local banker = npcs:find_first({name = "Banker"})
if banker then
    banker:click() -- Left-click the banker
end

interact(filter_input)

Right-click and select menu option by filters. Uses smart interaction with movement prediction for moving NPCs.

Parameters:

NameTypeDescription
filter_inputtable or nilOptional menu item filters

Returns: boolean - true if interaction succeeded, false otherwise

Example:

-- Attack an NPC
local goblin = npcs:find_first({name = "Goblin"})
if goblin then
    goblin:interact({action = "Attack"})
end

-- Talk to an NPC
local hans = npcs:find_first({name = "Hans"})
if hans then
    hans:interact({action = "Talk-to"})
end

-- Pickpocket
local farmer = npcs:find_first({name = "Farmer"})
if farmer then
    farmer:interact({action = "Pickpocket"})
end

is_moving()

Check if NPC is currently moving.

Returns: boolean - true if moving, false otherwise

Example:

local cow = npcs:find_first({name = "Cow"})
if cow and not cow:is_moving() then
    -- Cow is standing still, good time to attack
    cow:interact({action = "Attack"})
end

is_visible()

Check if NPC is visible in the viewport.

Returns: boolean - true if visible on screen, false otherwise

Example:

local npcs_nearby = npcs:find({name = "Chicken", within_distance_of_local = 10})
for _, npc in ipairs(npcs_nearby) do
    if npc:is_visible() then
        print("Can see:", npc:name())
    end
end

reachable()

Check if NPC is reachable from the local player's position using pathfinding.

Returns: boolean - true if the NPC can be reached from the player's current position, false otherwise

Example:

local banker = npcs:find_first({name = "Banker"})
if banker and banker:reachable() then
    banker:interact({action = "Bank"})
else
    print("Banker is not reachable - blocked by obstacles")
end

health_percent()

Get NPC health as a percentage (0-100).

Returns: number or nil - Health percentage (0-100). May return 100 when not in combat or when health bar is not visible; returns nil only when unavailable.

Example:

local goblin = npcs:find_first({name = "Goblin"})
if goblin then
    local health = goblin:health_percent()
    if health then
        print("Goblin health:", health .. "%")
        if health < 50 then
            print("Goblin is below 50% health!")
        end
    else
        print("Goblin health bar not visible")
    end
end

health_ratio()

Get NPC health ratio (current health value from the health bar).

Returns: number or nil - Current health ratio value. May return -1 when not in combat or when health bar is not visible; returns nil only when unavailable.

Note: This is the raw health ratio value. To get the percentage, use health_percent(). To calculate actual health, divide by health_scale().

Example:

local monster = npcs:find_first({name = "Goblin"})
if monster then
    local ratio = monster:health_ratio()
    local scale = monster:health_scale()
    if ratio and scale then
        print("Health:", ratio .. "/" .. scale)
    end
end

health_scale()

Get NPC health scale (maximum health value from the health bar).

Returns: number or nil - Maximum health scale value. May return -1 when not in combat or when health bar is not visible; returns nil only when unavailable.

Note: This represents the maximum health value. The current health can be obtained from health_ratio(). The percentage can be calculated as (health_ratio() / health_scale()) * 100 or use health_percent().

Example:

local boss = npcs:find_first({name = "Giant Mole"})
if boss then
    local scale = boss:health_scale()
    if scale then
        print("Boss max health scale:", scale)
    end
end