OnPlayerVanish
OnPlayerVanish is called when a player uses the server debugging invis command to turn themselves invisible, before the hiding logic runs. Returning a non-null value cancels the vanish.
object OnPlayerVanish(BasePlayer player)Parameters
| Parameter | Type | Description |
|---|---|---|
player | BasePlayer | The BasePlayer who is about to become invisible. Use it to check identity, permissions, team, or position before deciding whether to allow the vanish. |
Return value
Returning a non-null value stops the original command before it hides the player, so the vanish is cancelled and the player stays visible. Returning null (the normal case) lets the invisibility code run as usual. The return value is only tested for null, so any non-null object works.
How it works
The hook fires inside ConVar.Debugging.invis when the command is used to enable invisibility, and only on the branch where the player is currently visible and the requested value is true. It does not run when a player makes themselves visible again, and it does not fire for any other way of hiding a player.
The single player argument is the BasePlayer who issued the command. Because the injection happens before the code that hides the player from subscribers, anything you change here (teleporting, sending a message, recording a timestamp) takes effect immediately and the visibility update happens afterwards.
The injection passes the argument as a BasePlayer, so declaring the parameter as BasePlayer is the only sensible choice. There is no benefit to narrowing it further.
On a normal production server the invis command is admin-only, so this hook mainly matters for admin tools: logging stealth use, blocking it in arenas, or pairing it with your own vanish feature. Store a flag in a dictionary keyed by user ID if you need to know later that the player is invisible; this hook alone gives you only the transition into invisibility.
Example plugin: Restrict and log admin vanish
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("VanishRestrict", "RustPluginGenerator", "1.0.0")]
[Description("Restricts and logs the use of the admin invis command.")]
public class VanishRestrict : RustPlugin
{
private const string PermUse = "vanishrestrict.use";
private PluginConfig config;
private VanishLog logData;
private class PluginConfig
{
[JsonProperty("Broadcast vanish use to online admins")]
public bool BroadcastToAdmins { get; set; } = true;
[JsonProperty("Keep in-memory log on unload")]
public bool PersistLog { get; set; } = true;
}
private class VanishLog
{
[JsonProperty("Entries")]
public List<VanishEntry> Entries { get; set; } = new List<VanishEntry>();
}
private class VanishEntry
{
[JsonProperty("User ID")]
public string UserId { get; set; }
[JsonProperty("Name")]
public string Name { get; set; }
[JsonProperty("Time UTC")]
public string TimeUtc { get; set; }
}
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>
{
["NoPermission"] = "You are not allowed to vanish on this server.",
["VanishUsed"] = "{0} vanished.",
["LogSaved"] = "Saved {0} vanish entries to vanishrestrict.log"
}, 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 void OnServerInitialized()
{
logData = Interface.Oxide.DataFileSystem.ReadObject<VanishLog>("vanishrestrict.log");
if (logData == null || logData.Entries == null)
logData = new VanishLog();
}
private object OnPlayerVanish(BasePlayer player)
{
if (player == null)
return null;
if (!permission.UserHasPermission(player.UserIDString, PermUse))
{
player.ChatMessage(Msg("NoPermission", player.UserIDString));
return false;
}
if (logData != null)
{
logData.Entries.Add(new VanishEntry
{
UserId = player.UserIDString,
Name = player.displayName,
TimeUtc = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss")
});
}
if (config.BroadcastToAdmins)
{
foreach (BasePlayer target in BasePlayer.activePlayerList)
{
if (target != null && target.IsAdmin && target.IsConnected)
target.ChatMessage(Msg("VanishUsed", target.UserIDString, player.displayName));
}
}
return null;
}
private void Unload()
{
if (!config.PersistLog || logData == null)
return;
Interface.Oxide.DataFileSystem.WriteObject("vanishrestrict.log", logData);
}
}
}The plugin checks the vanishrestrict.use permission whenever a player runs the invis command. If the player lacks it, the hook returns a non-null value, which cancels the vanish, and sends them a chat message from the language file. When allowed, it records the player's user ID and display name in a vanishrestrict.log data file under oxide/data, sends the admins a broadcast, and returns null so the game hides the player normally. The data file is loaded in OnServerInitialized and written when the plugin unloads, giving server owners a simple audit trail of who used stealth. All player-facing text is pulled from lang, so the messages can be translated or edited without recompiling.
Common use cases
Permission-gated vanish
Only allow the invis command for players holding a specific permission by returning a non-null value for everyone else. This keeps regular admins from hiding from other staff unnoticed.
Audit log of stealth usage
Record user ID, name, and time in a data file each time a player vanishes, so you can review abuse or investigate reports of invisible players.
Combat and event zones
Block vanishing while a player is inside an arena or carries loot, keeping a specific game mode fair.
Pitfalls
Only the enable path fires
The hook is not called when the player turns invisibility off or when the value is already true. Do not use it as a full state tracker on its own.
Returning true does not force vanish
The return value is only checked for null. Returning true cancels the command just like returning false; you cannot use it to force invisibility.
Admin command only
Invis is a server debugging command restricted to admins. Blocking it for non-admins has no effect because they cannot run it in the first place.
Build a plugin with OnPlayerVanish
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 OnPlayerVanish
Generate