6.5 KiB
E3.M3 — ItemizationAndInventorySchema
Summary
| Field | Value |
|---|---|
| Module ID | E3.M3 |
| Epic | Epic 3 — Crafting Economy |
| Stage target | Prototype |
| Status | In Progress — Slice 1 backlog NEO-50–NEO-56 (E3M3-prototype-backlog; see dependency register) |
Purpose
Item definitions, rarity/quality, stackability, and equipment metadata plus InventorySlot representation. Foundation for craft outputs, quest rewards, combat loot, and trade.
Responsibilities
- Version
ItemDef/ItemInstanceschema; enforce stack and slot rules server-side.
Key contracts
| Contract | Role |
|---|---|
ItemDef |
Static template data. |
ItemInstance |
Per-item state (stack, durability hook, binds). |
InventorySlot |
Container model for players and exchanges. |
Module dependencies
- None
Dependents (by design)
- E3.M2, E3.M4, E5.M3, E7.M2, E8.M3, and any system moving items.
Designer note: stack, slot, and v1 scope
Each ItemDef row under content/items/*.json declares:
stackMax— maximum units per inventory slot for that def (inventory engine in E3M3-05+ enforces this on add).inventorySlotKind—bag(general inventory) vsequipment(equip-stub slot only in prototype; full loadout rules are later).prototypeRole— Slice 1 archetype for CI coverage (material→equip_stub); not a player-facing bucket label (see items.md design lenses).
Prototype v1: optional schema fields rarity, bindPolicy, durabilityMax exist for forward compatibility but are omitted on all six shipped rows. No durability mutation or repair sinks in Slice 1—those belong to E3.M4.
Prototype Slice 1 freeze (NEO-50)
The first shipped six-item spine under content/items/*.json is frozen for downstream references (gather yields, recipes, inventory grants) until a deliberate migration or follow-up issue expands the roster.
ItemDef.id |
prototypeRole |
inventorySlotKind |
stackMax |
|---|---|---|---|
scrap_metal_bulk |
material |
bag |
999 |
refined_plate_stock |
intermediate |
bag |
999 |
field_stim_mk0 |
consumable |
bag |
20 |
survey_drone_kit |
utility |
bag |
1 |
contract_handoff_token |
quest_token |
bag |
1 |
prototype_armor_shell |
equip_stub |
equipment |
1 |
Rules: Do not rename these id values—change displayName only, or add a new id in a follow-up issue. CI (scripts/validate_content.py) enforces exactly these six ids, one row per prototypeRole, and duplicate-id rejection across all item JSON files. Relaxing or changing that gate belongs in a new Linear issue once the catalog intentionally grows.
Related implementation slices
Epic 3 Slice 1 — MVP inventory; item_created, transfer failures.
Server load (NEO-51): On host startup, server/NeonSprawl.Server/Game/Items/ loads content/items/*_items.json with the same validation gates as CI (scripts/validate_content.py) and refuses to listen when the catalog is invalid. Config and discovery: server README — Item catalog. Plan: NEO-51 implementation plan.
Item definition registry (NEO-52): IItemDefinitionRegistry in server/NeonSprawl.Server/Game/Items/ wraps the startup-loaded catalog for read-only lookup by stable itemId and ordered enumeration. NEO-54+ (inventory engine) and future craft/gather callers should inject the interface rather than ItemDefinitionCatalog. Plan: NEO-52 implementation plan.
Item definitions HTTP (NEO-53): GET /game/world/item-definitions — versioned read-only projection (schemaVersion 1, items) backed by IItemDefinitionRegistry; Bruno bruno/neon-sprawl-server/item-definitions/. Plan: NEO-53 implementation plan.
Player inventory store (NEO-54): IPlayerInventoryStore + PlayerInventoryOperations in server/NeonSprawl.Server/Game/Items/ — fixed 24 bag + 1 equipment slots, stack limits from catalog, stable deny reason codes; in-memory + Postgres (V005__player_inventory.sql). Plan: NEO-54 implementation plan.
Player inventory HTTP (NEO-55): GET / POST /game/players/{id}/inventory — versioned snapshot + mutationKind add/remove backed by PlayerInventoryOperations; Bruno bruno/neon-sprawl-server/inventory/. Plan: NEO-55 implementation plan.
Inventory telemetry hooks (NEO-56): comment-only item_created (successful add) and inventory_transfer_denied + reasonCode anchors in PlayerInventoryOperations; server README — Player inventory (NEO-56). Plan: NEO-56 implementation plan; manual QA NEO-56.
Client inventory HUD (NEO-72): Godot inventory_client.gd + item_definitions_client.gd — boot GET inventory snapshot + cached item defs for displayName; UICanvas/InventoryLabel; manual refresh I (NEO-72, NEO-72 manual QA); client/README.md inventory HUD section.
Linear backlog (decomposed): E3M3-prototype-backlog.md — E3M3-01 NEO-50 (content + CI) through E3M3-07 NEO-56 (telemetry hooks). Client (Slice 5): inventory HUD landed — E3S5-client-prototype-backlog.md E3S5-01 NEO-72.
Source anchors
- Master plan:
neon_sprawl_vision.plan.md— Epic 3. - Module dependency register