Event payloads¶
Every event reaches a mod as one SNBT text, whatever language the mod is written in. This page is the reference for what that text carries. The language guides show how to subscribe; the fields are the same everywhere.
Two kinds of event¶
LeviLamina events are the ones in LeviLamina's own event registry, subscribed by their
full id, such as ll::event::MobDieEvent. Their payload is LeviLamina's own serialization
of the event, and Pier adds fields to it, described below, because that serialization
names engine objects without describing them.
Synthetic events are the ones Pier raises from its own hooks, such as
PlayerAttackTargetEvent. Their payload is written by Pier and documented per event in
each binding's list of event names.
What Pier adds to a LeviLamina event¶
An engine object in the payload is described next to it, under the same key with a leading
underscore. A field that is there was read by the host. A field it could not read is left
out or listed in _unresolved, and Pier puts no default in its place.
| The payload names | Pier adds | Shape |
|---|---|---|
the player the event is about (self) |
_player |
{name, xuid, uuid, pos:{x,y,z}} |
any other actor, or a non-player self |
_<key> |
{uid, type, name, isPlayer, dim}, and for a player also xuid and realName |
| a damage source | _<key> |
{cause, attackerUid?, attacker?, projectileUid?, projectile?} |
| an entity type | _identifier |
{full, namespace, name} |
| a block or an item | _<key> |
{name} |
a block source, or a self actor |
dim |
the dimension id, when the event did not carry one |
uid is the actor's unique id, the same number every actor slot takes, so a mod can act on
the actor a payload names. name is the name tag, which a plugin may have changed;
realName is the player's account name.
Who killed whom¶
MobDieEvent, PlayerDieEvent and ActorHurtEvent carry the damage source. When the
damage came from an actor, the source has:
attackerUid: the actor responsible. For a projectile that is the one that fired it, not the arrow.attacker: that actor described, when it still exists.projectileUidandprojectile: the arrow, trident or other projectile, for projectile damage only.
The uid is written even when the actor is already gone, so a kill by an arrow whose shooter
logged out still says who. An absent attacker therefore means "no longer here", and an
absent attackerUid means the damage did not come from an actor at all: fire, a fall, the
void. cause is the engine's damage cause number either way.
When something could not be resolved¶
An actor that is neither an online player nor in the runtime actor table cannot be
described. Its key is listed in _unresolved instead, and the event still arrives. A mod
making a protection decision on such a payload refuses rather than guesses; the Rust SDK's
check_complete() and dim() do that for you.
Conventions of synthetic events¶
Synthetic payloads follow three rules that let a mod tell an answer from a failure:
partial:"partial":1means at least one field could not be read and holds a default only. It appears inExplosionEvent,FarmlandDecayEvent,SpawnItemActorEvent,ChestPairEventandPistonPushEvent, and is absent when every read succeeded.targetKnown: inPlayerAttackTargetEventandPlayerInteractEntityEvent, 0 means the target could not be read.targetIsPlayeris 1 then, so a PvP rule refuses.- Cancelling: the callback receives a write-back, and a cancellable event is cancelled
by writing it back with the cancel set; the bindings wrap this, as
ev.cancel()in Rust. An event marked observation-only cannot be cancelled, and its documentation names the event to block instead.
When an event does not arrive¶
- The event may be turned off: a synthetic event named in
hooks.disabledinconfig.jsonrefuses the subscription with a line saying so. See Configuring. - A LeviLamina event whose engine hook point changed may stop arriving on a new engine version; Troubleshooting lists how to tell.