Skip to content

Loot & Inventory (in-raid)

Source: PROJECT_CONTEXT.md §8.3.1, §8.7; config.js loot; game.js renderStation, renderDock, equipNow, spillLoot, openBagSheet, autoEquipEmpty. Status: ⚠️ Partial / 🅿️ Parked — the full Loot Station is built but gated off (loot.inRunInventory = false); a Diablo-style ground-spill auto-grab mode runs in its place.

What it is

The in-raid looting layer: how you read, triage, and take loot from chests, corpses, and the ground while still exposed on the map. Two distinct modes exist, switched by one flag. When the in-run inventory is on, a non-pausing Loot Station bottom sheet handles all triage. When it's off (current default), loot simply spills on the ground and you vacuum it by walking over it.

How it works

Loot Station mode (inRunInventory = true)

  • One exposed, non-pausing bottom sheet (#lootSheet, renderStation) handles all in-raid inventory — no separate pausing bag modal.
  • At a container (chest/corpse): two panes — the container's c.loot on top, your bag below (+ Safe Pocket chip + bag/cap counter).
  • From the HUD bag button (openBagSheet): bag pane only, container pane hidden.
  • Layout — three stable zones: header · single-scroll list region (container stacked over bag) · a fixed-height inspector dock (renderDock) at the bottom. The dock has a constant row structure and swaps content in place, so selecting never resizes the sheet. It shows portrait · name · slot/rarity/level · power-verdict chip, a full 4-stat grid (statCellsHTML: now→next + colored delta per stat), and a passive gain/lose comparison (passiveCompareHTML: "+" what the candidate brings vs "−" what the displaced piece takes; completing a set shows the unlocked bonus, breaking a set shows a pulsing red warning).
  • Tap-primary verbs (drag-and-drop is a planned Phase-2 accelerant):
  • Gear = a decision → tap selects it into the dock (container gear too, so you judge stats before it costs a bag slot). ⤵ Take is the primary chip; ⚔ Equip now swaps straight from the chest.
  • Trinkets / coins / materials = no decision → tap takes instantly.
  • Bag item tap = select (tap again to deselect) → Equip / Protect / Dump chips.
  • Take all in the container header.
  • Dump pushes a bag item into the open container to free a slot (it stays as leftover, lost after the raid — the Arc Raiders model); bag-only mode falls back to Drop on the ground.
  • Gear cards show a ▲±Npw upgrade badge so keepers pop.
  • Equip-now is instant (equipNow) — the old rooted fieldEquipTime channel is gone. It is a snappy in-run power spike, emits a loud ping, and keeps your current HP/shield ratio (not a free heal). It is gated only by the exposure of being in the loud, non-pausing sheet.
  • Exposure is the cost. The sheet roots you (update() keys off lootSheetOpen), every transfer pulses loot.lootRootNoise (loud → draws enemies), and a hit slams it shut (lootInterruptOnHit).
  • Rarities drive value: common / rare / epic / legendary at value mult 1 / 1.8 / 3.0 / 5.0 (RAR_MULT).
  • Bag cap is BAG_CAP 18 when capping is on (loot.bagCap); economy safety comes from endRun, which forfeits a field-equipped piece on death and banks it only on extraction.

Spill / auto-grab mode (inRunInventory = false, current default)

  • Cracking a chest or felling an enemy spills its loot in an arc on the ground (spillLoot) — Diablo-style.
  • Each piece arcs out and settles before it can be read or grabbed: no name/value label or pickup until it lands. Landings clamp to reachable floor (nearestFloor) so loot never strands inside a wall.
  • You vacuum loot by walking over it — everything auto-grabs on contact while the inventory is parked.
  • The bag is uncapped (bagCap = -1); there is no Loot Station sheet, no field-equip, no Dump, no Safe Pocket button.
  • The haul banks on extract and autoEquipEmpty fills empty loadout slots with the best matching gear (this builds the starter kit, especially for the gearless tutorial start).

Tunables (config.js loot)

Key Default Note
inRunInventory false master toggle for Loot Station / field-equip / bag UI
autoEquipEmpty true on extract, fill empty loadout slots from the haul
bagCap -1 run bag slots; -1 = uncapped (18 when capped)
safeSlots 1 protected bag slots that survive death
chestTime 4.0 seconds to crack a chest
chestItems 3 items a normal chest holds (legendary +2)
lootRootNoise 240 noise radius (px) pulsed while rummaging
lootInterruptOnHit 1 a hit closes the loot sheet
corpseMinItems 2 min drops for a kill to leave a lootable body
spillRadius 64 radius (px) loot scatters into
spillTime 0.4 seconds an item arcs before settling
spillHop 34 peak height (px) of the spill arc
labelRadius 95 show name/value label on ground loot within this px

Rarity value multipliers (RAR_MULT, game.js): common 1 · rare 1.8 · epic 3.0 · legendary 5.0.

Design intent

Serves the hide-and-kill and accessible-extraction pillars (PROJECT_CONTEXT §2). The Loot Station turns "carrying loot" into "playing with loot" — triage, instant power spikes, and Safe-Pocket protection — while making looting itself a risk decision: rooting, noise pulses, and damage-interrupt mean a careful, well-positioned looter thrives and a greedy one gets caught. This is also the foundation for planned multiplayer, where standing in a container is genuinely dangerous. The parked spill/auto-grab mode keeps the loop frictionless for the current Diablo-2 / "We Are Warriors" pass — loot you can read by its arc and grab by walking over.

Open questions / deltas

  • The Loot Station is parked, not removed (§8.7). The full triage system is config-gated behind inRunInventory = false; flipping it to true restores it (chests hold their haul for the sheet, multi-item kills leave a lootable body). Decide whether the Unity port ships the Station or the spill mode as the baseline.
  • FTUE inspect/equip + dump/Safe-Pocket coaching steps are gated on inRunInventory (§8.6) — they vanish while it's off and return automatically if it's switched on.