Skip to main content

Combat API

Namespace: hexis.combat

Automated combat with entity targeting, pursuit AI, and manual combat primitives.

Choosing an Approach
  • start() — Background combat loop (auto-targeting, auto-attacking). Best for AFK grinding.
  • engage() — Fight a single entity your script provides. Best for bosses and slayers.
  • Async combat — Manual tick-based control. Best for custom combat logic.
  • Pursuit primitives — Chase an entity without attacking. Best for positioning before fighting.

Combat Loop

hexis.combat.start(options)

Starts a background combat loop that automatically targets and attacks entities.

Blocking: No (runs in background, use stop() to end)

hexis.combat.start({
targets = {"Enderman", "Zealot"},
style = "ranged",
weapon = "Juju Shortbow",
radius = 15,
aim_speed = 1.0,
attack_cps = 12,
})
ParameterTypeDefaultDescription
targetsstring[]requiredEntity names to target
stylestring"melee""ranged" or "melee"
weaponstringnilWeapon name to equip
radiusnumber10Search radius for entities
aim_speednumber1.0Camera aim speed multiplier
attack_cpsnumber10Clicks per second

hexis.combat.stop()

Stops the combat loop and releases camera control.

hexis.combat.stop()

hexis.combat.is_active()

Returns true if combat loop is running.


Hunt Mode

hexis.combat.hunt(options)

Hunt mode: automatically scans for, pursues, and attacks entities. Java handles target selection.

hexis.combat.hunt({
type = "Enderman",
hunt_radius = 30,
timeout = 10
})
ParameterTypeDefaultDescription
typestringrequiredEntity type to hunt
hunt_radiusnumber20Maximum hunt distance
timeoutnumber5Timeout in seconds

Engaged Combat

hexis.combat.engage(options)

Fights a single entity provided by the script. Blocking — returns when the mob dies, escapes, times out, or the player dies. Unlike hunt() which scans for targets, engage() receives the target from Lua, letting scripts handle target selection (boss detection, ownership checks, etc.).

Returns: string — "killed", "escaped", "timeout", "lost", or "died"

local boss = hexis.combat.find_boss({
boss_name = "Sven Packmaster",
entity_type = "wolf",
radius = 64
})

if boss then
local result = hexis.combat.engage({
entity = boss,
style = "engaged",
attack_range = 3.0,
cps = 7,
tracking_speed = 2.5,
timeout = 15
})

if result == "killed" then
hexis.log.info("Boss defeated!")
end
end
ParameterTypeDefaultDescription
entitytablerequiredEntity table with id field
stylestring"engaged""engaged" (kiting) or "1tap" (stationary)
attack_rangenumber3.0Maximum attack distance
cpsnumber7Clicks per second
tracking_speednumber2.5Camera tracking speed multiplier
timeoutnumber15Maximum combat duration in seconds
kite_min_rangenumber1.5Minimum kiting distance
kite_optimal_rangenumber2.0Optimal kiting distance
kite_max_rangenumber2.5Maximum kiting distance

Return Values:

ValueDescription
"killed"Target entity died or was removed
"escaped"Target moved out of reachable range
"timeout"Combat duration exceeded timeout
"lost"Target lost (despawned, teleported)
"died"Player died during combat
When to use engage() vs hunt() vs start()
  • engage() — Your script handles target selection (boss detection, ownership). Blocking, returns result.
  • hunt() — Java handles scanning and target selection. Blocking.
  • start() — Background combat loop. Non-blocking. Best for grinding while your script does other things.

Targeting

hexis.combat.find_target(options)

Finds the best matching entity using configurable priority and filters.

local target = hexis.combat.find_target({
type = "Enderman",
radius = 20,
priority = "closest",
require_los = true
})

if target then
hexis.log.info("Found: " .. target.name .. " at " .. target.distance)
end
ParameterTypeDefaultDescription
typestringnilEntity type to search for
radiusnumber20Search radius
prioritystring"closest""closest" or "lowest_health"
require_losbooleanfalseRequire line of sight

Returns an entity table with id, name, x, y, z, distance, etc., or nil if no match.

hexis.combat.find_boss(options)

Finds boss entities matching specific criteria. Designed for Hypixel slayer bosses.

local boss = hexis.combat.find_boss({
boss_name = "Sven Packmaster",
entity_type = "wolf",
radius = 64
})
ParameterTypeDefaultDescription
boss_namestringnilBoss display name pattern
entity_typestringnilEntity type (e.g., "wolf")
radiusnumber64Search radius

hexis.combat.get_targets(distance)

Returns table of entity names within distance.

local targets = hexis.combat.get_targets(20)
for _, name in ipairs(targets) do
hexis.log.info("Target: " .. name)
end

Validation Helpers

hexis.combat.is_valid(entity)

Returns true if the entity still exists in the world.

