Skip to content

World Map & POIs

Source: PROJECT_CONTEXT.md §6, §8.2, §8.5; config.js map, loot; game.js genMap. Status: ✅ Implemented (in-run inventory / floor-gear behaviors are config-gated — see Open questions).

What it is

The raid arena: a top-down 2D map the raider drops into, loots, and tries to leave alive. A fresh map is generated each run — handcrafted POIs are procedurally placed across it, surrounded by cover, roaming enemies, rival raiders, chests, and scattered ground loot. The map is the space the four player strategies play out in (loot-and-run, mob-hunt, raider-hunt, special-zone raid).

How it works

  • Grid & size. MAP 74×54 tiles at TILE 40 px (per §8.2). Live config defaults under map are larger (w:120, h:120) and are structural — they only apply on a page reload. Map size is read into MAP_W/MAP_H (let, settable per run via setMapSize); the tutorial uses smaller per-stage layouts.
  • Generation each run. genMap(playerPower) builds the world fresh: it lays cover (wall clusters, bush lines/clusters), places the handcrafted POIs, scatters roaming mobs and ground loot, and spawns the rival raiders. Re-rolling the run re-runs it.
  • Risk rings. The map is zoned by radius from center via map.ringCore / map.ringMid (0 = center → 1 = rim). The core is the deadly, loot-rich center (the Ruined Keep sits there with heavy guards). map.coreBias pulls roaming mobs toward the core, so danger and reward both concentrate inward.
  • Handcrafted POIs (placed by genMap, per §8.5):
  • Ruined Keep — the core fortress: the Thornback Brute boss + the richest non-vault (epic) loot, the most heavily guarded approach (core guardians such as a rocketeer + warden watch it).
  • Old Market — home of the Keykeeper (a Forest Warden variant) who carries / drops the Vault key.
  • Graveyard — a POI cluster.
  • Witch's Hollow — a dense stealth thicket (heavy bush cover for sneaking) holding epic loot.
  • Watchtower — guarded by a Stone Sentry (stationary, long sight visR 370) covering long sightlines.
  • The Vault — a locked corner room holding the legendary prize; entry requires the key (forced open over map.gateTime seconds at the gate).
  • World objects (§6):
  • Chests — a primary raid goal; hold gear / upgrade resources. Cracking takes loot.chestTime (CHEST_TIME ≈ 4–5s) of sustained presence — leave and the timer resets. A normal chest holds loot.chestItems items (legendary chests +2). Field chest density = loot.fieldChestDiv (1 per N tiles).
  • Mobs — drop resources on death (10 types, tiered; see the mob/combat docs). Roaming density = map.roamDiv (1 per N tiles).
  • Scattered ground loot — loose pickups across the map; density = loot.groundLootDiv.
  • Rival raidersmap.bots of them (default 5; §8.5 names 4 + one Keybearer), Power-matched to the player, running loot/flee/extract/combat AI.
  • Special / locked zones & the key economy (§6, §8.5): the rarest loot lives behind a lock. You get in by earning the key (hunt the Keykeeper for it) or by waiting for another raider (the Keybearer) to unlock it, then ambushing them to steal the haul. This is the high-risk strategy pillar.
  • Loot rarity (§8.2): common / rare / epic / legendary with value multipliers 1 / 1.8 / 3.0 / 5.0.

Tunables

map group (structural keys = reload; rest = re-roll):

Key Default Meaning
map.tile 40 tile size (px) — structural
map.w / map.h 120 / 120 map size in tiles — structural
map.roundTime 600 raid length (s)
map.spawnSafe 760 no-enemy radius around spawn (px)
map.gateTime 5.0 seconds to force the vault gate open
map.coverWallClusters 0.0138 wall clutter density (× area)
map.coverBushLines 0.0055 bush-line density (× area)
map.coverBushClusters 0.0075 bush-cluster density (× area)
map.roamDiv 450 1 roaming mob per N tiles
map.bots 5 rival raider count
map.coreBias 0.45 roaming pull toward the deadly core (0..1)
map.ringCore / map.ringMid 0.34 / 0.66 risk-ring radii (0 center → 1 rim)
map.wallH 30 wall cube height (px) — structural
map.tilt 0.67 2.5D vertical squash — structural

loot group (chests / scatter / rarity gating):

Key Default Meaning
loot.chestTime 4.0 seconds to crack a chest
loot.chestItems 3 items a normal chest holds (legendary +2)
loot.fieldChestDiv 720 1 field chest per N tiles
loot.groundLootDiv 520 1 ground item per N tiles
loot.maxGearPerMap 5 hard cap on gear pieces a map yields (scarcity); -1 = no cap
loot.gearChance 0.06 chance a loot roll is gear
loot.valuableChance 0.25 of non-gear rolls, chance it's a valuable (else material)
loot.coinChance 0.7 chance a chest also drops a coin
loot.consumableChance 0.45 chance a chest also drops a potion/cell
loot.floorGear false may floor loot contain gear (off = gear only from >t1 mobs/raiders/containers)
loot.t1Valuables false may tier-1 trash mobs drop gear/valuables (off = blueprints only)

Design intent

The map is where every pillar lands. Risk rings + coreBias make route the skill (§2 pillar 2): the best loot sits in the deadliest center and behind the locked Vault, so the player chooses how much risk to take and which way in. Handcrafted POIs give each run a readable shape (Keep = boss/epic, Vault = legendary-but-locked, Witch's Hollow = stealth-thicket) while procedural placement keeps runs fresh. Chests rewarding sustained presence turns looting into an exposure decision, and the key economy (earn it or ambush the Keybearer) directly enables the "raid high-risk special zones" and "hunt other players" strategies (§2).

Open questions / deltas

  • §8.2 size (74×54) vs config.js (120×120). The doc-quoted prototype size and the live config default differ; treat 74×54 as the §8.2 reference, 120×120 as the current reload default. Reconcile before the Unity port.
  • In-run inventory is parked (loot.inRunInventory = false, §8.7): with it off, cracked chests / fallen enemies spill loot in a Diablo-style arc you vacuum by walking over it (spillLoot, tuned by loot.spillRadius/spillTime/spillHop), gear auto-equips empty slots on extract, and the bag is uncapped. Flip the flag to restore the Loot Station triage sheet and the per-chest haul model.
  • Gear is source-gated. While parked, loot.floorGear=false + loot.t1Valuables=false mean gear comes only from >t1 mobs, rival raiders, and rare+ containers — never loose floor scatter or t1 trash.
  • 2.5D camera (§9.1). The map renders with an isometric tilt (map.tilt), not the flat top-down the concept names — Unity must decide whether to keep the 2.5D look.