Skip to content
RustPluginGenerator

CanStackItem

CanStackItem is called from Item.CanStack when the server checks whether two items of the same type can be merged into one stack. Returning a bool forces the answer; returning null lets the default comparison run.

Signature
object CanStackItem(Item item, Item item2)

Parameters

Hook parameters
ParameterTypeDescription
itemItemThe Item instance the game is trying to stack into. This is the item `CanStack` was called on, i.e. the destination stack.
item2ItemThe other item being tested against the destination. The game compares this one to `item` for prefab, skin, and stack limits.

Return value

Return true to allow stacking, false to forbid it, or null/any non-bool value to let the vanilla logic decide. The game returns your bool directly as the result of Item.CanStack.

How it works

The hook fires inside Item.CanStack(Item), which the server calls whenever it evaluates whether two item instances may be combined. Typical triggers are picking up an item that matches one in your inventory, moving a stack onto another in a container, splitting a stack and merging it back, and any internal inventory operation that tries to consolidate stacks.

Both parameters are Item objects: item is the destination (the instance whose method ran) and item2 is the candidate being tested. Useful members are info.shortname, skin, amount, info.stackable, and parent — compare these when you want to allow or forbid a merge.

You cannot narrow this hook by declaring a more specific parameter type: both parameters are always Item, and Oxide's dispatch still matches them. There is only one signature.

Because the hook runs on every stack check, keep the body cheap and avoid logging. A common use is blocking merges of items with different skins or custom data so a player's modified item does not disappear into a plain stack.

Example plugin: Block merging items that carry different skins

SkinSafeStacking.cs
using System;
using Newtonsoft.Json;

namespace Oxide.Plugins
{
    [Info("Skin Safe Stacking", "RustPluginGenerator", "1.0.0")]
    [Description("Prevents items with different skins from merging into one stack.")]
    public class SkinSafeStacking : RustPlugin
    {
        private PluginConfig config;

        private class PluginConfig
        {
            [JsonProperty("Block merges of items with different skins")]
            public bool BlockDifferentSkins { get; set; } = true;
        }

        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 CanStackItem(Item item, Item item2)
        {
            if (item?.info == null || item2?.info == null) return null;
            if (!config.BlockDifferentSkins) return null;
            if (item.info.itemid != item2.info.itemid) return null;

            if (item.skin != item2.skin) return false;

            return null;
        }
    }
}

The plugin overrides CanStackItem and refuses a merge when the two items have different skins, so a skinned or custom-skinned item is never absorbed into a plain vanilla stack. It also reads a config flag that lets admins turn the protection off entirely, in which case the hook returns null and vanilla behavior resumes. Every parameter is null-checked, and the hook body only compares two integer values, so it stays cheap on a busy server. The class registers no commands or permissions because the behavior is purely passive.

Common use cases

  • Protect skinned items

    Refuse merges when skin differs so a painted weapon or clothing item does not vanish into a default-skin stack.

  • Prevent cross-container merges

    Return false when the two items have different parent containers, keeping stacks where the player left them.

  • Cap merges for custom items

    Allow a merge only while the combined amount stays under a limit you define, then let the game handle the remainder normally.

Pitfalls

  • Fires very often

    The hook runs on every stack evaluation, including automatic inventory consolidation. Never call Puts or PrintWarning inside it and keep comparisons simple.

  • Returning a value skips vanilla checks

    A returned true bypasses the game's own prefab, skin, and stackable checks, so you can create oversized or mismatched stacks. Only return true when you fully understand the items involved.

  • Skin 0 is the default

    Items created without an explicit skin have skin == 0. Comparing skins directly handles that, but do not treat 0 as "invalid" or you will block ordinary stacking.

Build a plugin with CanStackItem

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

Prompt: Protect skinned items using the CanStackItem 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 CanStackItem

Generate