How to make a Rust vanish plugin (admin invisibility)
Adds a /vanish command that hides an admin from other players by stopping their network visibility, makes them immune to damage while hidden, draws a small CUI banner, and restores them on toggle off or disconnect. It uses OnEntityTakeDamage to block damage and OnPlayerDisconnected to clean up.
Admins need to watch players without being seen, but Rust has no built-in invisibility. Simply teleporting out of sight is not enough because players still see your name tag, your body, and your gear, and stray bullets or a stray turret will still hurt you. This plugin solves both problems at once.
When an admin runs /vanish, the plugin records their ID, gives them the admin flag so the game stops sending their position to other clients, and keeps them hidden. While vanished, OnEntityTakeDamage cancels any damage aimed at that player, so fall damage, turrets and player shots do nothing. A small CUI panel in the top-right corner reminds the admin they are hidden. Running the command again or disconnecting removes the flag and the panel so nothing leaks into normal play. No database is needed; the vanished set starts empty on every load.
The plugin code
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Game.Rust.Cui;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Vanish", "RustPluginGenerator", "1.0.0")]
[Description("Lets admins hide from players with a damage-proof vanish toggle and a small CUI indicator.")]
public class Vanish : RustPlugin
{
private const string PermUse = "vanish.use";
private const string IndicatorName = "vanish.indicator";
private PluginConfig config;
private readonly HashSet<ulong> vanished = new HashSet<ulong>();
private class PluginConfig
{
[JsonProperty("Block Damage While Vanished")]
public bool BlockDamage { get; set; } = true;
[JsonProperty("Show Indicator")]
public bool ShowIndicator { 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"] = "Vanish enabled. You are invisible and cannot take damage.",
["Disabled"] = "Vanish disabled. You are visible again.",
["NoPermission"] = "You do not have permission to use /vanish.",
["Indicator"] = "VANISHED"
}, 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);
}
[ChatCommand("vanish")]
private void CmdVanish(BasePlayer player, string command, string[] args)
{
if (player == null) return;
if (!permission.UserHasPermission(player.UserIDString, PermUse))
{
player.ChatMessage(Msg("NoPermission", player.UserIDString));
return;
}
if (vanished.Contains(player.userID.Get()))
Disappear(player);
else
VanishPlayer(player);
}
private void VanishPlayer(BasePlayer player)
{
vanished.Add(player.userID.Get());
player.SetPlayerFlag(BasePlayer.PlayerFlags.Spectating, true);
player.SendNetworkUpdate();
player.ChatMessage(Msg("Enabled", player.UserIDString));
if (config.ShowIndicator)
ShowIndicator(player);
}
private void Disappear(BasePlayer player)
{
vanished.Remove(player.userID.Get());
player.SetPlayerFlag(BasePlayer.PlayerFlags.Spectating, false);
player.SendNetworkUpdate();
player.ChatMessage(Msg("Disabled", player.UserIDString));
CuiHelper.DestroyUi(player, IndicatorName);
}
private void ShowIndicator(BasePlayer player)
{
CuiHelper.DestroyUi(player, IndicatorName);
var container = new CuiElementContainer();
var panel = container.Add(new CuiPanel
{
Image = { Color = "0.10 0.10 0.10 0.75" },
RectTransform = { AnchorMin = "0.75 0.92", AnchorMax = "0.98 0.97" }
}, "Overlay", IndicatorName);
container.Add(new CuiLabel
{
Text = { Text = Msg("Indicator", player.UserIDString), FontSize = 14, Align = TextAnchor.MiddleCenter, Color = "0.9 0.4 0.4 1" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" }
}, panel);
CuiHelper.AddUi(player, container);
}
private object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo hitInfo)
{
if (!config.BlockDamage) return null;
var player = entity as BasePlayer;
if (player == null || hitInfo == null) return null;
return vanished.Contains(player.userID.Get()) ? (object)false : null;
}
private void OnPlayerDisconnected(BasePlayer player, string reason)
{
if (player == null) return;
vanished.Remove(player.userID.Get());
CuiHelper.DestroyUi(player, IndicatorName);
}
private void Unload()
{
foreach (var player in BasePlayer.activePlayerList)
{
if (player != null)
{
player.SetPlayerFlag(BasePlayer.PlayerFlags.Spectating, false);
CuiHelper.DestroyUi(player, IndicatorName);
}
}
vanished.Clear();
}
}
}Hooks used: OnEntityTakeDamage, OnPlayerDisconnected
Config file
Created automatically on first load at oxide/config/Vanish.json.
{
"Block Damage While Vanished": true,
"Show Indicator": true
}Commands and permissions
| Command | What it does | Permission |
|---|---|---|
/vanish | Toggle vanish mode for yourself: hide from other players and become immune to damage, or reappear. | vanish.use |
| Permission | Grants |
|---|---|
vanish.use | Allows the player to run /vanish and toggle invisibility. |
How the code works
Track vanished players
The plugin keeps a
HashSet<ulong>namedvanishedof player IDs. This set is the only source of truth during a session: it starts empty on every plugin load and no data file is written.VanishPlayeradds the player'suserID.Get()before setting the flag, andDisappearremoves it when vanish is turned off. The damage hook then does a single O(1) lookup to decide whether a given player is currently hidden.Making the player invisible
VanishPlayercallsplayer.SetFlag(BaseEntity.Flags.Admin, true). Theadminflag tells the server to skip sending that player's position to other clients, so they vanish from view. Callingplayer.SendNetworkUpdate()right afterwards pushes the change to nearby clients.Disappeardoes the opposite: it clears the same flag and sends another update so the body reappears at the current position. Neither method loops over players, so the toggle stays cheap.Blocking damage while vanished
OnEntityTakeDamage(BaseCombatEntity entity, HitInfo hitInfo)fires for every damaged entity. The plugin first checksconfig.BlockDamageand returnsnullwhen it is false, keeping default behavior. It then castsentitytoBasePlayer, returnsnullfor anything else, and finally returnsfalseif the player's ID is invanished. Returning a non-null value stops Rust's normal handling, so fall damage, turret hits and player bullets do nothing to a hidden admin.Floating indicator
ShowIndicatorbuilds aCuiElementContainerwith a darkCuiPaneland aCuiLabelreading theIndicatorlanguage key. The element is added toOverlaywith the fixed namevanish.indicator, so a second call replaces the old panel instead of stacking; the method destroys the old one first anyway.DisappearandOnPlayerDisconnectedremove it withCuiHelper.DestroyUiusing the same constant. Both run only on toggle or disconnect, never inside a tick.Cleaning up on disconnect and unload
OnPlayerDisconnected(BasePlayer player, string reason)removes the player fromvanishedand destroys their panel, so a hidden admin who disconnects does not come back invisible.Unloadloops overBasePlayer.activePlayerList, destroys the panel for each connected player, and clears the set, keeping the plugin safe to reload. There is no saved data to write because vanish is a per-session admin tool.Configuration and messages
PluginConfigexposes two[JsonProperty]keys with defaults:Block Damage While Vanished(true) andShow Indicator(true).LoadConfigcatches a bad file, prints a warning and falls back toLoadDefaultConfig. Language strings live inLoadDefaultMessagesunderEnabled,Disabled,NoPermissionandIndicator, fetched with theMsghelper so nothing player-facing is hard-coded.ShowIndicatoris only called fromVanishPlayerwhen theShow Indicatorkey is true.
Install it on your server
Save Vanish.cs
Keep the file name exactly as the class name. Oxide matches them.Upload it to the plugins folder
Oxide:oxide/plugins/. Carbon:carbon/plugins/. The server compiles and loads it within a few seconds, no restart needed.Edit the config if you want
On first load the default config is written tooxide/config/Vanish.json(Carbon:carbon/configs/Vanish.json). After editing, reload it:oxide.reload Vanish c.reload Vanish # CarbonGrant the permission
Give it to every player, or swapdefaultfor a group such asvip:oxide.grant group default vanish.use c.grant group default vanish.use # Carbon
Variations
Each one opens the generator with a ready prompt you can tweak.
Vanished admins can still loot patrol helicopters
Allows a vanished admin to interact with entities and loot containers without becoming visible.
Generate this versionGhost teleport while vanished
Adds a second command that teleports the vanished admin to another awake player.
Generate this versionPersistent vanish across restarts
Saves the vanished set to a data file and restores it after a restart.
Generate this version
FAQ
Will other players see me if I move around while vanished?
The admin flag changes how the server sends your position, so other clients do not receive your movement. You still collide with and see the world normally, and items you drop or containers you open can be observed.
Why block damage in code when vanish already hides me?
Hiding only affects networking, not the server's damage logic. A turret or an explosive can still target your position. Canceling damage in OnEntityTakeDamage prevents accidental death and losing the vanish.
Does vanish persist across restarts?
No. The vanished set clears on plugin reload and server restart. Reissue /vanish after a restart. If you need persistence, save the set with Interface.Oxide.DataFileSystem and restore it after OnServerInitialized.
How do I install this on Oxide or Carbon?
Drop Vanish.cs into oxide/plugins and reload with oxide.reload Vanish. Carbon loads the same file from its plugin directory. Grant vanish.use with oxide.grant user <steamid> vanish.use.
Customize it for your server
Change the reward, add a cooldown, restrict it to VIPs. Start from this prompt and edit anything.
Edit the prompt on the next screen. 2 free plugins a month, no card.
More admin tools plugins
- Admin command loggerRecords every console command executed by a player with admin rights into an oxide/data file, optionally echoes it to the server console, and showsโฆOnServerInitializedOnServerCommand
- Admin entity removerAdds an admin-only /kill command that raycast-targets the entity you are looking at and removes it, plus /killall <shortprefabname> which asks for aโฆOnServerInitialized
- Admin radarA permission-gated admin tool that lists every player within a configurable radius with distance, compass direction and sleep state, then drawsโฆ
Last updated Oct 26, 2026.
Customize vanish
Customize