All inventory and equipment mutations in MMO Project are server-authoritative. Clients send intent messages — use item, drop item, pick up a ground item, or unequip a piece of equipment. The server validates the intent, applies the change in a database transaction, and persists the result before broadcasting the authoritative response. No inventory state is applied client-side before the server reply arrives.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/TaylorZaneKirk/MMO-Project/llms.txt
Use this file to discover all available pages before exploring further.
Supported actions
Use Item
Routes by item type: equippable items are handled via
TryEquipInventoryItemAsync; food items restore health and decrement the stack. Unknown or unsupported actions are rejected.Drop Item
Removes the item from
character_inventory and creates a ground_items row at the character’s current tile. Immediately visible to the owner; hidden from others until the private visibility window expires.Pick Up Ground Item
Validates that the character is standing on the item’s tile and that inventory has space. Moves the item from
ground_items into character_inventory.Unequip Item
Validates the target slot is occupied and that at least one inventory slot is open. Moves the item from the equipment slot into inventory.
Inventory item use
InventoryItemUseService.UseInventoryItemAsync handles the primary use action. Non-primary use actions are rejected immediately with use_status: unsupported_use_action.
For a valid request the service loads the inventory item by slot index. If the slot is empty it returns use_status: missing_inventory_item. Otherwise, it routes by item name:
- Food items — if the item name matches a built-in
FoodRestoreDefinition(e.g.Apple,Pie,Orc Burger), the service callsTryConsumeFoodItemAsync, which decrements the stack, applies a randomized health restore within the item’s defined range, and returns achat_message. The result carriesrouted_behavior: consume_foodandhealth_restored. - Equippable items — any item not matched as food falls through to
TryEquipInventoryItemAsync. The result carriesrouted_behavior: equip.
equip emits InventoryChangedEvent and EquipmentChangedEvent; consume_food emits InventoryChangedEvent and CharacterStatusChangedEvent.
Item drop
InventoryItemDropService.DropInventoryItemAsync runs inside an IInventoryGroundItemTransactionRunner to keep the inventory removal and ground-item insertion atomic. The service:
- Loads and locks the character’s
map_presence. Returnsdrop_status: MissingPresenceif absent. - Loads and locks the inventory item by slot index. Returns
drop_status: MissingInventoryItemif absent. - Deletes the
character_inventoryrow. - Inserts a new
ground_itemsrow at the character’s current tile, stampingdropped_atandvisible_to_others_at = dropped_at + DroppedItemPrivateVisibilitySeconds.
InventoryChangedEvent and GroundItemSpawnedEvent.
Ground item pickup
GroundItemPickupService.PickupGroundItemAsync also runs inside the transactional runner. The validation sequence is:
- Load and lock the
ground_itemsrow. Returnpickup_status: MissingGroundItemif not found. - If the character is not the owner and
visible_to_others_atis still in the future, returnpickup_status: NotVisible. - Load and lock the character’s
map_presence. Returnpickup_status: NotAtItemTileif the character is not on the exact tile where the item lies. - Find a merge slot (existing stack of the same item) or the first open slot. Return
pickup_status: InventoryFullif neither exists. - Call
AddInventoryItemAsyncthenDeleteGroundItemAsync.
InventoryChangedEvent and GroundItemRemovedEvent.
Unequip
EquipmentItemUnequipService.UnequipEquipmentItemAsync delegates to CharacterEquipmentRepository.TryUnequipEquipmentItemAsync, which validates the target slot is occupied and finds the first available inventory slot before moving the item. The response carries unequip_status: ok on success or unequip_status: inventory_full if no slot is available.
InventoryChangedEvent and EquipmentChangedEvent.
InventoryRules
InventoryRules is the canonical source of shared inventory constraints:
GroundItemPickupService and any other service that checks available slots reads InventoryRules.DefaultCapacity to keep the limit consistent. Stack count management and merge-slot logic live in the repository layer but are bounded by this constant.
Skill requirements
Equipment items carryskill_requirements and skill_modifiers arrays. Before equipping, the server checks the character’s base skill values against each entry in item_skill_requirements. A character whose base skill is below the required threshold cannot equip the item. Equipment modifiers adjust the character’s effective skill values reported in the world_snapshot and are visible in the client’s skill panel, but modifiers from currently-equipped items do not count toward satisfying the requirements of a new item being equipped.
Ground item visibility
When an item is dropped,visible_to_others_at is set to dropped_at + DroppedItemPrivateVisibilitySeconds. The owner can see and pick up the item immediately. Other characters do not see the item in world_snapshot.ground_items until the visibility window has elapsed.
GroundItemVisibilityWorker polls every second for items whose visible_to_others_at has passed and not yet been broadcast. For each such item it allocates a new map_revision and broadcasts a ground_item_spawned message to all delta clients on the map, then triggers a legacy snapshot refresh for non-delta clients.