152 lines
6.4 KiB
Markdown
152 lines
6.4 KiB
Markdown
# Agrarian Inventory Data Model
|
|
|
|
This document defines the baseline inventory model for the 0.1.E MVP. The
|
|
current implementation is intentionally small, but it needs a stable contract so
|
|
pickup, drop, splitting, use, equipment, persistence, and UI work all build on
|
|
the same assumptions.
|
|
|
|
## Goals
|
|
|
|
- Keep the server authoritative for every inventory mutation.
|
|
- Use stable item IDs so save files, recipes, drops, vendors, and future network
|
|
services do not depend on display text or asset names.
|
|
- Keep stacks compact enough for replication and save data.
|
|
- Support realistic constraints through slot count and weight before adding
|
|
more advanced volume, spoilage, durability, ownership, and container rules.
|
|
- Keep resource, food, tool, structure, medicine, and currency items inside one
|
|
shared model unless a later system proves it needs a separate path.
|
|
|
|
## Core Records
|
|
|
|
### Item Definition
|
|
|
|
`FAgrarianItemDefinition` is the canonical design-time description of an item.
|
|
It is authored through `UAgrarianItemDefinitionAsset`.
|
|
|
|
Required MVP fields:
|
|
|
|
- `ItemId`: stable `FName` used by inventory, crafting, persistence, drops, and
|
|
debug commands.
|
|
- `DisplayName`: player-facing label.
|
|
- `Description`: player-facing description.
|
|
- `ItemType`: broad item category.
|
|
- `UnitWeight`: per-unit carry weight used by movement and capacity systems.
|
|
- `MaxStackSize`: maximum units expected in one stack.
|
|
|
|
Future fields should be added to the item definition when they describe all
|
|
instances of an item type, such as durability profile, spoilage category,
|
|
nutrition profile, tool class, equipment slot, fuel value, material family, or
|
|
trade category.
|
|
|
|
### Item Stack
|
|
|
|
`FAgrarianItemStack` is the runtime and save-game representation of carried
|
|
items.
|
|
|
|
Required MVP fields:
|
|
|
|
- `ItemId`: stable reference to the item definition.
|
|
- `DisplayName`: cached player-facing label for early UI/debug display.
|
|
- `Quantity`: number of units in the stack.
|
|
- `UnitWeight`: cached per-unit weight so movement and debug views can work
|
|
without synchronously loading item assets.
|
|
|
|
Stacks are valid only when `ItemId != NAME_None` and `Quantity > 0`.
|
|
|
|
Future instance-specific fields, such as durability remaining, condition,
|
|
temperature, spoilage age, ownership, quality, or custom metadata, should live
|
|
on the stack only when individual instances of the same item can differ. If an
|
|
item can have per-instance metadata, stack merge rules must require matching
|
|
metadata before combining stacks.
|
|
|
|
## Inventory Component
|
|
|
|
`UAgrarianInventoryComponent` owns a replicated `TArray<FAgrarianItemStack>`.
|
|
The player character owns the MVP inventory component.
|
|
|
|
Current baseline:
|
|
|
|
- `Items`: replicated stack list.
|
|
- `MaxSlots`: maximum occupied stack slots.
|
|
- `OnInventoryChanged`: event for HUD/UI refresh.
|
|
- `HasItem`: quantity check by `ItemId`.
|
|
- `GetItemCount`: aggregate quantity across matching stacks.
|
|
- `GetTotalWeight`: sum of `Quantity * UnitWeight`.
|
|
- `AddItem`: server-only mutation.
|
|
- `RemoveItem`: server-only mutation.
|
|
- `ServerAddItem` and `ServerRemoveItem`: RPC wrappers for authorized requests.
|
|
|
|
The component currently merges stacks by `ItemId`. Later stack splitting and
|
|
metadata work must refine this into a `CanMergeStacks` rule that considers
|
|
`MaxStackSize` and any per-instance fields.
|
|
|
|
## Authority And Replication
|
|
|
|
Inventory is server authoritative.
|
|
|
|
- Clients may request inventory actions through server RPCs.
|
|
- The server validates item IDs, quantities, ownership, distance, and action
|
|
rules before mutating inventory.
|
|
- The replicated `Items` array is the client read model for the MVP.
|
|
- `OnRep_Items` triggers `OnInventoryChanged` for UI and debug refresh.
|
|
- Direct client-side inventory edits are not part of the supported model.
|
|
|
|
## Persistence
|
|
|
|
Save data stores the same `FAgrarianItemStack` array used by the runtime
|
|
component. This keeps the MVP save format simple and lets save/load restore the
|
|
player's inventory without a translation layer.
|
|
|
|
Save/load responsibilities:
|
|
|
|
- Save the player inventory from `UAgrarianInventoryComponent::Items`.
|
|
- Restore the stack array onto the component during load.
|
|
- Recompute derived values such as total weight after load from stack data.
|
|
- Avoid saving UI-only selection state as part of the inventory model.
|
|
|
|
## MVP Operations
|
|
|
|
The 0.1.E inventory work should implement these operations on top of the model:
|
|
|
|
- Pickup: world item validates range, authority, stack data, and available
|
|
inventory space before adding.
|
|
- Drop: server removes a stack quantity and spawns a world item or bundle near
|
|
the player.
|
|
- Stack splitting: server moves a requested quantity into a new stack when slots
|
|
are available.
|
|
- Item use: server validates the item type and applies item-specific effects.
|
|
- Equipment: only add dedicated slots once an item type needs equipped state.
|
|
- Carry capacity: continue using total weight first, with later volume or pack
|
|
systems layered on top.
|
|
- UI: read the replicated stack list and send requests back through server RPCs.
|
|
|
|
## Equipment Slot Decision
|
|
|
|
Dedicated equipment slots are deferred for the 0.1.E MVP. Current MVP tools,
|
|
including `basic_tool`, do not yet drive a separate equipped-state rule; they
|
|
can stay in inventory and be checked by item ID when a gather, craft, or build
|
|
action needs a tool requirement. Adding slots before a system reads them would
|
|
create replicated state, UI work, and save/load obligations without changing
|
|
gameplay.
|
|
|
|
Equipment slots should be added when at least one implemented system needs
|
|
state such as active hand item, worn clothing, armor, backpack, held weapon,
|
|
tool durability while equipped, animation stance, or first-person/third-person
|
|
mesh attachment. When that happens, equipment should be server authoritative,
|
|
replicated, persisted, and implemented as a small slot map that references
|
|
inventory stack IDs or moves stack instances between inventory and equipment.
|
|
|
|
## Design Rules
|
|
|
|
- `ItemId` is the stable key. Display names can change.
|
|
- Inventory mutations happen on the server.
|
|
- Stacks should not exceed the item definition's `MaxStackSize` once stack
|
|
splitting and pickup are implemented.
|
|
- Weight lives on item definitions and is cached onto stacks for runtime and
|
|
save simplicity.
|
|
- New item categories should extend `EAgrarianItemType` only when gameplay needs
|
|
distinct rules.
|
|
- Future world-scale storage, containers, vehicles, livestock packs, and markets
|
|
should reuse the same item definition and stack records unless they need
|
|
location-specific metadata.
|