Skip to content

Latest commit

 

History

History
70 lines (50 loc) · 2.83 KB

File metadata and controls

70 lines (50 loc) · 2.83 KB

Design notes

All features, backlog, and decisions of this project will be documented here.

Version-sensitive patches are listed in docs/PATCHES.md.

Released features

The server owns the capacity map and every inventory change.

  • Set the capacity of standard held bags by item-code pattern (BagCapacityOverrides)
  • Existing bags grow or shrink without hiding or deleting contents

Backlog

  • Placed chests, vessels, crates, and other block inventories. Those need storage-specific adapters; they don't share one safe capacity contract.

Locked decisions

Stowage is required on the server and every client. The server reads stowage.json. Clients receive the resulting bag attributes through normal game synchronization.

Compatibility is the standard held-bag behavior, not a list of mod names. A custom IHeldBag that ignores backpack.quantitySlots is reported and left alone. Guessing at an unsupported storage type is worse than leaving it.

Bag definitions change during AssetsFinalize, before the server sends collectible attributes to clients.

A dormant oversized bag must keep reporting its persisted size. Showing only the new size before migration would hide items even if the data still existed. Equipped bags migrate on equip or at PlayerNowPlaying; ground-stored and entity-attached bags migrate when opened. PlayerNowPlaying is the first join event with a ready inventory. Passive reconstruction has no authenticated player or safe drop position.

GetOrCreateSlots and GetQuantitySlots stay small universal patches. Their job is to keep every persisted slot readable until server migration finishes, because the asset layer cannot repair an existing item stack. Passive slot reads only touch the current item stack. Actual migration runs from verified server main-thread inventory and interaction paths.

On shrink: compact retained contents, route overflow into valid player storage (never back into the bag being reduced, and never into slots beyond another bag's pending capacity), drop any remainder, and only then save the smaller layout. If migration cannot finish, completed transfers stay saved and leftover overflow slots stay readable for a later interaction.

Detached ItemSlotBagContent wrappers must sit in an inventory that owns those same instances, or ItemSlot.TryPutInto rejects their dirty notification.

An entity-attached bag opens through packet 1001. The slot index lives in the upper bits (packetid >> 11). Lower ids are slot clicks.

Rules are checked in file order. The first match wins, so a specific rule can sit above a broad fallback.

Configuration

The server loads, cleans, and stores stowage.json during asset finalization. Clients don't read a local copy. Restart the dedicated server or reopen the singleplayer world after editing.

The full pattern syntax is in README.md.