Players API

Category: API Reference

Query and interact with player entities in the game world, including the local player and other players.

Functions

local_player

players:local_player() -> Player?

Returns the local player (the player being controlled).

Returns:

  • Player? - The local player, or nil if not available

Example:

local player = players:local_player()
if player then
    logger:info("Player name: " .. player:name())
    logger:info("Position: " .. player:x() .. ", " .. player:y())
end

find_first

players:find_first(filters: table?) -> Player?

Returns the first player matching the given filters.

Parameters:

ParameterTypeRequiredDescription
filterstableNoFilter options

Returns:

  • Player? - First matching player, or nil if none found

Filters:

FilterTypeDescription
namestringExact name match
name_containsstringName contains text
name_matches_regexstringName matches regex pattern
name_anytableMatch if name equals any in array of strings
name_contains_anytableMatch if name contains any substring in array
within_distance_of_localnumberDistance from local player in tiles
within_distance_oftableDistance from position {x, y, floor, max_distance}
attableExact tile location {x, y, z} or [x, y, z]
is_animatingbooleanCurrently animating
is_interactingbooleanCurrently interacting
not_interactingbooleanNot interacting
interacting_indexnumberMatch players interacting with specific actor index
is_movingbooleanCurrently moving

Example:

-- Find player by exact name
local player = players:find_first({name = "Player123"})

-- Find nearby player
local nearby = players:find_first({within_distance_of_local = 5})

-- Find non-moving player
local idle = players:find_first({is_moving = false})

-- Combine filters
local player = players:find_first({
    name_contains = "Player",
    within_distance_of_local = 10
})

-- Find players with any of multiple names
local player = players:find_first({
    name_any = {"Alice", "Bob", "Charlie"}
})

-- Find players with names containing any substring
local suspicious = players:find_first({
    name_contains_any = {"bot", "farm", "auto"}
})

-- Find player at specific tile
local player = players:find_first({
    at = {3200, 3210, 0}  -- or at = {x = 3200, y = 3210, floor = 0}
})

