Skip to content
RustPluginGenerator

OnUserRespawn

OnUserRespawn is called by Oxide's RustCore wrapper right before the game runs its respawn routine for a player object, letting a plugin substitute its own spawn result or react to the respawn attempt.

Signature
object OnUserRespawn(IPlayer iplayer)

Parameters

Hook parameters
ParameterTypeDescription
iplayerIPlayerThe Oxide IPlayer wrapper of the BasePlayer being respawned. Use its Object property to reach the BasePlayer, its Id/Name for identification, and its Connected flag to tell whether the player is still connected.

Return value

Returning null keeps the game's default respawn behavior. Returning a non-null object stops the original OnPlayerRespawn code path and that value becomes the method's result, so the game uses whatever you return in place of its own spawn resolution.

How it works

OnUserRespawn fires inside RustCore's OnPlayerRespawn(BasePlayer) bridge, which the game calls when it is about to resolve a spawning point for a player that is respawning. Because it is a core hook rather than a patched game method, it runs before the actual spawn placement happens. Only one parameter is passed: the IPlayer wrapper. Use iplayer.Object to cast to BasePlayer when you need position, team, inventory or permissions. The return value is inspected by the core bridge: returning a non-null value of the expected type stops the original respawn path and that value is used instead, while returning null lets the game proceed normally. In practice most plugins return null and treat the hook as a notification, using it to teleport the player afterwards, re-apply loadouts on the next tick, or log respawn events. You can declare the parameter as IPlayer only; narrowing to BasePlayer is not applicable because the argument is always the wrapper. Guard against iplayer or iplayer.Object being null and avoid heavy work here, since respawns can happen frequently on busy servers.

Example plugin: Delay respawn with a countdown and heal on arrival

RespawnDelay.cs
using Oxide.Core.Libraries.Covalence;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Respawn Delay", "RustPluginGenerator", "1.0.0")]
    [Description("Heals players to a configurable value shortly after they respawn")]
    public class RespawnDelay : RustPlugin
    {
        private const string PermUse = "respawndelay.use";

        private PluginConfig config;
        private readonly Dictionary<ulong, Timer> pending = new Dictionary<ulong, Timer>();

        private class PluginConfig
        {
            [JsonProperty("Delay before heal (seconds)")]
            public float Delay { get; set; } = 1f;

            [JsonProperty("Health after respawn")]
            public float RespawnHealth { get; set; } = 50f;
        }

        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>
            {
                ["RespawnHealed"] = "You respawned with {0} health."
            }, 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(PermUse, this);
        }

        private object OnUserRespawn(IPlayer iplayer)
        {
            if (iplayer == null) return null;

            BasePlayer player = iplayer.Object as BasePlayer;
            if (player == null || !player.IsConnected) return null;
            if (!permission.UserHasPermission(player.UserIDString, PermUse)) return null;

            ulong userId = player.userID.Get();
            if (pending.ContainsKey(userId)) return null;

            pending[userId] = timer.Once(config.Delay, () => FinishRespawn(userId));
            return null;
        }

        private void FinishRespawn(ulong userId)
        {
            pending.Remove(userId);

            BasePlayer player = BasePlayer.FindByID(userId);
            if (player == null || !player.IsConnected || player.IsDead()) return;

            player.health = Mathf.Clamp(config.RespawnHealth, 1f, player.MaxHealth());
            player.ChatMessage(Msg("RespawnHealed", player.UserIDString, player.health));
        }

        private void Unload()
        {
            foreach (var entry in pending)
            {
                entry.Value?.Destroy();
            }
            pending.Clear();
        }
    }
}

The plugin registers one permission and reads a config with a delay and a health value. When OnUserRespawn fires, it checks whether the player holds the permission and whether a timer is already pending for them. If so it starts a timer.Once that heals the player to the configured value and sends a chat notice through the lang system. Timers are tracked in a dictionary and destroyed in Unload, and the dictionary entry is cleared when the timer runs so repeated deaths do not stack. Nothing is returned from the hook, so the game's own spawn logic still runs.

Common use cases

  • Apply a loadout after respawn

    Schedule a short timer on respawn to give players their kit, since the inventory may not be ready during the hook itself.

  • Log or broadcast respawn events

    Track how often players respawn on the server for admin statistics or feed a respawn counter into a scoreboard plugin.

  • Enforce spawn protection

    Start a temporary invulnerability window for freshly respawned players, clearing it on damage via OnEntityTakeDamage.

Pitfalls

  • iplayer.Object can be null

    The wrapper is passed even if the underlying BasePlayer was disposed. Always null-check iplayer and iplayer.Object before casting.

  • Returning a value suppresses the default spawn

    A non-null return stops the core respawn path. If you only want to observe the event, return nothing (void method) or return null.

  • Runs on every respawn

    This hook can fire many times per second on populated servers. Keep the handler cheap and defer heavy work with NextTick or a timer.

Build a plugin with OnUserRespawn

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

Prompt: Apply a loadout after respawn using the OnUserRespawn 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 OnUserRespawn

Generate