Skip to main content

Events

Register with:

Game.registerEvent(Game.Events.TEXT_MESSAGE, function(ev)
-- handle
end)

Multiple listeners per event are supported. Game.unregisterEvent(ev, fn) removes one listener; Game.unregisterEvent(ev) clears all for that event.

Callbacks run on the Lua background thread. Do not block for long; heavy work should be short or deferred via timers.


Wired events

TEXT_MESSAGE

Server / client text messages (status, advance, loot, …).

FieldTypeNotes
textstringmessage body
channelIdnumberoften 0 for system
messageTypenumbersee Enums.MessageTypes (version-sensitive)
Game.registerEvent(Game.Events.TEXT_MESSAGE, function(ev)
if ev.text == "You are dead."
and (ev.channelId or 0) == 0 then
Client.sendHotkey(16777220, 0)
end
end)

TALK

Chat / creature talk.

FieldType
talker / namein payload string fields
textmessage

(Exact field names follow the native marshal — prefer print / log once when integrating.)

LABEL

Status-line / label text (client status line updates).

FieldType
textstring

CONTAINER_OPEN / CONTAINER_CLOSE

FieldTypeNotes
containerIdnumberopen / close
capacitynumberopen only

CONTAINER_CLOSE fires from the container metacall (handleCloseContainerMessage, id @ msg+0x18) after the client applies the close.

MAGIC_EFFECT / DISTANCE_SHOOT_EFFECT

Opt-in via hook_magic_effects=1 (default off). Resolve is optional: unique AOB miss ⇒ events stay off (no crash). Install re-checks prologue + stolen size.

Offline-verified offers: frame-1d8 (15.11 / 15.13), frame-208 (15.23 / 15.25 / gunzodus-15.25.3a).

EventFields
MAGIC_EFFECTtype, optional x,y,z (coords when Any parse + Coordinate* validate; else type-only)
DISTANCE_SHOOT_EFFECTtype, from x,y,z, to toX,toY,toZ (missile only when to Coordinate* is plausible — GraphicalEffect delay at the same offset is ignored)

CREATURE_APPEAR

FieldType
creature idnumber
x, y, zposition
namestring

LEVEL_UP

FieldType
old / new levelnumbers

PLAYER_STAT_CHANGE

FieldType
stat idhp / mana / exp / vocation codes
new valuenumber

Modal dialog interaction payload (button / choice ids).

IMBUEMENT_OPEN_WINDOW / IMBUEMENT_DATA

Fired when the client receives GameserverMessageImbuingDialogRefresh (shrine / imbuement dialog open or refresh).

IMBUEMENT_DATA payload (ZeroBot-compatible):

FieldTypeNotes
itemIdnumberitem currently in the imbuement window
slotsnumberimbuement slot capacity on the item
clearingCharmCostnumberoptional; present when packet flag bit 2 is set
slotImbuementsarraycurrent slot contents (may include empty=true entries)
availableImbuementsarrayimbuements that can be applied

Each entry in slotImbuements / availableImbuements:

FieldType
emptybool
imbuementIdnumber
imbuementLevelstring
imbuementNamestring
imbuementDescriptionstring
imbuementPricenumber
clearPricenumber
timeRemainingnumber
itemsarray of { itemId, count }

Remaining RE: astralSources (player materials on hand at msg+0x50/0x58).

QUEST_LOG

Fires when the client applies a quest-log update (after the server GameserverMessageQuestLog is parsed into TQuestLogStorage).

Callback receives one table (ZeroBot onInternalQuestLog shape):

Game.registerEvent(Game.Events.QUEST_LOG, function(data)
for _, q in ipairs(data.quests) do
print(q.id, q.name, q.state) -- state: Enums.QuestState PENDING=0 COMPLETED=1
end
end)
FieldType
questsarray of { id, name, state }

QUEST_LINES

Fires when quest-line / mission details are applied for a quest id.

ZeroBot positional fan-out: (questId, { missions = {...} }).

Game.registerEvent(Game.Events.QUEST_LINES, function(questId, missions)
for _, m in ipairs(missions.missions) do
print(m.missionId, m.name, m.description)
end
end)
Field (table form)Type
questIdnumber
missionsarray of { missionId, name, description }

PARTY_HUNT

Fires on handlePartyHuntAnalyserMessage (party hunt analyser RX).

ZeroBot fan-out passes the formatted output string (Engine tab party-hunt calculator scrapes Balance: from it). Opus also fills structured fields on the native event table.

Game.registerEvent(Game.Events.PARTY_HUNT, function(output)
print(output)
end)
Field (table form)Type
outputstring
sessionStartnumber
partyLeaderIdnumber
lootTypenumber
membersarray of { id, name, highlight, loot, supply, damage, healing }

Tick vs events

MechanismUse when
function onTick()polling vitals, HUD refresh, light logic every tick
Timer.newfixed-interval work (2s bless check, 500ms blink)
Game.registerEventreact to server/client messages without polling

Prefer events for “when X happens” and timers for “every N ms”. Avoid busy loops.