Player and inventory hooks
Lifecycle, pawn factory, loadout, jobs, player damage and inventory transactions with explicit authority.
Subscription contract
Gameplay events run synchronously on the process that raises them. Core policy and committed state channels are host-side unless their row says local or exposes IsHostAuthoritative. Higher priorities run first. Equal priorities retain registration order. Track the returned IDisposable so disable removes the handler.
| LitherarpGameEvent<T> member | Contract |
|---|---|
Subscribe(Action<T> handler, string? owner = null) | Subscribes at priority zero and returns the teardown handle. |
Subscribe(Action<T> handler, string? owner, int priority, string? subscriptionId = null) | Subscribes with explicit ordering and a stable diagnostic id. |
HasSubscribers | Read-only fast-path indicator. Event publication remains internal to LitheraRP. |
| Priority | Clamped from -1000 to 1000. Higher priorities run first; equal priorities retain registration order. |
| Capacity | At most 4,096 subscriptions per event channel and 256 per normalized owner. An omitted owner uses anonymous and has the same owner cap. A rejected subscription returns an inert disposable and logs one limit warning for that channel. |
A LitherarpCancelableRequest exposes IsDenied, DenyReason and Deny(reason). The first denial wins. Recoverable handler failures are isolated; three consecutive failures quarantine that subscription until it is recreated. A handler taking at least 25 ms is rate-limited in diagnostics. Same-event recursion is bounded to a depth of eight. At the limit, a cancelable request is denied and a post notification is suppressed.
Hooks and payloads
| Hook | Payload and public members | Timing and effect |
|---|---|---|
ConnectionRequested | LitherarpConnectionRequestConnection, SteamId, DisplayName, inherited Deny(reason) | Cancelable after server authorization, sanctions and effective whitelist checks, before a pawn exists. |
PlayerConnected | LitherarpPlayerConnectedEventConnection | Post-event when an accepted connection becomes active on the host. |
PlayerDisconnecting | LitherarpPlayerDisconnectingEventConnection, nullable Player | Post notification before core persistence and pawn cleanup. Leaving cannot be canceled. |
PlayerDisconnected | LitherarpPlayerDisconnectedEventConnection | Post notification after disconnect. The pawn may already be invalid. |
WorldReady | LitherarpWorldReadyEventScene | One host notification after map and persistent-world bootstrap. Hot addons should also use RunWhenWorldReady. |
ClientWorldReady | LitherarpClientWorldReadyEventScene | Local-client notification after each successful scene and verified addon snapshot barrier. A hot replacement lowers the barrier and emits again only after the complete snapshot succeeds. |
PlayerSpawnRequested | LitherarpPlayerSpawnRequestKind, Scene, nullable Connection, nullable ExistingPlayer, JobId, SpawnTransform, PawnPrefabPath, HasCustomSpawnTransform, HasPawnFactory; SetPawnPrefab, SetPawnFactory, SetJobId, SetSpawnTransform, Deny | Cancelable before initial pawn creation or respawn reset. Only an initial spawn can replace the prefab or install the highest-priority pawn factory. A factory object must belong to the requested scene and must not already be network-spawned. A null or invalid result falls back to the selected prefab. Core-required components are still installed and validated. |
PlayerPawnCreated | LitherarpPlayerPawnCreatedEventPlayer, Pawn, Connection, PawnPrefabPath, UsedPawnFactory; four-value Deconstruct compatibility overload | Post-event after initial pawn composition, before persistence restore and network spawn. UsedPawnFactory is an optional constructor value and is true only when the final valid pawn came from the factory, in which case PawnPrefabPath is empty. A null or invalid factory result reports false and the fallback prefab path actually used. |
PlayerLoadoutRequested | LitherarpPlayerLoadoutRequestPlayer, SandboxPlayer, Inventory, Kind, Job, GiveDefaultTools, GiveJobWeapons, ApplyJobKevlar, ApplyJobClothing, ApplySpawnProtection, IsMandatory; SetDefaultToolsEnabled, SetJobWeaponsEnabled, SetJobKevlarEnabled, SetJobClothingEnabled, SetSpawnProtectionEnabled, Deny | Cancelable policy before a normal core loadout. Denial suppresses that core loadout, not the authorized spawn. When IsMandatory is true, handlers may observe but denial and policy changes are ignored for the required system migration. |
PlayerLoadoutApplied | LitherarpPlayerLoadoutAppliedEventPlayer, Inventory, Kind, JobId | Post-event after core loadout policy. Add addon-owned equipment here. |
PlayerSpawned | LitherarpPlayerSpawnedEventPlayer, JobId, IsRespawn | Post-event when initial spawn or respawn is complete. |
JobChangeRequested | LitherarpJobChangeRequestPlayer, CurrentJobId, RequestedJobId, Deny | Cancelable before any job-change side effect. |
JobChanged | LitherarpJobChangedEventPlayer, PreviousJobId, NewJobId | Post-event after the job change committed. |
PlayerDamageRequested | LitherarpPlayerDamageRequestnullable Victim, nullable Attacker, nullable AttackerPlayer, Damage, Tags, DamageTags, Position, Origin; SetDamage, SetAttacker, SetPosition, SetOrigin, SetTags, AddTag, RemoveTag, BuildTagSet, Deny | Hot cancelable path after game filters and hitbox scaling, before armour or health changes. Damage, vectors, attacker references and tags are validated by their mutators. |
PlayerDamaged | LitherarpPlayerDamagedEventnullable Victim, BasePlayer, nullable Attacker, nullable AttackerPlayer, ResolvedDamage, HealthDamageApplied, DamageAbsorbedByArmour, UnappliedHealthDamage, PreviousHealth, CurrentHealth, PreviousArmour, CurrentArmour, Tags, Position, Origin, IsFatal | Host post-event after health and armour commit, including full armour absorption, and before PlayerDied. It separates approved pre-armour damage, real health loss, exact kevlar absorption and clamped lethal overkill. |
PlayerDied | LitherarpPlayerDiedEventVictim, nullable Killer, Damage, Tags | Post-event after host death state committed. |
ItemMoveRequested | LitherarpItemMoveRequestPlayer, Kind, FromSlot, ToSlot, ItemId, Quantity, Deny | Compatibility pre-hook for backpack swap, split, equip-to-hotbar and store-from-hotbar requests. |
InventoryMutationRequested | LitherarpInventoryMutationRequestOperationId, Player, Kind, Source, Destination, ItemId, RequestedQuantity, Quantity, Reason, IsHostAuthoritative; SetQuantity, Deny | Cancelable transaction before backpack, hotbar, reserve-ammo or weapon-clip changes. IsHostAuthoritative is true when raised by the host. Core backpack, reserve-ammo and weapon-clip paths are host-authoritative; a custom owner-side caller must inspect this flag before treating the request as authoritative. |
InventoryMutated | LitherarpInventoryMutationEventOperationId, Player, Kind, Source, Destination, ItemId, RequestedQuantity, AppliedQuantity, Reason | Post-event only after the transaction applies. Match OperationId to the request when authority matters because the post payload does not repeat IsHostAuthoritative. |
ItemUseRequested | LitherarpItemUseRequestPlayer, ItemId, Kind, Deny | Cancelable before a backpack consumable is consumed. |
ItemUsed | LitherarpItemUsedEventPlayer, ItemId, Kind | Post-event after one consumable unit is used. |
ItemPickedUp | LitherarpItemPickedUpEventPlayer, ItemId, Quantity | Post-event after an item enters a backpack from the world. |
ItemDropped | LitherarpItemDroppedEventPlayer, ItemId, Quantity, OperationId; three-value Deconstruct compatibility overload | Host post-event only after a world object spawned and the root drop transaction completed. OperationId is an optional constructor value. Published quantities never exceed InventoryMutated.AppliedQuantity. Multiple lots retain their item ids, use deterministic order, omit zero quantities and share the root OperationId. This covers normal and death drops without duplicate publication. |
Spawn and inventory enums
| Type | Values |
|---|---|
LitherarpPlayerSpawnKind | Initial, Respawn. |
LitherarpItemUseKind | Food, Kevlar, Ammo, Addon. |
LitherarpItemMoveKind | Swap, Split, EquipToHotbar, StoreFromHotbar. |
LitherarpInventoryContainerKind | None, Backpack, SafeDeposit, PhoneSlot, Hotbar, EquippedBackpack, StoredAmmo, AmmoReserve, WeaponClip, World, DeathLoot, Persistence. |
LitherarpInventoryMutationKind | Add, Remove, Clear, Move, Swap, Split, Merge, Equip, Unequip, Drop, Pickup, Consume, Update, Restore. |
LitherarpInventoryLocation | Container and Slot. Slot -1 means no fixed slot. |
SetQuantity accepts Add, Remove, Move, Split, Drop, Pickup, Consume and Update. Structural operations keep their fixed cardinality. Synchronous inventory mutations attempted from an inventory hook are rejected to prevent recursion around another addon's decision.
Committed damage and drops
PlayerDamaged.ResolvedDamage is the approved value before kevlar. HealthDamageApplied is the real health delta, DamageAbsorbedByArmour is the exact amount consumed by PlayerKevlar, and UnappliedHealthDamage is lethal overkill that could not be applied below zero health.
Match ItemDropped.OperationId with InventoryMutated.OperationId when a drop creates several world lots. Every emitted lot belongs to the same completed root mutation. No event is raised for a failed spawn, an uncommitted mutation or a zero allocation.