Skip to content
RustPluginGenerator

OnDefaultItemsReceived

OnDefaultItemsReceived is called at the end of PlayerInventory.GiveDefaultItems, after the server has handed a player the default starting items (rock, torch, and any server-configured loadout).

Signature
void OnDefaultItemsReceived(PlayerInventory playerInventory)

Parameters

Hook parameters
ParameterTypeDescription
playerInventoryPlayerInventoryThe PlayerInventory that just received its default loadout. Use playerInventory.baseEntity to reach the BasePlayer, and playerInventory.containerMain, containerBelt or containerWear to add, replace or inspect items.

Return value

The original method returns void and the call site uses continue, so any value you return is ignored and the default item code always finishes as normal.

How it works

This hook fires once at the tail of PlayerInventory.GiveDefaultItems, which the game runs shortly after a player spawns or is given a fresh inventory. By the time it fires the default rock and torch (and any skin or loadout variations the server configured) are already in the inventory, so you see the final state and can add to it or take items away.

The only argument is PlayerInventory. From it, playerInventory.baseEntity gives the owning BasePlayer, and the three containers containerMain, containerBelt and containerWear let you inspect what was granted. Because the hook runs after the defaults, you can grant extra kits, enforce a per-rank starting kit, or strip an item the server normally hands out.

You cannot narrow this hook by declaring a more specific parameter type: the game passes the PlayerInventory instance itself, which is not a BasePlayer, so a signature declaring BasePlayer would never be called. Do your work on the inventory and reach outward through baseEntity.

The hook can fire more than once for a player during a session (respawns, /inv style resets), and it does not fire for NPCs. Avoid heavy iteration over the whole entity registry inside it.

Example plugin: Grant a starting kit instead of the default rock and torch

StartingKitLoadout.cs
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Starting Kit Loadout", "RustPluginGenerator", "1.0.0")]
    [Description("Replaces the default rock and torch with a permission-based starting kit")]
    public class StartingKitLoadout : RustPlugin
    {
        private const string PermVip = "startingkitloadout.vip";
        private const string PermElite = "startingkitloadout.elite";

        private PluginConfig config;
        private readonly HashSet<ulong> processed = new HashSet<ulong>();

        private class KitItem
        {
            [JsonProperty("Item shortname")] public string Shortname = "bandage";
            [JsonProperty("Amount")] public int Amount = 1;
        }

        private class Kit
        {
            [JsonProperty("Items")] public List<KitItem> Items = new List<KitItem>();
        }

        private class PluginConfig
        {
            [JsonProperty("Give custom starting kit")] public bool Enabled = true;
            [JsonProperty("Default items to remove")] public List<string> RemoveDefaults = new List<string> { "rock", "torch" };
            [JsonProperty("Default kit")] public Kit Default = new Kit { Items = new List<KitItem> { new KitItem { Shortname = "bandage", Amount = 3 }, new KitItem { Shortname = "wood", Amount = 200 } } };
            [JsonProperty("VIP kit (permission startingkitloadout.vip)")] public Kit Vip = new Kit { Items = new List<KitItem> { new KitItem { Shortname = "bandage", Amount = 5 }, new KitItem { Shortname = "wood", Amount = 500 }, new KitItem { Shortname = "metal.fragments", Amount = 100 } } };
            [JsonProperty("Elite kit (permission startingkitloadout.elite)")] public Kit Elite = new Kit { Items = new List<KitItem> { new KitItem { Shortname = "bandage", Amount = 10 }, new KitItem { Shortname = "wood", Amount = 1000 }, new KitItem { Shortname = "metal.fragments", Amount = 250 }, new KitItem { Shortname = "hatchet", Amount = 1 } } };
        }

        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(PermVip, this);
            permission.RegisterPermission(PermElite, this);
        }

        private void Unload()
        {
            processed.Clear();
        }

        private void OnDefaultItemsReceived(PlayerInventory playerInventory)
        {
            if (!config.Enabled || playerInventory == null) return;

            BasePlayer player = playerInventory.baseEntity;
            if (player == null || player.IsNpc) return;

            ulong userId = player.userID.Get();
            if (!processed.Add(userId)) return;

            RemoveDefaults(playerInventory);
            GrantKit(player, ChooseKit(player));
        }

        private void RemoveDefaults(PlayerInventory inventory)
        {
            if (config.RemoveDefaults == null) return;

            ItemContainer belt = inventory.containerBelt;
            if (belt == null) return;

            for (int i = belt.itemList.Count - 1; i >= 0; i--)
            {
                Item item = belt.itemList[i];
                if (item?.info == null) continue;
                if (config.RemoveDefaults.Contains(item.info.shortname)) item.Remove();
            }
        }

        private Kit ChooseKit(BasePlayer player)
        {
            if (permission.UserHasPermission(player.UserIDString, PermElite)) return config.Elite;
            if (permission.UserHasPermission(player.UserIDString, PermVip)) return config.Vip;
            return config.Default;
        }

        private void GrantKit(BasePlayer player, Kit kit)
        {
            if (kit?.Items == null) return;

            foreach (KitItem entry in kit.Items)
            {
                if (entry == null || string.IsNullOrEmpty(entry.Shortname)) continue;

                Item item = ItemManager.CreateByName(entry.Shortname, Mathf.Max(1, entry.Amount));
                if (item == null) continue;

                if (!item.MoveToContainer(player.inventory.containerMain))
                {
                    player.GiveItem(item);
                }
            }
        }

        private void OnPlayerDisconnected(BasePlayer player, string reason)
        {
            if (player != null) processed.Remove(player.userID.Get());
        }
    }
}

The plugin listens for OnDefaultItemsReceived and checks the config for whether a custom starting kit is enabled. When active, it looks up the player via playerInventory.baseEntity, resolves their permission group against a list in the config, and gives the matching kit. Before granting it removes the default rock and torch by scanning containerBelt and calling Remove() on anything with a shortname in the stripped list, so the player starts clean. Items are created with ItemManager.CreateByName and pushed into containerMain using MoveToContainer, with GiveItem as a fallback so nothing is lost when the container is full. Duplicate protection is handled with a HashSet of user IDs so a respawn does not stack kits.

Common use cases

  • Swapping the rock and torch for a custom kit

    Remove the default items and grant a permission-based loadout so VIPs and regular players start with different gear on the same server.

  • Enforcing a wipe-day starter pack

    Give food, bandages and building materials to every player who receives defaults, keeping new players alive long enough to engage with the server.

  • Auditing what the server hands out

    Scan the main and belt containers after defaults are granted and log any unexpected shortnames to catch modded default items.

Pitfalls

  • Declaring BasePlayer as the parameter

    The game passes a PlayerInventory, not a BasePlayer. A hook method typed BasePlayer never matches and is silently skipped; use the inventory and call baseEntity to reach the player.

  • Not guarding against repeat grants

    The hook can fire again after respawns or inventory resets. Track processed user IDs, at least until the player disconnects, or the kit is duplicated each time.

  • Heavy work inside the hook

    This runs during the player's spawn sequence. Keep it to a few item operations and avoid scanning BaseNetworkable.serverEntities, which can stall the spawn.

Build a plugin with OnDefaultItemsReceived

Describe what should happen and get a compiled plugin that uses this hook.

Prompt: Swapping the rock and torch for a custom kit using the OnDefaultItemsReceived hook, with a config file and a permission
Generate this plugin

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 OnDefaultItemsReceived

Generate