How-To: Nest Bags

Goal: make an item that is itself an inventory, place items inside it, show one panel per bag, and move a bag with its contents.

Prerequisites
How-To: Author an Item Definition and How-To: Choose a Layout.

1. Add the Bag fragment to an item

PropertyMeaning
LayoutThe layout asset for the bag's interior.
IntCapacities / FloatCapacitiesCaps for the interior, keyed by the same constraint tags the layout reads (Crimson.Inventory.Constraint.Slots, .GridWidth, ...).
ConstraintsInstanced rule objects that apply inside the bag only.
bAllowNestedBags, MaxNestingDepthWhether bags may go inside this bag, and how deep (1 to 4).
ModeSeparatePanel: the bag is its own group and panel. ExpandRoot: its capacity rows are added to the root caps of the same tag instead (no panel). The inventory's bOverrideBagMode / BagModeOverride forces one mode for every bag. Either way a bag only contributes while it sits in a BAG SLOT (group BagSlotsLayoutGroupId, count = the Crimson.Inventory.Constraint.BagSlots cap) or nested inside an active bag.
GroupDisplayNameShown by UI as the panel title.

Open ID_LeatherBag, add Inventory Bag under Fragments. Set Layout to a flat-slot asset, add an Int Capacities entry Crimson.Inventory.Constraint.Slots = 8, set Group Display Name.

Verify
Give the bag. Dev Tools -> Groups shows two groups: 0 (root) and one with OwnerEntryId = the bag's entry id, depth 1, capacity hint 8.

2. Place an item inside the bag

From the client: Move Item on the routing component with a Make Crimson Placement Target whose Layout Group Id = the bag's GroupId from Get Layout Groups and Slot Index = the interior slot. From the server: Add Item Definition with Policy = Explicit Target and the same target.

Verify
Dev Tools -> Items shows the new entry with LayoutGroupId equal to the bag's group; Get Entry Views on the client agrees.

3. React when the group set changes

Crimson.Inventory.Message.LayoutGroupsChanged (payload FCrimsonInventory_Message_LayoutGroupsChanged: AddedGroupIds, RemovedGroupIds, ActivationChangedGroupIds) fires on server and clients whenever a rebuild produces a different group set. Bind one panel per active group and re-query GetLayoutGroups on receipt.

Bind Event to On Layout Groups Changed on the manager -> Get Layout Groups and rebuild the panel list.

Verify
Drop the bag (DropItemByEntry): the message arrives with the bag's group in RemovedGroupIds, and the spawned pickup's Contents holds the interior items.

4. Move a bag with its contents

ExtractSubtree removes a bag entry and everything nested under it as one FCrimsonInventorySubtree; AddSubtree places it in another inventory. TransferEntryTo and DropEntriesAsBag use the same path internally, so a bag never loses its contents in transit.

Server only: Extract Subtree (Root Entry Id = the bag) -> Add Subtree on the destination manager. Check bSuccess on the result.

Verify
Move a bag holding three items to a chest. The chest's Groups tab shows the bag group; its Items tab shows the three interior entries with the new group id.

See also

  • How-To: Drop and Pick Up Items
  • How-To: Bridge to Equipment (equip-to-open bags)
  • Concept: Layouts and Groups