World Map & POIs¶
Source: PROJECT_CONTEXT.md §6, §8.2, §8.5;
config.jsmap,loot;game.jsgenMap. 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 tilesatTILE 40px (per §8.2). Live config defaults undermapare larger (w:120, h:120) and are structural — they only apply on a page reload. Map size is read intoMAP_W/MAP_H(let, settable per run viasetMapSize); 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.coreBiaspulls 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.gateTimeseconds 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 holdsloot.chestItemsitems (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 raiders —
map.botsof 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 byloot.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=falsemean 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.