Design inventory data model
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
# 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.
|
||||
|
||||
## 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.
|
||||
Reference in New Issue
Block a user