How to make a Rust no vehicle decay plugin (per-type scaling)
Scales or disables decay damage on minicopters, boats, horses and modular cars per vehicle type, optionally only while inside a tool cupboard radius. It uses OnEntityTakeDamage(BaseCombatEntity, HitInfo).
Vehicles decay when nobody is around, and on a busy server that means admin-spawned minicopters, patrol boats and cars quietly rot away between wipes or get farmed by whoever finds them first. Turning decay off globally in the server's decay settings is all-or-nothing and also affects bases, so the clean approach is a damage hook that only touches decay hits on the vehicle types you name.
This plugin listens to OnEntityTakeDamage for BaseCombatEntity arguments, checks whether the hit is decay damage, and looks up the victim in a map of prefab and class rules. Each rule has a multiplier from 0 (never decays) to 1 (normal) to above 1. An optional tool cupboard rule only protects vehicles that sit inside a building privilege range, so abandoned vehicles in the open still rot. Multipliers are applied by scaling the damage types on the hit, and zero-damage hits are cancelled outright.
The plugin code
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("No Vehicle Decay", "RustPluginGenerator", "1.0.0")]
[Description("Scales or disables decay damage on vehicles per type, optionally only within a tool cupboard range")]
public class NoVehicleDecay : RustPlugin
{
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Require tool cupboard to protect")]
public bool RequireBuildingPrivilege { get; set; } = false;
[JsonProperty("Vehicle rules")]
public Dictionary<string, VehicleRule> Vehicles { get; set; } = new Dictionary<string, VehicleRule>
{
["minicopter.entity"] = new VehicleRule { Multiplier = 0.0f },
["boat.entity"] = new VehicleRule { Multiplier = 0.0f },
["ridablehorse.entity"] = new VehicleRule { Multiplier = 0.0f },
["modularcar.entity"] = new VehicleRule { Multiplier = 0.0f }
};
[JsonProperty("Ignored prefabs")]
public List<string> IgnoredPrefabs { get; set; } = new List<string>();
}
private class VehicleRule
{
[JsonProperty("Decay multiplier (0 = never)")]
public float Multiplier { get; set; } = 0.0f;
}
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);
private object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo hitInfo)
{
if (entity == null || hitInfo == null || hitInfo.damageTypes == null) return null;
if (entity is BasePlayer || entity.IsNpc) return null;
if (hitInfo.damageTypes.GetMajorityDamageType() != Rust.DamageType.Decay) return null;
if (hitInfo.InitiatorPlayer != null) return null;
string prefab = entity.ShortPrefabName;
if (string.IsNullOrEmpty(prefab)) return null;
if (config.IgnoredPrefabs != null && config.IgnoredPrefabs.Contains(prefab)) return null;
VehicleRule rule = ResolveRule(entity, prefab);
if (rule == null) return null;
if (config.RequireBuildingPrivilege && entity.GetBuildingPrivilege() == null) return null;
float multiplier = Mathf.Clamp(rule.Multiplier, 0f, 10f);
if (multiplier <= 0f)
{
hitInfo.damageTypes.ScaleAll(0f);
return true;
}
hitInfo.damageTypes.ScaleAll(multiplier);
return null;
}
private VehicleRule ResolveRule(BaseCombatEntity entity, string prefab)
{
if (config.Vehicles != null)
{
VehicleRule direct;
if (config.Vehicles.TryGetValue(prefab, out direct)) return direct;
foreach (var pair in config.Vehicles)
{
if (string.Equals(pair.Key, prefab, StringComparison.OrdinalIgnoreCase)) return pair.Value;
}
}
string fallback = ClassKey(entity);
if (fallback == null) return null;
if (config.Vehicles != null && config.Vehicles.TryGetValue(fallback, out var found)) return found;
return new VehicleRule { Multiplier = 0.0f };
}
private string ClassKey(BaseEntity entity)
{
if (entity == null) return null;
string prefab = entity.ShortPrefabName;
if (string.IsNullOrEmpty(prefab)) return null;
if (prefab.Contains("minicopter")) return "minicopter.entity";
if (prefab.Contains("boat")) return "boat.entity";
if (prefab.Contains("ridablehorse")) return "ridablehorse.entity";
if (prefab.Contains("modularcar")) return "modularcar.entity";
return null;
}
}
}Hooks used: OnEntityTakeDamage
Config file
Created automatically on first load at oxide/config/NoVehicleDecay.json.
{
"Require tool cupboard to protect": false,
"Vehicle rules": {
"minicopter.entity": {
"Decay multiplier (0 = never)": 0
},
"boat.entity": {
"Decay multiplier (0 = never)": 0
},
"ridablehorse.entity": {
"Decay multiplier (0 = never)": 0
},
"modularcar.entity": {
"Decay multiplier (0 = never)": 0
}
},
"Ignored prefabs": []
}How the code works
Intercepting decay hits
object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo hitInfo)fires for every hit on a combat entity. The plugin ignores players, NPCs, null info and nulldamageTypes, then checkshitInfo.damageTypes.GetMajorityDamageType() == Rust.DamageType.Decay. Only decay hits continue; everything else returnsnullso vanilla handling is untouched. A multiplier of0callsScaleAll(0f)and returnstrueto stop the hit.Matching the vehicle
ResolveRulefirst checks the entity'sShortPrefabNameagainst theVehiclesconfig keys, first exact and then case-insensitive, so you can add prefabs likeminicopter.entitywithout recompiling. If no prefab key matches,ClassKeyinspects the sameShortPrefabNamefor the substringsminicopter,boat,ridablehorseandmodularcarand returns the matching key such asminicopter.entity. If that fallback key is not present inVehicles, the plugin returns a default rule with multiplier0.0, so the decay is still disabled. IfClassKeyreturnsnull(no substring matches), the decay is left untouched.Applying the multiplier
When a rule matches,
hitInfo.damageTypes.ScaleAllmultiplies the whole damage list by the configured factor, clamped to between0and10. A factor of0callsScaleAll(0f)and returnstrueso the hit is not processed further. Values between 0 and 1 slow decay, and values above 1 accelerate it, which is useful for cleaning up abandoned vehicles faster than vanilla.Tool cupboard requirement
When
RequireBuildingPrivilegeis enabled (it defaults tofalse), the plugin skips any vehicle whoseGetBuildingPrivilege()returns null. That means only vehicles parked within a cupboard's radius are protected, and a spawn-zone or roadside vehicle still decays normally. Enable it on PvE and RP servers where players park vehicles next to their bases rather than in the open.Ignore list and player contact
The
IgnoredPrefabslist holds exactShortPrefabNamevalues that bypass the hook completely, useful for siege vehicles or event entities. Separately, ifhitInfo.InitiatorPlayeris set the plugin returns early, so a player deliberately damaging a vehicle never benefits from your multiplier. Both checks happen before the rule lookup, so they win over any config entry.Config loading and reload
LoadDefaultConfigbuilds aPluginConfigwith default rules forminicopter.entity,boat.entity,ridablehorse.entityandmodularcar.entity, all with multiplier0.LoadConfigre-reads the file, catches malformed JSON with a warning, and writes the file back throughSaveConfig. Because rules are read on every hit through the cachedconfigfield, editing the config on disk and reloading the plugin takes effect immediately with no restart.
Install it on your server
Save NoVehicleDecay.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/NoVehicleDecay.json(Carbon:carbon/configs/NoVehicleDecay.json). After editing, reload it:oxide.reload NoVehicleDecay c.reload NoVehicleDecay # Carbon
Variations
Each one opens the generator with a ready prompt you can tweak.
Only protect vehicles owned by players
Skip the multiplier when the vehicle has no OwnerID, so admin-spawned free vehicles still decay.
Generate this versionChat command to list vehicle rules
Useful when debugging a config where a prefab is matched by the wrong rule.
Generate this versionAnnounce decay to the owner
Warn the owner when a vehicle is about to decay so they can repair it.
Generate this version
FAQ
Does this stop vehicle decay when nobody is online?
Yes. Decay damage is applied by the server whenever the vehicle is unparked, and the hook runs regardless of who is connected. With a multiplier of 0 the damage is cancelled, so the vehicle stays at full health between wipes. With RequireBuildingPrivilege enabled, only vehicles inside a tool cupboard's range are protected.
Why does my modular car still decay?
Check IgnoredPrefabs first, then confirm the prefab name. The plugin first looks up Vehicles by exact ShortPrefabName, then case-insensitively, then falls back to substring matching on ShortPrefabName for minicopter, boat, ridablehorse and modularcar. If the fallback key (e.g. modularcar.entity) is absent from Vehicles, the default rule of 0.0 still applies, so a car usually stops decaying unless its prefab is on the ignore list.
Can I scale decay above 1?
Yes. Any value above 1 multiplies the decay damage, so abandoned vehicles destroy themselves faster. This is useful on PvP servers that want fewer free vehicles lying around while still protecting vehicles parked at bases through the tool cupboard rule. Values are clamped between 0 and 10.
How do I install it on Oxide or Carbon?
Drop the compiled .cs file into oxide/plugins, restart or reload the server, then edit oxide/config/NoVehicleDecay.json and run oxide.reload NoVehicleDecay. Carbon loads the same Oxide file, so no conversion is needed.
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 vehicles plugins
- Car spawn commandAdds a /car command that spawns a modular car with configured modules in front of the player, enforcing a permission, a spawn cooldown and a strictโฆOnEntityKill
- Horse spawn commandAdds a /horse command that spawns a ridable horse beside the player, tracks one horse per player, removes that player's previous horse and enforcesโฆOnServerInitializedOnEntityKill
- Unlimited vehicle fuelStops fuel drain on vehicles driven by players with a permission, limited to the vehicle types listed in config.OnFuelConsume
Last updated Oct 26, 2026.
Customize no vehicle decay
Customize