OnThreatLevelUpdate
OnThreatLevelUpdate is called by BasePlayer.EnsureUpdated when the game is about to recompute a player's cached threat level from their worn clothing. Returning a non-null value skips the recalculation and leaves the cached value at zero.
object OnThreatLevelUpdate(BasePlayer player)Parameters
| Parameter | Type | Description |
|---|---|---|
player | BasePlayer | The BasePlayer whose cached threat level is being recalculated. It is never null at this point, but the player may be sleeping or disconnected. |
Return value
Returning null (or letting the method fall through) lets the game recalculate and cache the threat level from worn gear. Returning any non-null object stops EnsureUpdated immediately, so cachedThreatLevel remains at 0 and the player is treated as non-threatening.
How it works
The hook fires inside BasePlayer.EnsureUpdated, before the game reads inventory.containerWear to work out how threatening the player looks to NPCs (scientists, animals, and similar AI). EnsureUpdated is only reached when the player has not been updated since the last timestamp, so it runs periodically rather than every tick. Note that EnsureUpdated returns early before the hook when the player IsSleeping(), so sleeping players never trigger it. The single argument is the player being evaluated; use it to read equipment, team, position or permissions. Declaring the parameter as BasePlayer is the only meaningful form here since the game already passes that exact type. Returning null lets Rust compute and cache the normal threat value. Returning anything non-null aborts the whole method before the cache is filled, which effectively forces the threat level to stay at the zero value set just above the hook.
Example plugin: Keep members of a permission group non-threatening to NPCs
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("Passive Threat Group", "RustPluginGenerator", "1.0.0")]
[Description("Lets permitted players stay non-threatening to NPCs by skipping the threat level calculation.")]
public class PassiveThreatGroup : RustPlugin
{
private const string PermUse = "passivethreatgroup.use";
private PluginConfig config;
private static readonly object StealthResult = new object();
private class PluginConfig
{
[JsonProperty("Enable stealth when permission is held")]
public bool EnableStealth { 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>
{
["Enabled"] = "Passive mode enabled. NPCs will treat you as non-threatening.",
["Disabled"] = "Passive mode disabled. Your threat level is calculated normally.",
["Usage"] = "Usage: /passive to toggle passive mode."
}, 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 OnThreatLevelUpdate(BasePlayer player)
{
if (!config.EnableStealth || player == null || player.IsNpc)
return null;
if (!permission.UserHasPermission(player.UserIDString, PermUse))
return null;
return StealthResult;
}
[ChatCommand("passive")]
private void CmdPassive(BasePlayer player, string command, string[] args)
{
if (player == null)
return;
if (!config.EnableStealth)
{
SendReply(player, Msg("Disabled", player.UserIDString));
return;
}
if (permission.UserHasPermission(player.UserIDString, PermUse))
{
permission.RevokeUserPermission(player.UserIDString, PermUse);
SendReply(player, Msg("Disabled", player.UserIDString));
}
else
{
permission.GrantUserPermission(player.UserIDString, PermUse, this);
SendReply(player, Msg("Enabled", player.UserIDString));
}
}
}
}The plugin registers a permission and a config toggle. Each time OnThreatLevelUpdate fires, EnsureUpdated is about to derive a threat value from the player's clothing, so the plugin checks whether the player holds the passive permission. If stealth mode is enabled and the player is authorised, the hook returns a non-null placeholder object, which aborts the recalculation and leaves the cached threat level at zero. Players without the permission get null, so their threat is computed normally from armour and clothing. /passive lets players toggle their own membership through the permission API, and every change is reported back through the language file.
Common use cases
Stealth perks for donors
Give a paid or trusted group reduced NPC aggression by returning a non-null value so their threat cache stays empty.
Disguise systems
When a player wears a specific outfit and holds a permission, suppress their computed threat so scientists treat them as harmless.
PvE-friendly zones
Combine with position checks to keep players in a designated safe area from being flagged as threats to wandering animals.
Pitfalls
Zero threat means zero, not controlled
Returning non-null skips the entire calculation, so
cachedThreatLevelstays at 0 rather than the specific value you might want. You cannot set an intermediate threat level with this hook.Sleeping players are skipped
EnsureUpdatedreturns before the hook when the player is sleeping, so a returned value never applies to offline or sleeping players until they wake and refresh again.Do not waste hot-path work
The hook can fire repeatedly as the player is re-evaluated, so keep the body to cheap permission checks and avoid logging or allocations inside it.
Build a plugin with OnThreatLevelUpdate
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 OnThreatLevelUpdate
Generate