How to make a Rust god mode plugin (damage immunity + full needs)
Adds a permission-gated /god toggle that blocks all damage through OnEntityTakeDamage and keeps health, food and water topped up from a repeating timer. State is dropped in OnPlayerDisconnected.
Server owners and moderators routinely need a damage-free state while inspecting builds, testing events or mediating disputes. Vanilla Rust has no per-user, permission-aware immunity, and nothing that also stops hunger and thirst from draining.
This plugin solves that with one hook and one timer. The OnEntityTakeDamage overload is declared for BasePlayer, so Oxide only calls it for players; if the player's user ID is in the tracked set, the hook zeroes out the damage list and reports the hit as handled. A repeating timer keeps health, metabolism.calories and metabolism.hydration at maximum while god mode is on, so an AFK admin does not starve or come back wounded. OnPlayerDisconnected removes the player from the set so the state never survives a reconnect. The toggle is a chat command behind a permission, and the permission is also re-checked in the damage hook and the timer, so revoking it disables protection at the next damage event.
The plugin code
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("God Mode", "RustPluginGenerator", "1.0.0")]
[Description("Permission-based damage immunity that also keeps health, food and water full")]
public class GodMode : RustPlugin
{
private const string PermUse = "godmode.use";
private PluginConfig config;
private readonly HashSet<ulong> protectedPlayers = new HashSet<ulong>();
private Timer healTimer;
private class PluginConfig
{
[JsonProperty("Permission")]
public string Permission { get; set; } = PermUse;
[JsonProperty("Top up interval in seconds")]
public float HealInterval { get; set; } = 1f;
}
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"] = "God mode enabled. You are now immune to damage.",
["Disabled"] = "God mode disabled.",
["NoPermission"] = "You do not have permission to use this command."
}, 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(config.Permission, this);
}
private void OnServerInitialized()
{
if (healTimer != null) healTimer.Destroy();
healTimer = timer.Every(Math.Max(0.25f, config.HealInterval), TopUp);
}
private void Unload()
{
if (healTimer != null) healTimer.Destroy();
healTimer = null;
protectedPlayers.Clear();
}
[ChatCommand("god")]
private void CmdGod(BasePlayer player, string command, string[] args)
{
if (player == null) return;
if (!permission.UserHasPermission(player.UserIDString, config.Permission))
{
SendReply(player, Msg("NoPermission", player.UserIDString));
return;
}
ulong id = player.userID.Get();
if (protectedPlayers.Contains(id))
{
protectedPlayers.Remove(id);
SendReply(player, Msg("Disabled", player.UserIDString));
return;
}
protectedPlayers.Add(id);
TopUp(player);
SendReply(player, Msg("Enabled", player.UserIDString));
}
private object OnEntityTakeDamage(BasePlayer player, HitInfo hitInfo)
{
if (player == null || hitInfo == null) return null;
if (!protectedPlayers.Contains(player.userID.Get())) return null;
if (!permission.UserHasPermission(player.UserIDString, config.Permission)) return null;
hitInfo.damageTypes?.ScaleAll(0f);
return true;
}
private void OnPlayerDisconnected(BasePlayer player, string reason)
{
if (player == null) return;
if (protectedPlayers.Remove(player.userID.Get()))
{
Puts($"{player.displayName} ({player.UserIDString}) lost god mode on disconnect");
}
}
private void TopUp()
{
if (protectedPlayers.Count == 0) return;
foreach (ulong id in new List<ulong>(protectedPlayers))
{
BasePlayer player = BasePlayer.FindByID(id);
if (player == null || !player.IsConnected) continue;
if (!permission.UserHasPermission(player.UserIDString, config.Permission))
{
protectedPlayers.Remove(id);
continue;
}
TopUp(player);
}
}
private void TopUp(BasePlayer player)
{
if (player == null || player.metabolism == null) return;
if (player.health < player.MaxHealth())
player.health = player.MaxHealth();
player.metabolism.calories.value = player.metabolism.calories.max;
player.metabolism.hydration.value = player.metabolism.hydration.max;
player.metabolism.SendChanges();
}
}
}Hooks used: OnServerInitialized, OnEntityTakeDamage, OnPlayerDisconnected
Config file
Created automatically on first load at oxide/config/GodMode.json.
{
"Permission": "godmode.use",
"Top up interval in seconds": 1
}Commands and permissions
| Command | What it does | Permission |
|---|---|---|
/god | Toggles damage immunity for yourself. Prints the new state in chat. | godmode.use |
| Permission | Grants |
|---|---|
godmode.use | Grants access to the /god command and the damage immunity it applies |
How the code works
Track who is protected
The plugin keeps a
HashSet<ulong>namedprotectedPlayersof user IDs that currently have god mode on. Both the damage hook and the top-up timer check that set first, so a player who never toggled it costs one hash lookup per incoming hit. Because the set is keyed byplayer.userID.Get(), it survives respawns within a session without extra bookkeeping, and the entry is only removed by/godagain or by a disconnect.Cancel damage in OnEntityTakeDamage
The hook is declared as
object OnEntityTakeDamage(BasePlayer player, HitInfo hitInfo). Oxide only calls a hook method when every argument matches the declared parameter type, so declaringBasePlayermeans structures, vehicles and NPC damage never reach this code. Inside, the body returnsnullwhenhitInfois null or the ID is not inprotectedPlayers. Otherwise it callshitInfo.damageTypes?.ScaleAll(0f)and returnstrue, which tells Oxide the damage was handled.Keep health, food and water full
OnServerInitializedstarts a singletimer.Everycallback namedTopUpat the interval from the config, storing it in thehealTimerfield.TopUp()iterates a copy ofprotectedPlayers, resolves each ID withBasePlayer.FindByID, skips disconnected players, and drops IDs whose owner no longer holds the permission. The single-player overload then clampsplayer.healthtoplayer.MaxHealth()and writesplayer.metabolism.calories.valueandplayer.metabolism.hydration.valueup to their maximums, followed bySendChangesToPlayer.Toggle with permission checks
[ChatCommand("god")]is the only player-facing entry point. It readsplayer.UserIDString, compares it withpermission.UserHasPermissionagainst the permission stored in config, and replies with theNoPermissionlanguage key when it fails. On enable it addsplayer.userID.Get()to the set, callsTopUp(player)immediately so the player is full straight away, and sends theEnabledmessage. On disable it removes the ID and sendsDisabled, leaving current health untouched.Clear state on disconnect
OnPlayerDisconnected(BasePlayer player, string reason)callsprotectedPlayers.Remove(player.userID.Get()). If the removal returns true the plugin writes aPutsline naming the player, so staff can see in console when protection was dropped by a kick, crash or normal logout. This guarantees a stale entry never survives a reconnect, and keeps the top-up loop small on populated servers.Language and configuration
All player text lives in
LoadDefaultMessagesas a dictionary keyed byEnabled,DisabledandNoPermission, resolved through theMsghelper andlang.GetMessage. ThePluginConfigclass has two[JsonProperty]fields:Permission(defaultgodmode.use) andTop up interval in seconds(default1.0).LoadConfigfalls back to defaults and prints a warning if the file cannot be parsed,SaveConfigwrites it back, andInitregisters whatever permission string the config holds.
Install it on your server
Save GodMode.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/GodMode.json(Carbon:carbon/configs/GodMode.json). After editing, reload it:oxide.reload GodMode c.reload GodMode # CarbonGrant the permission
Give it to every player, or swapdefaultfor a group such asvip:oxide.grant group default godmode.use c.grant group default godmode.use # Carbon
Variations
Each one opens the generator with a ready prompt you can tweak.
Timed god mode
Grants immunity for a fixed number of seconds instead of until toggled off.
Generate this versionGod mode for teams
Lets a permission holder apply god mode to every member of their Steam team.
Generate this versionGhost god mode
Adds invisibility and no-collision alongside the damage immunity for event setup.
Generate this version
FAQ
Does god mode stop fall damage and radiation too?
Yes. The hook zeroes the whole DamageTypeList with ScaleAll(0f), and fall, radiation, bleed, heat and explosion all route through the same damage pipeline. Bleeding stacks already applied before the toggle will stop dealing damage, though the indicator may still show until the wound expires naturally.
What happens if I revoke the permission while a player is in god mode?
Both the damage hook and the top-up loop call permission.UserHasPermission again on every pass. Protection ends at the next damage event and the ID is dropped from the set at the next timer tick, so health and needs stop being forced. Run /god from a second account with the node to turn it off cleanly.
Can a god-mode player still be killed by staff?
Yes. A direct call such as player.Kill() does not pass through OnEntityTakeDamage, so entity kill paths and standard admin tools still work. Keep the bypass to those direct paths rather than adding more conditions to the damage hook.
How do I install this on Oxide or Carbon?
Drop GodMode.cs into oxide/plugins, then run oxide.reload GodMode from console or RCON. Carbon reads the same file from the same folder. Grant godmode.use with oxide.grant user <name> godmode.use, then use /god in chat.
Will the timer cost performance on a full server?
TopUp runs once per interval and iterates a copy of protectedPlayers, normally a few staff accounts. Each entry is a FindByID lookup plus a handful of field writes; there is no entity scan and no per-tick work, so the cost is negligible at any population.
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 god mode
Customize