hafen.event: The Character and the Rosters
What one character’s own HUD reports: bars and buffs, food and study, equipment and hotbar, wounds, kin, quests, map pins and the radial menu. Every key hands the thing it is about and that character’s Session last, except MarkerChanged (the recorded map is one database for the client). Part of the catalogue.
hafen.event():on("BuffAdded", function(buff, session)
hafen.log():write(session:character() .. " gained " .. (buff:name() or buff:res()))
end)
| Rule |
Detail |
| The session argument |
nil where the client cannot name the login the widget stands in. A handler that took the parameter guards it. |
| Diff, one frame |
The client marks the subject dirty when the server messages about it and re-reads once on the next step. A value that changes and reverts inside that frame fires nothing. State the server never messages about (a buff’s meter running down against a clock) moves silently and is announced by the next message that arrives. Read such a number live off the object. |
| List keys |
For StudyChanged, EquipChanged, KinChanged, WoundChanged the payload is the full new list, not a delta. Read the initial state once with the section’s own :list(), then listen. A list key covers adds, removals and changes: WoundChanged fires for a wound appearing, healing and worsening. A buff arrives one at a time, and its edge is named. |
Character and status
From the HUD’s own widgets, so they start once the HUD is up. Attributes, learning points, weight, skills, credos and lore have no key: session:char() reads them after the action that changes them.
| Event |
Payload |
Fires |
MeterAdded |
Meter |
A HUD meter bar appears. |
MeterRemoved |
Meter |
A HUD meter bar goes away. The object still reads, :exists() is false. |
MeterChanged |
Meter |
A meter bar’s value or colour changes. |
BuffAdded |
Buff |
A buff appears on the buff bar. |
BuffRemoved |
Buff |
A buff leaves the bar. The object still reads, :exists() is false. |
BuffChanged |
Buff |
A bar buff’s content updates. |
FepChanged |
Food |
FEP or hunger changes. |
StudyChanged |
StudySlot[] |
The study slots change: an add, a removal, or data resolving. |
EquipChanged |
Item[] |
Worn equipment changes. |
ActionbarChanged |
Slot |
An action-bar slot is set, cleared or changed. |
WoundChanged |
Wound[] |
A wound is added or healed, or its severity changes. |
| Rule |
Detail |
| Containers are not here |
A chest is not a global fact: subscribe to the container with widget:on("ItemAdded"/"ItemRemoved"/"Removed", fn). EquipChanged is global because worn gear is one fixed surface. |
ActionbarChanged payload |
The changed slot as the interned Slot session:actionbar():get(n) returns, so payload and session:actionbar():get(payload:index()) are one object. Fires on a set, a clear, a drag, or a slot’s data resolving, not on :cooldown() ticking. At login the occupied slots stream in as a burst, one fire each. |
| A held slot fires on both edges |
Once when the hold takes the slot, once when it ends and the server’s content returns. While held, slot:res() is the entry’s identity. |
Roster, quests, markers
| Event |
Payload |
Fires |
KinChanged |
Kin[] |
A kin is added, removed or edited, or flips online or offline. |
QuestAdded |
Quest |
A new active quest appears. |
QuestCompleted |
Quest |
An active quest is completed. |
QuestFailed |
Quest |
An active quest is failed. |
MarkerChanged |
The marker collection |
A map marker is added or removed. |
| Rule |
Detail |
KinChanged payload |
The whole roster as the interned Kin objects session:kin():list() returns, in Kin-window sort order, so payload[1] and session:kin():get(payload[1]:id()) are one object. It says that the roster changed, not what. Keep your own map of the last state, keyed by the Kin itself rather than :name(). A rename then does not read as one kin leaving and another arriving. kin:info() is the plain table. |
| The outcome is the key |
QuestCompleted on done, QuestFailed on failed: a handler for success is one subscription and no if. Subscribe to both for either. A finished status the client does not recognise fires neither. |
| The quest payload |
The Quest itself: a handler that keeps it goes on reading it, quest:status() included. |
| Event |
Payload |
Fires |
FlowerMenuAdded |
Petal[], in ring order |
A right-click puts up a radial menu. |
FlowerMenuRemoved |
string \| nil, the label picked |
That menu goes away. |
Every FlowerMenuAdded is followed by exactly one FlowerMenuRemoved (a pick, Esc, a click away, a dropped connection). The payload is nil for everything but a pick. Both cover the client’s own menus (the Kin window’s) as well as the server’s. Read the ring from the payload or from session:flowermenu(), which also names the object it was opened on. session is the event’s last argument. A ring goes up on the character the pointer is on and stays up, readable, if you tab away.
Steam
| Event |
Payload |
Fires |
SteamStatsLoaded |
— |
The Steam client has finished loading the player’s stats and achievements, so hafen.steam() reads them. |
AchievementUnlocked |
Achievement |
An achievement is stored as unlocked. |
Both are the Steam client’s moments, not a character’s. They fire once per client, whichever session is on screen, and not at all on a client started outside Steam.
See Also