-- Find players interacting with a specific NPC
local npc = npcs:find_first({name = "Guard"})
if npc then
    local players_fighting = players:find_all({
        interacting_index = npc:index()  -- NPC indices are used directly
    })
    logger:info("Found " .. #players_fighting .. " players fighting this guard")
end

-- Find players interacting with local player
local local_player = players:local_player()
if local_player then
    local attackers = players:find_all({
        interacting_index = local_player:index() + 32768  -- Player indices offset by MAX_NPCS
    })
    if #attackers > 0 then
        logger:warn("Being attacked by " .. #attackers .. " players!")
    end
end

find_all

players:find_all(filters: table?) -> table

Returns all players matching the given filters.

Parameters:

ParameterTypeRequiredDescription
filterstableNoFilter options (same as find_first)

Returns:

  • table - Array of Player objects

Example:

-- Get all nearby players
local nearby = players:find_all({within_distance_of_local = 20})

for _, player in ipairs(nearby) do
    logger:info("Nearby: " .. player:name() .. " at distance " .. player:distance_to_local_player())
end

-- Get all animating players
local animating = players:find_all({is_animating = true})
logger:info("Found " .. #animating .. " animating players")

find_nearest

players:find_nearest(filters: table?) -> Player?

Returns the nearest player matching the given filters.

Parameters:

ParameterTypeRequiredDescription
filterstableNoFilter options (same as find_first)

Returns:

  • Player? - Nearest matching player, or nil if none found

Example:

-- Find nearest player
local nearest = players:find_nearest()

if nearest then
    logger:info("Nearest: " .. nearest:name() .. " (" .. nearest:distance_to_local_player() .. " tiles away)")
end

-- Find nearest hostile player
local enemy = players:find_nearest({within_distance_of_local = 30})

all

players:all() -> table

Returns all players currently in the game world.

Returns:

  • table - Array of all Player objects

Example:

local all_players = players:all()
logger:info("Total players: " .. #all_players)

-- Count players by distance
local nearby = 0
for _, player in ipairs(all_players) do
    if player:distance_to_local_player() < 10 then
        nearby = nearby + 1
    end
end
logger:info("Nearby: " .. nearby)

Common Patterns

Counting Nearby Players

local function count_nearby_players(distance)
    local count = 0
    local all = players:all()
    
    for _, player in ipairs(all) do
        if player:distance_to_local_player() <= distance then
            count = count + 1
        end
    end
    
    return count
end

local nearby = count_nearby_players(10)
logger:info("Players nearby: " .. nearby)

Finding All Animating Players

local function get_animating_players()
    local animating = players:find_all({is_animating = true})
    return animating
end

local busy_players = get_animating_players()
if #busy_players > 0 then
    logger:info("Found " .. #busy_players .. " animating players")
end

Wait for Players to Finish Animating

local function wait_for_players_idle()
    while true do
        local animating = players:find_all({is_animating = true})
        if #animating == 0 then
            break
        end
        sleep(100)
    end
end

wait_for_players_idle()
logger:info("All players are now idle")

Getting Players by Name Pattern

local function find_players_by_name_pattern(pattern)
    return players:find_all({name_matches_regex = pattern})
end

-- Find all players with "Bot" in their name
local bots = find_players_by_name_pattern(".*Bot.*")

for _, bot in ipairs(bots) do
    logger:info("Bot found: " .. bot:name())
end

Monitoring Local Player State

local function monitor_player_state()
    local player = players:local_player()
    
    if not player then
        logger:warn("Player not found")
        return
    end
    
    logger:info("=== Player State ===")
    logger:info("Name: " .. player:name())
    logger:info("Health: " .. player:health() .. "/" .. player:max_health())
    logger:info("Level: " .. player:level())
    logger:info("Position: " .. player:x() .. ", " .. player:y())
    logger:info("Animation: " .. player:animation())
    logger:info("Animating: " .. tostring(player:is_animating()))
    logger:info("Moving: " .. tostring(player:is_moving()))
    logger:info("Interacting: " .. tostring(player:is_interacting()))
    logger:info("===================")
end

monitor_player_state()

Detecting Player Activity

local function is_player_active(player)
    if not player then return false end
    
    return player:is_animating() or 
           player:is_moving() or 
           player:is_interacting()
end

local player = players:local_player()
if is_player_active(player) then
    logger:info("Player is active")
else
    logger:info("Player is idle")
end

Finding Players in Areas

local function find_players_in_area(area)
    local players_in_area = {}
    local all_players = players:all()
    
    for _, player in ipairs(all_players) do
        if area:contains_tile(player:tile()) then
            table.insert(players_in_area, player)
        end
    end
    
    return players_in_area
end

local training_area = Area.new(
    Tile.new(3200, 3200, 0),
    Tile.new(3210, 3210, 0)
)

local trainers = find_players_in_area(training_area)
logger:info("Players in training area: " .. #trainers)

Wait for Specific Player

local function wait_for_player(name, timeout)
    local start = os.time()
    
    while os.time() - start < timeout do
        local player = players:find_first({name = name})
        if player then
            return player
        end
        sleep(100)
    end
    
    return nil
end

local player = wait_for_player("Player123", 60)
if player then
    logger:info("Found player: " .. player:name())
else
    logger:warn("Player not found within timeout")
end

Player Safety Check

local function is_safe_from_players(distance)
    local all = players:all()
    
    for _, player in ipairs(all) do
        if player:distance_to_local_player() < distance then
            return false, player:name()
        end
    end
    
    return true
end

local safe, player = is_safe_from_players(10)
if not safe then
    logger:warn("Not safe! Player nearby: " .. player)
else
    logger:info("Safe from other players")
end

Multi-Player Interaction

local function interact_with_nearest_player()
    local nearest = players:find_nearest()
    
    if not nearest then
        logger:warn("No players found")
        return false
    end
    
    logger:info("Interacting with: " .. nearest:name())
    nearest:click()
    return true
end

Player Methods

Each Player object returned by these functions has methods to access its properties:

  • Basic Info

    • name() → string
    • level() → number
    • animation() → number
  • Position

    • x(), y(), floor() → number
    • tile() → Tile object
    • distance_to_local_player() → number
  • State

    • is_animating() → boolean
    • is_moving() → boolean
    • is_interacting() → boolean
    • health() → number
    • max_health() → number

See the methods listed above for complete Player functionality.


Filter Combinations

Filters can be combined to create complex queries:

-- Find idle players far away
local distant_idle = players:find_all({
    within_distance_of_local = 100,
    is_animating = false,
    is_moving = false
})

-- Find nearby animating players by name pattern
local nearby_bots = players:find_all({
    within_distance_of_local = 20,
    is_animating = true,
    name_contains = "Bot"
})

-- Find players in specific area (using distance from coordinates)
local area_players = players:find_all({
    within_distance_of = {
        x = 3200,
        y = 3200,
        floor = 0,
        max_distance = 10
    }
})

Related APIs

  • NPCs API - Query and interact with NPCs
  • Game Objects API - Query game objects
  • Movement API - Walk and navigate