Skip to content

Handling events

Alexandre 'kidev' Poumaroux edited this page Oct 21, 2026 · 4 revisions

Handling events

A plugin reacts to the game through events. A handler is a function decorated with @on, called with the event each time it happens.

from proleak import on


@on("chat.received", pre=True, priority=10)
def hide_spam(ev):
    if "free gold" in ev.text:
        ev.cancel()


@on("unit.spawned")
def spawned(ev):
    print(ev.unit, ev.type, ev.owner)

Events lists every event with its fields and phases.

Contents

Before and after the game acts

Phase Subscribe with The handler may
pre @on(name, pre=True) change editable fields, cancel the event
post (default) @on(name) read the final values; it never sees a cancelled event

Higher priority runs first; ties go by plugin load order. proleak.off(fn) removes the subscriptions of fn.

Some events have no pre phase, because the game has already acted when ProLeak sees them:

  • the unit.* events other than unit.selling, unit.downgrading and unit.trained;
  • the input.* events;
  • fighter.died, purchase.failed and the world events.

Subscribing to one of these with pre=True raises PostOnlyEvent.

Warning

Cancelling needs a capability

Cancelling or editing what the player sends (net.out.*, purchases, signals, pings) needs the actions capability, which only local games allow. See Plugin permissions.

The event object

Member Meaning
ev.<field> Each field of the event, as listed in Events; editable fields can be assigned in a pre handler.
ev.name The event name, such as unit.spawned.
ev.pre True in the pre phase.
ev.cancelled True once a pre handler cancelled it.
ev.cancel() Cancels the event: the remaining pre handlers and the game's own handling are skipped (pre phase only).
ev.frame The Unity frame number of the dispatch.
ev.net_ticks The game's network time of the dispatch, in 100 ns ticks (0 for events that carry none).
ev.fields() Every field, as a dict.

A curated field that names a player, unit, team, legion spell or playstyle arrives as the world object, so ev.player.name and ev.unit.hp work directly.

Warning

Keep values, never the event

ev is valid only during the call. Using it later raises EventExpired; copy the values you need instead.

Kinds of events

Kind Names Across game updates
Game events chat, the game and its waves, units, the world events, purchases, signals and pings, input Names and fields stay the same.
Incoming network messages net.in.<Message>: each message the server sends Follow the game's message classes and change with them.
Outgoing network messages net.out.<Message>: each message the client sends The same.

Prefer the game events: a plugin built on them keeps working when the game updates.

Errors

Each of them is in proleak.errors.

Exception Raised when
ReadOnlyField Writing a field that is read-only, or any field in a post handler.
NotCancellable Cancelling an event that cannot be cancelled, or from a post handler.
FieldTypeError Writing a value of the wrong type or out of range.
EventExpired Using ev after its dispatch ended.
NotAllowedHere The current server kind does not allow the capability (see Plugin permissions).
UnknownEvent Subscribing to a name that is not an event.
EventUnavailable The event is off on this game version: its game hook is missing, or what it reads changed.
FeatureUnavailable A ProLeak feature (world, camera, chat...) is off on this game version because what it uses changed.
ActionUnavailable A player action's game calls changed on this game version. A FeatureUnavailable.
AdvancedUnavailable The game type an advanced call names changed on this game version. A FeatureUnavailable.
PostOnlyEvent Subscribing with pre=True to an event that has no pre phase.
WrongThread Calling a main-thread API from another thread.
BlockingCallOnMainThread Sleeping, waiting or blocking on a socket from a main-thread handler.
PluginTimeout A handler ran past its budget. Derives from BaseException.

Game updates explains when events and features turn off.


Previous: Plugin basics | Next: Plugin settings

Clone this wiki locally