Object Lists are arrays containing SYNQ objects and their expected attributes and functions. Each list is filtered based on its own specific criteria, making it easy to work with groups of units, players, or objects in your routines.
Think of object lists as smart collections that automatically filter game objects based on specific rules. Instead of manually checking every unit in the game, you can use pre-filtered lists like synq.enemies or synq.friends to get exactly what you need.
Most lists remain completely empty until referenced. They're generated on-demand by filtering the unlocker's Object Manager (OM), then cached for constant time re-reads the rest of the current 'tick'. This means:
You must always grab lists fresh where you need them. You can't declare them locally outside of your working scope like you can static objects, or they'll become stale.
Good:
bm:Init(function()
synq.enemies.loop(function(enemy)
-- List is generated fresh every tick - always up to date
end)
end)
Bad:
local enemies = synq.enemies -- Stale after first tick - don't do this!
bm:Init(function()
enemies.loop(function(enemy) -- Using old data from first tick - incorrect!
end)
end)
Generally you'll want to access them directly from the synq namespace, e.g., synq.enemies. Though there are a couple of exceptions where they can be accessed by name directly (like enemies or group), namely inside the Routine Actor and your Spell Object :Callback functions.
Object Lists contain several Magic Methods which allow you to do powerful searches, iterations, and more with the objects contained. Some examples:
around – finds objects from the list that are within a given distance of another SYNQ objectloop – an iteration alternative to standard for loops, allowing you to mimic and reap the benefits of a continue statement to write cleaner, significantly less indented codeWe'll cover all the magic methods in detail below.
Other players in our party or raid, not including the player.
See also: fgroup - Players in our group, including the player. (fullGroup)
Usage: Players in your party or raid.
-- Basic pet healing maintenance for BM Hunter
mendPet:Callback(function(spell)
-- Check pet health and heal when needed
if pet.exists and pet.hp < 50 then
return spell:Cast(pet)
end
end)
Contains enemy units that are relevant to the player's current environment.
Note: Explosives are excluded from enemies and can be found in synq.explosives.
-- Basic Serpent Sting maintenance on enemies (BM Hunter)
serpentSting:Callback("maintain", function(spell)
synq.enemies.loop(function(enemy)
-- Skip enemies that already have Serpent Sting with more than 4 seconds remaining
-- dbr is shorthand for debuffRemains
if enemy.dbr(spell.id, player) > 4 then return end
-- Cast Serpent Sting on enemy and break loop on success
return spell:Cast(enemy)
end)
end)
Contains all friendly players within render distance.
Everywhere: All friendly players, even ones that are not in your group. This can be a needlessly large list in the open world.
-- Cast heal on any friend below 40% health
synq.friends.loop(function(friend)
-- Skip friends not in combat or above 40% health
if not friend.combat or friend.hp > 40 then return end
-- Cast heal on friend and break loop on success
return spell:Cast(friend)
end)
Contains all targetable dead units within render distance.
-- Cast battle res on a dead friendly player
synq.dead.loop(function(unit)
-- Skip units that aren't friendly
if not unit.friend then return end
-- Skip units that aren't players (only res players, not NPCs)
if not unit.player then return end
-- Cast battle res and break loop on success
return spell:Cast(unit)
end)
Contains enemy totems or related objects (PvP).
Tip: The list of totems and corresponding object IDs that populate this list can be found in lists.lua near SYNQ loader.
synq.totems.stomp(function(totem, uptime)
-- Only target totems that have been up for at least 300ms
-- This prevents targeting totems that are still spawning or despawning
if uptime < 0.3 then return end
-- Cast spell on totem to destroy it
return spell:Cast(totem)
end)
Contains M+ affix explosive objects, doesn't appear in synq.enemies.
someSpell:Callback("kill explosives", function(spell)
synq.explosives.loop(function(explosive)
return spell:Cast(explosive)
end)
end)
Contains all objects of type GameObject.
-- Find and interact with a soulwell object
synq.objects.loop(function(obj)
if obj.name == "Soulwell" then
-- Interact with the soulwell when found
obj:Interact()
end
end)
-- Find a specific quest object by ID
local quest_object_id = 123
synq.objects.loop(function(obj)
if obj.id == quest_object_id then
print("Found quest object with ID: " .. quest_object_id)
-- Return true to break the loop once we find what we're looking for
return true
end
end)
Magic Methods are available for every single SYNQ object list. You can make them available to a normal indexed array with synq.immerseOL(table).
All Magic Methods return true, so you can weave them into conditional statements if you want.
Find the number of units around a unit or position. You can set specific criteria (filter) they must meet to be added to the count. Receive a new list back with the units around.
local count, total, objects = list.around(unit, distance, criteria)
Parameters:
{x, y, z}: required - the unit or position to checkReturns:
-- Check for breakable crowd control around player before using brutal slash
local bcc, bsCount = enemies.around(player, 8, function(obj) return obj.bcc end)
-- bcc = count of enemies in breakable CC, bsCount = total enemies around player
-- Only cast if no enemies are in breakable CC and we'll hit at least 2 targets
if bcc == 0 and bsCount >= 2 then
brutalSlash:Cast()
end
The filter method creates a new object list containing all objects that pass the test implemented by the provided function.
-- Filter enemies to only include melee role enemies
local enemyMelee = enemies.filter(function(obj)
return obj.role == "melee"
end)
-- Loop through filtered melee enemies
enemyMelee.loop(function(obj)
-- Process each melee enemy here
end)
Iterate the object list, calling the provided function for each object. When any truthy value is returned, the loop will break.
Function is passed 3 arguments:
Benefits:
-- This accomplishes complex logic with clean, readable code using guard clauses
list.loop(function(unit)
-- Skip if we don't have hot streak or combustion buffs
if not hotStreak and not combustion then return end
-- Skip if unit isn't enemy, too far away, or out of line of sight
if not unit.enemy or unit.distance > 40 or not unit.los then return end
-- Skip if unit is immune to magic or is our current target
if unit.immuneMagic or unit.isUnit(target) then return end
-- Skip if unit is facing player or help flag is not set
if unit.facing(player) or not helpMePlease then return end
-- Cast spell and show alert on success
return spell:Cast(unit) and synq.alert("Casted the thing!", spell.id)
end)
-- Loop has extra features like uptime tracking built in synq.friends.loop(function(unit, i, uptime) -- uptime is 0 when we first detect a unit, useful for detecting new units if uptime == 0 then print("New friendly unit detected: " .. unit.name .. " (" .. unit.classString .. ")") end end)
### stomp
Very similar to `loop`, but with a couple of key differences:
1. Eliminates totems that are stuck at 1 hp or in the process of despawning from the iteration
2. Does not give back index - only object and uptime
```lua
synq.totems.stomp(function(totem, uptime)
-- Only target totems that have been up for at least 250ms
if uptime < 0.25 then return end
-- Cast spell if totem will die from this cast (damage is more than half its HP)
if totem.hp < spell.damage * 2 then
spell:Cast(totem)
end
end)
Sorts the list using basic Lua table.sort. Not very performant, should be used sparingly.
synq.enemies.sort(function(x, y) return x.hp < y.hp end)
You can create custom object lists that contain all other SYNQ object list methods. They only populate themselves when you attempt to read some value in them, like list.loop, list.filter, list[1] etc. Otherwise, they remain empty and do nothing.
synq.List:New(objectTypes, constructor)
local Unlocker, synq, example = ...
-- Create custom list for units (type 5) and players (type 6)
-- The constructor function filters objects - only includes Hunters and Warlocks
example.rangedDPS = synq.List:New({ 5, 6 }, function(object, objectType, guid)
-- Skip objects that are in our blacklist
if object.id and blacklist[object.id] then return end
-- Only include Hunters and Warlocks in this custom list
return object.class2 == "HUNTER" or object.class2 == "WARLOCK"
end)
-- Use the custom list just like any other SYNQ object list
example.rangedDPS.loop(function(unit)
print("Ranged DPS unit: " .. unit.name .. ", Health: " .. unit.health)
end)
#list will not trigger population of the list. Use list.length insteadObject lists are a powerful feature that make complex target selection and iteration tasks simple and performant in your SYNQ routines. They provide:
Next: Learn about all available Object Attributes for accessing unit information.