Lesson 46 of 170

Inventory owns possession, not every item meaning

Martinez AI Studios Academy

Model a small inventory contract using fungible quantities keyed by item-definition ID, explicit possession caps, validated mutations, and clear system boundaries.

669. Lesson identity

Module
2.5 — Inventory, equipment, and crafting
Lesson
1
Academic type
Systems
Estimated time
30–40 minutes, including practice
Core capability
Model a small inventory contract

670. Learning objective

After this lesson, you can define a small inventory contract that stores fungible quantities by item-definition ID, enforces an explicit per-definition possession cap, validates mutations, reports their results, and separates possession from item interpretation.

671. Why this matters

Equipment, crafting, rewards, shops, and save data may all depend on inventory state. If each system changes that state according to different assumptions, quantities can become negative, caps can be exceeded, and callers may report success when possession did not change.

A narrow inventory authority provides one answer to what the player possesses and one path for changing it. It does not make the inventory responsible for equipment effects, recipes, prices, progression, or narrative meaning.

672. Identity: definition IDs and instance IDs

This lesson distinguishes two forms of identity:

  • An item-definition ID identifies a reusable item type, such as bandage or scrap_metal. Multiple interchangeable units can share this ID.
  • An item-instance ID identifies one particular object when it has individual state, such as durability, generated properties, ownership history, or another per-instance value.

The small contract in this lesson supports only fungible quantities keyed by item-definition ID:

quantityByDefinitionId[definitionId] = quantity

It does not store item-instance IDs, stack records, or slot placement. Therefore, it cannot represent two separate stacks of the same definition or two individually different copies. A game that needs those distinctions requires a different or extended storage model.

673. Inventory authority and boundaries

The inventory is authoritative for:

  • whether a positive quantity of an item-definition ID is possessed;
  • the stored quantity for that definition ID;
  • whether an addition or removal satisfies the inventory contract;
  • applying or rejecting the mutation;
  • reporting a caller-visible result.

Other systems remain authoritative for:

  • whether an item can be equipped and what effect it has;
  • whether an item is a valid crafting ingredient;
  • shop prices and economic interpretation;
  • progression or unlock decisions;
  • narrative meaning;
  • item-definition data such as display information and the configured possession cap.

Other systems may read possession and request a mutation, but they should not rewrite the quantity map directly.

674. Supported storage and capacity model

For this lesson, each item definition has one aggregate quantity and an optional per-definition possession cap:

stored state: definition ID → aggregate quantity
valid quantity: 0 through possessionCap, inclusive

The cap limits the total quantity held under that definition ID. It is not a stack limit, slot limit, weight limit, or total inventory limit.

Examples:

bandage      quantity: 3   possession cap: 5
scrap_metal  quantity: 4   possession cap: 10
key_fold     quantity: 1   possession cap: 1

The item-definition data owns the configured cap. The inventory reads that value when validating possession changes. A quantity of zero may be omitted from storage, provided the contract states that a missing entry means zero.

675. Mutation contract

Use this sequence:

REQUEST → VALIDATE → MUTATE OR REJECT → REPORT RESULT

A minimal request identifies:

  • the operation: add or remove;
  • the item-definition ID;
  • a positive requested quantity.

Validation rules for this model:

  1. The definition ID must resolve to a known definition.
  2. The requested quantity must be greater than zero.
  3. Addition is valid only when current + requested <= possessionCap.
  4. Removal is valid only when current >= requested.
  5. Rejection leaves stored state unchanged.

A caller-visible result should include at least:

accepted: true or false
reason: accepted, unknown_definition, invalid_quantity, cap_exceeded, or insufficient_quantity
resultingQuantity: authoritative quantity after the request

Reporting the authoritative resulting quantity prevents the caller from guessing whether state changed.

676. Concrete example

Initial state and definitions:

bandage      quantity: 3   possession cap: 5
scrap_metal  quantity: 4   possession cap: 10
key_fold     quantity: 1   possession cap: 1
Request Result Stored state afterward
Add 2 bandage Accepted bandage = 5
Add 3 bandage from quantity 3 Rejected: cap_exceeded bandage = 3
Remove 2 scrap_metal Accepted scrap_metal = 2
Remove 2 key_fold Rejected: insufficient_quantity key_fold = 1
Equip key_fold Not an inventory mutation by itself Possession is unchanged

The rejected bandage addition is not split into multiple stacks because this model has no stack records. Supporting separate stacks would require stack identity and an appropriate container structure.

677. Responsibility table

Fact or decision Owning system
bandage definition exists Item-definition system
bandage possession cap is 5 Item-definition system
Player currently possesses 3 bandage Inventory
Add 3 would exceed the cap Inventory validation
bandage restores health Item-use or health system
scrap_metal is a valid recipe ingredient Crafting system
key_fold opens a particular door Interaction or narrative system

The inventory can supply possession evidence without becoming the authority for those interpretations.

678. Common mistakes

