Core Concepts

Object Functions

Complete reference guide to SYNQ object functions

Object functions are keys within a SYNQ object that must be called with () to return a value. Unlike attributes, functions perform calculations or operations and may accept parameters.

What's an Object Function?

An object function is a key within a SYNQ object that must be called with () to return a value. Think of them as methods that perform actions or calculations, rather than simple property lookups.

Key Features:

  • Non-case-sensitive – Most functions work regardless of case
  • Fallback aliases – Many functions have intuitive aliases for easier use
  • Parameter support – Functions can accept arguments to customize their behavior

Function Performance

Functions are less performant than attributes, as a lot of them cannot/do not use the same caching techniques, but they do not face the same limitations. This means:

  • More flexible – Can perform complex calculations and operations
  • Dynamic results – Results can vary based on parameters
  • Slightly slower – Not cached like attributes, so use them judiciously

General Functions

canAttack

Checks if the unit can attack another unit.

unit.canAttack(otherUnit) : true | false

Example:

if target.canAttack(focus) then
    print("My target unit can attack my focus unit - they are enemies!")
end

isUnit

Compares the object with another to determine if they're the same.

unit.isUnit(otherUnit) : true | nil

Example:

if target.isUnit(focus) then
    print("My target unit and focus unit are the same!")
end

friendOf

Checks if the unit is friends with another unit.

unit.friendOf(otherUnit) : true | false

Example:

if target.friendOf(focus) then
    print("My target unit and focus unit are friendly to each other!")
end

hasTalent

Checks if the object has the given talent or PvP talent selected.

unit.hasTalent(talent) : true | false

Note: Accepts talent name (non-case-sensitive string) or SpellID. This only works with members of your group, including the player object.

Example:

-- Check if friendly healer has Ascendance talent selected
print("Healer has Ascendance talent: " .. tostring(healer.hasTalent("Ascendance")))
-- res: true

-- Check if player has Ring of Frost talent selected (case-insensitive)
print("Player has Ring of Frost talent: " .. tostring(player.hasTalent("ring of frost")))
-- res: true

for _, member in ipairs(synq.group) do
    if member.class == "Hunter" and member.hasTalent("Aspect of the Beast") then
        print("Our Hunter group member has Aspect of the Beast talent!")
    end
end

Buffs & Debuffs

Note: All buff/debuff functions accept SpellID or Spell Names, and optionally any "SYNQ Object" as the second arg, which will only return a value if your given object was the caster of the buff/debuff. Spell name queries are non-case-sensitive. target.buff('combustion') works fine. SpellID is generally the only assuredly accurate method though, as there are several buffs & debuffs in game with the same name.

buff

Provides information about a specific buff on the object.

unit.buff(spell[, sourceObject]) : "buff", ... | nil

Returns: Identical to UnitBuff - [1] string name, ... | nil

Example:

if enemy.buff("combustion") then
    print("Enemy target has Combustion buff active - using Ice Block!")
    iceBlock:Cast()
end

buffRemains

The time remaining of a specific buff on the object.

unit.buffRemains(spell[, sourceObject]) : remains | 0

Example:

if ourHealer.buffRemains("avenger's wrath") > 10 then
    print("Our healer has Avenger's Wrath with more than 10 seconds remaining - we're safe!")
end

buffStacks

Number of stacks the object has of the given buff.

unit.buffStacks(spell[, sourceObject]) : stacks | 0

Example:

if player.buffStacks("Well Fed") > 1 then
    print("Player has more than 1 stack of Well Fed buff!")
end

buffUptime

The amount of time that the given buff has been active on the object.

unit.buffUptime(spell[, sourceObject]) : uptime | 0

Example:

if hunterPet.buffUptime("frenzy") > 10 then
    print("Hunter pet has had Frenzy buff active for more than 10 seconds!")
end

buffFrom

Query the object for a list of any active buffs matching the Spell IDs / Spell Names within the given array.

unit.buffFrom(spellList[, sourceObject]) : { buff, buff, ... } | nil

Similar: buffsFrom - Same as buffFrom, except it returns the number of buffs from the list that are active

