OnCowMilked
OnCowMilked is called after a player successfully milks a genetically modified Cow (Rust.Ai.Gen2.Cow), right after the milk item is handed to the player. It does not fire when milking fails or the cooldown is still active.
void OnCowMilked(Rust.Ai.Gen2.Cow cow, BasePlayer player, Item item)Parameters
| Parameter | Type | Description |
|---|---|---|
cow | Rust.Ai.Gen2.Cow | The Cow entity that was milked. Use it for position checks, effects or to reference the animal later. |
player | BasePlayer | The BasePlayer who completed the milking and received the milk item. |
item | Item | The milk Item that was just given to the player. It is already in the player's inventory when the hook fires. |
Return value
The return value is ignored; the hook cannot block milking or alter the item. TryMilk still returns true and the cooldown starts regardless of what your handler returns.
How it works
The hook fires inside Rust.Ai.Gen2.Cow.TryMilk after the game has handed the produced milk item to the player and played the milk effect. It runs before the internal milk cooldown timer is started. Triggering it requires a player to interact with a live Gen2 Cow while it is not on cooldown.
cow is the animal that was milked, useful for its position, ownership or to award bonuses near a base. player is the milker and can be checked for permissions, teams or building privilege. item is the exact milk item that was given, so you can read its amount and skin.
Declaring more specific types does not help here; the parameters are already concrete. This hook is a post-action notification, so it cannot cancel the milking. If you need to modify the milk before it reaches the player, adjust or remove the item after the fact. Keep the handler light: it runs every time a player finishes milking, which can be frequent on large farms.
Example plugin: Reward players with bonus milk based on permission
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Cow Milk Bonus", "RustPluginGenerator", "1.0.0")]
[Description("Grants extra milk to players with a permission and tracks milk production.")]
public class CowMilkBonus : RustPlugin
{
private const string PermBonus = "cowmilkbonus.vip";
private const string PermStats = "cowmilkbonus.stats";
private PluginConfig config;
private Dictionary<string, int> milkStats;
private class PluginConfig
{
[JsonProperty("Bonus milk per milking")]
public int BonusAmount = 1;
[JsonProperty("Max milk per grant")]
public int MaxPerGrant = 5;
}
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>
{
["Bonus"] = "You received {0} extra milk from the cow.",
["Stats"] = "You have milked {0} cows this wipe.",
["NoStats"] = "You have not milked any cows yet."
}, 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(PermBonus, this);
permission.RegisterPermission(PermStats, this);
milkStats = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, int>>(Name) ?? new Dictionary<string, int>();
}
private void Unload()
{
Interface.Oxide.DataFileSystem.WriteObject(Name, milkStats);
}
[ChatCommand("milkstats")]
private void CmdMilkStats(BasePlayer player, string command, string[] args)
{
if (player == null) return;
if (!permission.UserHasPermission(player.UserIDString, PermStats))
{
SendReply(player, Msg("NoStats", player.UserIDString));
return;
}
int count;
milkStats.TryGetValue(player.UserIDString, out count);
SendReply(player, count > 0 ? Msg("Stats", player.UserIDString, count) : Msg("NoStats", player.UserIDString));
}
private void OnCowMilked(Rust.Ai.Gen2.Cow cow, BasePlayer player, Item item)
{
if (player == null || item == null || cow == null) return;
int count;
milkStats.TryGetValue(player.UserIDString, out count);
milkStats[player.UserIDString] = count + 1;
if (!permission.UserHasPermission(player.UserIDString, PermBonus)) return;
int amount = Mathf.Clamp(config.BonusAmount, 1, config.MaxPerGrant);
var bonus = ItemManager.CreateByName(item.info.shortname, amount, item.skin);
if (bonus == null) return;
player.GiveItem(bonus);
SendReply(player, Msg("Bonus", player.UserIDString, amount));
}
}
}The plugin listens for OnCowMilked and, if the player holds the cowmilkbonus.vip permission, gives them an extra milk item per milking. It logs each bonus to a simple running counter that can be checked with the cowmilkbonus.stats chat command. The reward is created with ItemManager.CreateByName using the same shortname and skin as the milk item that was just produced, then handed to the player with GiveItem. All player-facing text comes from the language file, and permissions are registered on load.
Common use cases
VIP bonus milk
Grant extra milk items to players with a permission, scaling with their rank, to reward donors on a farming server.
Farm analytics
Increment a counter per player and per cow position to track which farms produce the most milk over a wipe.
Area effects
Play a sound or spawn a particle effect at the cow's position when a player finishes milking, for a polished farm experience.
Pitfalls
The item is already given
By the time the hook fires, the milk is in the player's inventory. Changing
item.amounthere does not retroactively update the stack reliably; give a new item instead.Cooldown starts after the hook
The milk timer is started after the hook call. Granting bonus milk does not reduce the cooldown; the player still waits the full yield-scaled time.
Not every animal is a Cow
The hook only fires for
Rust.Ai.Gen2.Cowentities. Horses, chickens and legacy animals will not trigger it, so do not assume it covers all livestock.
Build a plugin with OnCowMilked
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 OnCowMilked
Generate