Skip to content
RustPluginGenerator

OnEntityKill

OnEntityKill is called from BaseNetworkable.Kill before the entity is flagged destroyed and removed from the world. Returning a non-null value cancels the kill entirely.

Signature
object OnEntityKill(BaseNetworkable entity)

Parameters

Hook parameters
ParameterTypeDescription
entityBaseNetworkableThe BaseNetworkable instance that is being killed, or has already been marked destroyed. Cast it to a more specific type (BasePlayer, BuildingBlock, StorageContainer, LootableCorpse) to inspect the entity that triggered the hook.

Return value

Return null to let the kill proceed normally. Return any non-null value to cancel the kill: the original method exits before destroying the entity, so the object remains in the world.

How it works

The hook fires inside BaseNetworkable.Kill, before the engine increments its kill counter and destroys the object. It is used for every networked entity: players, building blocks, deployables, dropped items, corpses, vehicles and NPCs. Because the injection is at the top of Kill, entity.IsDestroyed is still false when your method runs, so you can safely read OwnerID, ShortPrefabName, position and any type-specific state. Declaring the parameter as a specific subclass such as BuildingBlock or BasePlayer makes Oxide skip the call whenever the entity is a different type, which is the cheapest way to scope the hook. Returning any non-null object stops the original kill path: the entity survives and stays in the world. This is a powerful but sharp tool, so prefer returning null for entities you do not handle. Do not run heavy work here, since large bases being wiped can fire the hook thousands of times in a single frame.

Example plugin: Protect building blocks during a raid grace window

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

namespace Oxide.Plugins
{
    [Info("Raid Protected Kill", "RustPluginGenerator", "1.0.0")]
    [Description("Blocks building block destruction during an admin-controlled raid protection window.")]
    public class RaidProtectedKill : RustPlugin
    {
        private class PluginConfig
        {
            [JsonProperty("Protection duration (minutes)")]
            public int DurationMinutes = 30;

            [JsonProperty("Required permission")]
            public string Permission = "raidprotectedkill.use";
        }

        private PluginConfig config;
        private DateTime protectionEndsUtc = DateTime.MinValue;

        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>
            {
                ["Started"] = "Raid protection is now active for {0} minutes.",
                ["NotPermitted"] = "You do not have permission to use this command."
            }, 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(config.Permission, this);
        }

        [ConsoleCommand("raidprotectedkill.start")]
        private void CmdStart(ConsoleSystem.Arg arg)
        {
            var player = arg.Player();
            if (player != null && !permission.UserHasPermission(player.UserIDString, config.Permission))
            {
                SendReply(player, Msg("NotPermitted", player.UserIDString));
                return;
            }

            protectionEndsUtc = DateTime.UtcNow.AddMinutes(config.DurationMinutes);
            Server.Broadcast(Msg("Started", null, config.DurationMinutes));
            Puts($"Raid protection active until {protectionEndsUtc:u}");
        }

        private object OnEntityKill(BuildingBlock block)
        {
            if (block == null || block.IsDestroyed) return null;
            if (DateTime.UtcNow >= protectionEndsUtc) return null;
            return true;
        }
    }
}

The plugin uses OnEntityKill to block the destruction of BuildingBlock entities for a configurable number of minutes after a raid starts. An admin command raidprotect.start records a start time, and OnEntityKill returns a non-null sentinel while the window is open and the entity is a wall or foundation. Entities of any other type fall through and are killed normally. When the timer expires the hook returns null again. Config holds the protection duration and the required admin flag, and the remaining time is broadcast to chat when the window opens.

Common use cases

  • Cancel despawn of player-owned items

    Return a non-null value for DroppedItem or LootableCorpse instances whose OwnerID matches a tracked player so their belongings never vanish on server cleanup.

  • Audit base wipes

    Record the ShortPrefabName, position and OwnerID of every BuildingBlock that is killed so admins can review which structures were destroyed and when.

  • Cancel NPC team kills

    Prevent friendly ScientistNPC instances from being killed by teammates by returning a non-null value when OwnerID belongs to a protected team.

Pitfalls

  • Fires for every despawn

    Server cleanup, plugin calls to Kill() and player wipes all route through this hook. Restrict to specific types with the parameter type to avoid running logic on unrelated entities.

  • Returning non-null leaks entities

    If you cancel the kill and never schedule a retry, the entity stays alive indefinitely. Track it and call Kill() later once protection expires.

  • Runs during mass wipes

    A plugin calling Kill() on hundreds of entities in a loop triggers the hook each time. Keep body code O(1) and avoid chat output or disk writes here.

Plugin recipes that use OnEntityKill

Build a plugin with OnEntityKill

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

Prompt: Cancel despawn of player-owned items using the OnEntityKill 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 OnEntityKill

Generate