Example:

if friend.buffFrom({980, 172, 1822}) then
    print("Friend has one or more debuffs from the specified spell list!")
end

debuff

Provides information about a specific debuff on the object.

unit.debuff(spell[, sourceObject]) : "debuff", ... | nil

Returns: Identical to UnitDebuff - [1] string name, ... | nil

Example:

if ourHealer.debuff("freezing trap") then
    print("Our healer has Freezing Trap debuff active!")
end

debuffRemains

The time remaining of a specific debuff on the object.

unit.debuffRemains(spell[, sourceObject]) : remains | 0

Example:

if target.debuffRemains("Kidney Shot") > 4 then
    print("Target has Kidney Shot debuff with more than 4 seconds remaining!")
end

debuffStacks

Number of stacks the object has of the given debuff.

unit.debuffStacks(spell[, sourceObject]) : stacks | 0

Example:

if friend.debuffStacks(980) > 3 and decurse:Cast(friend) then
    return synq.alert("Decursed them stacks!", 475)
end

debuffUptime

The amount of time that the given debuff has been active on the object.

unit.debuffUptime(spell[, sourceObject]) : uptime | 0

Example:

if player.debuffUptime("Agony") > 25 then
    decurse:Cast(player)
    print("Player has had Agony debuff for more than 25 seconds - removing it!")
end

debuffFrom

Query the object for a list of any active debuffs matching the Spell IDs / Spell Names within the given array.

unit.debuffFrom(spellList[, sourceObject]) : { debuff, debuff, ... } | nil

Similar: debuffsFrom - Same as debuffFrom, except it returns the number of debuffs from the list that are active

Example:

local badStuff = {"Storm Bolt", 408, "Cheap Shot"}
if player.debuffFrom(badStuff) then
    if iceBlock:Cast() then
        return synq.alert("I've had enough of that.", 45438)
    end
end

Spells / Casting

cooldown

Estimates the cooldown of any Unit's spell based on combat log event tracking happening in the background by the framework.

unit.cooldown(spellID | spellName) : cooldown | 0

Example:

-- Using spell IDs is most performant
if enemy.cooldown(22812) > 6 then
    if kidney:Cast(enemy) then
        synq.alert("Kidney Shot (No Skin)", kidney.id)
    end
end

-- Spell names also work (non-case-sensitive) but are less performant
if enemy.cooldown("avenging wrath") > 30 then
    print("Enemy's Avenging Wrath is on cooldown for more than 30 seconds - we're safe!")
end

used

Checks if the Unit has cast the given spell in the past x seconds, based on combat log event tracking happening in the background by the framework.

unit.used(spellID | spellName[, durationSeconds]) : true | nil

Example:

-- Using spell IDs is most performant
if player.used(22812, 15) then
    print("Player used Barkskin within the last 15 seconds!")
end

-- Spell names also work (non-case-sensitive) but are less performant
if enemy.used("avatar", 5) then
    print("Enemy used Avatar within the last 5 seconds!")
end

Movement & Position

distanceTo

Distance between the object and another object, accounting for combat reach and bounding radius.

unit.distanceTo(otherObject) : distance | 9999

Sister Attribute: distance - checks distance from the player to the object
Similar: distanceToLiteral - same as distanceTo but ignores combatReach

Example:

if target.distanceTo(enemyHealer) > 40 then
    print("Target is more than 40 yards away from enemy healer - out of heal range!")
    stormBolt:Cast(target)
end

facing

Checks if the object is facing another object at a 180 degree angle by default - the required facing angle to cast spells. You can check a specific angle (in degrees) by passing it as the 2nd arg.

unit.facing(otherUnit[, angle]) : isFacing | false

Sister Attribute: playerFacing[, Angle] - checks if the player is facing the object. e.g, target.playerFacing or target.playerFacing45

Example:

if player.facing(target) then
    print("Player is facing the target - can cast spells that require facing!")
end

if player.facing(target, 45) then
    print("Player is facing the target at less than 45 degree angle!")
end

