Zeeshaun 525f9442c3
All checks were successful
Deploy Promiscuity Auth API / deploy (push) Successful in 48s
Deploy Promiscuity Character API / deploy (push) Successful in 47s
Deploy Promiscuity Inventory API / deploy (push) Successful in 59s
Deploy Promiscuity Locations API / deploy (push) Successful in 46s
k8s smoke test / test (push) Successful in 10s
Adding Kenney UI and item management
2026-03-20 13:11:47 -05:00
..
2026-03-15 10:21:49 -05:00
2026-03-20 09:50:17 -05:00
2026-03-15 10:21:49 -05:00
2026-03-15 10:21:49 -05:00
2026-03-15 13:57:15 -05:00
2026-03-15 10:21:49 -05:00
2026-03-15 13:57:15 -05:00

InventoryApi

Purpose

Owns item-instance state.

This service should answer:

  • what item records currently belong to a character, location, or other container owner
  • where each item currently is
  • whether an item move, split, merge, equip, or consume action is valid
  • which specific item instance is being traded, auctioned, or transferred

This service should not own:

  • auth/token issuance
  • character identity creation
  • location generation
  • auction bidding logic

Ownership model

  • every inventory record has an ownerType and ownerId
  • USER can read and mutate items owned by their own characters
  • USER can read and mutate location/container items only when gameplay rules allow it
  • SUPER can read and mutate any inventory item
  • access should be resolved through the current owner, not from the item id alone

Initial design

Use one MongoDB document per inventory item record.

Practical interpretation:

  • non-stackable items: one document per item instance
  • stackable items: one document per stack

Reasons:

  • every item or stack gets a stable UUID, which is useful for auctions, trade, mail, and auditing
  • ownership transfer is explicit and cheap: update ownerType, ownerId, and slot fields
  • future item metadata like durability, rarity rolls, or provenance can live on the item document
  • auction listings can point to specific item ids instead of vague stack descriptions

Tradeoffs:

  • inventory reads are queries over many documents instead of one aggregate read
  • stack merging and slot enforcement need careful indexes and mutation logic
  • transfers should use transactions when they touch multiple item documents

Suggested endpoints

  • GET /api/inventory/by-owner/{ownerType}/{ownerId} Return all item records currently owned by that container owner.
  • POST /api/inventory/by-owner/{ownerType}/{ownerId}/grant Create a new item record or add quantity into an existing compatible stack.
  • POST /api/inventory/by-owner/{ownerType}/{ownerId}/move Move an item or stack within the same owner inventory.
  • POST /api/inventory/transfer Move quantity from one owner inventory to another.
  • POST /api/inventory/items/{itemId}/consume Consume quantity from a specific item record.
  • POST /api/inventory/items/{itemId}/equip Equip a specific item into a character equipment slot.
  • POST /api/inventory/items/{itemId}/unequip Return an equipped item to a character inventory slot.

Notes:

  • equip and unequip only make sense for character-owned items
  • transfer is the core world interaction primitive for looting, dropping, trading, chest interaction, and auction handoff
  • a future AuctionApi can reserve or re-own specific item ids without redesigning InventoryApi

Item identity

Every inventory record should have a stable UUID string such as:

  • a8d4218b-5e20-4e47-8b5f-0f0f0b9d7e10

Each record also carries an itemKey such as:

  • wood
  • stone
  • pistol
  • small_health_potion

Recommended distinction:

  • id: unique item-record identifier used for ownership changes, auctions, and references
  • itemKey: item definition identifier used to decide stackability and gameplay behavior

Each item document should include:

  • id
  • itemKey
  • quantity
  • ownerType
  • ownerId
  • slot
  • equippedSlot
  • ownerUserId when applicable
  • createdUtc
  • updatedUtc

Optional future fields:

  • durability
  • rarity
  • instanceData
  • listingId
  • reservedUntilUtc

MVP rules

  • an item record must belong to exactly one owner at a time
  • stackable items may share itemKey but should still be represented by one stack record per occupied slot
  • non-stackable items must always have quantity = 1
  • equipped items should set equippedSlot and clear slot
  • unequipped bag items should set slot and clear equippedSlot
  • slot occupancy must be unique per (ownerType, ownerId, slot)
  • all mutating endpoints should be idempotent where practical

Definition source

Item behavior is fully data-driven through the ItemDefinitions collection inside InventoryApi.

That means:

  • no hardcoded stack-size rules
  • no automatic item-definition seeding
  • item instances can only be created for itemKey values that already exist in ItemDefinitions

Client shape

The Godot client should fetch all items for the currently relevant owner and group them into a bag view locally.

Good pattern:

  • login/select character
  • GET /api/inventory/by-owner/character/{characterId}
  • when opening a stash or world container: GET /api/inventory/by-owner/location/{locationId}
  • cache the returned item records locally
  • call transfer/equip/consume endpoints using specific itemId values
  • replace local state with the server response after each mutation