# DESIGN & TECHNICAL SPECIFICATIONS: INVENTORY, PERSONAL STASH, PREMIUM MERCHANT TAB & 2D SPATIAL GRID
# PROJECT FREEEXILE: GRIMDARK SAVAGE PRIMAL EXILE ARPG 2.5D

> **Responsible Departments**: Lead Systems Designer (`poe2_game_designer`), Lead Documentation Architect (`lead_documentation_architect`), Lead iOS Client Engineer (`ios_client_engineer`), Lead Server Architect (`server_systems_architect`).  
> **Document Version**: 1.0.0-CANONICAL  
> **Document Code**: `WIKI-SPEC-INV-001-EN`  
> **Implementation Modules**: [`server/inventory/`](file:///c:/Projects/FreeExile/server/inventory/), [`client/webapp/js/ui/inventory_stash.js`](file:///c:/Projects/FreeExile/client/webapp/js/ui/inventory_stash.js), [`docs/game_design/EQUIPMENT_SLOT_AND_SPATIAL_GRID_SYSTEM.md`](file:///c:/Projects/FreeExile/docs/game_design/EQUIPMENT_SLOT_AND_SPATIAL_GRID_SYSTEM.md).

---

## 1. DESIGN PHILOSOPHY & THREE-TIER STORAGE ARCHITECTURE

Item management in `FreeExile` honors the tactical heritage of classic hardcore ARPGs (*Path of Exile 2*, *Diablo II*), emphasizing spatial value, perceived mass, and strategic inventory management during hostile wasteland survival.

```mermaid
flowchart TD
    Player[Exile Wanderer] --> Bag[Tier 1: Survival Backpack\n12x5 = 60 Grid Slots]
    Player --> Stash[Tier 2: Personal Stash\n3 Tabs x 144 Grid Slots]
    Player --> Merchant[Tier 3: Premium Merchant Tab\n144 Grid Slots]

    subgraph MegaShop Gating
        Merchant -.-> Check{SKU Owned?}
        Check -- No --> Locked[Locked Tab & Prompt 500 Blood Coins]
        Check -- Yes --> Active[Instant Bazaar Listing Enabled]
        ShopCatalog[MegaShop: item_premium_merchant_stash_tab] --> Active
    end

    subgraph Two-Phase Commit [2PC Anti-Duplication]
        Active --> Consignment[The Outcast Bazaar Vault]
        Consignment --> DistributedLedger[Immutable Event Sourcing Ledger]
    end
```

### Storage Tiers Specification:

| Storage Tier | Identifier | Grid Canvas | Max Capacity | Authorization & Domain Characteristics |
| :--- | :--- | :---: | :---: | :--- |
| **Survival Backpack** | `INVENTORY_BAG` | $12 \times 5$ | $60$ slots | Unlocked by default; carried into combat zones. Features 8-slot equipment paperdoll. |
| **Personal Stash** | `PERSONAL_STASH` | $12 \times 12$ / tab | $144$ slots / tab ($3$ tabs = $432$ slots) | Located in Haven / Astral Hideout. Comprises General, Currency, and Equipment tabs. |
| **Merchant Stash** | `PREMIUM_MERCHANT` | $12 \times 12$ | $144$ slots | **Premium Feature**: Requires 500 Blood Coins in MegaShop. Directly lists items to The Outcast Bazaar. |

---

## 2. PREMIUM MERCHANT STASH TAB & MEGASHOP GATING

### 2.1. Unlock Protocol & Currency Gating
- **Registered SKU**: [`item_premium_merchant_stash_tab`](file:///c:/Projects/FreeExile/server/shop/shop_catalog.py#L90-L98).
- **Category**: `ShopCategory.ITEMS` (Account Convenience & Utility).
- **Price**: $500$ Outcast Blood Coins (Gold Cores) $\approx \$5.00\text{ USD}$.
- **Entitlement Scope**: Permanent account entitlement across all exile characters in the active seasonal league.
- **Locked State UI**: When unowned, the tab displays a `🔒 PREMIUM TRADE` badge, darkens the slot grid, and renders an unlock button redirecting to MegaShop (`window.unlockMerchantStashViaShop`).

### 2.2. Distributed Two-Phase Commit (2PC) Anti-Dupe Engine
All listing, re-pricing, and item withdrawal operations synchronize with [`two_phase_commit.py`](file:///c:/Projects/FreeExile/server/trade/two_phase_commit.py) via **SQLite Exclusive 2PC**:
1. **Phase 1 (Prepare / Escrow Lock)**: Initiates `BEGIN EXCLUSIVE TRANSACTION` in the SQLite Trade Ledger to secure an exclusive write lock, ensuring the item is not contested by concurrent sessions and mitigating fake packet duplication.
2. **Phase 2 (Commit / Rollback)**: Transfers item ownership to the Outcast Bazaar public vault. Automatically deducts a $5\%$ transaction tax burned permanently from database ledgers to eliminate hyperinflation.

---

## 3. 2D SPATIAL GRID SLOT MATRIX

Unlike primitive $1 \times 1$ grid games, `FreeExile` allocates physical bounding boxes ($W \times H$) reflecting item bulk and weapon length:

```
[TWO-HAND WEAPON]   [BODY ARMOR]   [HELM/BOOTS/GLOVE]   [BELT]      [RING/GEM]
    ┌───┬───┐         ┌───┬───┐          ┌───┬───┐       ┌───┬───┐     ┌───┐
    │ 1 │ 2 │         │ 1 │ 2 │          │ 1 │ 2 │       │ 1 │ 2 │     │ 1 │
    ├───┼───┤         ├───┼───┤          ├───┼───┤       └───┴───┘     └───┘
    │ 3 │ 4 │         │ 3 │ 4 │          │ 3 │ 4 │        (2 x 1)      (1 x 1)
    ├───┼───┤         ├───┼───┤          └───┴───┘
    │ 5 │ 6 │         │ 5 │ 6 │           (2 x 2)
    ├───┼───┤         └───┴───┘
    │ 7 │ 8 │          (2 x 3)
    └───┴───┘
     (2 x 4)
```

### Standardized Bounding Box Matrix:

| Equipment Category | Width ($W$) | Height ($H$) | Total Slots ($S$) | Representative Archetypes |
| :--- | :---: | :---: | :---: | :--- |
| **Two-Handed Weapons** | $2$ | $4$ | $8$ slots | Executioner Greatblade, Greataxe, Bronze Spade, War Spear |
| **Greatbows** | $2$ | $4$ | $8$ slots | Bone Recurve Greatbow, Sun-Piercing Celestial Bow |
| **One-Handed Weapons** | $1$ | $3$ | $3$ slots | Azure Wind Ancient Sword, One-Handed Cleaver, War Mace |
| **Daggers & Claws** | $1$ | $2$ | $2$ slots | Nether Blood Claw, Outcast Fang Dagger |
| **Body Armor** | $2$ | $3$ | $6$ slots | Yaksha Blood Plate, Eight Wilds Heart Armor |
| **Helmets / Gloves / Boots / Shields** | $2$ | $2$ | $4$ slots | Crane Helm, Demon Slayer Gloves, Feral Bone Shield |
| **Belts** | $2$ | $1$ | $2$ slots | Five Elements Cord, Rusted Iron Link Belt |
| **Jewelry & Barter Bloodstones** | $1$ | $1$ | $1$ slot | Bone Relic Amulet, Spirit Ring, Blood Soul Gem (Max Stack 5,000) |

---

## 4. BACKEND SPATIAL ENGINE & DEFRAGMENTATION ALGORITHMS

Implemented in [`server/inventory/spatial_inventory_grid.py`](file:///c:/Projects/FreeExile/server/inventory/spatial_inventory_grid.py):

### 4.1. Boundary & AABB Collision Check (`can_place`)
Calculates placement validity for an item of size $W \times H$ at grid coordinate $(x, y)$:
$$\text{Valid} \iff (x \ge 0) \land (y \ge 0) \land (x + W \le W_{\text{grid}}) \land (y + H \le H_{\text{grid}}) \land \left(\forall (i, j) \in [0, W) \times [0, H), \text{Grid}[y+j][x+i] = \emptyset \right)$$

### 4.2. Intelligent First-Fit Search (`find_first_fit`)
Performs a Row-Major raster scan ($y: 0 \to H-1$, $x: 0 \to W-1$) to determine the earliest unoccupied coordinate anchor $(x_0, y_0)$ that satisfies `can_place`.

### 4.3. Auto-Sort & 2D Bin-Packing Defragmentation (`auto_compact`)
Optimizes inventory space through heuristic packing:
1. Gathers all current items into a transient collection and flushes the grid.
2. Sorts items in strict priority:
   - **Decreasing Area**: $S = W \times H \downarrow$.
   - **Decreasing Height**: $H \downarrow$ (Places $2 \times 4$ great weapons before $2 \times 3$ armor).
   - **Decreasing Item Level**: $\text{iLvl} \downarrow$.
3. Re-inserts each item sequentially via `find_first_fit` to eliminate fragmentation holes.

---

## 5. CLIENT USER INTERFACE & TDD VERIFICATION

- **8-Slot Equipment Paperdoll**: Distinct visual slots (`MAIN_HAND`, `OFF_HAND`, `HELMET`, `BODY_ARMOR`, `GLOVES`, `BOOTS`, `AMULET`, `RING_1`).
- **Slot Dimension Tags**: Items render lightweight badge tags (e.g. `2x4`, `2x3`, `1x1`) in the upper-left corner.
- **Quick Controls**:
  - `⚡ Sắp Xếp Gọn / Auto-Sort`: Executes `window.autoSortInventoryBag()` client-side defragmentation.
  - Shortcut `I`: Toggles Inventory & Stash Modal.
- **Automated Test Coverage**:
  - [`tests/unit/test_spatial_inventory_grid.py`](file:///c:/Projects/FreeExile/tests/unit/test_spatial_inventory_grid.py): Unit tests for collision, boundaries, removal, and auto-compact.
  - [`tests/unit/test_inventory_service.py`](file:///c:/Projects/FreeExile/tests/unit/test_inventory_service.py): Multi-container management and coin gating tests.
