Multi Stack Item Collection

Use a Multi Stack Item Collection when one common Item should occupy several bounded stacks. For example, a Bag with a stack limit of 10 stores 25 Health Potion Items as three stacks: 10, 10, and 5.

The stack-size limit applies to each stack, not to the collection as a whole. This collection can create any number of stacks unless an Inventory restriction limits them.

Configure a bounded Bag

  1. Select the GameObject with the Inventory component.
  2. Under Item Collections, select the collection used for general storage.
  3. Set Name to Bag.
  4. Set Collection Type to Multi Stack Item Collection.
  5. Set Purpose to Main when Bag should receive calls to Inventory.AddItem by default.
  6. Set Default Stack Size Limit. Use 10 while following the example on this page; the released Version 1 default is 99.
  7. Keep Stack Size Limit Attribute Name set to StackSizeLimit. This is the released Version 1 default.

The two stack settings apply only to the Multi Stack Item Collection. The inherited Overflow Options control what happens when an Inventory restriction accepts less than the requested Amount.

Set a different limit for one Item

Use Default Stack Size Limit when most common Items should use the same limit. Use an integer attribute when one definition needs a different value:

  1. In the Item Category editor, declare an Item Definition int attribute named StackSizeLimit on a suitable parent such as Consumable.
  2. Select Health Potion in the Item Definition editor.
  3. Set its StackSizeLimit value to a positive whole number, such as 5.
  4. Confirm that Stack Size Limit Attribute Name on Bag exactly matches StackSizeLimit.

At runtime, the collection asks the Item for an integer with that name. When it cannot find one, it uses Default Stack Size Limit. The value must be greater than zero: released Version 1 does not clamp or reject zero before using it in stack calculations, and zero can cause a divide-by-zero exception.

Keep a stack limit on the Item Definition when every Health Potion should use the same value. See Defining Attributes and Common Attributes for the data workflow.

Follow the stack order

When an Amount is added, the collection uses this order:

  1. fill a supplied target ItemStack first, when the caller provides one that belongs to Bag;
  2. scan compatible existing stacks in collection order and fill their remaining space;
  3. append as many full new stacks as required; and
  4. append one remainder stack when an Amount remains.

With a limit of 10, adding 25 Health Potion to an empty Bag produces 10, 10, 5. Adding 7 more fills the last stack to 10, then appends a stack of 2, producing 10, 10, 10, 2.

Removal by Item without a target walks matching stacks from the end, so it normally reduces the newest remainder before earlier full stacks. Supplying a specific ItemInfo targets its ItemStack first and can leave that stack partially filled in its current collection position. The Item Definition removal overload first resolves a matching ItemInfo, so code should not depend on every removal overload choosing the same stack.

This is collection order, not a permanent UI slot assignment. An Inventory Grid can filter, sort, or maintain its own grid indexes independently.

Choose which Items may stack

Item configuration Multi Stack behavior Shared example
Immutable, common Matching Items from the same definition fill compatible stacks, then create more stacks. Health Potion
Mutable, common Matching additions can merge into the stored common Item; the existing Item values are retained. Use only when shared mutable values are intentional.
Unique, mutable or immutable Each Item remains separate with an Amount of 1, even when the requested Amount is greater than one. Iron Sword with per-Item Durability
Different Item Definitions Items never share a stack. Health Potion and another consumable remain separate.

The collection is most useful for common Items. Do not make Iron Sword common merely to use a larger stack limit; keep it mutable and unique when each sword must retain its own Durability.

Limit the number of stacks

Default Stack Size Limit and StackSizeLimit do not limit Bag’s total capacity. To cap the number of ItemStacks:

  1. create an Item Restriction Set;
  2. add an Item Collection Stack Amount Restriction;
  3. include Bag under Item Collection Names; and
  4. set Max Stack Amount to the total number of stacks Bag may hold.

The restriction counts existing stacks and asks the Multi Stack Item Collection how much of the incoming request fits in their free space plus the available new stacks. It can therefore accept a partial Amount. The rejected remainder then follows Bag’s Overflow Options.

Use an Item Collection Category Restriction as well when Bag should accept Consumable Items but reject Equipment. Use the Multi Stack fields, rather than a second stack-size restriction, for this collection’s per-stack limit. See Item Restrictions.

Connect UI and saving

Each ItemStack is a separate ItemInfo in the Inventory cache. An Inventory Grid can therefore show 10, 10, and 5 Health Potion as three separate entries. Its filter, sorter, and Use Grid Index behavior determine the visible order; the collection itself does not reserve fixed UI slots.

