Skip to content
RustPluginGenerator

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

Vanish.cs
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.

Vanish.json
{
  "Block Damage While Vanished": true,
  "Show Indicator": true
}

Commands and permissions

Chat and console commands
CommandWhat it doesPermission
/vanishToggle vanish mode for yourself: hide from other players and become immune to damage, or reappear.vanish.use
Permissions
PermissionGrants
vanish.useAllows the player to run /vanish and toggle invisibility.

How the code works

  1. Track vanished players

    The plugin keeps a HashSet<ulong> named vanished of 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. VanishPlayer adds the player's userID.Get() before setting the flag, and Disappear removes 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.

  2. Making the player invisible

    VanishPlayer calls player.SetFlag(BaseEntity.Flags.Admin, true). The admin flag tells the server to skip sending that player's position to other clients, so they vanish from view. Calling player.SendNetworkUpdate() right afterwards pushes the change to nearby clients. Disappear does 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.

  3. Blocking damage while vanished

    OnEntityTakeDamage(BaseCombatEntity entity, HitInfo hitInfo) fires for every damaged entity. The plugin first checks config.BlockDamage and returns null when it is false, keeping default behavior. It then casts entity to BasePlayer, returns null for anything else, and finally returns false if the player's ID is in vanished. Returning a non-null value stops Rust's normal handling, so fall damage, turret hits and player bullets do nothing to a hidden admin.

  4. Floating indicator

    ShowIndicator builds a CuiElementContainer with a dark CuiPanel and a CuiLabel reading the Indicator language key. The element is added to Overlay with the fixed name vanish.indicator, so a second call replaces the old panel instead of stacking; the method destroys the old one first anyway. Disappear and OnPlayerDisconnected remove it with CuiHelper.DestroyUi using the same constant. Both run only on toggle or disconnect, never inside a tick.

  5. Cleaning up on disconnect and unload

    OnPlayerDisconnected(BasePlayer player, string reason) removes the player from vanished and destroys their panel, so a hidden admin who disconnects does not come back invisible. Unload loops over BasePlayer.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.

  6. Configuration and messages

    PluginConfig exposes two [JsonProperty] keys with defaults: Block Damage While Vanished (true) and Show Indicator (true). LoadConfig catches a bad file, prints a warning and falls back to LoadDefaultConfig. Language strings live in LoadDefaultMessages under Enabled, Disabled, NoPermission and Indicator, fetched with the Msg helper so nothing player-facing is hard-coded. ShowIndicator is only called from VanishPlayer when the Show Indicator key is true.

Install it on your server

  1. Save Vanish.cs

    Keep the file name exactly as the class name. Oxide matches them.
  2. 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.
  3. Edit the config if you want

    On first load the default config is written to oxide/config/Vanish.json (Carbon: carbon/configs/Vanish.json). After editing, reload it:oxide.reload Vanish c.reload Vanish # Carbon
  4. Grant the permission

    Give it to every player, or swap default for a group such as vip: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 version
  • Ghost teleport while vanished

    Adds a second command that teleports the vanished admin to another awake player.

    Generate this version
  • Persistent 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.

Prompt: Create a Rust Oxide vanish plugin with a /vanish command, permission vanish.use, a damage-block hook, a top-right CUI indicator, config keys for damage block and indicator, and cleanup on disconnect and unload.
Customize for my server

Edit the prompt on the next screen. 2 free plugins a month, no card.

Last updated Oct 26, 2026.

Customize vanish

Customize