Skip to content
RustPluginGenerator

OnPlayerDeath

OnPlayerDeath is called inside BasePlayer.Die just before the player fully dies, after the wound check. Return a non-null value to skip the vanilla death sequence (sleeping bag registration and base death handling).

Signature
object OnPlayerDeath(BasePlayer player, HitInfo info)

Parameters

Hook parameters
ParameterTypeDescription
playerBasePlayerThe BasePlayer who is dying. Check it for null and use IsNpc() to separate bots and scientists from real players when your logic should only cover humans.
infoHitInfoThe HitInfo describing the killing blow: InitiatorPlayer (the attacker if a player landed it), Initiator, Weapon, HitPositionWorld and damageTypes. It can be null when the player dies from environment or suicide, so null-check it before reading anything.

Return value

Return null to let the vanilla death continue: sleeping bag death handling runs and the base death logic executes. Return any non-null value to abort that block, so the player is not registered as dead through the normal path and stays as they were.

How it works

The hook fires from BasePlayer.Die at the point where the game has decided the player is not going to be wounded instead. It runs after the active belt item has been dropped and after WoundInsteadOfDying returns false, but before SleepingBag.OnPlayerDeath and the base Die call. That ordering matters: the player still exists, is still connected, and their backpack, sleeping bags and world state have not been touched yet.

player is the victim. info is the hit that caused the death and is the only way to identify the killer from this hook; it may be null for non-combat deaths. Read info.InitiatorPlayer for the player responsible, or info.Initiator for turrets, traps and animals. Declaring the second parameter as the exact HitInfo type is required; you cannot narrow it further.

Returning a non-null object suppresses the rest of the death path, which makes this useful for postponing or replacing a death, but the player is not revived automatically. Call Heal and reset wounds yourself if you block it.

Example plugin: New-player spawn protection from player kills

DeathProtection.cs
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Death Protection", "RustPluginGenerator", "1.0.0")]
    [Description("Protects freshly connected players from being killed by other players.")]
    public class DeathProtection : RustPlugin
    {
        private const string PermBypass = "deathprotection.bypass";

        private PluginConfig config;
        private readonly Dictionary<ulong, float> joinTimes = new Dictionary<ulong, float>();

        private class PluginConfig
        {
            [JsonProperty("Protection seconds after connect")]
            public float ProtectionSeconds { get; set; } = 300f;

            [JsonProperty("Announce blocked kills to attacker")]
            public bool NotifyAttacker { get; set; } = true;
        }

        protected override void LoadDefaultConfig() => config = new PluginConfig();

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                config = Config.ReadObject<PluginConfig>();
                if (config == null) throw new Exception();
            }
            catch
            {
                PrintWarning("Configuration file is invalid, using defaults");
                LoadDefaultConfig();
            }
            SaveConfig();
        }

        protected override void SaveConfig() => Config.WriteObject(config);

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["Protected"] = "You killed {0}, but they are under spawn protection.",
                ["Blocked"] = "Your spawn protection saved you from {0}."
            }, this);
        }

        private string Msg(string key, string userId = null, params object[] args)
            => string.Format(lang.GetMessage(key, this, userId), args);

        private void Init()
        {
            permission.RegisterPermission(PermBypass, this);
        }

        private void OnPlayerConnected(BasePlayer player)
        {
            if (player == null) return;
            joinTimes[player.userID] = Time.realtimeSinceStartup;
        }

        private void OnPlayerDisconnected(BasePlayer player, string reason)
        {
            if (player == null) return;
            joinTimes.Remove(player.userID);
        }

        private bool IsProtected(BasePlayer player)
        {
            if (player == null) return false;
            if (permission.UserHasPermission(player.UserIDString, PermBypass)) return false;

            float joined;
            if (!joinTimes.TryGetValue(player.userID, out joined)) return false;
            return Time.realtimeSinceStartup - joined < config.ProtectionSeconds;
        }

        private object OnPlayerDeath(BasePlayer player, HitInfo info)
        {
            if (player == null || player.IsNpc || !player.IsConnected) return null;
            if (!IsProtected(player)) return null;

            if (info == null) return null;

            BasePlayer attacker = info.InitiatorPlayer;
            if (attacker == null || attacker == player || attacker.IsNpc) return null;

            if (attacker.currentTeam != 0 && attacker.currentTeam == player.currentTeam) return null;

            player.Heal(player.MaxHealth());

            if (config.NotifyAttacker)
                attacker.ChatMessage(Msg("Protected", attacker.UserIDString, player.displayName));

            player.ChatMessage(Msg("Blocked", player.UserIDString, attacker.displayName));
            return true;
        }
    }
}

The plugin tracks how long each player has been connected and shields anyone under the configured threshold from dying to another player. In OnPlayerDeath it confirms the victim is a real connected player, reads info.InitiatorPlayer, and skips NPCs, attackers on the same team and non-player kills. If the victim is still protected it heals them to full, notifies the attacker and returns true so the vanilla death path is skipped. The join timestamp is stored in memory and cleared on disconnect, so no data files are involved. All chat text goes through the language file, and the protection flag is exposed as a permission for staff.

Common use cases

  • Spawn protection

    Cancel deaths of freshly connected players who are killed by other players, then heal them and warn the attacker. Keep a timer or join timestamp to know who is still protected.

  • Kill feed and kill rewards

    Read info.InitiatorPlayer to identify the killer, then award Economics currency or broadcast a kill message. Returning null keeps the death normal.

  • Arena and event handling

    Detect deaths inside a custom event zone, strip the victim's event kit and return them to a lobby. Pair with OnPlayerRespawn to restore normal gear afterwards.

Pitfalls

  • info can be null

    Fall damage, starvation, radiation and suicide do not always carry a HitInfo. Always null-check info and info.InitiatorPlayer before using them, or the hook will throw for those deaths.

  • Blocking death does not revive the player

    Returning a value skips the vanilla death block only. If you want the player to survive, call Heal with the max health and make sure they are not already flagged wounded; otherwise state can desync.

  • This is not OnEntityDeath

    OnEntityDeath fires for every entity including players, but OnPlayerDeath fires earlier, inside BasePlayer.Die. Use this hook when you need the pre-death state, and OnEntityDeath when you need the corpse or loot that exists after the kill.

Plugin recipes that use OnPlayerDeath

Build a plugin with OnPlayerDeath

Describe what should happen and get a compiled plugin that uses this hook.

Prompt: Spawn protection using the OnPlayerDeath hook, with a config file and a permission
Generate this plugin

Edit the prompt on the next screen. 2 free plugins a month, no card.

Last updated Oct 26, 2026. Found a mistake? Email support@rustplugingenerator.com.

Build a plugin with OnPlayerDeath

Generate