Skip to content

actor

Anything in the world with a spawn id: your own character, your target, any nearby NPC or player, and every member of an encounter.

An actor is a plain Lua table of zero-argument functions, so call its members with ., not :.

local t = mq.TLO.Target
if t.ID() ~= 0 then
  eq2.print(("%s (lvl %d, %.1fm) hp=%d%%")
    :format(t.Name(), t.Level(), t.Distance(), t.PctHP()))
end

mq.TLO.Me is an actor too — see character for the members it adds on top.

Members

string Name

The actor's display name.

number ID

Spawn id. 0 means the actor did not resolve — this is the check to guard every other read on.

number Level

Level.

number EffectiveLevel

Mentored level. Differs from Level() only while mentoring.

string Class

Class name.

number ClassID

Subclass enum id.

number PctHP

Health, 0100.

number PctPower

Power, 0100.

number Con

Raw, unmapped con value. Not translated to a colour name the way MacroQuest's ${Spawn.ConColor} is. Prefer ConTier().

number ConTier

Con-colour tier as a small integer: 0 = Gray … 6 = Red.

string ConColor

The con tier as a colour name.

number DiffClass

number DifficultyClass

Difficulty class: 0 = Solo, 1 = Heroic, 2 = Epic x2, 3 = Epic x3, 4 = Epic x4. Both spellings are bound and return the same value.

number Difficulty

Raw difficulty value.

string DifficultyText

Difficulty as text (Solo, Heroic, Epic x2, …).

bool IsHeroic

DiffClass() == 1.

bool IsEpic

DiffClass() >= 2.

Position

number X

number Y

number Z

World coordinates. 0.0 if the actor has no resolvable position.

number Heading

Facing.

Warning

The axis choice here is an unverified best guess, not a confirmed signature. Don't build precision turning on it.

number Distance

3D distance from you to this actor.

Always measured from Me, never between two arbitrary actors — a.Distance() and b.Distance() are both "how far from me", so there is no way to ask for the distance between a and b short of computing it from X/Y/Z.

Fails open

Returns 0.0 on any failed read, including a failed local player read. Require d > 0 in every distance gate.

string Zone

Current zone name. World-global — the same value regardless of which actor you call it on. Offered here as a convenience alongside mq.TLO.Zone.Name().

Classification

bool IsPlayer

True for player characters.

bool IsNamed

Best-available "proper-name NPC" proxy. Returns true when the actor's display name starts with a capital letter (named mobs use proper names; generic spawns start lowercase).

Warning

Treat this as a priority hint, not loot/boss truth. Proper-named pets also read true — exclude pets separately with IsAPet().

bool IsAPet

True if this actor has an owner.

bool IsMyPet

True if this actor's owner is you.

number OwnerID

Spawn id of this actor's owner. 0 when it has none.

bool OwnerIsPlayer

True when the owner is a player character.

bool Attackable

Combat-capable target — mobs and PCs. Not the same as hostile: this does not tell you friend from foe.

bool NotAttackable

The inverse of Attackable().

Combat and encounter

number TargetID

Spawn id of this actor's own target — "target's target". 0 when idle or unresolved.

actor TargetActor

actor for TargetID(), resolved through the local actor map. nil if there is no target, or the target isn't currently loaded in your zone (streamed out, out of range).

number ThreatPct

number SecondaryThreatPct

number PetThreatPct

Threat percentage, 0100, toward this actor: yours, the next person down the hate list, and your pet's.

Fails open, same as Distance()

These read 0 both when there is genuinely no threat and when the underlying read is gated off or fails to resolve — "no threat data" and "no threat" look identical. Don't build a hard "I have zero threat" decision on a bare ThreatPct() == 0 check without also confirming the actor otherwise resolved (e.g. ID() ~= 0).

number EncounterSize

Size of this actor's encounter/pull group.

array EncounterMembers

Array of actor for the other members of this actor's encounter. Capped at 64; unresolvable ids are skipped. Empty when EncounterSize() == 0.

bool InCombat

Aggro/attacker-cache proxy. Same underlying read as HasAggro().

bool HasAggro

"Something has established threat against this actor."

Warning

This is an attacker-cache read, not a true combat-mode flag. It can false-negative for a group DPS who never holds aggro. Don't use it as the sole "am I fighting" gate.

Effects

number EffectCount

Number of visible effect icons on this actor.

array Effects

Array of effect. Icon and id only at this tier — there is no name or duration data for a remote actor.

bool Buff(name)

Is an effect matching name currently showing on this actor? Resolves name through the local ability-name cache, then checks icon presence.

Works on any actor. For your own character, Me.Buff(name) reads the maintained bar directly and is more precise.

Targeting

number GhostHandle

The actor's internal ghost handle (uint16). This is the client-local key the native target function needs to select an actor. Returned as uint32 to avoid marshalling quirks; 0xFFFF means the actor is unresolved.

Most scripts never need this — use eq2.target_by_id() to target an actor by spawn id. GhostHandle() is exposed for diagnostics and for scripts that need to inspect the raw value.

Struct inspection

A small guarded raw-read surface, added for lua/inspector.lua. Reads are actor-relative, bounds-checked, and routed through an SEH-guarded reader, so a bad offset returns 0/empty instead of crashing the client.

Use it to confirm struct offsets live, before wiring them into C++.

number Address

Raw actor pointer, for display only — may lose low bits for very high pointers. 0 when the actor is unresolved.

number U8(off)

number U16(off)

number U32(off)

Unsigned read at actor + off. 0 on a failed read.

number I32(off)

Signed 32-bit read at actor + off.

number F32(off)

32-bit float read at actor + off.

array Bytes(off, len)

len bytes (capped at 256) as a 1-based array of 0255. Empty on a failed read.
-- Confirm the con-tier / difficulty-class offsets on your current target:
local t = mq.TLO.Target
if t.ID() ~= 0 then
  eq2.print(("ConTier=%d raw+0x460=0x%02X | DiffClass=%d raw+0x464=0x%02X")
    :format(t.ConTier(), t.U8(0x460), t.DiffClass(), t.U8(0x464)))
end

See also