OnPlayerSleep
OnPlayerSleep is called when a connected player transitions into the sleeping state, fired from BasePlayer.StartSleeping before restraints and safe-zone handling are processed.
void OnPlayerSleep(BasePlayer player)Parameters
| Parameter | Type | Description |
|---|---|---|
player | BasePlayer | The BasePlayer who is entering the sleeping state. Not null at this point; the player is still connected and may soon be represented by a sleeper entity. |
Return value
The hook fires through Interface.CallHook in a void method, so any return value is ignored and the original sleep sequence always continues. Return values cannot cancel or alter the transition.
How it works
This hook fires once inside BasePlayer.StartSleeping, right after the early-out that returns if the player is already sleeping and before restraints are released and the safe-zone check runs. It is triggered by the normal game flow that puts a player to sleep: disconnecting a player who leaves a body behind, and any server action that calls StartSleeping directly (for example admin or plugin-driven sleep commands). A player who is already sleeping does not fire it again.
The single player argument is the connection owner, still fully available here, so you can read displayName, UserIDString, position, inventory and team before the character becomes a sleeper. If you only need events after the sleeper exists, use OnPlayerSleepEnded instead.
Declaring the parameter as BasePlayer is the only signature. There is no overload narrowing beyond that, since the injection always passes a BasePlayer.
Because this runs before the engine finishes putting the player to sleep, it is a good place to persist state, stamp metadata or start a timer. Do not treat the player as already sleeping: IsSleeping() may still report false when your hook runs.
Example plugin: Reward the player who just went to sleep
using UnityEngine;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("Sleep Reward", "RustPluginGenerator", "1.0.0")]
[Description("Gives a configurable scrap reward when a permitted player goes to sleep")]
public class SleepReward : RustPlugin
{
private const string PermReward = "sleepreward.use";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Enable reward")]
public bool Enable { get; set; } = true;
[JsonProperty("Scrap amount")]
public int ScrapAmount { get; set; } = 5;
}
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>
{
["Reward"] = "You received {0} scrap for going to sleep.",
["NoRoom"] = "No room for your sleep reward; it was left on the ground nearby."
}, this);
}
private string Msg(string key, string userId = null, params object[] args)
{
return string.Format(lang.GetMessage(key, this, userId), args);
}
private void Init()
{
permission.RegisterPermission(PermReward, this);
if (config.ScrapAmount <= 0)
{
PrintWarning("Scrap amount must be greater than zero; reward will do nothing.");
}
}
private void OnPlayerSleep(BasePlayer player)
{
if (!config.Enable || player == null) return;
if (config.ScrapAmount <= 0) return;
if (!permission.UserHasPermission(player.UserIDString, PermReward)) return;
var item = ItemManager.CreateByName("scrap", config.ScrapAmount);
if (item == null) return;
if (player.inventory.GiveItem(item))
{
player.ChatMessage(Msg("Reward", player.UserIDString, config.ScrapAmount));
}
else
{
item.Drop(player.transform.position + UnityEngine.Vector3.up * 0.5f, UnityEngine.Vector3.zero);
player.ChatMessage(Msg("NoRoom", player.UserIDString));
}
}
}
}The plugin grants a small amount of scrap when a player goes to sleep, but only if configured to, and it respects a permission that server owners can give to VIPs. On sleep the hook null-checks the player, checks the toggle and permission, then gives a configured scrap item through inventory.GiveItem. It also sends a localized chat message so the player knows the reward came in. Messages are loaded into the language system, the reward amounts live in a config file, and the permission is registered in Init. Because the player is still connected at this point, chat and inventory calls are safe.
Common use cases
Sleep location logging
Record each player's position the moment they fall asleep so admins can later audit where players left their sleeper bodies, useful against combat logging into unreachable spots.
VIP sleep rewards
Grant a small daily bonus of scrap or a resource to players with a permission when they log off, encouraging the sleep mechanic instead of staying idle.
Sleep-triggered notifications
Notify a server Discord relay or in-game staff chat when a watched player goes to sleep, so moderators know a session just ended.
Pitfalls
Fires only on real transitions
StartSleeping returns early if the player is already sleeping, so repeated sleep commands or calls while asleep will not fire this hook again.
Not the same as a disconnect
The hook fires before the sleeper entity is fully established and does not mean the player is offline; use OnPlayerDisconnected for connection teardown logic.
Avoid heavy work here
Every natural sleep hits this path. Keep logic light and skip any expensive iteration over all players unless you gate it behind a flag.
Build a plugin with OnPlayerSleep
Describe what should happen and get a compiled plugin that uses this hook.
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 OnPlayerSleep
Generate