Calling an aggregate cap a stack limit

A stack limit applies to a stack record. This lesson stores no stack records, so its rule is a per-definition possession cap.

Treating a definition ID as an instance ID

bandage identifies a type shared by interchangeable units. It does not distinguish one bandage from another. Individual durability or generated properties require instance records.

Leaving capacity unspecified

The word “capacity” is ambiguous unless the contract identifies whether it means slots, weight, stacks, total items, or a per-definition quantity. This contract supports only the last of those.

Allowing direct writes

Callers that edit the quantity map can bypass validation. Additions and removals should use explicit operations.

679. Guided practice

Create a contract and decision table for these definitions:

ration         possession cap: 4
copper_wire    possession cap: 10
access_token   possession cap: 1

Use this template:

Supported identity model:
Stored state:
Meaning of a missing entry:
Cap ownership and meaning:
Add validation:
Remove validation:
Rejected-request behavior:
Caller-visible result:
Unsupported storage features:
Responsibilities outside inventory:

Resolve these cases:

  1. Add 4 ration to quantity 0.
  2. Add 1 more ration after case 1.
  3. Remove 2 access_token when quantity is 1.
  4. Decide whether copper_wire is a valid crafting ingredient.
  5. Explain what must change in the storage model if two ration units need different durability values.

For each mutation, record the accepted flag, reason, resulting quantity, and whether stored state changed.

680. Validation and evidence

Submit the contract and result table through the attached practical assessment. Check that:

  • definition IDs and optional instance IDs are explicitly distinguished;
  • the supported model is limited to fungible aggregate quantities;
  • the cap is defined as a per-definition possession cap;
  • no answer relies on stack splitting, slots, or weight;
  • additions and removals validate before mutation;
  • rejected requests leave state unchanged;
  • caller-visible results include acceptance, reason, and resulting quantity;
  • crafting or another interpretation is assigned outside inventory;
  • the need for instance records is recognized when units have individual state.

681. Key takeaways

  • This inventory stores aggregate fungible quantities keyed by item-definition ID.
  • An item-definition ID identifies a type; an item-instance ID would identify one particular object.
  • This model uses a per-definition possession cap, not stacks, slots, or weight.
  • Inventory owns possession and validated possession changes, not every interpretation of an item.
  • Every mutation must validate first and return an explicit result.

682. Next lesson

2.5 L2 — Equipment changes capability through a contract keeps inventory authoritative for possession while equipment owns equipped state and effect interpretation.

683. Knowledge check

Answer these items for yourself before reading the answers.

Which fact should the inventory own?

  • A. Whether the player possesses an item definition and in what quantity
  • B. The item's sale price in every shop
  • C. The damage dealt by an equipped weapon
  • D. The narrative meaning of a key item
Show answer and feedback

Answer: Whether the player possesses an item definition and in what quantity

Why: Inventory owns possession and quantity. Price, combat effects, and narrative meaning belong to other systems.

What should happen before an inventory mutation is applied?

  • A. The quantity must change first and be checked afterward
  • B. Every system that can read the inventory should edit it directly
  • C. The narrative system must approve it
  • D. The request must be validated against the inventory contract
Show answer and feedback

Answer: The request must be validated against the inventory contract

Why: Validation before mutation prevents invalid quantities and ensures rejected requests leave state unchanged.

Which identity does bandage represent when several interchangeable units share that value?

  • A. An item-definition ID
  • B. An item-instance ID
  • C. A stack-record ID
  • D. An equipment-slot ID
Show answer and feedback

Answer: An item-definition ID

Why: A definition ID identifies a shared item type. Distinguishing individual units would require instance IDs and instance records.

In the lesson's aggregate model, what does a possession cap of 5 for bandage mean?

  • A. The complete inventory has exactly 5 slots
  • B. Each bandage weighs 5 units
  • C. Each stack may contain 5 units, and any number of stacks may exist
  • D. The total aggregate quantity stored under that definition ID cannot exceed 5
Show answer and feedback

Answer: The total aggregate quantity stored under that definition ID cannot exceed 5

Why: The supported model stores one aggregate quantity per definition ID. It does not represent stacks, slots, or weight.

An inventory stores ration → 4, and the ration definition has a possession cap of 4. A caller requests add ration, 2. Which diagnosis and result are consistent with the contract?

  • A. ration is a definition ID; reject with cap_exceeded, report resulting quantity 4, and leave state unchanged
  • B. ration is an instance ID; accept and store quantity 6
  • C. ration is a slot ID; create a second stack of 2 without changing the model
  • D. ration is definition data; reject but report resulting quantity 6
Show answer and feedback

Answer: ration is a definition ID; reject with cap_exceeded, report resulting quantity 4, and leave state unchanged

Why: The stored key is a definition ID, and adding 2 would exceed its aggregate possession cap. Rejection must preserve quantity 4 and report that authoritative result.

Put this lesson into practice

Related free templates and checklists

Support