-- Example: Count enemies in Shockwave cone before casting
local bin = synq.bin
-- Base angle is 45 degrees, add 30 more if player has Big Shockwave talent
local angle = 45 + bin(30, player.hasTalent("big shockwave"))
local caught = 0

-- Count enemies within 8 yards that are in the cone angle
for _, enemy in ipairs(synq.enemies) do
    caught = caught + bin(enemy.distance < 8 and player.facing(enemy, angle))
end

-- Cast Shockwave if we'll hit at least 3 enemies
if caught >= 3 then
    shockwave:Cast()
end

losOf

Checks if the object and another object are in line of sight of each other.

unit.losOf(otherUnit) : isLoS | false

Sister Attribute: los - checks between player & object

Example:

if not target.losOf(enemyHealer) then
    print("Target is out of line of sight from enemy healer - good time to attack!")
end

position

Current 3D position of the object.

unit.position() : x, y, z | nil

Example:

local x, y, z = target.position()
print("Target position: X=" .. x .. ", Y=" .. y .. ", Z=" .. z)
-- 2039.393103, 1083.11938, 81.9

predictPosition

The object's estimated position after the given time, based on current velocity & moving direction.

unit.predictPosition(timeInSeconds) : x, y, z | curX, curY, curZ | nil

Example:

-- Predict where the unit will be in 0.5 seconds using linear movement prediction
local x, y, z = unit.predictPosition(0.5)
-- Cast AoE spell at predicted position
spell:AoECast(x, y, z)

movingToward

Checks if the unit is / has been moving toward another unit, given the angle and duration passed (if any).

unit.movingToward(otherUnit[, { angle = degrees, duration = seconds }]) : true | false

Both angle and duration are optional. You may check one or the other, or neither.

  • Default duration: 0 (Immediately returns true when movement direction meets angle)
  • Default angle: 30deg (Returns true when object is moving toward at an acute angle)

Example:

if player.movingToward(target) then
    print("Player is moving toward the target!")
end

if enemy.movingToward(player, { angle = 45 }) then
    print("Enemy is moving toward player at less than 45 degree angle!")
end

if enemy.movingToward(healer, { angle = 90, duration = 0.5 }) then
    print("Enemy has been moving toward our healer for at least 0.5 seconds!")
end

movingAwayFrom

Checks if the unit is / has been moving away from another unit, given the angle and duration passed (if any).

unit.movingAwayFrom(otherUnit[, { angle = degrees, duration = seconds }]) : true | false

Both angle and duration are optional. You may check one or the other, or neither.

  • Default duration: 0 (Immediately returns true when movement direction meets angle)
  • Default angle: 220deg (Returns true when object is moving away from at a 140deg angle)

Example:

if player.movingAwayFrom(enemy, { angle = 300, duration = 0.25 }) then
    print("Player has been moving away from enemy for at least 0.25 seconds!")
end

if healer.movingAwayFrom(enemy, { angle = 280, duration = 0.5 }) then
    print("Healer is kiting the enemy - consider rooting the enemy!")
end

Actions

face

Faces the unit or angle as given.

unit.face() : void
player.face(unit) : void
player.face(angle) : void

Example:

local exampleAngle = getExampleAngle()
player.face(exampleAngle)

if enemy.stupid then
    -- Face the enemy directly
    enemy.face()
    -- Alternative: face the enemy from player's perspective
    player.face(enemy)
end

setFocus

Sets the unit as focus.

unit.setFocus() : void

setTarget

Sets the unit as target.

unit.setTarget() : void

Summary

Object functions provide powerful interactive capabilities for SYNQ objects, enabling sophisticated routine logic and real-time decision making. They allow you to:

  • Query buffs and debuffs – Check status effects with precision
  • Track cooldowns – Monitor enemy and ally ability usage
  • Calculate positions – Predict movement and check facing
  • Perform actions – Control targeting and facing

Key Takeaways:

  • Functions require () to call, unlike attributes
  • Most accept SpellID or spell names (non-case-sensitive)
  • Many support optional source object parameters
  • Use them for dynamic calculations and operations

Next: Learn about Player Attributes for player-specific information.