hexis.combat.is_alive(entity)

Returns true if the entity's health is above 0.

hexis.combat.has_los(entity)

Returns true if the player has line of sight to the entity (lenient — single ray).

hexis.combat.has_los_strict(entity)

Returns true if the player has clear line of sight (strict — 3+ rays from different angles).

hexis.combat.distance_to(entity)

Returns the Euclidean distance to the entity.

hexis.combat.blacklist(entity, duration_ms)

Temporarily ignore an entity for the given duration in milliseconds.

hexis.combat.blacklist(entity, 5000)  -- Ignore for 5 seconds

hexis.combat.is_blacklisted(entity)

Returns true if the entity is currently blacklisted.


Async Combat

Manual tick-based combat where your script controls every frame. Use this when you need custom logic between attacks (ability usage, positioning, conditional behavior).

hexis.combat.start_async(options)

Starts async combat mode. Non-blocking — you must call tick() every frame in your loop.

hexis.combat.start_async({
cps = 10,
tracking_speed = 2.5
})
ParameterTypeDefaultDescription
cpsnumber10Clicks per second
tracking_speednumber2.5Camera tracking speed

hexis.combat.set_target(entity)

Sets the current target for async combat. Pass an entity table from find_target() or get_nearby_entities().

local target = hexis.combat.find_target({type = "Enderman", radius = 20})
if target then
hexis.combat.set_target(target)
end

hexis.combat.tick()

Updates aim and attack for async combat. Call every frame.

hexis.combat.start_async({cps = 10})

while hexis.script.is_running() do
local target = hexis.combat.find_target({type = "Enderman", radius = 20})
if target then
hexis.combat.set_target(target)
end
hexis.combat.tick()
hexis.wait(0.05)
end

hexis.combat.stop_async()

hexis.combat.stop_async()

Stops async combat and releases camera control.

hexis.combat.is_async_active()

Returns true if async combat is running.

hexis.combat.has_target()

Returns true if a valid target is set.


Pursuit

Chase an entity without attacking. Useful for positioning before combat or following NPCs.

hexis.combat.pursue(entity)

Starts non-blocking pursuit. The pathfinder navigates toward the entity and updates the path as it moves.

local boss = hexis.combat.find_boss({boss_name = "Sven Packmaster"})
if boss then
hexis.combat.pursue(boss)
hexis.combat.set_camera_lock(boss)

while hexis.combat.is_pursuing() and hexis.script.is_running() do
hexis.combat.pursuit_tick()
if hexis.combat.pursuit_distance() < 3.0 then
break
end
hexis.wait(0.05)
end

hexis.combat.pursue_stop()
end

hexis.combat.pursue_stop()

Stops pursuit and releases navigation.

hexis.combat.is_pursuing()

Returns true if currently pursuing.

hexis.combat.pursuit_distance()

Returns the current distance to the pursuit target.

hexis.combat.pursuit_tick()

Updates pursuit pathfinding. Call every frame during pursuit.


Behavior & Camera

hexis.combat.set_behavior(behavior)

Sets the combat movement behavior.

BehaviorDescription
"normal"Standard combat movement
"backup"Walk backward while fighting
"strafe"Circle-strafe around the target
hexis.combat.set_behavior("strafe")

hexis.combat.set_kite_range(min, optimal, max)

Configures kiting distances for engage() with engaged style.

hexis.combat.set_kite_range(1.5, 2.5, 3.5)

hexis.combat.set_camera_lock(entity)

Locks the camera on a specific entity per-frame.

hexis.combat.clear_camera_lock()

Releases the camera lock.


Attack Primitives

Low-level attack functions for precise control over individual attacks.

hexis.combat.in_range(entity, range)

Returns true if the entity is within the given attack range.

if hexis.combat.in_range(target, 3.0) then
hexis.combat.swing()
end

hexis.combat.can_attack()

Returns true if the attack cooldown is ready.

hexis.combat.swing()

Performs a single weapon swing (left-click attack).


Example: Custom Slayer Loop

function hexis.main()
while hexis.script.is_running() do
local boss = hexis.combat.find_boss({
boss_name = "Sven Packmaster",
entity_type = "wolf",
radius = 64
})

if boss then
-- Pursue until in range
hexis.combat.pursue(boss)
hexis.combat.set_camera_lock(boss)

while hexis.combat.is_pursuing() and hexis.script.is_running() do
hexis.combat.pursuit_tick()
if hexis.combat.pursuit_distance() < 3.0 then
break
end
hexis.wait(0.05)
end
hexis.combat.pursue_stop()

-- Fight
local result = hexis.combat.engage({
entity = boss,
style = "engaged",
timeout = 30
})

hexis.combat.clear_camera_lock()
hexis.log.info("Combat result: " .. result)
end

hexis.wait(1.0)
end
end