🧠 Inventory System — Mental Model¶
This page explains how to think about Inventory in RevFramework.
It is not an API reference.
It is a conceptual map that helps you decide:
- Where does this behaviour belong?
- Which extension point should I use?
- What should I never touch?
If you understand this page, the API will feel obvious.
🎯 The Core Idea¶
Inventory is a service-controlled container system with explicit mutation boundaries and deterministic results.
Inventory is not “a list of items on a character”.
It is a service‑driven container system designed to guarantee:
- consistent slot semantics
- deterministic mutation results
- clear authority boundaries
- predictable UI updates
Everything in the system exists to enforce those guarantees.
🧱 The Single Source of Truth¶
SceneInventoryService¶
There is exactly one authority on inventory state in a scene:
SceneInventoryService
It is the default Unity host and orchestration layer.
It is responsible for:
- container creation and tracking
- mutation orchestration
- authority validation
- delta publication (via internal tracking)
Nothing else should:
- mutate container contents
- create containers directly
- bypass authority checks
- emit container change events
If something outside the service does these things, the design boundaries of the system have likely been violated.
📦 Containers (The Fundamental Unit)¶
An inventory container is the fundamental storage unit.
A container contains:
Slots → ItemStacks → ItemDefinitions
Key properties:
- containers belong to an owner GameObject
- containers are identified by
ContainerId - containers contain slot arrays (resizable via service)
- each slot holds zero or one stack
Containers are created lazily by the service when first required.
Consumers never construct containers directly.
🧾 Item Stacks¶
An ItemStack represents a quantity of an item definition.
Stacks contain:
- item definition (
ItemDefinition) - quantity
- durability
- metadata
Stacks are value-like data, not live objects.
Important rules:
- quantity must respect
ItemDefinition.maxStack - empty stacks are represented by
ItemStack.Empty - equality comparisons are implementation-defined (internal utilities)
Stacks are safe for:
- UI
- persistence
- serialization
🔄 The Mutation Boundary¶
All inventory mutations occur through:
IInventoryService
Every mutation returns:
InvOpResult
Operations include:
- adding items
- removing items
- splitting stacks
- merging stacks
- swapping slots
- moving between containers
Mutations are always explicit and deterministic.
No mutation silently fails.
📊 Events (State Observation)¶
Inventory state changes are communicated through:
OnContainerChanged
Events provide an InventoryDelta describing:
- container owner
- container id
- slot-level changes
These events allow UI to update without polling.
Rule of thumb:
UI listens to events.
UI never mutates containers directly.
🔎 Read vs Mutation Surfaces¶
Inventory deliberately separates read access from mutation access.
Read¶
IInventoryService(read operations)IReadOnlyInventoryContainer(via IInventoryService.Get)
Used by:
- UI
- debugging tools
- search systems
Mutation¶
IInventoryService
Used by:
- gameplay systems
- equipment
- crafting
- pickups
This separation prevents accidental mutations.
🧰 Convenience Wrappers¶
These components provide usability layers on top of the service.
CharacterInventory¶
Provides a character-local wrapper around a container.
Useful for:
- debugging
- inspector display
- local gameplay logic
However, it does not replace the service.
For multiplayer or authority-sensitive logic, prefer IInventoryService.
CharacterEquipment¶
Manages fixed equipment slots and integrates with inventory containers.
Responsibilities:
- equip items from inventory
- unequip items to inventory
- enforce equipment filters
Equipment uses internal containers but exposes safe, result-first APIs.
ItemUseSystem¶
Consumes inventory items and executes their configured use effects.
Effects are resolved through:
UseEffectResolver
The system:
- applies effects
- consumes items
- respects authority rules
It does not manage containers directly.
🔍 Searching & Sorting¶
Inventory supports:
- container searching
- slot sorting
These behaviours are provided through strategy interfaces:
IInventorySearchIInventorySorter
Important:
- search and sort operate on existing containers only
- they do not create containers implicitly
🔐 Authority¶
Inventory mutations may be guarded by an authority policy.
Authority is provided by:
IInventoryAuthority
Typical setups include:
- single-player (always true)
- multiplayer ownership validation
Authority checks occur inside the service before mutation.
External code must never bypass them.
💾 Snapshots & Persistence¶
Inventory supports snapshot capture and restoration.
Snapshots store:
- inventory containers
- equipment containers
- item stacks
Snapshot behaviour is controlled by:
InventorySnapshotOptionsMissingItemPolicy
Snapshots support: - save/load - missing-item handling
Snapshots are state helpers, not a full persistence system.
🔌 Extension Points¶
Inventory exposes safe extension seams:
IInventorySearchIInventorySorterIInventoryAuthorityIItemDatabaseIUseEffect
These allow behaviour to be customized without modifying core systems.
🚫 What Never Belongs Where¶
- UI must never mutate containers
- containers must never be created manually
- gameplay systems must not bypass the service
- inventory logic must not depend on presentation systems
- external systems must not access internal container classes
Violating these rules breaks the system’s guarantees.
🧠 The One-Sentence Model¶
Inventory is a service-controlled container system that guarantees deterministic mutations and observable state changes.
TL;DR¶
- One authoritative service
- Containers hold slot-based stacks
- Mutations go through
IInventoryService - UI observes
InventoryDeltaevents - Extension points enable custom behaviour without modifying core systems