CanNpcEat
CanNpcEat is called from BaseNpc.WantsToEat when an NPC evaluates whether a nearby entity is worth eating. Returning a bool overrides the NPC's own trait and food logic.
object CanNpcEat(BaseNpc npc, BaseEntity best)Parameters
| Parameter | Type | Description |
|---|---|---|
npc | BaseNpc | The BaseNpc instance that is deciding whether to eat. Cast it to a specific NPC type (BaseAnimalNPC, ScientistNPC, ScarecrowNPC) when you only care about certain NPCs. |
best | BaseEntity | The BaseEntity the NPC is considering as food. Usually a dropped item, corpse or food box; check its traits or cast it to compare against what your plugin allows. |
Return value
Return null to let Rust run its normal WantsToEat logic (trait checks and food matching). Return a bool to skip that logic entirely: true makes the NPC treat the entity as food and start moving to eat it, false makes it reject the entity.
How it works
The hook fires inside BaseNpc.WantsToEat(BaseEntity best), the method the animal and NPC brain uses to test a candidate entity before moving to it to eat. Rust calls it during NPC AI scans of nearby entities, so it can fire frequently for wild animals such as bears, wolves, boars and chickens, and for any custom or modded NPC that inherits BaseNpc.
npc is the entity doing the evaluation, best is the candidate. In vanilla logic the method first checks whether best has the Food trait, so a dropped food item, a corpse or a food box can all reach the hook. Because best is only a BaseEntity, you can inspect ShortPrefabName, cast to DroppedItem / LootableCorpse / BaseOven, or compare against a whitelist of prefabs.
You can narrow dispatch by declaring a more specific first parameter, for example BaseAnimalNPC or ScientistNPC. Oxide only calls your method when every argument matches the declared parameter type, so a narrower type keeps the hook from firing for unrelated NPCs. Returning null leaves the vanilla decision untouched, which is the safe default for a plugin that only wants to veto specific cases.
Example plugin: Stop bears and wolves from eating player food drops
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("NoAnimalFoodTheft", "RustPluginGenerator", "1.0.0")]
[Description("Prevents configured NPCs from eating protected dropped food items and food containers.")]
public class NoAnimalFoodTheft : RustPlugin
{
private const string PermBypass = "noanimalfoodtheft.bypass";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Blocked NPC prefabs")]
public List<string> BlockedNpcs = new List<string> { "bear", "wolf", "boar", "chicken", "stag", "horse" };
[JsonProperty("Protected item shortnames")]
public List<string> ProtectedItems = new List<string> { "bearmeat", "wolfmeat", "chicken", "cookedmeat", "can_beans", "chocolate" };
[JsonProperty("Protected container prefabs")]
public List<string> ProtectedContainers = new List<string> { "box.wooden", "fridge", "foodbox" };
}
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 void Init()
{
permission.RegisterPermission(PermBypass, this);
}
private bool IsBlockedNpc(string prefab)
{
if (string.IsNullOrEmpty(prefab)) return false;
foreach (var p in config.BlockedNpcs)
if (prefab.StartsWith(p, StringComparison.OrdinalIgnoreCase)) return true;
return false;
}
private bool HoldsProtectedItem(ItemContainer container)
{
if (container?.itemList == null) return false;
foreach (var item in container.itemList)
{
if (item?.info == null) continue;
if (config.ProtectedItems.Contains(item.info.shortname)) return true;
}
return false;
}
private object CanNpcEat(BaseNpc npc, BaseEntity best)
{
if (npc == null || best == null || best.IsDestroyed) return null;
if (!IsBlockedNpc(npc.ShortPrefabName)) return null;
var dropped = best as DroppedItem;
if (dropped?.item?.info != null && config.ProtectedItems.Contains(dropped.item.info.shortname))
return false;
var corpse = best as LootableCorpse;
if (corpse != null && HoldsProtectedItem(corpse.containers?[0]) && !IsPlayerLootable(corpse))
return false;
var container = best as StorageContainer;
if (container != null && HoldsProtectedItem(container.inventory))
return false;
return null;
}
private bool IsPlayerLootable(LootableCorpse corpse)
{
var owner = corpse.OwnerID;
if (owner == 0) return false;
var player = BasePlayer.FindByID(owner);
return player != null && permission.UserHasPermission(player.UserIDString, PermBypass);
}
}
}The plugin keeps a per-prefab list, configurable in oxide/config/NoAnimalFoodTheft.json, of NPC prefabs that should not be allowed to eat. CanNpcEat first checks that a config rule applies, then checks whether the candidate entity is a dropped item or a loot container holding one of the protected food shortnames. When both match, it returns false and the animal skips the food and wanders on. Returning null in every other case keeps vanilla eating behavior for bears, wolves, boars and scientists. The settings are read on load and re-read when the config file is reloaded, so admins can tune the list without recompiling.
Common use cases
Protect player loot from animals
Return
falsewhen the candidate is a dropped item or food box that players would rather keep, so bears and boars stop walking off with it.Restrict diet for custom NPCs
Declare
BaseNpcand returnfalsefor your own spawned NPC prefabs unless the candidate matches a shortname whitelist you configured.Force NPCs to eat specific bait
Return
truewhenbestis a prefab you placed as bait, so animals are lured to it regardless of the food trait the vanilla check looks for.
Pitfalls
The hook fires often
WantsToEatruns during AI scans. Keep the callback cheap: noPuts, noPrintWarning, no per-call config writes, and cache parsed prefab lists at load time.Returning true bypasses trait checks
A
truereturn makes the NPC accept the entity even if it lacks the Food trait. If you force acceptance of arbitrary prefabs, the NPC may path to something it cannot actually consume.Narrow parameter types skip other NPCs
Declaring
BaseAnimalNPCmeans Oxide will not call your method for ScientistNPC or other BaseNpc subclasses. If you need both, keep the parameter asBaseNpcand branch inside.
Build a plugin with CanNpcEat
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 CanNpcEat
Generate