An Inventory Saver records every stack as an Item ID and Amount in collection order. Loading a non-slot collection adds those saved entries back through the collection API. If the stack limit or Inventory restrictions changed after saving, the loaded Items can be merged, split, or rejected according to the new configuration instead of recreating the old stack objects exactly.

Use Inventory System Manager Item Saver to preserve mutable or unique Item state. Use Inventory Grid Saver when player-arranged grid positions must also persist. See Save System and Inventory Grid.

Editor checkpoint

Before entering Play Mode, confirm that:

  • Bag uses Multi Stack Item Collection and has the intended Purpose;
  • Default Stack Size Limit is greater than zero;
  • Stack Size Limit Attribute Name exactly matches an int attribute or deliberately falls back to the default;
  • Health Potion is common and immutable for the simple stacking example;
  • Iron Sword remains unique when its runtime values must stay separate;
  • an Item Collection Stack Amount Restriction exists if Bag needs a total stack limit;
  • the Inventory Grid is allowed to show more than one entry for the same definition; and
  • the save setup includes both Item state and grid-position savers when the game needs them.

Verify in Play Mode

  1. Start with an empty Bag and a stack limit of 10.
  2. Add 25 Health Potion. Confirm that Bag contains three stacks with Amounts 10, 10, and 5.
  3. Add 7 more. Confirm that the stacks become 10, 10, 10, and 2.
  4. Remove 7 through the same Health Potion Item reference without specifying a stack. Confirm that the raw collection order returns to 10, 10, and 5.
  5. Add two unique Iron Sword Items. Confirm that they appear as two separate Amount-1 stacks and keep independent Durability values.
  6. If a stack-count restriction is configured, fill Bag to its limit and add another Health Potion. Confirm the partial or rejected Amount and the configured overflow response.
  7. Save, change the scene, then load. Confirm the stack totals and, when configured, the visible Inventory Grid positions.

Troubleshooting

Symptom Check Fix
All Health Potion Items stay in one large stack Bag’s Collection Type Select Multi Stack Item Collection, then re-enter its type-specific settings if the type changed.
Every stack uses 99 instead of the definition value Attribute name, type, and location Define an Item Definition int named StackSizeLimit and match the Inspector string exactly.
Adding an Item throws a divide-by-zero exception Default Stack Size Limit and the resolved StackSizeLimit value Set both possible values to positive integers.
Bag keeps creating more stacks Whether an Item Collection Stack Amount Restriction includes Bag Add or correct that restriction; Multi Stack has no total capacity by itself.
A partial stack is not the first visible slot Inventory Grid filter, sorter, and Use Grid Index Treat collection order and visible grid order separately; configure the grid for the intended presentation.
Two swords merge or share changing values Weapon’s Mutable and Unique category settings Make per-instance weapons mutable and unique.
One add request triggers several callbacks How many existing or new stacks were affected Handle OnItemAdded per stack, or query and aggregate the final state after AddItem returns.
Loaded stacks have different boundaries Stack limit or restrictions changed since the save Keep those rules stable across saves, or migrate and retest the saved Inventory.
Grid positions reset after loading Whether Inventory Grid Saver is configured Save the Inventory content and grid index state together.

Use the Multi Stack API

Query total Amount and stack count separately:

var bag = inventory.GetItemCollection("Bag")
    as MultiStackItemCollection;
var potionDefinition = InventorySystemManager.GetItemDefinition("Health Potion");

var added = bag.AddItem(potionDefinition, 25);
var totalAmount = bag.GetItemAmount(potionDefinition, false);
var stackCount = bag.GetItemAmount(potionDefinition, false, true);
var stacks = bag.GetAllItemStacks();
var removed = bag.RemoveItem(added.Item, 7);

The collection exposes DefaultStackSizeLimit and StackSizeLimitAttributeName as writable properties. Set them before adding Items. Changing a limit does not immediately rebalance existing stacks; a later add, remove, or load can reshape them.

When AddItem touches several stacks, released Version 1 invokes OnItemAdded and EventNames.c_Inventory_OnAdd_ItemInfo_ItemStack once for each affected stack. The returned ItemInfo normally reports an aggregate accepted Amount, but its stack reference can identify an unchanged compatible stack visited later in the loop. Use the per-stack add events when the exact changed stack matters. Return Overflow can also replace the Amount with the amount returned to the source; inspect destination state for a precise partial-transfer result. A removal spanning several stacks produces one combined OnItemRemoved result.

Only pass a target ItemStack when it belongs to Bag and contains a stackable-equivalent Item. Released Version 1 checks that the target belongs to the collection but does not validate target compatibility before increasing its Amount.

Register and unregister matching event signatures over the same Unity lifecycle. See Events for the released Version 1 event pattern.