Back to Game
Cartographer's Fog - Game Design Guide
Game Concept
# Cartographer's Fog
## Theme
You are the Royal Cartographer of a kingdom that has lost its maps. A mysterious fog has swallowed the realm, erasing all knowledge of what lies beyond the capital. Your task: venture into the unknown, map the terrain, and rediscover the world. But the fog is alive — it creeps back slowly, reclaiming unmapped territory. What you map must be maintained, or the world fades again.
## Visual Game World
The Canvas displays a dark fog-covered terrain grid. At the center: your camp (a small fire with warm glow). Surrounding it: unseen darkness peppered with subtle hints — faint glimmers suggesting water, shadows of mountains, flickers that might be civilization. As you direct cartographers outward, they carve paths through the fog, revealing what's beneath: forests (dark green clusters), rivers (blue ribbons winding), mountains (grey peaks), ancient ruins (crumbled stone), and resource nodes (glinting minerals). The fog at the edges constantly undulates, slowly encroaching on revealed land — a visual reminder of the ongoing threat.
## Player Interaction
The player DIRECTLY interacts with the Canvas through three core actions:
1. **Click on fog tiles to send a cartographer there** — The selected cartographer physically walks across the map, revealing tiles as they pass. The player chooses which adjacent fog tile to explore next, creating organic pathing decisions based on visible hints.
2. **Drag from one revealed tile to another to establish trade routes** — Once two locations are revealed and connected by explored path, the player can draw a route. Merchants then travel this route automatically, generating resources.
3. **Click on resource nodes to assign workers** — When a cartographer reveals iron, gold, or herbs, the player clicks to build a harvest camp. Workers appear and begin gathering, visible as small sprites carrying resources back to camp.
4. **Right-click on cartographers to cycle their specialization** — Scout (moves faster, reveals larger area), Mapper (leaves permanent trail markers that slow fog regrowth), or Explorer (can uncover special hidden locations).
5. **Click on revealed ancient ruins to investigate** — Special locations that the player must choose to spend time/resources exploring, revealing unique upgrades or story fragments.
## Entity Types
### Cartographer
- **Sprite**: Knight sprite (recolored to brown/tan explorer outfit), using ProceduralSprite color variant
- **Appearance**: Small humanoid with wide-brimmed hat, carrying a scroll and compass. Animated walking frame (4 frames). Leaves small light trail as they move through fog.
- **Behavior**: Walks from tile to tile along player-selected paths. Movement speed varies by specialization. Reveals a 3x3 tile area around current position. Has limited stamina — must return to camp to rest.
- **Interaction**: Player clicks adjacent fog to send them there. Right-click to cycle specialization. They cannot enter deep fog without sufficient torch upgrades.
### Fog
- **Sprite**: ProceduralSprite — semi-transparent dark grey overlay tiles
- **Appearance**: Dark undulating clouds covering unexplored tiles. Edge tiles have animated wisps that drift inward (visualizing regrowth). Deep fog is darker; edge fog has subtle gradients.
- **Behavior**: Slowly regrows on tiles that haven't been visited recently (based on a "mapped stability" meter). Certain tile types (mountains, deep forest) resist fog regrowth. Ancient landmarks create permanent fog-free zones.
- **Interaction**: Fog is what the player fights against. Cartographers clear it. Upgrades slow its return. Special locations can push it back.
### Worker
- **Sprite**: Slime sprite (recolored to human skin tones), using ProceduralSprite
- **Appearance**: Small humanoid figure with a sack over shoulder. Animates between resource node and camp. Carries visible resource icon.
- **Behavior**: Spawns at assigned resource camps. Walks to resource, harvests (visible animation), walks back to camp. Each trip takes 5-10 seconds. Dies if fog overtakes their camp.
- **Interaction**: Player assigns them by clicking resource nodes. Can be reassigned. Maximum workers per camp based on upgrades.
### Merchant
- **Sprite**: Wizard sprite (recolored to merchant blue/gold), using ProceduralSprite
- **Appearance**: Robed figure with pack, animated walking along established routes. Leaves faint gold trail.
- **Behavior**: Automatically patrols trade routes the player draws. Generates passive income based on route length and tiles passed. Faster on roads (player can upgrade routes).
- **Interaction**: Player draws routes by dragging between locations. Merchants appear and begin patrolling. Can be raided by fog-born shadow creatures.
### Shadow Creature
- **Sprite**: Ghost sprite (recolored to black/purple), using ProceduralSprite
- **Appearance**: Wraith-like entity that emerges from deep fog. Animated floating movement with flickering opacity.
- **Behavior**: Spawns in deep fog near revealed territory. Attacks cartographers, workers, and merchants. Moves toward nearest friendly entity. Becomes more frequent as more territory is revealed.
- **Interaction**: Player can click to have nearby cartographers defend (if they have combat upgrades). Can be permanently banished by building lantern towers.
### Lantern Tower
- **Sprite**: ProceduralSprite — tall structure with glowing top (animated pulse)
- **Appearance**: Stone tower with burning brazier at top. Glows visible yellow/orange, pushing back nearby fog. Animated flame flicker.
- **Behavior**: Stationary structure placed by player. Emits light that prevents fog regrowth in radius. Damages shadow creatures that enter range. Must be built on revealed tiles.
- **Interaction**: Player clicks revealed tile to place (costs resources). Multiple towers can create overlapping safe zones.
## Core Loop
### Second-to-Second (ACTIVE GAMEPLAY)
- **What they DO**: Click adjacent fog tiles to direct cartographers into the unknown. Watch them walk, reveal terrain, and discover resources. Decide which direction to explore based on visible hints (shadows of mountains, glints of water). Click on discovered resources to assign workers. Draw trade routes between valuable locations.
- **What they SEE**: Cartographers walking through dark fog, leaving light trails. Tiles transitioning from darkness to revealed terrain (forests, rivers, mountains). Workers marching to and from resource nodes. Merchants patrolling routes. Fog slowly creeping back at the edges of explored territory.
- **What DECISIONS they make**: Which direction to explore next (follow the river toward the mountains, or head toward those mysterious ruins?). Which resource nodes are worth exploiting now vs. later. Where to place lantern towers for maximum fog protection. Which trade routes will be most profitable. When to push deep into fog vs. secure current territory.
### Minute-to-Minute (STRATEGIC DECISIONS)
- **What upgrades they buy**: Better torches (larger reveal radius), faster cartographer movement, more workers, lantern towers, combat training for cartographers, road upgrades for merchants.
- **What they check**: How much territory is being lost to fog regrowth vs. gained through exploration. Resource stockpiles and production rates. Which undiscovered areas are worth prioritizing (visible hints in fog).
- **How Canvas gameplay CHANGES**: More cartographers on screen simultaneously. Larger revealed territory. More complex trade route networks. More lantern towers pushing back fog. Shadow creatures becoming more common, requiring defensive placement. Ancient ruins being discovered and investigated.
### Session-Level (META STRATEGY)
- **What long-term build/strategy they're pursuing**: "Expansionist" — push rapidly outward, accept some fog loss, build wide network of lantern towers to stabilize. "Consolidationist" — secure small areas completely before expanding, maximize trade route efficiency. "Hunter" — actively seek and investigate ancient ruins for unique upgrades.
- **How visual game world has evolved**: From a small campfire in darkness to a sprawling network of revealed lands, roads connecting resource nodes, towers keeping fog at bay, and ancient sites being uncovered. The canvas transforms from mostly dark to mostly revealed — but the fog keeps pushing at the edges.
- **The push toward prestige**: Eventually the player reaches the edge of the known world — the ultimate map boundary. They can choose to Ascend: their cartographer becomes a legend, knowledge is enshrined in the Royal Archives, and they start fresh in a new, more challenging region with permanent bonuses.
## The 30-Second Gameplay Description
The player's cartographer stands at the edge of revealed grassland, where it meets the rolling fog. They click three tiles forward — the cartographer walks, light spreading from their lantern. The fog reveals a river glinting in the darkness. The player clicks along the riverbank, guiding the explorer forward while keeping the water in sight for navigation. Suddenly the cartographer stops — an iron deposit! The player quickly clicks it to assign a worker. A small figure appears from camp and begins marching toward the iron. To the south, the fog ripples — a shadow creature emerges! The player right-clicks their cartographer to switch to combat mode, then clicks the creature. The cartographer draws a sword and charges. As the battle concludes, the player notices the fog has begun creeping back on the northern edge of their territory. They click back toward camp, then pivot eastward toward the mountains visible in the distance.
## Currencies
### Gold
- **Role**: Primary currency
- **Earned by**: Merchants patrolling trade routes (gold coins appear on map when merchant returns to camp), selling collected resources from workers
- **Spent on**: Hiring additional cartographers, building lantern towers, upgrading equipment
- **Feel**: The steady heartbeat of your economy. Visible, predictable, necessary for everything.
### Knowledge
- **Role**: Upgrade/Unlock currency
- **Earned by**: Revealing new tiles for the first time (floating scroll icon appears), investigating ancient ruins (large burst of scrolls)
- **Spent on**: Unlocking new cartographer specializations, revealing map hints in fog, prestige currency
- **Feel**: The reward for exploration. Pushing into the unknown directly gives you power.
### Torches
- **Role**: Resource management / limiting factor
- **Earned by**: Worker harvesting from forest tiles, passive regeneration at camp
- **Spent on**: Each tile a cartographer explores consumes torch light. Deep fog consumes more. Lantern towers burn torches over time.
- **Feel**: The ticking clock that forces decisions. Can't explore forever without gathering more.
### Influence
- **Role**: Strategic/late-game currency
- **Earned by**: Building and upgrading lantern towers, banishing shadow creatures, connecting trade routes to distant locations
- **Spent on**: Permanent map-wide upgrades, slowing fog regrowth globally, prestige multiplier
- **Feel**: The measure of how thoroughly you've mastered the region.
### Currency Flow
Gold buys cartographers and towers → Cartographers reveal tiles (Knowledge) and find resources → Workers gather resources (produces Gold) → Lantern towers protect territory (generates Influence) → Knowledge unlocks better torches (saves Torches) → Influence upgrades reduce costs (saves Gold) → More gold for expansion → More exploration → More Knowledge.
Knowledge is earned by exploring, spent to explore more efficiently.
Gold is earned by settled territory, spent to expand.
Torches limit exploration rate, must be balanced with expansion.
Influence rewards securing territory, provides permanent power.
## Progression Hooks
### Early Game (0-5 minutes)
- First cartographer appears. The immediate "aha" is revealing the first few tiles and seeing that different terrain has different values (mountain vs. forest vs. water).
- The first discovery of an ancient ruin visible through the fog — a tantalizing mystery in the distance.
- First resource node appears, and the worker system unlocks. The economy starts flowing.
### Mid Game (5-15 minutes)
- Shadow creatures begin spawning. The game transforms from pure exploration to exploration + defense. Lantern towers unlock.
- Trade route system unlocks. The player begins optimizing merchant paths for maximum gold.
- Multiple cartographers can be active simultaneously. Coordination becomes important.
- Ancient ruins can be investigated, revealing unique upgrades.
### Late Game (15-30 minutes)
- The map boundary is reached. The player must decide whether to prestige or maximize current territory.
- Fog becomes more aggressive, shadow creatures more common. The final challenge is holding territory.
- Deep fog areas unlock — special high-reward zones that require elite cartographers.
### Key Milestones
1. **First Reveal** — Cartographer leaves camp, reveals surrounding 3x3 area. Canvas goes from dark to visible.
2. **First Resource** — Iron deposit discovered. Worker system unlocks.
3. **First Trade Route** — Two locations connected, merchant appears. Economy engine starts.
4. **First Shadow** — Fog creature emerges. Combat unlocks.
5. **First Lantern** — Tower built. Territory can be permanently held.
6. **First Ruin** — Ancient site investigated. Unique upgrade gained.
7. **Multi-Explorer** — Second cartographer hired. Can explore multiple directions.
8. **Map Edge** — Reach the boundary. Prestige becomes available.
9. **Deep Fog** — Special zones unlock. Elite cartographers required.
10. **Ascension** — Player chooses to prestige, becoming a legendary cartographer.
## Meaningful Choices
- **Choice 1**: Cartographer Specialization — Scout (faster exploration, smaller light radius), Mapper (leaves permanent markers that slow fog in area, slower), or Explorer (can enter deep fog, reveals special locations, slower movement). The player's choice changes how they approach exploration — quick reconnaissances, methodical territory securing, or high-risk high-reward ventures. Different playstyles visible on Canvas: Scout players have many fast-moving cartographers darting around; Mapper players have fewer cartographers but stable territory; Explorer players have cartographers that venture far into dangerous fog.
- **Choice 2**: Lantern Tower vs. Mobile Cartographer — Spend resources on static defenses that hold territory (towers) or mobile exploration units that reveal more (cartographers). Towers protect existing lands but don't expand. Cartographers expand but leave territory vulnerable. The player must balance offense vs. defense. Visible on Canvas as a well-defended but small territory vs. a large but constantly shifting territory.
## Prestige Concept
- **Trigger**: Player reaches the map edge and chooses to Ascend, OR has explored 90% of the map and has sufficient Influence.
- **What resets**: All territory, cartographers, towers, workers, merchants, and accumulated resources return to zero. Fog resets completely.
- **What persists**: Knowledge (prestige currency), unlocked specializations, and permanent bonuses chosen with Influence.
- **Prestige currency**: Cartography Points — earned based on total tiles revealed across all runs, ancient ruins investigated, and map percentage at prestige.
- **Acceleration**: First run reveals basic terrain slowly. Later runs start with better torches (larger reveal radius), faster cartographer movement, and the ability to see hints in fog from further away. Expansion is faster because the player knows what they're doing and has better tools.
- **Visual transformation**: After each prestige, the new region is visually distinct — different terrain colors, different ancient ruin styles, new resource types. The fog has a different character (different undulation patterns, colors). The campfire evolves into increasingly impressive bases.
## Controls Display
- Left Click → Send cartographer / Place tower / Assign worker / Investigate ruin
- Right Click → Cycle cartographer specialization
- Drag → Create trade route between locations
- 1, 2, 3 → Select cartographer (when multiple active)
- Space → Pause / Resume fog regrowth
## Getting Started Tutorial
• Click on dark fog tiles to send your cartographer exploring and reveal the map
• Discover resources and click them to assign workers who gather gold
• Build lantern towers to protect your territory from the encroaching fog
• Reach ancient ruins and investigate them for powerful knowledge upgrades
## Unique Selling Point
The fog that constantly fights back against your exploration creates a dynamic tension — you're not just revealing a static map, you're actively HOLDING territory against an encroaching darkness. Every tile you reveal is a tile you must defend, and the most valuable locations attract the most fog. The game becomes a balancing act between expansion and consolidation.
## Visual Direction
Color palette: Dark foreground (#1a1a2e to #16213e for fog gradients), vibrant revealed terrain (#2d6a4f forest, #0077b6 water, #6c757d mountain, #d4a373 ruins). Warm golds and oranges for friendly entities and campfires. Purple-black for shadow creatures. Glowing effects on lantern towers and cartographer torches. The contrast between dark fog and vibrant revealed land should be stark and satisfying.
## Technical Scope Check
Very implementable with the sprite framework:
- Grid-based map is straightforward data structure
- Fog of war is just an overlay system with timers
- Cartographers walking and revealing is pathfinding + visibility checks
- Workers and merchants are simple state machines
- Towers are static entities with radius checks
- All sprites available: Knight (cartographer), Slime (worker), Wizard (merchant), Ghost (shadow creature), plus procedural shapes for towers, resources, fog
- No complex physics, just grid movement and timer-based fog regrowth
- Trade routes are stored paths with merchant agents following them
- Prestige is standard incremental save/load with permanent bonuses
Currencies
{
"game_name": "Cartographer's Fog",
"section": "currencies",
"job_id": 69,
"phase": 2,
"currencies": {
"gold": {
"displayName": "Gold",
"icon": "🪙",
"startingAmount": 50,
"cap": null,
"decimals": 0,
"suffixes": [
"K",
"M",
"B",
"T"
],
"persistsOnPrestige": false,
"role": "Primary currency for hiring units and building structures"
},
"knowledge": {
"displayName": "Knowledge",
"icon": "📜",
"startingAmount": 0,
"cap": null,
"decimals": 0,
"suffixes": [
"K",
"M"
],
"persistsOnPrestige": false,
"role": "Upgrade currency earned through exploration"
},
"torches": {
"displayName": "Torches",
"icon": "🔥",
"startingAmount": 20,
"cap": 100,
"decimals": 0,
"suffixes": [],
"persistsOnPrestige": false,
"role": "Exploration fuel that limits expansion rate"
},
"influence": {
"displayName": "Influence",
"icon": "✨",
"startingAmount": 0,
"cap": null,
"decimals": 1,
"suffixes": [
"K",
"M"
],
"persistsOnPrestige": true,
"role": "Strategic currency for permanent upgrades"
},
"cartographyPoints": {
"displayName": "CP",
"icon": "🗺️",
"startingAmount": 0,
"cap": null,
"decimals": 2,
"suffixes": [
"K",
"M"
],
"persistsOnPrestige": true,
"role": "Prestige currency for permanent bonuses across runs"
}
},
"currencySources": {
"tileReveal": {
"currency": "knowledge",
"formula": "tileKnowledgeValue",
"tileKnowledgeValue": {
"grass": 1,
"forest": 2,
"water": 3,
"mountain": 3,
"ruins": 5
},
"gameplayAction": "Cartographer walks onto fog tile"
},
"ruinInvestigate": {
"currency": "knowledge",
"formula": "15 + 5 * ruinTier",
"baseReward": 15,
"tierMultiplier": 5,
"gameplayAction": "Player clicks ancient ruin to investigate"
},
"ruinInvestigateInfluence": {
"currency": "influence",
"formula": "5 + 2 * ruinTier",
"baseReward": 5,
"tierMultiplier": 2,
"gameplayAction": "Player clicks ancient ruin to investigate"
},
"shadowKilled": {
"currency": "influence",
"formula": "2 + 0.5 * shadowLevel",
"baseReward": 2,
"levelMultiplier": 0.5,
"gameplayAction": "Cartographer defeats shadow creature"
},
"shadowKilledGold": {
"currency": "gold",
"formula": "5 * (1 + 0.1 * territoryPercent)",
"baseReward": 5,
"territoryMultiplier": 0.1,
"gameplayAction": "Cartographer defeats shadow creature"
},
"merchantReturn": {
"currency": "gold",
"formula": "2 * routeTiles * (1 + 0.05 * roadLevel)",
"baseMerchantYield": 2,
"gameplayAction": "Merchant completes patrol route to camp"
},
"workerGoldMining": {
"currency": "gold",
"formula": "5 * (1 + 0.1 * mineLevel)",
"baseGoldYield": 5,
"gameplayAction": "Worker returns from gold/iron mine to camp"
},
"workerTorchHarvest": {
"currency": "torches",
"formula": "3 * (1 + 0.05 * forestLevel)",
"baseTorchYield": 3,
"gameplayAction": "Worker returns from forest to camp"
},
"lanternTowerPassive": {
"currency": "influence",
"formula": "0.1 * towerLevel / 60",
"perTowerPerLevel": 0.1,
"gameplayAction": "Passive generation per second (no action)"
},
"campTorchRegen": {
"currency": "torches",
"formula": "1 / 3",
"perSecond": 0.333,
"gameplayAction": "Passive regeneration at camp (no action)"
},
"prestige": {
"currency": "cartographyPoints",
"formula": "tilesRevealed * 0.1 + ruinsInvestigated * 5 + mapPercent * 50 + firstPrestigeBonus",
"tileMultiplier": 0.1,
"ruinMultiplier": 5,
"mapPercentMultiplier": 50,
"firstPrestigeBonus": 10,
"gameplayAction": "Player chooses to Ascend at map edge"
}
},
"collectibles": {
"knowledgeScroll": {
"sprite": "scroll",
"scale": 1.2,
"lifetime": 8,
"collectRadius": 24,
"bobAmplitude": 2,
"bobSpeed": 2,
"spawnAnimation": "popIn",
"collectAnimation": "burst",
"color": "cyan"
},
"goldCoin": {
"sprite": "goldCoin",
"scale": 1.5,
"lifetime": 8,
"collectRadius": 24,
"bobAmplitude": 2,
"bobSpeed": 2.5,
"spawnAnimation": "popIn",
"collectAnimation": "burst",
"color": "gold"
},
"influenceSparkle": {
"sprite": "sparkle",
"scale": 1.3,
"lifetime": 6,
"collectRadius": 20,
"bobAmplitude": 3,
"bobSpeed": 3,
"spawnAnimation": "popIn",
"collectAnimation": "burst",
"color": "purple"
}
},
"upgradeCosts": {
"hireCartographer": {
"baseCost": 50,
"costMultiplier": 1.3,
"currency": "gold",
"oneTimeTorchCost": 5
},
"assignWorker": {
"baseCost": 25,
"costMultiplier": 1.15,
"currency": "gold"
},
"buildLanternTower": {
"baseCost": 75,
"costMultiplier": 1.25,
"currency": "gold",
"oneTimeTorchCost": 10
},
"unlockScout": {
"baseCost": 20,
"costMultiplier": 1,
"currency": "knowledge",
"oneTime": true
},
"unlockMapper": {
"baseCost": 30,
"costMultiplier": 1,
"currency": "knowledge",
"oneTime": true
},
"unlockExplorer": {
"baseCost": 40,
"costMultiplier": 1,
"currency": "knowledge",
"oneTime": true
},
"torchCapacity": {
"baseCost": 15,
"costMultiplier": 1.5,
"currency": "knowledge",
"effect": "capacity +10"
},
"combatTraining": {
"baseCost": 25,
"costMultiplier": 1.4,
"currency": "knowledge",
"effect": "canFightShadows + damage"
},
"revealHint": {
"baseCost": 5,
"costMultiplier": 1.1,
"currency": "knowledge",
"dynamicCost": true
},
"globalCostReduction": {
"baseCost": 5,
"costMultiplier": 1.5,
"currency": "influence",
"effect": "allGoldCosts -5%",
"maxLevel": 10
},
"fogRegrowthSlow": {
"baseCost": 10,
"costMultiplier": 1.8,
"currency": "influence",
"effect": "fogRegrowthDelay +10%",
"maxLevel": 5
}
},
"conversions": {
"goldToTorches": {
"input": {
"currency": "gold",
"amount": 20
},
"output": {
"currency": "torches",
"amount": 5
},
"unlockCondition": "always"
}
},
"fogMechanics": {
"torchCostPerTile": 1,
"deepFogTorchMultiplier": 2,
"towerTorchDrainPerSecond": 0.1,
"baseRegrowthDelaySeconds": 30,
"maxTorches": 100
},
"prestigeUpgrades": {
"startingTorches": {
"baseCost": 1,
"costMultiplier": 2,
"currency": "cartographyPoints",
"effect": "startingTorches +5",
"maxLevel": 10
},
"fogRegrowthDelay": {
"baseCost": 10,
"costMultiplier": 2.5,
"currency": "cartographyPoints",
"effect": "initialFogDelay +10%",
"maxLevel": 5
},
"revealRadiusBonus": {
"baseCost": 5,
"costMultiplier": 2,
"currency": "cartographyPoints",
"effect": "revealRadius +0.5 tiles",
"maxLevel": 8
},
"cartographerSpeedBonus": {
"baseCost": 3,
"costMultiplier": 1.8,
"currency": "cartographyPoints",
"effect": "cartographerSpeed +10%",
"maxLevel": 10
}
},
"balanceTargets": [
{
"time": "0:00",
"gold": 50,
"knowledge": 0,
"torches": 20,
"influence": 0,
"event": "Game start"
},
{
"time": "0:30",
"gold": 25,
"knowledge": 5,
"torches": 18,
"influence": 0,
"event": "First worker hired"
},
{
"time": "1:00",
"gold": 15,
"knowledge": 20,
"torches": 15,
"influence": 0,
"event": "Scout spec unlocked"
},
{
"time": "2:00",
"gold": 30,
"knowledge": 45,
"torches": 25,
"influence": 0,
"event": "First tower built"
},
{
"time": "3:00",
"gold": 50,
"knowledge": 70,
"torches": 20,
"influence": 5,
"event": "First shadow killed"
},
{
"time": "4:00",
"gold": 35,
"knowledge": 95,
"torches": 18,
"influence": 8,
"event": "Second cartographer"
},
{
"time": "5:00",
"gold": 60,
"knowledge": 120,
"torches": 25,
"influence": 15,
"event": "First ruin investigated"
},
{
"time": "6:00",
"gold": 100,
"knowledge": 135,
"torches": 22,
"influence": 20,
"event": "Trade route active"
},
{
"time": "10:00",
"gold": 250,
"knowledge": 200,
"torches": 35,
"influence": 45,
"event": "Multi-cartographer economy"
},
{
"time": "15:00",
"gold": 800,
"knowledge": 350,
"torches": 50,
"influence": 120,
"event": "Fog becomes aggressive"
},
{
"time": "20:00",
"gold": 2500,
"knowledge": 500,
"torches": 60,
"influence": 250,
"event": "Late game optimization"
},
{
"time": "25:00",
"gold": 8000,
"knowledge": 650,
"torches": 70,
"influence": 400,
"event": "Map edge reachable"
},
{
"time": "30:00",
"gold": 15000,
"knowledge": 800,
"torches": 80,
"influence": 550,
"event": "Prestige available"
}
],
"qualityCriteria": [
"Economy flow diagram shows ALL 5 currencies with sources, sinks, and conversions",
"Primary currency (Gold) has multiple gameplay-earned sources: merchant returns, worker mining, shadow kills",
"Knowledge earned through visible Canvas action: cartographer reveals tiles, player investigates ruins",
"All formulas are exact and copy-pasteable into code",
"Conversions create decisions: Gold→Torches for emergency exploration vs. spending on expansion",
"Pacing timeline supports 15-30 minute target with first 30 seconds feeling generous (50 starting gold)",
"Torches scarce enough to force hard choices: limited cap, exploration drains them, towers burn them",
"No currency becomes irrelevant: Gold always needed for expansion, Knowledge for upgrades, Torches for exploration",
"Consistent variable naming: camelCase for config, snake_case for derived calculations",
"Economy forms a web: Gold→Cartographers→Knowledge→Upgrades→Gold savings, Influence→cost reduction→Gold efficiency",
"Developable from diagrams alone: complete state machines, event flows, and CONFIG spec",
"Collectible state machines defined for all 3 types: knowledgeScroll, goldCoin, influenceSparkle",
"Currency event flows show complete chains: tile reveal→spawn→collect→UI update",
"CONFIG.currencies spec complete with all properties for 5 currencies",
"CONFIG.collectibles spec defines sprite, scale, lifetime, radius for all 3 collectible types",
"CONFIG.currencySources spec defines formulas for all 11 earning pathways",
"CONFIG.upgradeCosts spec defines all 11 upgrades with baseCost, costMultiplier, currency",
"CONFIG.conversions spec defines goldToTorches conversion with amounts"
]
}
Currencies
# Cartographer's Fog - Currency System Design
## 1. Economy Flow Diagram
```mermaid
flowchart LR
subgraph "Sources (Gameplay Actions)"
TileReveal["Tile Revealed\n+1-3 Knowledge\nfirst-time bonus"]
RuinInvestigate["Ruin Investigated\n+10-25 Knowledge\n+5-15 Influence"]
ShadowKill["Shadow Creature Banished\n+2-5 Influence\n+5 Gold"]
MerchantReturn["Merchant Returns\n+10-30 Gold\nper route tile"]
end
subgraph "Sources (Passive)"
WorkerGold["Worker Gold Mining\n+5-15 Gold/trip\n5-10s per trip"]
WorkerTorch["Forest Torch Harvest\n+2-4 Torches/trip\n3-6s per trip"]
TowerPassive["Lantern Tower Passive\n+0.1 Influence/sec\nper tower level"]
TorchRegen["Camp Torch Regen\n+1 Torch/3s\nbase rate"]
end
subgraph "Currencies"
Gold((Gold\nPrimary\nstart: 50\nuncapped))
Knowledge((Knowledge\nUpgrade\nstart: 0\nuncapped))
Torches((Torches\nFuel\nstart: 20\ncap: 100))
Influence((Influence\nStrategic\nstart: 0\npersists))
CP((Cartography Points\nPrestige\nstart: 0\npersists))
end
subgraph "Sinks"
HireCartographer["Hire Cartographer\ncost: 50 * 1.3^count Gold"]
BuildTower["Build Lantern Tower\ncost: 75 * 1.25^count Gold\n+ 10 Torches"]
AssignWorker["Assign Worker\ncost: 25 * 1.15^count Gold"]
UnlockScout["Unlock Scout Spec\ncost: 20 Knowledge"]
UnlockMapper["Unlock Mapper Spec\ncost: 30 Knowledge"]
UnlockExplorer["Unlock Explorer Spec\ncost: 40 Knowledge"]
RevealHint["Reveal Fog Hint\ncost: 5 Knowledge"]
TorchUpgrade["Torch Efficiency\ncost: 15 Knowledge\n+10% torch capacity"]
FogSlow["Fog Slow Upgrade\ncost: 10 CP\nprestige bonus"]
CostReduction["Global Cost Reduction\ncost: 5 CP * level"]
ConvertGoldToTorch["Gold → Torches\n20 Gold → 5 Torches"]
end
TileReveal --> Knowledge
RuinInvestigate --> Knowledge
RuinInvestigate --> Influence
ShadowKill --> Influence
ShadowKill --> Gold
MerchantReturn --> Gold
WorkerGold --> Gold
WorkerTorch --> Torches
TowerPassive --> Influence
TorchRegen --> Torches
Gold --> HireCartographer
Gold --> BuildTower
Gold --> AssignWorker
Gold --> ConvertGoldToTorch
Knowledge --> UnlockScout
Knowledge --> UnlockMapper
Knowledge --> UnlockExplorer
Knowledge --> RevealHint
Knowledge --> TorchUpgrade
Influence --> CostReduction
CP --> FogSlow
ConvertGoldToTorch --> Torches
```
## 2. Currency Definitions Diagram
```mermaid
graph TD
subgraph "Gold [Primary Currency]"
G_display["Display: 🪙 Gold\n0 decimals\nSuffixes: K/M/B"]
G_earn["Earning:\nMerchant return: baseMerchantYield * routeTiles * (1 + 0.05 * roadLevel)\nWorker gold mining: baseGoldYield * (1 + 0.1 * mineLevel)\nShadow kill: 5 * (1 + 0.1 * territoryPercent)"]
G_spend["Spending:\nHire cartographer: 50 * 1.3^cartographerCount\nBuild tower: 75 * 1.25^towerCount + 10 torches\nAssign worker: 25 * 1.15^workerCount\nConvert to torches: 20 Gold → 5 Torches"]
G_inflation["Inflation Control:\nExponential unit costs (1.15-1.3^count)\nTorch conversion drain\nPrestige reset\nInfluence cost reduction (permanent)"]
end
```
```mermaid
graph TD
subgraph "Knowledge [Upgrade/Exploration Currency]"
K_display["Display: 📜 Knowledge\n0 decimals\nSuffixes: K/M"]
K_earn["Earning:\nTile first reveal: 1 Knowledge (grass), 2 (forest), 3 (water/mountain)\nRuin investigate: 15 + 5 * ruinTier Knowledge\nDeep fog reveal: +1 bonus Knowledge"]
K_spend["Spending:\nUnlock Scout: 20 Knowledge\nUnlock Mapper: 30 Knowledge\nUnlock Explorer: 40 Knowledge\nReveal fog hint: 5 Knowledge per tile\nTorch capacity: 15 Knowledge * level\nCombat training: 25 Knowledge * level"]
K_inflation["Inflation Control:\nKnowledge accumulates through exploration (finite map)\nHint costs scale with distance from camp\nUpgrade costs increase linearly"]
end
```
```mermaid
graph TD
subgraph "Torches [Exploration Fuel]"
T_display["Display: 🔥 Torches\n0 decimals\nNo suffixes (hard cap)"]
T_earn["Earning:\nWorker forest harvest: 3 Torches/trip\nCamp regeneration: 1 Torch/3s\nMapper trail: +0.5 Torch/sec while walking\nTorch capacity upgrades raise cap"]
T_spend["Spending:\nTile exploration: 1 Torch (normal), 2 (deep fog)\nTower operation: 0.1 Torch/sec/tower\nCartographer spawn: 5 Torch one-time"]
T_inflation["Inflation Control:\nHard cap at 100 (upgradable with Knowledge)\nExploration limited by torch availability\nTowers drain continuously, forcing expansion"]
end
```
```mermaid
graph TD
subgraph "Influence [Strategic/Prestige Currency]"
I_display["Display: ✨ Influence\n1 decimal\nSuffixes: K/M"]
I_earn["Earning:\nRuin investigate: 5 + 2 * ruinTier Influence\nShadow banished: 2 + 0.5 * shadowLevel Influence\nTower passive: 0.1 * towerLevel Influence/sec\nTrade route to edge: +10 Influence (one-time)"]
I_spend["Spending:\nGlobal cost reduction: 5 Influence * level (5% reduction per level)\nFog regrowth slow: 10 Influence * level (10% slower per level)\nPrestige multiplier bonus: varies by tier"]
I_inflation["Inflation Control:\nInfluence persists on prestige (permanent progression)\nCosts scale exponentially\nDiminishing returns on repeat actions"]
end
```
```mermaid
graph TD
subgraph "Cartography Points [Prestige Currency]"
CP_display["Display: 🗺️ CP\n2 decimals\nSuffixes: K/M"]
CP_earn["Earning:\nPrestige: tilesRevealed * 0.1 + ruinsInvestigated * 5 + mapPercent * 50\nFirst prestige bonus: +10 CP\nAchievement milestones: +5-25 CP each"]
CP_spend["Spending:\nStarting torches: 1 CP → +5 starting Torches\nFog regrowth delay: 10 CP → +10% initial fog delay\nReveal radius: 5 CP → +0.5 tile reveal radius\nCartographer speed: 3 CP → +10% cartographer speed"]
CP_inflation["Inflation Control:\nCosts increase with each purchase (same run)\nPrestige creates fresh scarcity (reset to 0 each run)\nDiminishing returns on repeated prestiges"]
end
```
## 3. Conversion Rate Diagram
```mermaid
flowchart LR
Gold["Gold (20)"] -->|"Gold to Torches\nAlways available\nNo cooldown\nEmergency torch supply"| Torches["Torches (+5)"]
Gold["Gold (50)"] -->|"Hire Cartographer\nPrimary expansion path\nCost scales with count"| NewCart["New Cartographer\nExploration capacity"]
Knowledge["Knowledge (5)"] -->|"Reveal Fog Hint\nReconnaissance tool\nCost increases with distance"| FogHint["Fog Tile Hint\nShows tile type in fog"]
Influence["Influence (5)"] -->|"Cost Reduction\nPermanent bonus\nScales per level"| CostRed["Global Cost -5%\nAll Gold purchases cheaper"]
```
## 4. Pacing Timeline
```mermaid
gantt
title Currency Pacing - First 30 Minutes
dateFormat m:ss
axisFormat %M:%S
section Gold Milestones
First worker (25 Gold) :milestone, 0:30, 0
First tower (75 Gold) :milestone, 2:00, 0
Second cartographer (65 Gold) :milestone, 4:00, 0
Trade route unlocked :milestone, 6:00, 0
Multi-cartographer economy :milestone, 12:00, 0
Late-game surplus :milestone, 20:00, 0
section Knowledge Milestones
Scout unlock (20 Knowledge) :milestone, 1:00, 0
Mapper unlock (30 Knowledge) :milestone, 3:00, 0
Explorer unlock (40 Knowledge) :milestone, 5:00, 0
First torch upgrade (15 Knowledge) :milestone, 7:00, 0
Combat training (25 Knowledge) :milestone, 9:00, 0
section Key Gameplay Events
First shadow creature spawns :milestone, 3:00, 0
First ancient ruin discovered :milestone, 5:00, 0
Fog becomes aggressive :milestone, 15:00, 0
Map edge reachable :milestone, 22:00, 0
Prestige available :milestone, 25:00, 0
```
## 5. Upgrade Cost Curves
```mermaid
graph LR
subgraph "Cartographer Hiring Costs"
C1["Count: 1\nCost: 50 Gold\n+1 exploration unit"]
C2["Count: 2\nCost: 65 Gold\n+1 exploration unit"]
C3["Count: 3\nCost: 85 Gold\n+1 exploration unit"]
C4["Count: 5\nCost: 144 Gold\n+1 exploration unit"]
C1 --> C2 --> C3 --> C4
end
```
```mermaid
graph LR
subgraph "Lantern Tower Costs"
T1["Count: 1\nCost: 75 Gold\n+10 Torches\nTerritory protection"]
T2["Count: 2\nCost: 94 Gold\n+10 Torches\nTerritory protection"]
T3["Count: 4\nCost: 147 Gold\n+10 Torches\nTerritory protection"]
T1 --> T2 --> T3
end
```
```mermaid
graph LR
subgraph "Worker Assignment Costs"
W1["Count: 1\nCost: 25 Gold\nResource gathering"]
W2["Count: 3\nCost: 38 Gold\nResource gathering"]
W3["Count: 6\nCost: 58 Gold\nResource gathering"]
W1 --> W2 --> W3
end
```
```mermaid
graph LR
subgraph "Knowledge Upgrade Costs"
K1["Scout Spec\nCost: 20 Knowledge\nFaster, smaller light"]
K2["Mapper Spec\nCost: 30 Knowledge\nTrail markers, slower"]
K3["Explorer Spec\nCost: 40 Knowledge\nDeep fog access"]
K4["Torch Capacity Lv1\nCost: 15 Knowledge\n+10 Torch cap"]
K5["Combat Training Lv1\nCost: 25 Knowledge\nCan fight shadows"]
K1 --> K4 --> K5
K2 --> K4 --> K5
K3 --> K4 --> K5
end
```
## 6. Collectible Entity State Machine
```mermaid
stateDiagram-v2
[*] --> Spawning: tile first revealed / shadow killed
Spawning --> Active: spawn animation (300ms, scale 0→1)
Active --> Collected: player clicks within 24px
Active --> Expired: lifetime exceeded (8s)
Active --> Drifting: magnetism unlocked (auto-collect range)
Drifting --> Collected: reaches cartographer/camp
Drifting --> Expired: lifetime exceeded
Collected --> [*]: add currency + floating text + particle burst
Expired --> [*]: fade out animation (500ms, opacity 1→0)
note right of Active
Knowledge Scroll: bob animation (±2px), cyan glow
Gold Coin: bob animation (±2px), yellow glow
Influence Sparkle: bob animation (±3px), purple glow
Clickable radius: 24px
Shows value on hover
Lifetime: 8 seconds
end note
note right of Collected
Triggers: currency.add(type, value)
Triggers: floatingText("+{value}", color)
Triggers: particle burst (5-8 particles)
Sound: collect.mp3
end note
```
## 7. Currency Event Flow
### Tile Reveal (Knowledge Collection)
```mermaid
sequenceDiagram
participant Canvas as Canvas (Game World)
participant Cart as Cartographer Entity
participant Fog as Fog System
participant Currency as CurrencyManager
participant UI as HUD Display
participant EventBus as EventBus
Canvas->>Cart: cartographer.moveTo(tile)
Cart->>Cart: walking animation (0.5-1s per tile)
Cart->>Fog: fog.checkReveal(tile, revealRadius)
Fog->>Fog: tile.firstRevealed === true
Fog->>EventBus: emit('tile-revealed', {tileType, position, isFirst})
EventBus->>Currency: currency.add('knowledge', tileKnowledgeValue)
EventBus->>Canvas: spawnCollectible({type: 'knowledgeScroll', position, value: tileKnowledgeValue})
Canvas->>Canvas: scroll spawns with pop-in animation
Note over Canvas: Player clicks or waits for auto-collect
Canvas->>EventBus: emit('collectible-collected', {type: 'knowledge', value, position})
EventBus->>UI: floatingText("+{value} 📜", position, 'cyan')
EventBus->>UI: updateDisplay('knowledge')
UI->>UI: count-up animation (200ms)
```
### Shadow Kill (Influence + Gold)
```mermaid
sequenceDiagram
participant Canvas as Canvas (Game World)
participant Cart as Cartographer Entity
participant Shadow as Shadow Creature
participant Currency as CurrencyManager
participant UI as HUD Display
participant EventBus as EventBus
Cart->>Shadow: cartographer.attack(shadow)
Shadow->>Shadow: hp -= damage
Shadow->>Shadow: hp <= 0 → die()
Shadow->>Canvas: death animation + particles
Shadow->>EventBus: emit('shadow-killed', {level, position})
EventBus->>Currency: currency.add('influence', baseInfluence * level)
EventBus->>Currency: currency.add('gold', baseGold * (1 + 0.1 * territoryPercent))
EventBus->>Canvas: spawnCollectible({type: 'influenceSparkle', position, value})
EventBus->>Canvas: spawnCollectible({type: 'goldCoin', position, goldValue})
Canvas->>Canvas: sparkles and coins spawn
Note over Canvas: Player clicks collectibles
Canvas->>EventBus: emit('collectible-collected', {type, value, position})
EventBus->>UI: floatingText("+{value} ✨", position, 'purple')
EventBus->>UI: floatingText("+{gold} 🪙", position, 'gold')
EventBus->>UI: updateDisplay('influence')
EventBus->>UI: updateDisplay('gold')
```
### Merchant Return (Gold)
```mermaid
sequenceDiagram
participant Canvas as Canvas (Game World)
participant Merchant as Merchant Entity
participant Route as Trade Route
participant Currency as CurrencyManager
participant UI as HUD Display
participant EventBus as EventBus
Merchant->>Route: merchant.patrol(route)
Route->>Merchant: route.tiles traversed
Merchant->>Merchant: reaches camp (end of route)
Merchant->>EventBus: emit('merchant-return', {routeLength, roadLevel, position})
EventBus->>Currency: gold = baseMerchantYield * routeLength * (1 + 0.05 * roadLevel)
EventBus->>UI: floatingText("+{gold} 🪙", campPosition, 'gold')
EventBus->>UI: updateDisplay('gold')
UI->>UI: count-up animation (300ms)
Merchant->>Merchant: reverse animation, begin return trip
```
## CONFIG Spec: currencies Section
```javascript
// Cartographer's Fog - Currency Configuration
CONFIG.currencies = {
gold: {
displayName: 'Gold',
icon: '🪙',
startingAmount: 50,
cap: null,
decimals: 0,
suffixes: ['K', 'M', 'B', 'T'],
persistsOnPrestige: false,
},
knowledge: {
displayName: 'Knowledge',
icon: '📜',
startingAmount: 0,
cap: null,
decimals: 0,
suffixes: ['K', 'M'],
persistsOnPrestige: false,
},
torches: {
displayName: 'Torches',
icon: '🔥',
startingAmount: 20,
cap: 100,
decimals: 0,
suffixes: [],
persistsOnPrestige: false,
},
influence: {
displayName: 'Influence',
icon: '✨',
startingAmount: 0,
cap: null,
decimals: 1,
suffixes: ['K', 'M'],
persistsOnPrestige: true,
},
cartographyPoints: {
displayName: 'CP',
icon: '🗺️',
startingAmount: 0,
cap: null,
decimals: 2,
suffixes: ['K', 'M'],
persistsOnPrestige: true,
},
};
CONFIG.currencySources = {
tileReveal: {
currency: 'knowledge',
formula: 'tileKnowledgeValue * (1 + 0.1 * cartographerRevealBonus)',
tileKnowledgeValue: {
grass: 1,
forest: 2,
water: 3,
mountain: 3,
ruins: 5,
},
},
ruinInvestigate: {
currency: 'knowledge',
formula: '15 + 5 * ruinTier + ruinTier * 2',
baseReward: 15,
tierMultiplier: 5,
},
ruinInvestigateInfluence: {
currency: 'influence',
formula: '5 + 2 * ruinTier',
baseReward: 5,
tierMultiplier: 2,
},
shadowKilled: {
currency: 'influence',
formula: '2 + 0.5 * shadowLevel',
baseReward: 2,
levelMultiplier: 0.5,
},
shadowKilledGold: {
currency: 'gold',
formula: '5 * (1 + 0.1 * territoryPercent)',
baseReward: 5,
territoryMultiplier: 0.1,
},
merchantReturn: {
currency: 'gold',
formula: 'baseMerchantYield * routeTiles * (1 + 0.05 * roadLevel)',
baseMerchantYield: 2,
},
workerGoldMining: {
currency: 'gold',
formula: 'baseGoldYield * (1 + 0.1 * mineLevel)',
baseGoldYield: 5,
levelMultiplier: 0.1,
},
workerTorchHarvest: {
currency: 'torches',
formula: 'baseTorchYield * (1 + 0.05 * forestLevel)',
baseTorchYield: 3,
levelMultiplier: 0.05,
},
lanternTowerPassive: {
currency: 'influence',
formula: '0.1 * towerLevel / 60', // per second, calculated per tick
perTowerPerLevel: 0.1,
},
campTorchRegen: {
currency: 'torches',
formula: '1 / 3', // per second
perSecond: 0.333,
},
prestige: {
currency: 'cartographyPoints',
formula: 'tilesRevealed * 0.1 + ruinsInvestigated * 5 + mapPercent * 50 + firstPrestigeBonus',
tileMultiplier: 0.1,
ruinMultiplier: 5,
mapPercentMultiplier: 50,
firstPrestigeBonus: 10,
},
};
CONFIG.collectibles = {
knowledgeScroll: {
sprite: 'scroll',
scale: 1.2,
lifetime: 8, // seconds
collectRadius: 24, // pixels
bobAmplitude: 2, // pixels
bobSpeed: 2, // Hz
spawnAnimation: 'popIn', // 300ms scale 0→1
collectAnimation: 'burst', // 5 particles
color: 'cyan',
},
goldCoin: {
sprite: 'goldCoin',
scale: 1.5,
lifetime: 8,
collectRadius: 24,
bobAmplitude: 2,
bobSpeed: 2.5,
spawnAnimation: 'popIn',
collectAnimation: 'burst',
color: 'gold',
},
influenceSparkle: {
sprite: 'sparkle',
scale: 1.3,
lifetime: 6,
collectRadius: 20,
bobAmplitude: 3,
bobSpeed: 3,
spawnAnimation: 'popIn',
collectAnimation: 'burst',
color: 'purple',
},
};
CONFIG.upgradeCosts = {
// Unit hiring
hireCartographer: {
baseCost: 50,
costMultiplier: 1.3,
currency: 'gold',
oneTimeTorchCost: 5,
},
assignWorker: {
baseCost: 25,
costMultiplier: 1.15,
currency: 'gold',
},
// Structures
buildLanternTower: {
baseCost: 75,
costMultiplier: 1.25,
currency: 'gold',
oneTimeTorchCost: 10,
},
// Specializations (Knowledge)
unlockScout: {
baseCost: 20,
costMultiplier: 1,
currency: 'knowledge',
oneTime: true,
},
unlockMapper: {
baseCost: 30,
costMultiplier: 1,
currency: 'knowledge',
oneTime: true,
},
unlockExplorer: {
baseCost: 40,
costMultiplier: 1,
currency: 'knowledge',
oneTime: true,
},
// Knowledge upgrades
torchCapacity: {
baseCost: 15,
costMultiplier: 1.5,
currency: 'knowledge',
effect: 'capacity +10',
},
combatTraining: {
baseCost: 25,
costMultiplier: 1.4,
currency: 'knowledge',
effect: 'canFightShadows + damage',
},
revealHint: {
baseCost: 5,
costMultiplier: 1.1,
currency: 'knowledge',
dynamicCost: true, // increases with distance from camp
},
// Influence upgrades (permanent)
globalCostReduction: {
baseCost: 5,
costMultiplier: 1.5,
currency: 'influence',
effect: 'allGoldCosts -5%',
maxLevel: 10,
},
fogRegrowthSlow: {
baseCost: 10,
costMultiplier: 1.8,
currency: 'influence',
effect: 'fogRegrowthDelay +10%',
maxLevel: 5,
},
// Prestige upgrades (CP)
startingTorches: {
baseCost: 1,
costMultiplier: 2,
currency: 'cartographyPoints',
effect: 'startingTorches +5',
maxLevel: 10,
},
fogRegrowthDelay: {
baseCost: 10,
costMultiplier: 2.5,
currency: 'cartographyPoints',
effect: 'initialFogDelay +10%',
maxLevel: 5,
},
revealRadiusBonus: {
baseCost: 5,
costMultiplier: 2,
currency: 'cartographyPoints',
effect: 'revealRadius +0.5 tiles',
maxLevel: 8,
},
cartographerSpeedBonus: {
baseCost: 3,
costMultiplier: 1.8,
currency: 'cartographyPoints',
effect: 'cartographerSpeed +10%',
maxLevel: 10,
},
};
CONFIG.conversions = {
goldToTorches: {
input: { currency: 'gold', amount: 20 },
output: { currency: 'torches', amount: 5 },
unlockCondition: 'always',
cooldown: 0,
},
};
CONFIG.fogMechanics = {
torchCostPerTile: 1,
deepFogTorchMultiplier: 2,
towerTorchDrainPerSecond: 0.1,
baseRegrowthDelaySeconds: 30,
maxTorches: 100,
};
```
## Exact Formulas
```
Cartographer cost: 50 * 1.3^count Gold
Worker cost: 25 * 1.15^count Gold
Lantern Tower cost: 75 * 1.25^count Gold + 10 Torches
Torch Capacity upgrade: 15 * 1.5^level Knowledge (cap +10 per level)
Combat Training: 25 * 1.4^level Knowledge
Reveal Hint: 5 * 1.1^distance * distanceFromCamp Knowledge
Global Cost Reduction: 5 * 1.5^level Influence (5% reduction per level, max 50%)
Fog Regrowth Slow: 10 * 1.8^level Influence (10% delay per level, max 50%)
Merchant Yield: 2 * routeTiles * (1 + 0.05 * roadLevel) Gold
Worker Gold: 5 * (1 + 0.1 * mineLevel) Gold per trip
Worker Torch: 3 * (1 + 0.05 * forestLevel) Torches per trip
Shadow Influence: 2 + 0.5 * shadowLevel Influence
Shadow Gold: 5 * (1 + 0.1 * territoryPercent) Gold
Tile Knowledge: 1 (grass) / 2 (forest) / 3 (water/mountain) / 5 (ruins)
Ruin Knowledge: 15 + 5 * ruinTier
Ruin Influence: 5 + 2 * ruinTier
Prestige CP: tilesRevealed * 0.1 + ruinsInvestigated * 5 + mapPercent * 50 + firstPrestigeBonus(10)
```
## Balance Targets
| Time | Gold | Knowledge | Torches | Influence | Key Event |
|------|------|-----------|---------|-----------|-------------|
| 0:00 | 50 | 0 | 20 | 0 | Game start |
| 0:30 | ~25 | ~5 | ~18 | 0 | First worker hired |
| 1:00 | ~15 | ~20 | ~15 | 0 | Scout spec unlocked |
| 2:00 | ~30 | ~45 | ~25 | 0 | First tower built |
| 3:00 | ~50 | ~70 | ~20 | ~5 | First shadow killed |
| 4:00 | ~35 | ~95 | ~18 | ~8 | Second cartographer |
| 5:00 | ~60 | ~120 | ~25 | ~15 | First ruin investigated |
| 6:00 | ~100 | ~135 | ~22 | ~20 | Trade route active |
| 10:00 | ~250 | ~200 | ~35 | ~45 | Multi-cartographer economy |
| 15:00 | ~800 | ~350 | ~50 | ~120 | Fog becomes aggressive |
| 20:00 | ~2.5K | ~500 | ~60 | ~250 | Late game optimization |
| 25:00 | ~8K | ~650 | ~70 | ~400 | Map edge reachable |
| 30:00 | ~15K | ~800 | ~80 | ~550 | Prestige available |
## Edge Cases
- **Overflow protection**: Switch to BigNum at 1e6 for all currencies except Torches (hard cap)
- **Negative balance**: `canAfford(cost, currency)` check before all purchases
- **Torch overflow**: Any torch gain above cap is lost (wasted, encourages spending)
- **Zero torch state**: Cannot explore tiles when torches = 0, must wait for regen or convert gold
- **Map exhaustion**: Knowledge becomes scarce when 90%+ explored, pushing toward prestige
- **Ruin cooldown**: Same ruin cannot be re-investigated for 60 seconds
- **Shadow scaling**: Shadow spawn rate increases with revealed territory (1 per 50 tiles revealed)
- **Territory loss**: If fog reclaims a tile with active worker/tower, that entity is destroyed
- **Prestige validation**: Minimum 50% map explored OR 20 tiles revealed required to prestige
Progression
{
"game_name": "Cartographer's Fog",
"section": "progression",
"job_id": 69,
"phase": 2,
"unlocks": {
"workerSystem": {
"requirement": "tilesRevealed >= 3",
"unlocks": "workerAssignment",
"toast": "Worker System Unlocked!",
"indicator": "worker-button-glow",
"triggerType": "gameplay",
"unlockTime": "0:45"
},
"scoutSpec": {
"requirement": "knowledge >= 20",
"unlocks": "scoutSpecialization",
"toast": "Scout Specialization Available!",
"indicator": "spec-button-flash",
"triggerType": "currency",
"unlockTime": "1:30"
},
"mapperSpec": {
"requirement": "knowledge >= 30",
"unlocks": "mapperSpecialization",
"toast": "Mapper Specialization Available!",
"indicator": "spec-button-flash",
"triggerType": "currency",
"unlockTime": "2:30"
},
"explorerSpec": {
"requirement": "knowledge >= 40",
"unlocks": "explorerSpecialization",
"toast": "Explorer Specialization Available!",
"indicator": "spec-button-flash",
"triggerType": "currency",
"unlockTime": "4:00"
},
"lanternTower": {
"requirement": "gold >= 75 && torches >= 10",
"unlocks": "lanternTowerBuild",
"toast": "Lantern Tower Unlocked!",
"indicator": "build-button-glow",
"triggerType": "currency",
"unlockTime": "2:00"
},
"combatTraining": {
"requirement": "knowledge >= 25 && shadowsDefeated >= 1",
"unlocks": "cartographerCombat",
"toast": "Combat Training Available!",
"indicator": "upgrade-button-flash",
"triggerType": "gameplay",
"unlockTime": "3:30"
},
"tradeRoute": {
"requirement": "revealedLocations >= 2 && pathBetweenExplored",
"unlocks": "tradeRouteSystem",
"toast": "Trade Routes Unlocked!",
"indicator": "route-tool-enable",
"triggerType": "gameplay",
"unlockTime": "6:00"
},
"deepFog": {
"requirement": "mapPercent >= 50",
"unlocks": "deepFogZones",
"toast": "Deep Fog Discovered! Dangerous but valuable...",
"indicator": "fog-edge-change",
"triggerType": "milestone",
"unlockTime": "15:00"
},
"prestige": {
"requirement": "mapPercent >= 80 || mapEdgeReached",
"unlocks": "prestigeButton",
"toast": "Ascension Available! The journey continues...",
"indicator": "prestige-button-active",
"triggerType": "milestone",
"unlockTime": "25:00"
}
},
"milestones": [
{
"id": "firstSteps",
"trigger": "tilesRevealed >= 3",
"reward": {
"gold": 5
},
"toast": "🏆 First Steps! The journey begins!",
"once": true,
"time": "0:05"
},
{
"id": "resourcePioneer",
"trigger": "firstResourceDiscovered",
"reward": {
"unlocks": [
"workerSystem"
]
},
"toast": "🏆 Resources discovered! Assign workers to gather.",
"once": true,
"time": "0:30"
},
{
"id": "lightBringer",
"trigger": "firstTowerBuilt",
"reward": {
"influence": 10
},
"toast": "🏆 Territory secured! The light pushes back darkness.",
"once": true,
"time": "2:00"
},
{
"id": "shadowBanisher",
"trigger": "shadowsDefeated >= 1",
"reward": {
"knowledge": 25
},
"toast": "🏆 Darkness pushed back! The shadows fear light.",
"once": true,
"time": "3:00"
},
{
"id": "routeFinder",
"trigger": "firstTradeRouteCreated",
"reward": {
"gold": 50
},
"toast": "🏆 Trade established! Merchants bring prosperity.",
"once": true,
"time": "6:00"
},
{
"id": "ruinInvestigator",
"trigger": "ruinsInvestigated >= 1",
"reward": {
"knowledge": 20,
"influence": 10
},
"toast": "🏆 Secrets revealed! The ruins yield knowledge.",
"once": true,
"time": "5:00"
},
{
"id": "multiExplorer",
"trigger": "cartographerCount >= 2",
"reward": {
"torches": 5
},
"toast": "🏆 Expedition grows! Multiple paths open.",
"once": true,
"time": "8:00"
},
{
"id": "mapMaker",
"trigger": "mapPercent >= 50",
"reward": {
"gold": 100,
"knowledge": 50
},
"toast": "🏆 Half the realm known! The kingdom remembers.",
"once": true,
"time": "15:00"
},
{
"id": "edgeFinder",
"trigger": "mapEdgeReached",
"reward": {
"unlocks": [
"prestige"
]
},
"toast": "🏆 The world's edge found! What lies beyond?",
"once": true,
"time": "22:00"
},
{
"id": "ascension",
"trigger": "prestigeCompleted",
"reward": {
"cartographyPoints": 10
},
"toast": "✨ Ascension Complete! A new chapter begins...",
"once": false,
"time": "25:00+"
}
],
"upgradeTiers": {
"tier1": {
"name": "Basic Equipment",
"unlocks": "gameStart",
"upgrades": {
"cartographerSpeed": {
"name": "Cartographer Speed",
"cost": {
"gold": 30
},
"costMultiplier": 1.2,
"maxLevel": 5,
"effect": "movementTime -10%",
"visible": "cartographer walks faster"
},
"torchCapacity": {
"name": "Torch Capacity",
"cost": {
"knowledge": 15
},
"costMultiplier": 1.5,
"maxLevel": 5,
"effect": "maxTorches +10",
"visible": "torch cap increases in UI"
},
"workerSpeed": {
"name": "Worker Efficiency",
"cost": {
"gold": 20
},
"costMultiplier": 1.15,
"maxLevel": 5,
"effect": "harvestTime -10%",
"visible": "workers harvest faster"
}
}
},
"tier2": {
"name": "Advanced Equipment",
"unlocks": "mapPercent >= 25",
"unlocksAt": "5:00",
"upgrades": {
"lanternTowerDamage": {
"name": "Tower Damage",
"cost": {
"gold": 50,
"knowledge": 20
},
"costMultiplier": 1.3,
"maxLevel": 3,
"effect": "towerDamage +5",
"visible": "tower projectiles more visible"
},
"merchantCapacity": {
"name": "Merchant Packs",
"cost": {
"gold": 40
},
"costMultiplier": 1.25,
"maxLevel": 3,
"effect": "merchantYield +20%",
"visible": "merchants carry more"
},
"fogVision": {
"name": "Fog Hints",
"cost": {
"knowledge": 25
},
"costMultiplier": 1.2,
"maxLevel": 3,
"effect": "fogHintRadius +1",
"visible": "fog shows more details"
}
}
},
"tier3": {
"name": "Master Techniques",
"unlocks": "mapPercent >= 60",
"unlocksAt": "15:00",
"upgrades": {
"territoryLock": {
"name": "Territory Lock",
"cost": {
"influence": 50,
"knowledge": 50
},
"costMultiplier": 1.5,
"maxLevel": 1,
"effect": "revealedTilesNeverRegrow",
"visible": "revealed tiles permanent (no fog return)"
},
"rapidExploration": {
"name": "Rapid Exploration",
"cost": {
"influence": 30
},
"costMultiplier": 1.4,
"maxLevel": 3,
"effect": "allCartographers +20% speed",
"visible": "all cartographers move faster visibly"
},
"shadowRepellent": {
"name": "Shadow Repellent",
"cost": {
"influence": 40
},
"costMultiplier": 1.5,
"maxLevel": 2,
"effect": "shadowsSpawnRate -25%",
"visible": "fewer shadows spawn"
}
}
}
},
"prestige": {
"teaserWave": 80,
"minWave": 80,
"formula": "floor(tilesRevealed * 0.1 + ruinsInvestigated * 5 + mapPercent * 50)",
"threshold": 100,
"resets": [
"gold",
"knowledge",
"torches",
"influence",
"cartographers",
"workers",
"towers",
"merchants",
"territory"
],
"persists": [
"cartographyPoints",
"prestigeUpgrades",
"achievements",
"unlockedSpecs"
],
"visualTiers": [
{
"tier": 0,
"minPrestiges": 0,
"background": "#1a1a2e",
"fogColor": "#0a0a12",
"terrainShift": 0,
"name": "Starting Region"
},
{
"tier": 1,
"minPrestiges": 1,
"background": "#1a2e2a",
"fogColor": "#120f1a",
"terrainShift": 30,
"name": "Crimson Peaks"
},
{
"tier": 2,
"minPrestiges": 3,
"background": "#1a1a3e",
"fogColor": "#0f1a2e",
"terrainShift": 60,
"name": "Verdant Wilds"
},
{
"tier": 3,
"minPrestiges": 5,
"background": "#2e2a1a",
"fogColor": "#1a0f2e",
"terrainShift": 120,
"name": "Azure Expanse"
},
{
"tier": 4,
"minPrestiges": 8,
"background": "#3e2a1a",
"fogColor": "#2e1a3e",
"terrainShift": 180,
"name": "Golden Expanse"
},
{
"tier": 5,
"minPrestiges": 12,
"background": "#2a1a3e",
"fogColor": "#3e1a2a",
"terrainShift": 240,
"name": "Obsidian Domain"
}
],
"upgrades": {
"startingTorches": {
"name": "Extra Torches",
"cost": 1,
"costMultiplier": 2,
"effect": "startingTorches +5",
"visible": "start with more torches",
"maxLevel": 10
},
"fogRegrowthDelay": {
"name": "Fog Delay",
"cost": 10,
"costMultiplier": 2.5,
"effect": "initialFogDelay +10%",
"visible": "fog returns slower",
"maxLevel": 5
},
"revealRadiusBonus": {
"name": "Greater Light",
"cost": 5,
"costMultiplier": 2,
"effect": "revealRadius +0.5 tiles",
"visible": "cartographers reveal larger area",
"maxLevel": 8
},
"cartographerSpeedBonus": {
"name": "Swift Movement",
"cost": 3,
"costMultiplier": 1.8,
"effect": "cartographerSpeed +10%",
"visible": "all cartographers move faster",
"maxLevel": 10
},
"startingGold": {
"name": "Royal Funding",
"cost": 15,
"costMultiplier": 2.2,
"effect": "startingGold +25",
"visible": "start with more gold",
"maxLevel": 5
},
"workerEfficiency": {
"name": "Master Craftsmen",
"cost": 20,
"costMultiplier": 2.5,
"effect": "workerSpeed +15%",
"visible": "workers start more efficient",
"maxLevel": 3
}
}
},
"fog": {
"baseRegrowthDelaySeconds": 30,
"aggressiveThresholdPercent": 50,
"aggressiveRegrowthDelaySeconds": 15,
"deepFogThresholdPercent": 60,
"shadowSpawnRate": {
"base": "1 shadow per 10 revealed tiles",
"scaled": "1 shadow per 5 revealed tiles (aggressive)"
}
},
"qualityCriteria": [
"Unlock flow diagram shows EVERY unlock with exact trigger conditions and times",
"Triggers use gameplay events (tile reveals, shadows defeated, map milestones) not just currency amounts",
"First 30 seconds have visible gameplay: cartographer walks, reveals tiles, knowledge spawns",
"No phase lasts more than 5 minutes without something new (unlocks at 0:45, 1:30, 2:00, 2:30, 3:00, 3:30, 4:00, 5:00, 6:00)",
"Major unlocks CHANGE Canvas: workers appear (sprites), towers built (new structures), merchants patrol (new units), shadows spawn (new enemies)",
"Hard gates have estimated wait times under 2 minutes (first resource 30s, tower 2min, trade route 6min)",
"Timeline covers 0-30 minutes completely with onboarding (0-2), expansion (2-6), complexity (6-15), mastery (15-30)",
"Tension curve has clear peaks (4/5 at shadows, 5/5 at aggressive fog) and valleys (3/5 at multi-cartographer era)",
"Prestige teased at 50% (15min) before available at 80% (25min)",
"10 milestones spread across session from 5 seconds to 25 minutes",
"Developer can read diagrams and know exactly when to show/hide every UI element",
"Entity spawn/unlock state machines cover 5 categories: cartographer, worker, shadow creature, lantern tower, merchant",
"Fog/territory state machine defines complete tile lifecycle from unexplored to protected",
"CONFIG.progression spec has exact values for all 9 unlocks with requirement, toast, indicator, trigger type, unlock time",
"CONFIG.milestones spec has 10 milestones with trigger conditions, rewards, toasts, and times",
"CONFIG.upgradeTiers spec has 3 tiers with 9 total upgrades, each with cost, multiplier, max level, effect, visible change",
"CONFIG.prestige spec has 6 visual tiers with background colors, 6 prestige upgrades with costs and effects"
]
}
Progression
# Cartographer's Fog - Progression System Design
## 1. Unlock Flow Diagram
```mermaid
flowchart TD
Start["Game Start\n0:00\nCamp with 1 cartographer"] --> FirstReveal["First Tile Revealed\n0:05\nPlayer clicks adjacent fog"]
FirstReveal -->|"3 tiles revealed"| FirstResource["🏆 First Resource Discovery\n0:30\nIron/Gold deposit found"]
FirstReveal -->|"5 Knowledge revealed"| KnowledgeDisplay["📜 Knowledge Display Revealed\n0:20\nSecondary currency visible"]
FirstResource -->|"Player clicks resource"| WorkerUnlock["🔓 Worker System Unlock\n0:45\nCan assign gatherers"]
WorkerUnlock -->|"Worker returns gold"| FirstGoldIncome["🪙 First Gold Income\n1:00\nEconomy engine starts"]
KnowledgeDisplay -->|"20 Knowledge"| ScoutUnlock["🏃 Scout Spec Unlock\n1:30\nFaster, smaller radius"]
ScoutUnlock -->|"30 Knowledge"| MapperUnlock["🗺️ Mapper Spec Unlock\n2:30\nTrail markers, slower"]
FirstGoldIncome -->|"50 Gold + 10 Torches"| TowerUnlock["🏯 Lantern Tower Unlock\n2:00\nTerritory defense"]
TowerUnlock -->|"Tower placed"| InfluenceDisplay["✨ Influence Display Revealed\n2:45\nStrategic currency visible"]
MapperUnlock -->|"40 Knowledge"| ExplorerUnlock["🧭 Explorer Spec Unlock\n4:00\nDeep fog access"]
TowerUnlock -->|"3 tiles revealed past camp"| FirstShadow["👻 First Shadow Spawns\n3:00\nCombat enters game"]
FirstShadow -->|"Shadow defeated"| CombatUnlock["⚔️ Combat Training Unlock\n3:30\nCan fight shadows"]
FirstShadow -->|"25 Knowledge"| CombatUnlocked["Combat Upgrade Available\n4:00\n+damage, +HP"]
ExplorerUnlock -->|"15 tiles revealed"| FirstRuin["🏛️ First Ancient Ruin\n5:00\nSpecial location"]
FirstRuin -->|"Player investigates"| TradeRouteUnlock["🛤️ Trade Route Unlock\n6:00\nDrag between locations"]
TradeRouteUnlock -->|"Route active"| MerchantSpawn["🎭 Merchant Appears\n6:30\nPassive income begins"]
MerchantSpawn -->|"Second cartographer hired"| MultiExplore["🗺️ Multi-Cartographer Era\n8:00\nCan explore multiple dirs"]
MultiExplore -->|"50% map explored"| AggressiveFog["🌫️ Aggressive Fog Era\n15:00\nFog speed +50%"]
AggressiveFog -->|"80% map explored"| MapEdge["📍 Map Edge Reached\n22:00\nBoundary discovered"]
MapEdge -->|"Can choose to ascend"| PrestigeAvailable["✨ Ascension Available\n25:00\nPrestige button active"]
```
## 2. Gate Dependency Graph
```mermaid
graph TD
subgraph "Hard Gates (progress pauses until player acts)"
HG1["⛔ Gate: First Resource\nRequirement: Click adjacent fog tiles\nWait: ~30 sec\nBlocks: Worker system, gold income"]
HG2["⛔ Gate: Tower Build\nRequirement: 75 Gold + 10 Torches\nWait: ~2 min\nBlocks: Territory holding, Influence display"]
HG3["⛔ Gate: Combat Training\nRequirement: 25 Knowledge + first shadow spawn\nWait: ~3.5 min\nBlocks: Shadow defense, influence farming"]
HG4["⛔ Gate: Trade Route\nRequirement: 2 revealed locations + path between\nWait: ~6 min\nBlocks: Merchant system, passive income"]
HG5["⛔ Gate: Prestige\nRequirement: 80% map explored OR map edge reached\nWait: ~25 min\nBlocks: New region, permanent bonuses"]
end
subgraph "Soft Gates (progress slows, multiple options)"
SG1["🟡 Gate: Torch Scarcity\nTiles revealed: 10-20\nPlayer redirected to: Forest harvest or gold conversion"]
SG2["🟡 Gate: Mid-game Knowledge Plateau\nKnowledge: 50-80 range\nPlayer redirected to: Ruin investigation or deep fog"]
SG3["🟡 Gate: Expansion vs Consolidation\nGold: 200-500 range\nPlayer redirected to: More cartographers (offense) or towers (defense)"]
SG4["🟡 Gate: Pre-prestige grind\nMap explored: 60-80%\nPlayer redirected to: Optimize trade routes or push for final %"]
end
HG1 --> SG1
HG2 --> SG3
HG3 --> SG2
HG4 --> SG3
SG2 --> SG4
SG4 --> HG5
```
## 3. Progression Timeline
```mermaid
gantt
title Progression Pacing - Cartographer's Fog (30 Minutes)
dateFormat m:ss
axisFormat %M:%S
section Onboarding (0-2 min)
Cartographer spawns at camp :active, 0:00, 5s
First tile revealed by player :milestone, 0:05, 0
Knowledge display appears :milestone, 0:20, 0
First resource discovered :milestone, 0:30, 0
Worker system unlocked :milestone, 0:45, 0
First gold income from worker :milestone, 1:00, 0
section Expansion (2-6 min)
Scout spec unlocked (20 Knowledge) :milestone, 1:30, 0
Lantern tower unlocked :milestone, 2:00, 0
Influence display revealed :milestone, 2:45, 0
Mapper spec unlocked (30 Knowledge) :milestone, 2:30, 0
First shadow creature spawns :milestone, 3:00, 0
Combat training unlock (25 Knowledge) :milestone, 3:30, 0
Explorer spec unlocked (40 Knowledge) :milestone, 4:00, 0
section Complexity (6-15 min)
First ancient ruin discovered :milestone, 5:00, 0
Trade route system unlocked :milestone, 6:00, 0
First merchant patrolling :milestone, 6:30, 0
Multi-cartographer economy :active, 8:00, 7m
Second ruin investigated :milestone, 10:00, 0
Third cartographer hired :milestone, 12:00, 0
section Mastery & Prestige (15-30 min)
Fog becomes aggressive :milestone, 15:00, 0
Deep fog zones unlock :milestone, 18:00, 0
Map edge reachable :milestone, 22:00, 0
Prestige available :milestone, 25:00, 0
Optimizing final territory :active, 25:00, 5m
```
## 4. Tension Curve
```mermaid
graph LR
subgraph "Emotional Arc - Cartographer's Fog"
T1["0-1 min\n🟢 Excitement\nTension: 2/5\nFirst exploration, camp established"]
T2["1-3 min\n🟢 Discovery\nTension: 3/5\nResources found, workers assigned"]
T3["3-5 min\n🟡 First Challenge\nTension: 4/5\nShadows appear, need towers"]
T4["5-8 min\n🟢 Expansion\nTension: 3/5\nTrade routes, merchants, multi-cartographer"]
T5["8-12 min\n🟡 Strategic Depth\nTension: 3/5\nBalancing exploration vs consolidation"]
T6["12-15 min\n🟢 Rising Threat\nTension: 4/5\nMore shadows, fog creeping faster"]
T7["15-22 min\n🔴 Peak Challenge\nTension: 5/5\nAggressive fog, deep fog zones"]
T8["22-25 min\n🟢 Achievement\nTension: 3/5\nMap edge reached, prestige available"]
T9["25-30 min\n🟢 Decision Point\nTension: 4/5\nTo prestige or optimize final territory"]
end
T1 --> T2 --> T3 --> T4 --> T5 --> T6 --> T7 --> T8 --> T9
```
## 5. Milestone Rewards
```mermaid
graph LR
subgraph "Gameplay Milestones"
M1["🏆 First Steps\nReveal 3 tiles\nReward: +5 Gold\nToast: The journey begins!"]
M2["🏆 Resource Pioneer\nDiscover first resource\nReward: Worker system unlock\nToast: Resources discovered!"]
M3["🏆 Light Bringer\nBuild first tower\nReward: +10 Influence\nToast: Territory secured!"]
M4["🏆 Shadow Banisher\nDefeat first shadow\nReward: +25 Knowledge\nToast: Darkness pushed back!"]
M5["🏆 Route Finder\nCreate trade route\nReward: +50 Gold\nToast: Trade established!"]
M6["🏆 Ruin Investigator\nInvestigate ancient ruin\nReward: +20 Knowledge, +10 Influence\nToast: Secrets revealed!"]
M7["🏆 Multi-Explorer\nHire second cartographer\nReward: +5 Torches\nToast: Expedition grows!"]
M8["🏆 Map Maker\nReach 50% explored\nReward: +100 Gold, +50 Knowledge\nToast: Half the realm known!"]
M9["🏆 Edge Finder\nReach map boundary\nReward: Prestige unlocked\nToast: The world's edge found!"]
M10["✨ Ascension\nComplete first prestige\nReward: +10 CP, new region\nToast: A new chapter begins!"]
end
```
## 6. Tutorial / First-Time Flow
```mermaid
sequenceDiagram
actor Player
participant Canvas as Game Canvas
participant UI as Game UI
participant Fog as Fog System
Note over Player,UI: First 60 Seconds - Onboarding Flow
Player->>Canvas: Game loads
Canvas->>Player: Camp with cartographer visible at center
UI->>Player: HUD shows Gold (50), Torches (20), Knowledge (0)
UI->>Player: Tutorial overlay: "Click adjacent dark tiles to explore"
Player->>Canvas: Clicks fog tile adjacent to camp
Canvas->>Canvas: Cartographer walks to tile (0.5s animation)
Canvas->>Fog: Fog clears around tile (reveal radius 3x3)
Fog->>Canvas: Terrain revealed (grass/forest/water)
Canvas->>Canvas: Knowledge scroll spawns floating (+1)
Note over Player,Canvas: Player clicks 2 more tiles
Canvas->>Canvas: Resource node revealed (iron deposit)
Canvas->>UI: Toast "🏆 Resource Found! Click to assign worker"
UI->>Player: Worker button highlights in UI
Player->>UI: Clicks worker button (25 Gold)
UI->>Canvas: Worker spawns and walks to resource
Canvas->>Canvas: Worker returns to camp with gold (+5)
Canvas->>UI: Floating "+5 🪙" text
UI->>UI: Gold counter animates 50→30→35
Canvas->>UI: Knowledge reaches 5, display updates
UI->>Player: Scout spec button appears (20 Knowledge to unlock)
Player->>Canvas: Continues exploring...
```
## 7. Entity Spawn/Unlock State Machine
### Cartographer (Player Unit)
```mermaid
stateDiagram-v2
[*] --> Locked: game start
Locked --> Active: cartographer spawns at camp (automatic)
Active --> Idle: at camp with no target
Active --> Moving: player clicks fog tile destination
Idle --> Moving: player assigns destination
Moving --> Idle: destination reached
Moving --> Revealing: enters fog tile
Revealing --> Moving: fog cleared, continue to target
Moving --> Defending: shadow creature in range + combat training
Defending --> Moving: shadow defeated
Defending --> Dying: shadow kills cartographer
Dying --> Dead: death animation (1s)
Dead --> Respawning: player hires new cartographer
Respawning --> Active: spawns at camp
note right of Locked
Max cartographers: 1 (start), upgradable to 5
First cartographer: free, spawns immediately
end note
note right of Active
Sprite: Knight (brown/tan recolor)
Visible on Canvas: humanoid with lantern
Selection indicator: gold ring when selected
end note
note right of Moving
Speed: 0.5-1s per tile (varies by spec)
Cost: 1 Torch per tile (2 for deep fog)
Trail: light particles while moving
end note
note right of Revealing
Radius: 3x3 tiles (expandable)
Reward: Knowledge based on tile type
Visual: fog fades with ripple effect
end note
```
### Worker (Gatherer Unit)
```mermaid
stateDiagram-v2
[*] --> Locked: game start (no worker system)
Locked --> Unlocked: first resource discovered (0:30)
Unlocked --> Available: player can afford (25 Gold)
Available --> Spawning: player clicks resource to assign
Spawning --> Moving: walks to resource (3s)
Moving --> Harvesting: reaches resource node
Harvesting --> Returning: inventory full (5s harvest)
Returning --> Depositing: reaches camp
Depositing --> Moving: walks back to resource (3s)
Moving --> Dying: fog reclaims tile while worker there
Dying --> Dead: death animation
Dead --> [*]: remove from canvas
note right of Locked
Unlock condition: first resource tile revealed
Toast: "Worker System Unlocked! Assign gatherers to resources"
end note
note right of Spawning
Sprite: Slime (human skin tone recolor)
Spawn point: camp
Target: assigned resource node
end note
note right of Harvesting
Duration: 5s (base), 3s with upgrades
Yield: varies by resource (iron=5g, gold=10g, herbs=3t)
Visual: worker bends, particles from resource
end note
```
### Shadow Creature (Enemy)
```mermaid
stateDiagram-v2
[*] --> Dormant: fog exists (no shadows yet)
Dormant --> Spawning: territory > 10 tiles revealed
Spawning --> Emerging: spawns at fog edge (1s animation)
Emerging --> Hunting: finds nearest target
Hunting --> Chasing: target in range, moves toward it
Chasing --> Attacking: reaches target (cartographer/worker/merchant)
Attacking --> Chasing: target survives, continues chase
Attacking --> Dying: target defeats shadow (combat required)
Chasing --> Idle: target lost/dead, returns to fog
Idle --> Dormant: no targets, despawns at fog edge
Dying --> [*]: drops influence + gold, fades
note right of Dormant
Spawn condition: revealedTerritory > 10 tiles
Spawn rate increases with territory (1 per 10 tiles)
Not visible until spawned
end note
note right of Emerging
Sprite: Ghost (black/purple recolor)
Spawn point: deep fog edge near revealed territory
Animation: fade in + wraith materialize (1s)
end note
note right of Hunting
Target priority: cartographer > worker > merchant
Speed: 0.3s per tile (slower than cartographer)
Damage: 10 HP per attack (cartographer has 50 HP)
end note
note right of Dying
Requires: cartographer with combat training
Rewards: 2-5 Influence, 5-15 Gold
Visual: purple burst, fades to black
end note
```
### Lantern Tower (Structure)
```mermaid
stateDiagram-v2
[*] --> Locked: tower system not researched
Locked --> Unlocked: 75 Gold + 10 Torches affordable
Unlocked --> Placing: player clicks revealed tile
Placing --> Constructing: build animation (2s)
Constructing --> Active: tower pulses with light
Active --> Draining: consumes torches (0.1/s)
Draining --> Active: torches available
Active --> Damaged: shadow in range (deals 5 damage/s)
Active --> Destroyed: fog reclaims tile (no torches)
Destroyed --> [*]: tower crumbles, removed
note right of Unlocked
Cost: 75 Gold + 10 Torches (scales with count)
Unlock time: ~2:00 into game
Toast: "Lantern Tower Unlocked! Defend your territory"
end note
note right of Active
Sprite: ProceduralSprite tall structure
Effect: yellow/orange glow, radius 5 tiles
Passive: +0.1 Influence/sec, prevents fog regrowth in radius
end note
note right of Damaged
Combat: auto-attacks shadows in range
Damage: 5 per second to each shadow
Visual: tower flashes, projectile to shadow
end note
```
### Merchant (Trade Unit)
```mermaid
stateDiagram-v2
[*] --> Locked: trade route system not unlocked
Locked --> Unlocked: 2 revealed locations connected by explored path
Unlocked --> Spawning: player drags route between locations
Spawning --> Outbound: leaves first location
Outbound --> Patrolling: following trade route
Patrolling --> Inbound: reaches second location
Inbound --> Returning: begins return trip
Returning --> Delivered: reaches first location (camp)
Delivered --> Outbound: begins next patrol cycle
Delivered --> Dying: fog reclaims route midpoint
Patrolling --> Dying: shadow attacks merchant
Dying --> [*]: merchant disappears, gold lost
note right of Unlocked
Unlock condition: 2 revealed locations + explored path between
Unlock time: ~6:00 into game
Toast: "Trade Route Established! Merchant patrolling"
end note
note right of Spawning
Sprite: Wizard (blue/gold recolor)
Spawn point: first location of route
Visual: merchant appears with brief pop-in
end note
note right of Delivered
Gold reward: 2 * routeTiles * (1 + 0.05 * roadLevel)
Visual: "+X 🪙" floating text at camp
Frequency: completes route in 10-30s depending on length
end note
```
## 8. Fog/Territory State Machine
```mermaid
stateDiagram-v2
[*] --> Unexplored: initial game state (all fog except camp)
Unexplored --> Revealed: cartographer enters tile
Revealed --> Stable: tile has visitedWithinLastSeconds
Stable --> Warning: tile not visited for 20s
Warning --> Fading: tile not visited for 30s (base regrowth delay)
Fading --> Revealed: cartographer re-visits before fog returns
Fading --> FogRegrown: regrowth timer completes
FogRegrown --> Unexplored: fog returns completely
Revealed --> Protected: lantern tower in range
Protected --> Revealed: tower destroyed, reverts to normal
note right of Unexplored
Visual: dark fog overlay with animated wisps
Not clickable (player must explore adjacent first)
May show subtle hint (shadow for mountain, glint for water)
end note
note right of Revealed
Visual: terrain visible (grass/forest/water/mountain/ruins)
Player can click adjacent fog tiles
Cartographer can move through freely
end note
note right of Fading
Visual: fog overlay returns at 20% opacity
Warning to player: territory being lost
Duration: 10s before fully regrown (base)
end note
note right of Protected
Modifier: lantern tower prevents regrowth
Visual: subtle yellow tint on tile
Bonus: +0.1 Influence/sec from tower
end note
```
## CONFIG Spec: progression Section
```javascript
// Cartographer's Fog - Progression Configuration
CONFIG.progression = {
// Entity unlock progression
unlocks: {
workerSystem: {
requirement: 'tilesRevealed >= 3',
unlocks: 'workerAssignment',
toast: 'Worker System Unlocked!',
indicator: 'worker-button-glow',
triggerType: 'gameplay', // Tile reveal action
},
scoutSpec: {
requirement: 'knowledge >= 20',
unlocks: 'scoutSpecialization',
toast: 'Scout Specialization Available!',
indicator: 'spec-button-flash',
triggerType: 'currency',
oneTime: true,
},
mapperSpec: {
requirement: 'knowledge >= 30',
unlocks: 'mapperSpecialization',
toast: 'Mapper Specialization Available!',
indicator: 'spec-button-flash',
triggerType: 'currency',
oneTime: true,
},
explorerSpec: {
requirement: 'knowledge >= 40',
unlocks: 'explorerSpecialization',
toast: 'Explorer Specialization Available!',
indicator: 'spec-button-flash',
triggerType: 'currency',
oneTime: true,
},
lanternTower: {
requirement: 'gold >= 75 && torches >= 10',
unlocks: 'lanternTowerBuild',
toast: 'Lantern Tower Unlocked!',
indicator: 'build-button-glow',
triggerType: 'currency',
},
combatTraining: {
requirement: 'knowledge >= 25 && shadowsDefeated >= 1',
unlocks: 'cartographerCombat',
toast: 'Combat Training Available!',
indicator: 'upgrade-button-flash',
triggerType: 'gameplay', // Requires shadow kill
},
tradeRoute: {
requirement: 'revealedLocations >= 2 && pathBetweenExplored',
unlocks: 'tradeRouteSystem',
toast: 'Trade Routes Unlocked!',
indicator: 'route-tool-enable',
triggerType: 'gameplay', // Path exists
},
deepFog: {
requirement: 'mapPercent >= 50',
unlocks: 'deepFogZones',
toast: 'Deep Fog Discovered! Dangerous but valuable...',
indicator: 'fog-edge-change',
triggerType: 'milestone',
},
prestige: {
requirement: 'mapPercent >= 80 || mapEdgeReached',
unlocks: 'prestigeButton',
toast: 'Ascension Available! The journey continues...',
indicator: 'prestige-button-active',
triggerType: 'milestone',
},
},
// Milestone rewards
milestones: [
{
id: 'firstSteps',
trigger: 'tilesRevealed >= 3',
reward: { gold: 5 },
toast: '🏆 First Steps! The journey begins!',
once: true,
},
{
id: 'resourcePioneer',
trigger: 'firstResourceDiscovered',
reward: { unlocks: ['workerSystem'] },
toast: '🏆 Resources discovered! Assign workers to gather.',
once: true,
},
{
id: 'lightBringer',
trigger: 'firstTowerBuilt',
reward: { influence: 10 },
toast: '🏆 Territory secured! The light pushes back darkness.',
once: true,
},
{
id: 'shadowBanisher',
trigger: 'shadowsDefeated >= 1',
reward: { knowledge: 25 },
toast: '🏆 Darkness pushed back! The shadows fear light.',
once: true,
},
{
id: 'routeFinder',
trigger: 'firstTradeRouteCreated',
reward: { gold: 50 },
toast: '🏆 Trade established! Merchants bring prosperity.',
once: true,
},
{
id: 'ruinInvestigator',
trigger: 'ruinsInvestigated >= 1',
reward: { knowledge: 20, influence: 10 },
toast: '🏆 Secrets revealed! The ruins yield knowledge.',
once: true,
},
{
id: 'multiExplorer',
trigger: 'cartographerCount >= 2',
reward: { torches: 5 },
toast: '🏆 Expedition grows! Multiple paths open.',
once: true,
},
{
id: 'mapMaker',
trigger: 'mapPercent >= 50',
reward: { gold: 100, knowledge: 50 },
toast: '🏆 Half the realm known! The kingdom remembers.',
once: true,
},
{
id: 'edgeFinder',
trigger: 'mapEdgeReached',
reward: { unlocks: ['prestige'] },
toast: '🏆 The world\'s edge found! What lies beyond?',
once: true,
},
],
// Upgrade tiers (replaces skill tree)
upgradeTiers: {
tier1: {
// Available from start - basic stats
name: 'Basic Equipment',
unlocks: 'gameStart',
upgrades: {
cartographerSpeed: {
name: 'Cartographer Speed',
cost: { gold: 30 },
costMultiplier: 1.2,
maxLevel: 5,
effect: 'movementTime -10%',
visible: 'cartographer walks faster',
},
torchCapacity: {
name: 'Torch Capacity',
cost: { knowledge: 15 },
costMultiplier: 1.5,
maxLevel: 5,
effect: 'maxTorches +10',
visible: 'torch cap increases in UI',
},
workerSpeed: {
name: 'Worker Efficiency',
cost: { gold: 20 },
costMultiplier: 1.15,
maxLevel: 5,
effect: 'harvestTime -10%',
visible: 'workers harvest faster',
},
},
},
tier2: {
// Unlocks at wave milestone - build diversity
name: 'Advanced Equipment',
unlocks: 'mapPercent >= 25',
unlocksAt: '5:00',
mutuallyExclusive: false,
upgrades: {
lanternTowerDamage: {
name: 'Tower Damage',
cost: { gold: 50, knowledge: 20 },
costMultiplier: 1.3,
maxLevel: 3,
effect: 'towerDamage +5',
visible: 'tower projectiles more visible',
},
merchantCapacity: {
name: 'Merchant Packs',
cost: { gold: 40 },
costMultiplier: 1.25,
maxLevel: 3,
effect: 'merchantYield +20%',
visible: 'merchants carry more',
},
fogVision: {
name: 'Fog Hints',
cost: { knowledge: 25 },
costMultiplier: 1.2,
maxLevel: 3,
effect: 'fogHintRadius +1',
visible: 'fog shows more details',
},
},
},
tier3: {
// Unlocks later - synergy bonuses
name: 'Master Techniques',
unlocks: 'mapPercent >= 60',
unlocksAt: '15:00',
mutuallyExclusive: false,
upgrades: {
territoryLock: {
name: 'Territory Lock',
cost: { influence: 50, knowledge: 50 },
costMultiplier: 1.5,
maxLevel: 1,
effect: 'revealedTilesNeverRegrow',
visible: 'revealed tiles permanent (no fog return)',
},
rapidExploration: {
name: 'Rapid Exploration',
cost: { influence: 30 },
costMultiplier: 1.4,
maxLevel: 3,
effect: 'allCartographers +20% speed',
visible: 'all cartographers move faster visibly',
},
shadowRepellent: {
name: 'Shadow Repellent',
cost: { influence: 40 },
costMultiplier: 1.5,
maxLevel: 2,
effect: 'shadowsSpawnRate -25%',
visible: 'fewer shadows spawn',
},
},
},
},
// Fog progression
fog: {
baseRegrowthDelaySeconds: 30,
aggressiveThresholdPercent: 50, // After 50% explored
aggressiveRegrowthDelaySeconds: 15, // Half the time
deepFogThresholdPercent: 60,
shadowSpawnRate: {
base: '1 shadow per 10 revealed tiles',
scaled: '1 shadow per 5 revealed tiles (aggressive)',
},
},
};
CONFIG.prestige = {
teaserWave: 80, // % map explored
minWave: 80, // prestige becomes clickable
formula: 'floor(tilesRevealed * 0.1 + ruinsInvestigated * 5 + mapPercent * 50)',
threshold: 100, // minimum CP to see prestige as viable
resets: ['gold', 'knowledge', 'torches', 'influence', 'cartographers', 'workers', 'towers', 'merchants', 'territory'],
persists: ['cartographyPoints', 'prestigeUpgrades', 'achievements', 'unlockedSpecs'],
visualTiers: [
{ tier: 0, minPrestiges: 0, background: '#1a1a2e', fogColor: '#0a0a12', terrainShift: 0 },
{ tier: 1, minPrestiges: 1, background: '#1a2e2a', fogColor: '#120f1a', terrainShift: 30, name: 'Crimson Peaks' },
{ tier: 2, minPrestiges: 3, background: '#1a1a3e', fogColor: '#0f1a2e', terrainShift: 60, name: 'Verdant Wilds' },
{ tier: 3, minPrestiges: 5, background: '#2e2a1a', fogColor: '#1a0f2e', terrainShift: 120, name: 'Azure Expanse' },
{ tier: 4, minPrestiges: 8, background: '#3e2a1a', fogColor: '#2e1a3e', terrainShift: 180, name: 'Golden Expanse' },
{ tier: 5, minPrestiges: 12, background: '#2a1a3e', fogColor: '#3e1a2a', terrainShift: 240, name: 'Obsidian Domain' },
],
upgrades: {
startingTorches: {
name: 'Extra Torches',
cost: 1,
costMultiplier: 2,
effect: 'startingTorches +5',
visible: 'start with more torches',
maxLevel: 10,
},
fogRegrowthDelay: {
name: 'Fog Delay',
cost: 10,
costMultiplier: 2.5,
effect: 'initialFogDelay +10%',
visible: 'fog returns slower',
maxLevel: 5,
},
revealRadiusBonus: {
name: 'Greater Light',
cost: 5,
costMultiplier: 2,
effect: 'revealRadius +0.5 tiles',
visible: 'cartographers reveal larger area',
maxLevel: 8,
},
cartographerSpeedBonus: {
name: 'Swift Movement',
cost: 3,
costMultiplier: 1.8,
effect: 'cartographerSpeed +10%',
visible: 'all cartographers move faster',
maxLevel: 10,
},
startingGold: {
name: 'Royal Funding',
cost: 15,
costMultiplier: 2.2,
effect: 'startingGold +25',
visible: 'start with more gold',
maxLevel: 5,
},
workerEfficiency: {
name: 'Master Craftsmen',
cost: 20,
costMultiplier: 2.5,
effect: 'workerSpeed +15%',
visible: 'workers start more efficient',
maxLevel: 3,
},
},
};
```
## Anti-Frustration Features
- **Stuck detection**: If no new tiles revealed for 60 seconds, highlight fog edge with pulsing effect showing "Explore here!" hint
- **Catchup mechanics**: If player has < 10 Torches for 30 seconds, spawn "Emergency Torch Cache" ruin that can be investigated for free torches
- **Visual progress**: Progress bar on map always visible, showing X% explored with "Map Edge: Y tiles away" indicator
- **Death recovery**: Cartographer death respawns at camp after 5 seconds (no cost), but player loses torches spent on current path
- **Resource overflow**: If at torch cap, highlight torch-spending options with gold glow to encourage spending
## Motivator Summary
| Timeframe | What Drives Player |
|-----------|----------------------|
| Next 30 sec | Almost can afford next upgrade, watching cartographer reveal tiles |
| Next 2 min | New specialization or tower about to unlock (scout at 20 Knowledge, tower at 75 Gold) |
| Next 5 min | Ancient ruin visible in fog, trade route system when second location found |
| Session | Prestige for permanent power, new visual world region (color shift) |
Ui Ux
{
"game_name": "Cartographer's Fog",
"section": "ui-ux",
"job_id": 69,
"phase": 2,
"overview": "Dark atmospheric exploration interface where Canvas game world dominates 70% of viewport. UI surrounds with minimal chrome—dark semi-transparent panels that enhance rather than distract from fog-covered exploration experience.",
"colorPalette": {
"background": {
"primary": "#1a1a2e",
"secondary": "#16213e",
"tertiary": "#2a2a4e"
},
"canvas": {
"base": "#0f0f1a",
"ground": "#1a1a2e",
"fog": "#16213e",
"grass": "#2d6a4f",
"forest": "#1a4a3a",
"water": "#0077b6",
"mountain": "#6c757d",
"ruins": "#d4a373"
},
"text": {
"primary": "#e0e0d0",
"secondary": "#a0a0a0",
"muted": "#606060"
},
"accent": {
"gold": "#d4a373",
"knowledge": "#4FC3F7",
"torches": "#f59e42",
"influence": "#9b59c3",
"cp": "#E040FB"
},
"success": "#4CAF50",
"warning": "#ffb700",
"danger": "#ff4436",
"prestige": "#E040FB"
},
"typography": {
"fontFamily": "'Cinzel', 'Segoe UI', Tahoma, sans-serif",
"headings": "Bold 700, 18-22px",
"bodyText": "Regular 400, 14-16px",
"numbersCurrency": "'Roboto Mono', 'Courier New', monospace",
"buttons": "SemiBold 600, 14-16px"
},
"screenLayout": {
"canvas": {
"heightPercent": 70,
"aspectRatio": "16:9",
"centered": true
},
"hudBar": {
"height": 50,
"position": "overlay top"
},
"bottomPanel": {
"heightPercent": 30,
"collapsible": true,
"minHeight": 200
}
},
"hudBar": {
"goldCurrency": {
"position": "left 20px from left",
"icon": "🪙",
"content": "amount + rate/sec",
"animation": "300ms",
"colorCode": "#d4a373"
},
"knowledgeCurrency": {
"position": "left after gold 180px",
"icon": "📜",
"content": "amount",
"animation": "300ms",
"colorCode": "#4FC3F7"
},
"torchesCurrency": {
"position": "left after knowledge 340px",
"icon": "🔥",
"content": "amount/max (X/100)",
"animation": "300ms",
"colorCode": "#f59e42"
},
"influenceCurrency": {
"position": "left after torches 500px",
"icon": "✨",
"content": "amount",
"animation": "300ms",
"colorCode": "#9b59c3"
},
"fogWarning": {
"position": "center-left below currencies",
"content": "⚠️ Low Torches! when < 15%",
"pulseColor": "#ffb700"
},
"mapProgress": {
"position": "center-right below currencies",
"content": "Map: 47.3%",
"gradient": "dark grey to cyan"
},
"settingsButton": {
"position": "far right 16px from edge",
"icon": "⚙️"
}
},
"canvas": {
"dimensions": "min 800px responsive width, height scales to 16:9 aspect",
"background": "radial gradient from center #0f0f1a to edges #1a1a2e",
"layers": [
"background (terrain, ground, sky)",
"fogOverlay",
"entities (all game sprites)",
"effects (damage numbers, death particles, ability effects)",
"hudOverlay (health bars, selection indicators, range circles)"
],
"camera": {
"fixed": true,
"centeredOnCampfire": true,
"panMargin": "0.1 (10% when cartographer near edges)"
},
"clickTouchInteractions": [
{
"action": "Left-click fog tile",
"description": "Send selected cartographer to explore that tile",
"behavior": "pathfinding to adjacent tiles only",
"invalidClickFeedback": "red flash 200ms on cursor"
},
{
"action": "Left-click revealed resource",
"description": "Assign worker to gather (spawns worker at camp, walks to resource)",
"affordCheck": "canAfford(25 gold)",
"invalidClickFeedback": "gray flash if insufficient gold"
},
{
"action": "Left-click ancient ruin",
"description": "Investigate ruin (sends cartographer if in range, shows investigation UI)",
"rangeRequired": "80px",
"progressBar": "5s investigation, shows above ruin"
},
{
"action": "Left-click revealed tile (with building mode)",
"description": "Place lantern tower (shows placement preview, confirms on click)",
"snapToGrid": "16px tiles",
"preview": "dotted cyan circle 50% opacity, 5-tile radius"
},
{
"action": "Right-click cartographer",
"description": "Cycle specialization (Scout → Mapper → Explorer)",
"visualFeedback": "cartographer flashes with spec icon"
},
{
"action": "Drag between two revealed locations",
"description": "Create trade route (shows path preview, releases to spawn merchant)",
"pathPreview": "animated cyan line following cursor"
},
{
"action": "Left-click collectible",
"description": "Collect currency (within 24px radius of knowledge scroll, gold coin, or influence sparkle)",
"collectRadius": "24px"
}
],
"visualFeedback": {
"fogTileReveal": {
"effect": "pulsing cyan glow 0.6s duration, 0.5s interval",
"rewardSpawn": "knowledge scroll spawns with pop-in animation 300ms"
},
"resourceNodeDiscovery": {
"effect": "resource node shows Assign Worker tooltip on hover with cost and yield info"
},
"ancientRuinDiscovery": {
"effect": "ruin shows Investigate tooltip with Knowledge/Influence rewards listed"
},
"towerPlacementPreview": {
"effect": "dotted cyan circle shows 5-tile radius, updates with cursor movement"
},
"tradeRoutePathPreview": {
"effect": "animated cyan line draws between two locations, highlights when valid route"
}
}
},
"entitySpecs": {
"cartographer": {
"sprite": "Knight brown/tan recolor",
"scale": 3,
"team": "player",
"hp": 50,
"damage": 10,
"attackSpeed": 1.0,
"attackRange": 40,
"moveSpeed": 0.5,
"revealRadius": 3,
"states": {
"idle": { "frames": [0, 1], "frameDuration": 500 },
"moving": { "frames": [0, 1, 2, 3], "frameDuration": 200 },
"revealing": { "animation": "fog fade with ripple 300ms", "reward": "knowledge based on tile type" },
"defending": { "frames": [2, 3], "frameDuration": 150, "spawnProjectile": true },
"dying": { "animation": "opacity 1→0 over 500ms", "particles": 5 spark burst" }
},
"healthBar": { "show": true, "width": 32, "height": 4, "yOffset": -8, "color": "#4CAF50" },
"glow": "white pulse 300ms when selected",
"flip": true
},
"worker": {
"sprite": "Slime human skin tone recolor",
"scale": 2.5,
"team": "player",
"hp": 20,
"carryCapacity": 10,
"moveSpeed": 0.3,
"harvestSpeed": 5,
"states": {
"idle": { "frames": [0, 1], "frameDuration": 500 },
"movingToResource": { "duration": 3000 },
"harvesting": { "frames": [0, 1], "frameDuration": 5000 },
"returningToCamp": { "duration": 500 },
"dying": { "animation": "fade out 1→0 over 400ms", "carriedResourcesLost": true }
},
"healthBar": { "show": true, "width": 24, "height": 3, "yOffset": -4, "color": "#4CAF50" },
"carryVisible": "small sack sprite shows when carrying resources",
"flip": true
},
"shadowCreature": {
"sprite": "Ghost black/purple recolor",
"scale": 2.5,
"team": "enemy",
"hp": 30,
"hpPerMapTier": 10,
"damage": 5,
"moveSpeed": 0.3,
"attackSpeed": 0.5,
"reward": { "gold": 5, "influence": 2 },
"states": {
"spawning": { "trigger": "revealedTerritory > 10 tiles", "animation": "purple fog swirl, shadow materializes 1s fade in 0→1" },
"emerging": { "animation": "fade in 0→1 over 1s" },
"hunting": { "pathfinding": "direct line to target, ignores obstacles" },
"chasing": { "targetPriority": "cartographer > worker > merchant" },
"attacking": { "frames": [2, 3], "frameDuration": 150, "cooldown": 1000 },
"dying": { "animation": "fade out 1→0 over 500ms", "particles": 5 spark burst", "dropRewards": true }
},
"healthBar": { "show": true, "width": 28, "height": 3, "yOffset": -6, "color": "#9b59c3" },
"faintPurple": "2s duration pulse when attacking",
"flip": false
},
"merchant": {
"sprite": "Wizard blue/gold recolor",
"scale": 2.5,
"team": "player",
"hp": 25,
"carryCapacity": 20,
"moveSpeed": 0.4,
"yield": { "base": 2, "roadMultiplier": 1.05 },
"states": {
"spawning": { "animation": "merchant fades in 300ms at first location" },
"outbound": { "duration": "varies by route length 10-30s" },
"patrolling": { "tilesPerSecond": 2, "goldTrailParticles": true },
"inbound": { "duration": 500, "depositReward": true },
"returning": { "duration": 500, "flipForReturn": true },
"dying": { "animation": "fade out 1→0 over 400ms", "carriedGoldLost": true }
},
"healthBar": { "show": true, "width": 26, "height": 3, "yOffset": -5, "color": "#d4a373" },
"flip": true
},
"lanternTower": {
"sprite": "ProceduralSprite tall structure with animated pulse",
"scale": 3,
"team": "player",
"hp": 50,
"damage": 5,
"attackRange": 80,
"torchDrain": 0.1,
"influenceGen": 0.1,
"states": {
"placing": { "animation": "tower rises from ground scale 0→1 over 2s", "dustParticles": 6 },
"draining": { "glowDim": "slight dim when torches low" },
"damaging": { "projectilePerSecond": 1 },
"destroyed": { "animation": "tower crumbles scale 1→0.8 over 500ms", "brickParticles": 10, "fogReturns": true }
},
"glow": "yellow/orange pulse at top (brazier), 2s period",
"noHealthBar": true
},
"resourceNode": {
"sprite": "ProceduralSprite geometric shape",
"scale": 2,
"yieldPerTrip": { "iron": 5, "gold": 10, "herbs": 3 },
"respawnTime": 30,
"states": {
"discovered": { "spriteColor": "iron=grey, gold=yellow, herbs=green" },
"revealed": { "assignable": true, "showProgress": true, "maxWorkers": 5 },
"assigned": { "progressBar": "0-100% per worker", "showNodeDepleted": true },
"depleted": { "spriteDarkened": true, "showCompleted": false, "respawnTimer": 30 }
},
"noHealthBar": true,
"noFlip": false
},
"ancientRuin": {
"sprite": "ProceduralSprite crumbled stone structure",
"scale": 4,
"investigationDuration": 5,
"cooldown": 60,
"tier": 1,
"states": {
"locked": { "visibility": "hidden until revealed" },
"revealed": { "investigatable": true, "showPreview": true },
"investigating": { "progressBar": "5s, showsKnowledgeReward": true },
"completed": { "oneTimeReward": true, "cannotReinvestigate": true },
"cooldown": { "dimmed": true, "showTimer": true }
},
"progressBar": { "show": true, "width": 40, "height": 4, "yOffset": -10, "color": "#4FC3F7" }
},
"collectible": {
"knowledgeScroll": {
"sprite": "scroll",
"scale": 1.2,
"lifetime": 8,
"collectRadius": 24,
"bobAmplitude": 2,
"bobSpeed": 2,
"spawnAnimation": "popIn 300ms scale 0→1",
"color": "cyan"
},
"goldCoin": {
"sprite": "goldCoin",
"scale": 1.5,
"lifetime": 8,
"collectRadius": 24,
"bobAmplitude": 2,
"bobSpeed": 2.5,
"spawnAnimation": "popIn 300ms scale 0→1",
"color": "gold"
},
"influenceSparkle": {
"sprite": "sparkle",
"scale": 1.3,
"lifetime": 6,
"collectRadius": 20,
"bobAmplitude": 3,
"bobSpeed": 3,
"spawnAnimation": "popIn 300ms scale 0→1",
"color": "purple"
}
}
},
"entityInteractionDiagram": {
"playerUnits": ["cartographer", "worker", "merchant"],
"enemyUnits": ["shadowCreature"],
"structures": ["lanternTower"],
"collectibles": ["knowledgeScroll", "goldCoin", "influenceSparkle"],
"interactions": {
"cartographer_spawn_worker": "cartographer assigned → worker spawns",
"cartographer_spawn_merchant": "cartographer at route → merchant spawns",
"cartographer_attack_shadow": "cartographer in range → shadow takes damage",
"shadow_attack_cartographer": "shadow in range → cartographer takes damage",
"shadow_attack_worker": "shadow in range → worker takes damage",
"shadow_attack_merchant": "shadow in range → merchant takes damage",
"shadow_death → knowledge_gold_drop": "shadow hp <= 0 → drops rewards",
"tower_damage_shadow": "tower in range → shadow takes damage per second",
"worker_harvest → gold_coin_spawn": "worker finishes harvest → gold coin spawns at resource",
"worker_death": "worker hp <= 0 → dies (no drop, fog reclaims tile)",
"merchant_return → gold_income": "merchant reaches camp → gold income",
"merchant_death": "merchant hp <= 0 → dies (gold lost at death location)",
"player_click_collectible": "player click within radius → collect rewards",
"ruin_investigate → knowledge_influence_reward": "ruin investigated → knowledge + influence rewarded"
}
},
"hudOverlay": {
"entityHealthBars": {
"showAboveEntity": true,
"smallColoredBar": "4px from entity top, red gradient for enemies, cyan for allies",
"updateOnDamage": true,
"fadeOutOnDeath": true
},
"floatingDamageNumbers": {
"position": "at damage location",
"style": "-X in red white, +X in green white",
"floatUpward": "30px over 800ms, fade out",
"fontSize": "14px bold"
},
"floatingRewardNumbers": {
"position": "at death/complete location",
"style": "+X with icon in currency color",
"floatUpward": "30px over 800ms, fade out",
"fontSize": "14px bold"
},
"waveIndicator": {
"position": "top center of canvas",
"content": "Wave 5 incoming!",
"appearDuration": 2000,
"fadeDuration": 2000,
"notUsed": "true (Cartographer's Fog has no waves)"
},
"spawnIndicators": {
"position": "at spawn points",
"style": "pulsing circle 100% opacity",
"showsWhereEnemiesWillAppear": true
}
},
"bottomPanel": {
"height": 250,
"collapsibleHeight": 40,
"tabs": [
{
"id": "upgrades",
"label": "UPGRADES",
"icon": "🛠️",
"unlockedAt": "gameStart",
"columns": 2
},
{
"id": "specialize",
"label": "SPECIALIZE",
"icon": "🎭️",
"unlockedAt": "knowledge >= 20",
"columns": 3
},
{
"id": "routes",
"label": "ROUTES",
"icon": "🛤️",
"unlockedAt": "mapPercent >= 10",
"columns": 1
},
{
"id": "stats",
"label": "STATS",
"icon": "📊",
"unlockedAt": "mapPercent >= 25",
"columns": 1
},
{
"id": "settings",
"label": "SETTINGS",
"icon": "⚙️",
"unlockedAt": "gameStart"
}
]
},
"tabContents": {
"upgrades": {
"cardLayout": "2 columns, card icon + name + description + effect + cost + buy button",
"cards": [
{
"name": "cartographerSpeed",
"icon": "⚡",
"label": "Cartographer Speed",
"description": "Movement speed +10%",
"cost": { "gold": 30 },
"currency": "gold",
"maxLevel": 5,
"currentEffect": "+10% speed",
"nextEffect": "+20% speed"
},
{
"name": "torchCapacity",
"icon": "🔥",
"label": "Torch Capacity",
"description": "Max torches +10",
"cost": { "knowledge": 15 },
"currency": "knowledge",
"maxLevel": 5,
"currentEffect": "+10 capacity",
"nextEffect": "+20 capacity"
},
{
"name": "workerSpeed",
"icon": "⚡",
"label": "Worker Efficiency",
"description": "Harvest time -10%",
"cost": { "gold": 20 },
"currency": "gold",
"maxLevel": 5,
"currentEffect": "-10% harvest",
"nextEffect": "-20% harvest"
},
{
"name": "towerDamage",
"icon": "🏯",
"label": "Tower Damage",
"description": "Damage +5 per second",
"cost": { "gold": 50, "knowledge": 20 },
"currencies": { "gold": 50, "knowledge": 20 },
"maxLevel": 3,
"unlockCondition": "mapPercent >= 25",
"currentEffect": "+5 damage/s",
"nextEffect": "+10 damage/s"
}
]
},
"specialize": {
"cards": [
{
"name": "scout",
"icon": "🏃",
"label": "Scout",
"description": "Fast exploration, smaller light",
"stats": "Speed: +20%, Reveal: 2×2",
"oneTime": true,
"currentSpec": "none"
},
{
"name": "mapper",
"icon": "🗺️",
"label": "Mapper",
"description": "Trail markers, slower movement",
"stats": "Speed: -10%, Fog delay: +20%",
"oneTime": true,
"currentSpec": "none"
},
{
"name": "explorer",
"icon": "🧭",
"label": "Explorer",
"description": "Can enter deep fog, reveals special locations",
"stats": "Speed: -30%, Special reveal",
"oneTime": true,
"currentSpec": "none"
}
]
},
"routes": {
"routeList": "displays all trade routes with status (active/blocked)",
"routeDisplay": "Camp → Iron Mine (5 tiles, 10g/trip, Merchant 1/1, Status: ACTIVE)",
"createNewRoute": "drag between two revealed locations",
"merchantStats": "Merchant: 1/2 (active), Capacity: 20g, Yield: 2g/tile × tiles",
"actionButtons": "Assign more merchants (if affordable), Cancel route, Delete route"
},
"stats": {
"mapBreakdown": "Revealed: 127 (21.2%), Fog-covered: 471 (78.8%)",
"productionRates": "Gold: +12.3/s, Knowledge: +0.5/s, Torches: +0.8/s, Influence: +0.2/s",
"cartographerList": "Scout #1 (Idle, 20% speed), Mapper #0 (Locked), Explorer #0 (Locked)",
"resourceNodes": "Iron mines: 7 (3 active, 4 depleted), Gold veins: 4 (2 active, 2 depleted), Herb patches: 5 (2 active, 3 depleted)",
"structures": "Lantern Towers: 3 (pushing back 15 tiles), Ancient Ruins: 2 (1 investigated, 1 remaining)"
}
},
"notifications": {
"toastArea": {
"position": "top-right",
"slideInFrom": "right",
"stackMax": 3,
"stackDuration": 3000,
"autoDismiss": 3000
},
"milestonePopup": {
"position": "centered screen",
"showIcon": true,
"showRewardBreakdown": true,
"dismissOnClick": true,
"autoDismiss": 3000
},
"fogWarning": {
"message": "⚠️ Low Torches!",
"threshold": 15,
"pulseColor": "#ffb700",
"showWhen": "torches < 15% of capacity"
},
"routeBlockedWarning": {
"message": "⚠️ Trade route blocked by fog!",
"showWhen": "fog reclaims route tile",
"flashColor": "red"
}
},
"upgradeCard": {
"affordable": {
"borderColor": "#4CAF50",
"buttonColor": "#4CAF50",
"buttonBg": "#4CAF50",
"textColor": "#e0e0d0"
},
"maxed": {
"borderColor": "#4CAF50",
"buttonHidden": true,
"maxBadge": "MAX",
"badgeColor": "#e0e0d0"
},
"locked": {
"opacity": 0.5,
"dimmed": true,
"lockIcon": "🔒",
"noTooltip": "???",
"unlockTooltip": "shows spec name and unlock condition"
},
"affordableHover": {
"highlightEffect": "card raises 2px",
"showTooltip": true,
"detailedStats": "current/max/level, effect per level"
},
"affordableClick": {
"flash": "white 200ms",
"numberTickUp": "cost flies toward currency display 400ms",
"satisfactionFeedback": "entities affected glow briefly"
},
"unaffordableClick": {
"shake": "±5px x, 200ms",
"costFlash": "red 200ms",
"noPurchase": true
},
"newUnlock": {
"tabGlow": "tab icon pulses 2s",
"notificationDot": "appears, toast shows unlock",
"toast": "New tab unlocked!"
}
},
"currencyDisplay": {
"numberAnimation": "count-up 300ms duration",
"rateDisplay": "per-second in smaller 12px text",
"largeNumberSuffixes": "K/M/B/T",
"color": "matches accent color for currency",
"earnedByGameplayFlash": "200ms glow/pulse when currency earned from defeating enemies or merchant returns (distinct from passive income)"
},
"milestoneAchievement": {
"appearance": "slide in from right 300ms ease-in",
"duration": 3500,
"stackMax": 3,
"stackVertically": "10px gap between toasts",
"icon": "★",
"dismiss": "click outside or Got It button"
},
"prestigePanel": {
"layout": "centered modal 600px wide, sections side-by-side",
"sections": {
"keepsSection": {
"color": "green",
"title": "LOST",
"items": ["gold", "knowledge", "torches", "influence", "cartographers", "workers", "merchants", "towers", "territory"]
},
"gainsSection": {
"color": "green",
"title": "YOU WILL EARN",
"items": ["1,250 CP", "2,750 CP (after +1,250)"],
"bonusMultiplier": "× total tiles revealed × 0.1 + ruins investigated × 5 + map percent × 50"
},
"visualChange": {
"title": "VISUAL CHANGE",
"items": ["Terrain color shift +30", "Fog color changes to purple"],
"newRegionName": "Crimson Peaks"
},
"actionButtons": {
"reset": { "label": "RESET ALL", "confirmation": true },
"cancel": { "label": "CANCEL", "confirmation": false },
"prestige": { "label": "PRESTIGE!", "confirmation": true }
}
},
"currencyDisplay": "shows current CP, will earn CP, keeps/persists items list"
},
"skillTreeRenderer": {
"layout": "CSS Grid, 3 columns × 2 rows max",
"nodeSize": "64px × 64px per node",
"connectionLines": "SVG 2px stroke, #606060 color 60% opacity white, animated dash flow",
"nodeStates": {
"starting": { "filled": "hollow accent circle", "icon": true },
"available": { "filled": "accent color fill", "border": "accent color" },
"selected": { "filled": "accent color fill", "border": "white 2px" },
"maxed": { "filled": "success color fill", "badge": "MAX white" },
"locked": { "filled": "dimmed 50% opacity", "lock icon center" }
}
},
"tooltip": {
"trigger": "hover desktop after 200ms delay",
"position": "above cursor, clamped to viewport",
"arrow": "points toward node if space available",
"width": "240px max"
},
"settingsPanel": {
"layout": "centered overlay 500px wide, categories in collapsible sections",
"numberFormat": {
"standard": "Standard (1,234,567.89)",
"scientific": "Scientific (1.23K, 567.89K)",
"switchable": true
},
"animationSpeed": {
"slider": "0.5x-2x",
"effect": "scales all animation durations and canvas game speed"
},
"autoSaveInterval": {
"options": [10, 30, 60],
"default": 30
},
"canvasQuality": {
"toggle": "high (glow effects + particles) / low (no glows, reduced particles)",
"high": "full visual effects",
"low": "performance mode for slower devices"
},
"hardReset": {
"button": "with confirmation",
"confirmationText": "Reset all progress. This cannot be undone!"
},
"exportSave": "copies save string to clipboard with toast",
"importSave": "prompts for save string, parses and loads game state"
},
"controlsPanel": {
"position": "bottom of screen, below Canvas, 40px from edge",
"alwaysVisible": true,
"content": [
{ "action": "Click fog tile to explore", "hotkey": "none" },
{ "action": "Right-click cartographer to cycle spec", "hotkey": "none" },
{ "action": "Drag: Create trade route between locations", "hotkey": "none" }
],
"style": "semi-transparent dark background (#16213e 80% opacity), light text (#e0e0d0), compact single-line layout, monospace for hotkeys"
},
"gettingStartedOverlay": {
"trigger": "first page load automatically",
"dismiss": "Got It! button OR click anywhere outside",
"persistence": "localStorage 'tutorialDismissed' flag, don't show again",
"content": "• Click on dark fog tiles to send your cartographer exploring and reveal the map\n• Discover resources and click them to assign workers who gather gold\n• Build lantern towers to protect your territory from encroaching fog\n• Reach ancient ruins and investigate them for powerful knowledge upgrades",
"style": "semi-transparent dark overlay (#1a1a2e 90% opacity), centered modal, large readable 18px text, prominent dismiss button",
"zIndex": 9999
},
"responsiveness": {
"minWidth": 1280,
"maxWidth": "no cap, canvas fills available width",
"scaling": "canvas scales to fit, bottom panel uses rem-based 16px sizing",
"panelCollapseBehavior": "bottom panel can be collapsed to 40px for more canvas space on narrow viewports, defaults to collapsed on mobile"
},
"accessibility": {
"contrastRatios": "all text meets WCAG AA 4.5:1 minimum",
"focusIndicators": "visible 2px #4FC3F7 outlines for keyboard navigation",
"screenReader": "currency amounts have aria-live regions, tooltips have aria-describedby",
"reducedMotion": "prefers-reduced-motion media query disables Canvas animations, uses static sprites"
},
"config": {
"canvas": {
"width": 800,
"height": 450,
"backgroundColor": "#1a1a2e",
"gridCellSize": 16,
"layers": ["background", "entities", "effects", "hudOverlay"]
},
"ui": {
"tickRate": 60,
"autoSaveInterval": 30000,
"theme": "dark",
"hudHeight": 50,
"bottomPanelHeight": 250,
"bottomPanelCollapsedHeight": 40,
"canvasMinHeight": 400,
"tabs": [
{ "id": "upgrades", "label": "UPGRADES", "icon": "🛠️", "unlockedAt": "gameStart", "columns": 2 },
{ "id": "specialize", "label": "SPECIALIZE", "icon": "🎭️", "unlockedAt": "knowledge >= 20", "columns": 3 },
{ "id": "routes", "label": "ROUTES", "icon": "🛤️", "unlockedAt": "mapPercent >= 10", "columns": 1 },
{ "id": "stats", "label": "STATS", "icon": "📊", "unlockedAt": "mapPercent >= 25", "columns": 1 },
{ "id": "settings", "label": "SETTINGS", "icon": "⚙️", "unlockedAt": "gameStart" }
],
"notifications": {
"toastDuration": 3000,
"toastPosition": "top-right",
"milestoneDisplayDuration": 5000,
"stackLimit": 3,
"fogWarningThreshold": 0.15
}
},
"effects": {
"particles": {
"crystalCollection": { "count": 5, "sprite": "spark", "lifetime": 500, "spread": 20 },
"enemyDeath": { "count": 5, "sprite": "spark", "lifetime": 400, "spread": 15 },
"bossDeath": { "count": 30, "sprite": "spark", "lifetime": 800, "spread": 40 },
"structureDestroyed": { "count": 10, "sprite": "spark", "lifetime": 600, "spread": 25 }
},
"floatingText": {
"duration": 800,
"riseSpeed": 30,
"fontSize": 14,
"fontWeight": "bold",
"colors": {
"gold": "#FFD700",
"damage": "#FF4444",
"heal": "#44FF44",
"xp": "#44AAFF"
}
},
"screenFlash": {
"waveComplete": { "color": "#FFFFFF", "opacity": 0.3, "duration": 200 },
"prestige": { "color": "#FFFFFF", "opacity": 1.0, "duration": 500 },
"bossSpawn": { "color": "#000000", "opacity": 0.2, "duration": 300 }
},
"placementFlash": { "duration": 200, "color": "#FFFFFF", "opacity": 0.5 }
},
"colorPalette": {
"background": { "primary": "#0f0f1a", "secondary": "#1a1a2e", "tertiary": "#2a2a4e" },
"canvas": "#0f0f1a",
"text": { "primary": "#e0e0d0", "secondary": "#a0a0a0", "muted": "#606060" },
"accent1": "#FFD700",
"accent2": "#4FC3F7",
"accent3": "#E040FB",
"success": "#4CAF50",
"warning": "#ffb700",
"danger": "#FF4436",
"prestige": "#E040FB"
}
},
"qualityCriteria": [
"The Canvas game world is PRIMARY element, occupying 60-70% of screen height",
"Upgrade panels are SECONDARY, in bottom panel (not whole screen)",
"Currency displays are ALWAYS visible in HUD (never hidden behind tabs)",
"Every entity type from idea.md has visual specs (sprite, scale, animation states)",
"Canvas layers are specified (background, entities, effects, HUD overlay)",
"Every UI element has specified states (locked, available, affordable, maxed)",
"Feedback is specified for BOTH Canvas effects AND UI effects",
"Floating damage/reward numbers are specified for Canvas",
"The color palette has enough contrast for readability (dark theme)",
"Tab unlock conditions match progression.md unlock sequence",
"Number formatting rules cover full range from 0 to 1T+",
"The prestige UI shows visual transformation info",
"The skill tree rendering approach is implementable in vanilla CSS/JS (CSS Grid)",
"Accessibility basics are covered (contrast, keyboard, reduced motion)",
"The design works at 1280×720 minimum resolution",
"There is NO language about 'the UI IS THE game' — Canvas is THE game",
"Every entity type has a state machine diagram with all visual states",
"Entity interaction diagram shows how all entity types relate",
"UI event flow diagrams cover all major interaction paths (place, kill, collect, upgrade, fog reclaim)",
"UI state machine shows game phases (loading, playing, paused, prestige, game over)",
"CONFIG.entities spec has every entity with sprite, scale, team, hp, states, healthBar",
"CONFIG.canvas spec has width, height, backgroundColor, gridCellSize, layers",
"CONFIG.ui spec has tab definitions with unlock conditions",
"CONFIG.effects spec has particle, floatingText, and screenFlash definitions",
"CONFIG.colorPalette has hex values for every UI color role",
"Entity state definitions in CONFIG match state machine diagrams exactly",
"A permanent controls panel is designed showing ALL 5 player interactions (click tile to explore, right-click unit to cycle spec, drag between locations to create route, click collectible to collect)",
"A How to Play overlay is designed for first-load tutorial (4 bullet points)",
"The controls panel is ALWAYS visible (not hidden behind tabs/menus)",
"The tutorial overlay has a dismiss button and localStorage persistence",
"30-second gameplay description is entirely Canvas-based (no numbers/currencies mentioned)",
"Player interacts with Canvas directly every 2-5 seconds (exploring tiles is constant action)",
"Bystander would understand game from Canvas visuals alone (clear exploration narrative)",
"All major actions have both Canvas and UI feedback specified",
"Multiple rewards visible at any time (upgrades, unlocks, production rates, map progress)",
"Currency displays always visible (all 4 currencies shown in HUD)",
"Dark theme by default (all colors specified for dark background with warm gold accents)",
"Cartographer's Fog is recognizable game name (not abstract poetry)",
"Variable rewards implemented (tile knowledge varies by terrain type, shadow rewards scale with level, ruin rewards scale with tier, merchant yields vary by route)",
"Currency displays have earned-by-gameplay flash distinction (200ms glow for active earning vs subtle tick for passive)",
"Number suffix switching implemented (K/M/B/T for all currencies with 2+ decimal display except gold which is 0 decimals)",
"Minimum canvas height 400px guaranteed (30% panel at 1080p = 324px viewport minimum)",
"Panel collapse to 40px on mobile specified (gives Canvas more space on narrow screens)",
"Tab appearance animation specified (slides in from right 300ms ease, subtle glow pulse on icon when unlocked)",
"Upgrade card states specified (affordable/maxed/locked with different borders, button colors, hover effects)",
"Entity health bars specified (4px × 24-32px with color-coded by team, 4-8px offset from entity top)",
"Health bar fade out on death specified (300ms ease-out, no health bar for structures/collectibles)",
"Selection ring specified (gold stroke 2px width, pulsing animation 2s duration)",
"Tower placement preview specified (dotted cyan circle 5-tile radius, 50% opacity, updates with cursor movement)",
"Trade route path preview specified (animated cyan line following cursor between two locations)",
"Specialization cards specified (Scout/Mapper/Explorer with one-time unlock, current spec badge shown, stats listed, SELECT button for current spec)",
"Stats panel specified (revealed/fog-covered tile counts, production rates with all currencies shown, cartographer list with specs, resource nodes with active/depleted counts, structure summary)",
"Settings panel categories specified (number format with standard/scientific switch, animation speed slider 0.5x-2x, auto-save interval dropdown 10/30/60s, canvas quality high/low toggle, hard reset with confirmation, export/import save buttons)",
"Getting Started overlay specified (4 bullet points from idea.md Getting Started Tutorial, centered modal, large readable 18px text, prominent dismiss button, 9999 z-index, semi-transparent dark overlay with 90% opacity)",
"Accessibility features specified (WCAG AA 4.5:1 contrast ratios, visible 2px focus outlines, aria-live regions for currency updates with screen reader announcement, aria-describedby for tooltips, prefers-reduced-motion media query for disabling animations, keyboard navigation enabled)",
"Responsive behavior specified (1280px minimum width, no cap on maximum width, canvas scales to fit, bottom panel uses rem-based 16px sizing, panel collapses to 40px on narrow viewports, defaults to collapsed on mobile)",
"Fog warning indicator specified (pulses red #ffb700 when torches below 15% of capacity, shows ⚠️ Low Torches! toast)",
"Map progress bar specified (47.3% with gradient from dark grey to cyan, percentage label white text 14px in center, no current/max for single value)",
"Settings modal specified (centered overlay 500px wide, collapsible sections for each category, applies changes immediately on toggle/confirm, closes on outside click or cancel button)",
"Skill tree rendering specified (CSS Grid 3 columns × 2 rows max, 64px × 64px nodes, SVG 2px stroke white dash 60% opacity animated connection lines, node states with filled/selected/locked/maxed appearance)",
"Tooltip specified (hover desktop after 200ms delay, position above cursor clamped to viewport, max 240px width, arrow points toward node if space available)",
"Toast notifications specified (slide in from right 300ms ease-in, 3s duration, max 3 stacked vertically, auto-dismiss after 3s)",
"Milestone popup specified (centered screen modal with ★ achievement icon, shows reward breakdown, dismiss on click outside or Got It button, 3s auto-dismiss)",
"Prestige panel specified (centered modal with sections side-by-side, LOST in green, YOU WILL EARN in green, VISUAL CHANGE section, RESET ALL and CANCEL/PRESTIGE buttons, CP currency display showing current/will earn/keeps/persists items lists)",
"Screen flash effects specified (wave complete white flash 0.3 opacity 200ms, prestige white fade 1.0 opacity 500ms, boss spawn black flash 0.2 opacity 300ms)",
"Placement flash specified (white 200ms duration with 0.5 opacity)",
"Entity death particles specified (spark particles 5-30 count based on entity type, burst spread 10-40px, 200-800ms lifetime)",
"Floating text animation specified (floats upward 30px over 800ms duration, fades out, 14px bold, color-coded by currency/damage type)",
"Player controls panel always visible specified (bottom of screen below Canvas, 40px from edge, semi-transparent dark background with light text, lists all 5 player actions with triggers, compact single-line layout with monospace for hotkeys, never hidden behind tabs)"
]
}
Ui Ux
# Cartographer's Fog - UI/UX Design
## Overview
Cartographer's Fog features a dark, atmospheric exploration interface where the Canvas game world dominates the viewport (70% height). The UI surrounds the game with minimal chrome—dark semi-transparent panels that enhance rather than distract from the core experience of revealing a mysterious, fog-covered realm. The aesthetic evokes the feeling of being a Royal Cartographer exploring forgotten lands—parchment browns, warm golds, mysterious purples, and the living darkness of fog itself.
The Canvas IS the game. Players spend 80%+ of their time directly interacting with the game world—clicking fog tiles to send cartographers, dragging routes between locations, assigning workers to resources, right-clicking to cycle specializations. The bottom UI panel exists solely to facilitate strategic decisions BETWEEN moments of active Canvas gameplay.
## Color Palette
| Role | Color (hex) | Usage |
|------|-------------|-------|
| Background (primary) | #1a1a2e | Main background behind Canvas (dark void) |
| Background (secondary) | #16213e | Panels, cards, bottom panel background |
| Background (tertiary) | #2a2a4e | Card hover states, active elements, buttons |
| Canvas background | #0f0f1a | The game world ground/fog base |
| Text (primary) | #e0e0d0 | Main headings, currency amounts, upgrade names |
| Text (secondary) | #a0a0a0 | Labels, descriptions, button text |
| Text (muted) | #606060 | Disabled, locked items, secondary information |
| Accent 1 (Gold) | #d4a373 | Primary currency, Gold UI, gold highlights |
| Accent 2 (Knowledge) | #4FC3F7 | Secondary currency, Knowledge UI, cyan glow |
| Accent 3 (Torches) | #f59e42 | Fuel currency, Torches UI, orange highlights |
| Accent 4 (Influence) | #9b59c3 | Strategic currency, Influence UI, purple glow |
| Accent 5 (CP) | #E040FB | Prestige currency, CP UI, rainbow gradient |
| Success | #4CAF50 | Affordable, completed upgrades, positive feedback |
| Warning | #ffb700 | Almost affordable, attention needed, fog warnings |
| Danger | #ff4436 | Cannot afford, low torch warning, combat damage |
| Prestige | #E040FB | Prestige currency, prestige UI elements, ascension glow |
**Color Rationale:**
- Dark canvas background (#0f0f1a) represents the fog-covered unknown world
- Warm gold (#d4a373) for exploration tools feels natural and valuable
- Cyan knowledge (#4FC3F7) contrasts against dark fog, representing enlightenment
- Orange torches (#f59e42) signals warmth/light/fire against darkness
- Purple influence (#9b59c3) represents mystical power gained from defending territory
## Typography
- **Font family**: 'Cinzel', 'Segoe UI', Tahoma, sans-serif fallback (Google Font: Cinzel)
- **Headings**: Bold 700, 18-22px range for panel headers, currency displays
- **Body text**: Regular 400, 14-16px for descriptions, labels
- **Numbers/currencies**: 'Roboto Mono', 'Courier New', monospace fallback, Regular 500, 16-20px for currency counts
- **Buttons**: SemiBold 600, 14-16px, uppercase labels
**Typography Hierarchy:**
```
H1: "UPGRADES" (18px, Bold, #e0e0d0, uppercase, letter-spacing: 2px)
H2: "Cartographer Specializations" (16px, SemiBold, #e0e0d0, uppercase)
H3: "Light Bringer" (14px, Regular, #a0a0a0, capitalize)
B1: "Hire Cartographer\n50 Gold" (16px, SemiBold, #d4a373, uppercase action)
B2: "The path to knowledge begins here." (14px, Regular, #a0a0a0)
B3: "+5 🪙" (20px, Roboto Mono, Regular 500, #e0e0d0)
```
## Screen Layout
### Master Layout
```
+--------------------------------------------------+
| [HUD Bar - currencies, torch count, fog warning] |
+--------------------------------------------------+
| |
| [CANVAS - Main Game World] |
| (70% of screen height ~ 500-600px) |
| Fog-covered terrain grid |
| Animated sprites (cartographers, workers, merchants) |
| Resource nodes, ancient ruins, lantern towers |
| Background gradient, campfire at center |
| |
+--------------------------------------------------+
| [Bottom Panel - upgrades, specializations] |
| (30% of screen height ~ 200-300px, collapsible) |
| [Tab: UPGRADES] [Tab: SPECIALIZE] ... [▾] |
+--------------------------------------------------+
```
**Layout Ratios:**
- Canvas: 70% height (500-600px), centered horizontally
- HUD Bar: 50px fixed height, overlays top of Canvas
- Bottom Panel: 30% height (200-300px minimum), sits below Canvas
- Responsive: Canvas shrinks when panel expands, maintains 16:9 aspect ratio minimum
### HUD Bar (Always Visible, overlays top of screen)
| Element | Position | Content | Behavior |
|---------|----------|---------|----------|
| Gold currency display | Left (20px from left) | Icon 🪙 + amount + rate/sec | Animate on change (300ms), color-coded (#d4a373) |
| Knowledge currency display | Left (after Gold, 180px) | Icon 📜 + amount | Animate on change (300ms), color-coded (#4FC3F7) |
| Torches currency display | Left (after Knowledge, 340px) | Icon 🔥 + amount/max | Animate on change (300ms), color-coded (#f59e42), shows "X/100" format |
| Influence currency display | Left (after Torches, 500px) | Icon ✨ + amount | Animate on change (300ms), color-coded (#9b59c3) |
| Fog warning indicator | Center-left (below currencies) | "⚠️ Low Torches!" when < 15% | Puses orange (#ffb700), flashes when critical (< 5%) |
| Map progress bar | Center-right (below currencies) | "Map: 47.3% | Updates each tile reveal, shows gradient from dark to light |
| Wave/Round info | Right side ( currencies right) | Not used (no waves) | Reserved for future wave-based content |
| Settings button | Far right (16px from edge) | Gear icon ⚙️ | Opens settings modal |
**HUD Behavior:**
- Currency displays show icon, current amount, and per-second rate in smaller text
- All numbers use count-up animation (300ms duration) when changing
- Fog warning appears when torches below 15% of capacity, pulses slowly
- Map progress shows percentage with gradient bar (dark grey → cyan)
### Game World Canvas
- **Dimensions**: Responsive width (min 800px), height scales to fit available viewport (maintains 16:9 aspect ratio)
- **Background**: Radial gradient from center (#0f0f1a at campfire) to edges (#1a1a2e at distant fog), simulating torch light fading into darkness
- **Layers** (drawn in order):
1. **Background layer**: Terrain tiles (grass #2d6a4f, forest #1a4a3a, water #0077b6, mountain #6c757d, ruins #d4a373), fog overlay (#16213e with 70% opacity, animated wisps
2. **Entity layer**: Cartographers (Knight recolor), Workers (Slime recolor), Merchants (Wizard recolor blue/gold), Shadow Creatures (Ghost recolor black/purple), Resource nodes (procedural shapes)
3. **Effect layer**: Floating damage/reward numbers, death particle bursts, lantern tower glow halos, collectible bob animations, torch light trails from cartographers
4. **HUD overlay layer**: Entity health bars (4px × 24px, 4px from entity top, red gradient for enemies, cyan for allies), selection rings (gold stroke, 2px width, pulsing), range indicators (dotted cyan circle for tower radius, placement preview for structures), floating labels above resources/ruins
- **Camera**: Fixed position, cantered on center of campfire, slight pan when cartographer moves near edges (10% margin)
- **Click/touch interaction (CRITICAL)**:
1. **Left-click fog tile**: Send selected cartographer to explore that tile (pathfinding to adjacent tiles only)
2. **Left-click revealed resource**: Assign worker to gather (spawns worker at camp, walks to resource)
3. **Left-click ancient ruin**: Investigate ruin (spends cartographer if within range, shows investigation UI)
4. **Left-click revealed tile (with building mode)**: Place lantern tower (shows placement preview, confirms on click)
5. **Right-click cartographer**: Cycle specialization (Scout → Mapper → Explorer → Scout)
6. **Drag between two revealed locations**: Create trade route (shows path preview, releases to spawn merchant)
7. **Left-click collectible (knowledge scroll, gold coin, influence sparkle)**: Collect currency (within 24px radius)
**Canvas Interaction Feedback:**
- Clickable fog tiles pulse with subtle cyan glow (0.6s duration, 0.5s interval) when adjacent to revealed tile
- Invalid clicks (non-adjacent fog, insufficient torches) show red flash on cursor (200ms) and shake animation
- Resource nodes show "Assign Worker" tooltip on hover with cost and yield info
- Ancient ruins show "Investigate" tooltip with Knowledge/Influence rewards listed
- Lantern tower placement shows radius preview (dotted cyan circle, 50% opacity)
- Trade route creation shows animated path line between locations
### Entity Visual Specs
#### Cartographer (Player Unit)
**Sprite**: Knight recolor (brown/tan explorer outfit with wide-brimmed hat)
**Scale**: 3 (48px rendered, 16px sprite × 3)
**Team**: player
**HP**: 50
**Damage**: 10 (with combat training)
**Attack speed**: 1.0 attacks per second
**Attack range**: 40px (melee, only with combat training)
**Move speed**: 0.5-1s per tile (varies by spec)
**Reveal radius**: 3x3 tiles (expandable)
**States:**
```mermaid
stateDiagram-v2
[*] --> Spawning: hired at camp
Spawning --> Idle: spawn animation (300ms, scale 0→1)
Idle --> Moving: player clicks fog tile destination
Idle --> Selected: player clicks cartographer to select
Selected --> Idle: player deselects or clicks destination
Selected --> Moving: player clicks destination
Moving --> Revealing: enters fog tile
Moving --> Idle: destination reached
Revealing --> Moving: continue path if destination beyond
Revealing --> Defending: shadow creature in range + combat training
Defending --> Idle: shadow defeated
Defending --> Dying: hp <= 0
Idle --> Dying: hp <= 0 (shadow attack without combat)
Moving --> Dying: hp <= 0 (environmental hazard - deep fog without torches)
Dying --> [*]: death animation (500ms fade out + spark particles), remove from entity list
note right of Idle
Frames: 0-1 (standing)
Frame duration: 500ms
Animation: subtle bob (±2px, 1s period)
Selection: gold ring pulse when selected
end note
note right of Moving
Frames: 0-3 (walking cycle)
Frame duration: 200ms
Flip: based on horizontal direction
Trail: torch light particles spawn every 200ms
Speed: 0.5-1s per tile based on spec
end note
note right of Revealing
Visual: fog fades with ripple effect (300ms)
Reward: knowledge scroll spawns (+1-3 based on tile type)
Range: 3x3 tiles centered on cartographer
Color: cyan glow for brief moment
end note
note right of Defending
Only available with combat training unlocked
Frames: 2-3 (attack animation)
Frame duration: 150ms
Spawns: "spark" projectile (visual only)
Range: 40px
Damage: 10 to shadow
end note
note right of Dying
Animation: opacity 1→0 over 500ms
Particles: 5 spark sprites burst outward
Color shift: slight red flash at death
end note
```
**Health bar**: { show: true, width: 32, height: 4, yOffset: -8, color: '#4CAF50', bgColor: '#16213e' }
**Flip**: true (horizontal direction)
**Glow**: White pulse (300ms) when selected, gold ring
#### Worker (Gatherer Unit)
**Sprite**: Slime recolor (human skin tones, carrying sack)
**Scale**: 2.5 (40px rendered)
**Team**: player
**HP**: 20 (dies if fog reclaims resource tile)
**Carry capacity**: 10 gold, 5 torches
**Move speed**: 0.3s per tile (slower than cartographer)
**Harvest speed**: 5s harvest duration (3s with upgrades)
**States:**
```mermaid
stateDiagram-v2
[*] --> Spawning: player assigns to resource
Spawning --> MovingToResource: walks from camp to resource (3s)
MovingToResource --> Harvesting: reaches resource node
Harvesting --> ReturningToCamp: inventory full (5s harvest)
ReturningToCamp --> Depositing: reaches camp
Depositing --> MovingToResource: walks back to resource
MovingToResource --> Dying: fog reclaims tile while worker there
Harvesting --> Dying: shadow attacks worker
ReturningToCamp --> Dying: shadow attacks worker
Depositing --> [*]: deposit complete, gold added to currency
note right of Harvesting
Frames: 0-1 (bending animation)
Duration: 5s (3s with efficiency upgrades)
Visual: worker bends, particles flow from resource to worker
Sound: "digging" or "chopping" effect (visual only)
end note
note right of Depositing
Frames: 0-1 (depositing animation)
Duration: 500ms
Visual: gold particles flow from worker to campfire
Floating text: "+X 🪙" appears at camp
end note
note right of Dying
Animation: fade out 1→0 over 400ms
No death particles (worker just disappears)
Carried resources lost
end note
```
**Health bar**: { show: true, width: 24, height: 3, yOffset: -4, color: '#4CAF50', bgColor: '#16213e' }
**Flip**: true (horizontal direction)
**Carry visible**: Small sack sprite on worker shows when carrying resources
#### Shadow Creature (Enemy)
**Sprite**: Ghost recolor (black/purple, wraith appearance)
**Scale**: 2.5 (40px rendered)
**Team**: enemy
**HP**: 30 (50HP +10 per map tier beyond first)
**Damage**: 5 (to cartographer/worker/merchant)
**Move speed**: 0.3s per tile (slower than cartographer)
**Attack speed**: 0.5 attacks per second
**Reward**: { gold: 5-15, influence: 2-5 }
**States:**
```mermaid
stateDiagram-v2
[*] --> Spawning: spawns at fog edge near revealed territory
Spawning --> Emerging: fade in animation (1s, opacity 0→1)
Emerging --> Hunting: spawn complete, finds nearest target
Hunting --> Chasing: target in range (cartographer > worker > merchant)
Chasing --> Attacking: reaches target
Attacking --> Chasing: target survives
Attacking --> Dying: target defeats shadow or shadow dies of old age (60s in game)
Chasing --> Idle: target lost, returns to fog edge
Idle --> Dormant: no targets for 10s, despawns
Dying --> [*]: death animation (500ms fade out + spark particles), drops rewards
note right of Spawning
Trigger: revealedTerritory > 10 tiles
Spawn rate: 1 shadow per 10 tiles revealed (scales with map tier)
Location: fog edge near revealed territory
Animation: purple fog swirl, shadow materializes
Initial opacity: 0 (fades in)
end note
note right of Hunting
Target priority: cartographer > worker > merchant
Pathfinding: direct line to target, ignores obstacles
Speed: 0.3s per tile (slower than cartographer)
end note
note right of Attacking
Frames: 2-3 (attack animation)
Duration: 200ms per attack
Damage: 5 to target
Cooldown: 1s between attacks
Visual: shadow flashes purple, target flashes white
end note
note right of Dying
Reward spawns on death position (knowledge scroll from map enemies, or influence sparkle from shadows)
Animation: fade out 1→0 over 500ms
Particles: 5 spark burst
Death chance: increases based on map tier (base 5%, +2% per tier)
end note
```
**Health bar**: { show: true, width: 28, height: 3, yOffset: -6, color: '#9b59c3', bgColor: '#16213e' }
**Flip**: false (always faces target)
**Glow**: Faint purple pulse (2s duration) when attacking
#### Merchant (Trade Unit)
**Sprite**: Wizard recolor (merchant blue/gold with pack)
**Scale**: 2.5 (40px rendered)
**Team**: player
**HP**: 25 (dies if shadow attacks or route blocked by fog)
**Carry capacity**: 20 gold (varies by pack upgrade)
**Move speed**: 0.4s per tile
**Yield**: 2 gold × routeTiles × (1 + 0.05 × roadLevel)
**States:**
```mermaid
stateDiagram-v2
[*] --> Spawning: trade route created
Spawning --> Outbound: leaves first location
Outbound --> Patrolling: following route tiles
Patrolling --> Inbound: reaches second location
Inbound --> Returning: begins return trip
Returning --> Delivered: reaches first location (camp)
Delivered --> Outbound: begins next patrol cycle
Patrolling --> Dying: fog reclaims route midpoint
Patrolling --> Dying: shadow attacks merchant
Inbound --> Dying: fog reclaims location
Returning --> Dying: shadow attacks merchant
note right of Spawning
Trigger: player drags between two revealed locations with explored path
Animation: merchant fades in (300ms) at first location
Spawn point: first location of route
Visual: gold trail particles spawn behind merchant while moving
end note
note right of Patrolling
Duration: varies by route length (10-30s)
Tiles per second: 2 tiles
Visual: merchant walks along path, leaves faint gold trail
Yield awarded: when merchant reaches destination
end note
note right of Delivered
Reward: 2 × routeTiles × (1 + 0.05 × roadLevel) gold
Visual: "+X 🪙" floating text at camp
Animation: merchant deposits gold (particles flow to campfire)
Duration: 500ms deposit animation
Turn animation: merchant flips direction for return
end note
note right of Dying
Animation: fade out 1→0 over 400ms
Carried gold lost (drops at death location)
No death particles
end note
```
**Health bar**: { show: true, width: 26, height: 3, yOffset: -5, color: '#d4a373', bgColor: '#16213e' }
**Flip**: true (horizontal direction)
**Yield visible**: Gold particles trail behind merchant, intensifies near route end
#### Lantern Tower (Structure)
**Sprite**: ProceduralSprite tall structure with burning brazier (animated pulse)
**Scale**: 3 (48px rendered)
**Team**: player
**HP**: 50 (tower destroyed when depleted)
**Damage**: 5 per second (to all shadows in range)
**Attack range**: 80px (5 tile radius)
**Torch drain**: 0.1 torches per second
**Influence gen**: 0.1 influence per second per level
**States:**
```mermaid
stateDiagram-v2
[*] --> Placing: player clicks revealed tile to build
Placing --> Constructing: build animation (2s)
Constructing --> Active: tower complete
Active --> Draining: consumes torches over time
Draining --> Active: torches available
Active --> Damaging: shadow in range
Damaging --> Active: shadow defeated or leaves range
Active --> Destroyed: hp <= 0 (tower destroyed)
Destroyed --> [*]: tower crumbles, removed from map
note right of Placing
Requires: 75 gold + 10 torches (scales with count)
Preview: dotted cyan circle shows 5-tile radius
Snap: placement snaps to grid (16px tiles)
Validation: cannot place on fog, cannot overlap structures
end note
note right of Constructing
Animation: tower rises from ground (scale 0.5→1 over 2s)
Particles: dust particles spawn around base
Sound: building construction effect (visual only)
end note
note right of Active
Visual: yellow/orange glow at top (brazier), pulses every 2s
Light radius: 5 tiles, shown as subtle cyan overlay on ground
Passive: +0.1 influence/sec per tower level (shown as floating "+0.1 ✨" every 10s)
end note
note right of Draining
Rate: 0.1 torches per second
Visual: tower glow dims slightly when torches low
Warning: at 20% torch capacity, tower flashes red
end note
note right of Destroyed
Animation: tower crumbles (scale 1→0.8 over 500ms)
Particles: 3-5 brick particles burst outward
Fog: immediately returns to tower radius tiles
end note
```
**No health bar** (structures show damage via crumbling animation)
**No flip** (static structure)
**Glow**: Pulsing yellow/orange (2s period), brightens when dealing damage
#### Resource Nodes (Collectible)
**Types**: Iron, Gold, Herbs (forest torches)
**Sprite**: ProceduralSprite geometric shapes
**Scale**: 2 (32px rendered)
**Yield per trip**: Iron=5g, Gold=10g, Herbs=3t
**Respawn time**: 30s (after depletion)
**States:**
```mermaid
stateDiagram-v2
[*] --> Discovered: hidden by fog
Discovered --> Revealed: cartographer reveals tile
Revealed --> Unassigned: no worker assigned
Unassigned --> Assigned: player clicks to assign worker
Assigned --> Depleting: worker harvesting
Depleting --> Dormant: resource depleted (temporary)
Dormant --> Revealed: resource respawns (30s)
Assigned --> Destroyed: fog reclaims tile before worker arrives
Depleting --> Revealed: worker finishes, resource respawns
note right of Discovered
Not clickable, not visible
Fog overlay hides completely
May show subtle hint (shimmer for gold, shadow for mountain)
end note
note right of Revealed
Sprite appears: different colors per type (iron=grey, gold=yellow, herbs=green)
Tooltip on hover: shows yield, cost to assign worker, trip duration
Click triggers: worker assignment panel
end note
note right of Assigned
Worker sprite visible walking to/from node
Node shows small progress bar (0-100%) per worker
Multiple workers possible (up to 5 per node, scales with upgrades)
end note
note right of Depleting
Temporary: resource gone for 30s
Node shows "depleted" visual (darker, faded)
Workers idle at camp until respawn
end note
note right of Destroyed
Fog overtook tile
Worker on way dies
Resource will respawn elsewhere after 30s
Player notification: "Resource lost to fog!"
end note
```
**Health bar**: { show: false } (nodes have health, not shown)
**No flip**
**Glow**: Resource type pulses when assigned worker (2s period)
#### Ancient Ruins (Special Locations)
**Sprite**: ProceduralSprite crumbled stone structure
**Scale**: 4 (64px rendered)
**States**: Locked → Revealed → Investigating (5s) → Completed
**States:**
```mermaid
stateDiagram-v2
[*] --> Discovered: hidden by fog
Discovered --> Revealed: cartographer reveals tile
Revealed --> Available: no cartographer investigating
Available --> Investigating: player clicks ruin, cartographer in range
Investigating --> Cooldown: investigation complete
Cooldown --> Available: 60s cooldown expires
Available --> Revealed: fog reclaims (ruins don't regrow)
Investigating --> Interrupted: cartographer recalled or killed
note right of Discovered
Not visible until revealed
Shows as mysterious mound in fog
May have subtle purple glow hinting at location
end note
note right of Investigating
Duration: 5s base (varies by ruin tier)
Cartographer must be in range (80px)
Progress bar shows over ruin
Rewards preview shown in tooltip
end note
note right of Cooldown
Ruin cannot be reinvestigated for 60s
Visual: ruin shows dimmed state
Timer shown: "XXs" in tooltip
end note
note right of Completed
One-time reward per run (per ruin)
Visual: gold particles flow from ruin
Toast: "Ancient secrets revealed!"
end note
```
**Progress bar**: { show: true, width: 40, height: 4, yOffset: -10, color: '#4FC3F7', bgColor: '#16213e' }
**No flip**
**Glow**: Mysterious purple pulse (3s period) when available to investigate
#### Collectibles (Currency Drops)
**Types**: Knowledge scroll, Gold coin, Influence sparkle
**Sprite**: ProceduralSprite with animations
**States:**
```mermaid
stateDiagram-v2
[*] --> Spawning: entity death / generator tick
Spawning --> Active: spawn animation (300ms, scale 0→1)
Active --> Collected: player clicks within 24px radius
Active --> Expired: lifetime exceeded (8s)
Active --> Drifting: auto-collect unlocked (within 100px of camp)
Drifting --> Collected: reaches camp/cartographer
Drifting --> Expired: lifetime exceeded
Collected --> [*]: currency added, floating text + particle burst
Expired --> [*]: fade out animation (500ms, opacity 1→0)
note right of Spawning
Position: at death location or generator spawn point
Animation: scale 0→1 over 300ms
Initial opacity: 0 (fades in)
end note
note right of Active
Bob animation: ±2px at 2Hz
Clickable radius: 24px from center
Lifetime: 8s (6s for influence sparkles)
Value shown on hover
end note
note right of Collected
Floating text: "+X [icon]" floats up and fades (800ms)
Particle burst: 5-8 particles explode outward (200ms)
Sound: "collect" effect
Currency display: count-up animation (300ms)
end note
note right of Expired
Animation: fade out 1→0 over 500ms
No feedback (just disappears)
end note
```
**No health bar** (collectibles don't have health)
**Auto-collect range**: 100px from camp (can be upgraded)
**Magnetism**: Spawns "drifting" state, moves toward camp slowly
### Entity Interaction Diagram
```mermaid
flowchart LR
subgraph Player Entities
Cartographer["Cartographer\n(reveals fog, attacks shadows)"]
Worker["Worker\n(gathers resources)"]
Merchant["Merchant\n(patrols trade routes)"]
end
subgraph Enemy Entities
Shadow["Shadow Creature\n(attacks player entities)"]
end
subgraph Structures
Tower["Lantern Tower\n(defends area, slows fog)"]
end
subgraph Collectibles
Knowledge["Knowledge Scroll\n(+1-3 per reveal)"]
GoldCoin["Gold Coin\n(enemy drops, merchant returns)"]
InfluenceSparkle["Influence Sparkle\n(shadow kills, tower passive)"]
end
Cartographer -->|"spawns"| Worker
Cartographer -->|"spawns"| Merchant
Cartographer -->|"attacks"| Shadow
Shadow -->|"attacks"| Worker
Shadow -->|"attacks"| Merchant
Shadow -->|"attacks"| Tower
Shadow -->|"on death → drops"| Knowledge
Shadow -->|"on death → drops"| GoldCoin
Shadow -->|"on death → drops"| InfluenceSparkle
Tower -->|"damages"| Shadow
Tower -->|"generates passive"| InfluenceSparkle
Worker -->|"on harvest → spawns"| GoldCoin
Merchant -->|"on return → spawns"| GoldCoin
Knowledge -->|"player clicks → collect"| Cartographer
GoldCoin -->|"player clicks → collect"| Cartographer
InfluenceSparkle -->|"player clicks → collect"| Cartographer
```
### HUD Overlay (drawn ON Canvas)
| Element | Position | Content | Behavior |
|---------|----------|---------|----------|
| Entity health bars | Above each entity | Small colored bar, 4px from top | Updates with damage, fades on death, cyan for allies, purple for enemies |
| Floating damage numbers | At damage location | "-X" in red, "+X" in green/white | Floats upward 30px over 800ms, fades out |
| Floating reward numbers | At death/complete location | "+X 🪙/📜/✨" in currency colors | Floats upward 30px over 800ms, fades out |
| Selection ring | Around selected entity | Gold stroke, 2px width, pulsing | Shows which unit selected, fades on deselect |
| Tower placement preview | At cursor location | Dotted cyan circle, 50% opacity, 5-tile radius | Shows affected area, updates with cursor movement |
| Route creation preview | Between drag start/end | Animated cyan line following cursor | Shows path, highlights when valid route |
### Bottom Panel (Upgrade/Management Area)
```
+--------------------------------------------------+
| [UPGRADES] [SPECIALIZE] [TRADE ROUTES] [SETTINGS] [▾] |
+--------------------------------------------------+
| |
| [Active Tab Content Area] |
| Upgrade cards, specialization options, |
| route management, tower stats, etc. |
| |
+--------------------------------------------------+
```
- **Height**: 250px (30% of viewport at 1080p height)
- **Collapse button**: Arrow icon (↑/↓) to minimize panel to 40px (just tab bar)
- **When collapsed**: Only tab bar visible (single row of icons/labels), saves Canvas space
- **Background**: Semi-transparent dark (#16213e with 80% opacity) to not block Canvas visual
### Navigation / Tab Bar
| Tab | Icon/Label | Unlocked At | Content |
|-----|------------|-------------|---------|
| Upgrades | 🛠️ UPGRADES | Game start | Unit stats (speed, capacity), torch upgrades |
| Specialize | 🎭️ SPECIALIZE | 20 Knowledge (1:30) | Cartographer specs (Scout/Mapper/Explorer), combat training |
| Trade Routes | 🛤️ ROUTES | 2 locations + path (6:00) | Route list, create new route, merchant stats |
| Stats | 📊 STATS | 10% map explored (15:00) | Territory breakdown, production rates, cartographer list |
| Settings | ⚙️ SETTINGS | Always available | Game options, save management, reset |
**Tab appearance animation**: New tab slides in from right (300ms fade + translate), subtle glow pulse on icon
**Locked tab appearance**: Icon desaturated (40% opacity), label grayed out, "LOCKED" tooltip on hover
**Active tab appearance**: Icon fully saturated, label bright, background accent color bar at bottom
### Tab Contents
#### Tab 1: Upgrades
```
+---------------------------------------+
| [UNIT UPGRADES] |
| +--------+ +--------+ |
| |Upgrade | |Upgrade | |
| | Card | | Card | |
| |[Lv.0] | |[Lv.1] | |
| |Cartographer| |Worker | |
| |Speed +10% |Harvest -10% | |
| |Cost: 30g |Cost: 20g | |
| |[BUY] |[BUY] | |
| +--------+ +--------+ |
+---------------------------------------+
| [STRUCTURE UPGRADES] |
| +--------+ +--------+ |
| |Upgrade | |Upgrade | |
| | Card | | Card | |
| |[Lv.2] | |[Lv.0] | |
| |Lantern Tower |Torch Capacity |
| |Damage +5 |Max +10 |
| |Cost: 50g + K|Cost: 15K |
| |[BUY] |[MAX] | |
| +--------+ +--------+ |
+---------------------------------------+
```
**Upgrade Card States:**
| State | Appearance | Interaction |
|---------|-------------|----------|
| Available (affordable) | Normal brightness, border color #4CAF50, green BUY button | Hover shows tooltip with detailed stats, click triggers purchase animation |
| Available (maxed) | Border color #4CAF50, "MAX" badge, BUY button hidden | No interaction possible, shows current/max stats |
| Locked | Entire card dimmed (50% opacity), lock icon overlay | No details visible, tooltip shows "???" and unlock condition |
| Available (cannot afford) | Border color #ff4436, red cost text, grayed out BUY button | Hover shows tooltip, click triggers shake animation, red flash on cost |
#### Tab 2: Specializations
```
+---------------------------------------+
| [CARTOGRAPHER SPECS] |
| +--------+ +--------+ |
| |Spec | |Spec | |
| |Option | |Option | |
| |Card | |Card | |
| |[CURRENT] | | | |
| |Scout |Mapper |Explorer |
| |Fast explore, |Slow but |Deep fog |
| |small light |trail markers |access |
| |Cost: 20K |One-time |Cost: 40K |
| |[SELECT] | |[LOCKED] |
| +--------+ +--------+ |
+---------------------------------------+
| [COMBAT TRAINING] |
| Allows cartographers to |
| fight shadow creatures |
| |
| Damage: +10, Range: 40px |
| Cost: 25K |
| [LEARN - ONE TIME] |
+---------------------------------------+
```
**Specialization Cards:**
| State | Appearance | Interaction |
|---------|-------------|----------|
| Available (affordable) | Normal brightness, border #4FC3F7 (cyan) | SELECT button, click applies spec to selected cartographer |
| Current (active) | Gold border glow, "CURRENT" badge | Cannot select again, shows active stats |
| Locked | Dimmed (50% opacity), lock icon | Tooltip shows spec name and unlock condition |
| One-time unlock | Green flash on unlock, spec applied immediately to cartographer |
**Combat Training Card:**
One-time unlock, grants all cartographers ability to attack shadows. Shows damage/range stats.
#### Tab 3: Trade Routes
```
+---------------------------------------+
| [ACTIVE ROUTES] |
| +--------+ +--------+ |
| |Route | |Route | |
| |Display | |Display | |
| |Camp → Iron Mine |Camp → Gold Node| |
| |5 tiles (10g/trip) |7 tiles (14g/trip) | |
| |Status: ACTIVE |Status: ACTIVE | |
| |Merchant: 1/1 |Merchant: 2/2 | |
| |[MERCHANT] |[MERCHANT] | |
| |[CANCEL] |[DELETE] | |
| +--------+ +--------+ |
+---------------------------------------+
| [CREATE NEW ROUTE] |
| Drag between two revealed |
| locations to establish trade route |
| |
+---------------------------------------+
```
**Route Display:**
| Element | Content | Behavior |
|---------|---------|----------|
| Route name | "Camp → Iron Mine" | Location names, shows resource type if applicable |
| Tile count | "5 tiles" | Route length in tiles |
| Yield/merchant | "10g/trip" | Gold per merchant trip |
| Merchant count | "1/1" | Active/assigned merchants (max 3 per route) |
| Status indicator | "ACTIVE" (green) / "BLOCKED" (red, fog on route) | Changes color when fog blocks route |
| Action buttons | Merchant (assign more), Cancel (delete route) | Icon buttons, confirm on click |
#### Tab 4: Stats
```
+---------------------------------------+
| [TERRITORY BREAKDOWN] |
| |
| Revealed: 127 tiles (21.2%) |
| Fog-covered: 471 tiles (78.8%) |
| |
| Production Rates: |
| • Gold: +12.3/s |
| • Knowledge: +0.5/s |
| • Torches: +0.8/s |
| • Influence: +0.2/s |
| |
| Cartographer List: [Scout #1] [Mapper #2] |
| |
| Resource Nodes: 7 active, 3 depleted |
| Lantern Towers: 3 active, pushing back 15 tiles |
| Ancient Ruins: 2 investigated, 1 remaining |
+---------------------------------------+
```
**Purpose**: Overview of game state, helps player assess progress and make strategic decisions
#### Tab 5: Settings
| Setting | Type | Default | Effect |
|---------|------|---------|--------|
| Number format | Dropdown (standard/scientific) | Standard | Changes 1,234,567.89K vs 1.23M, 567.9K |
| Animation speed | Slider (0.5x-2x) | 1x | Scales all animation durations and Canvas game speed |
| Auto-save interval | Dropdown (10s/30s/60s/off) | 30s | How often game state saves |
| Canvas quality | Toggle (high/low) | High | Low disables glow effects and particles for performance |
| Hard reset | Button (with confirmation) | — | Wipes all data, confirms via modal |
| Export save | Button | — | Copies save string to clipboard |
| Import save | Button | — | Prompts for save string, loads game state |
| How to Play | Button | — | Re-shows tutorial overlay |
**Settings Modal**: Centered overlay, 600px wide, auto-closes on outside click
### Notifications Area
| Element | Content | Behavior |
|---------|---------|----------|
| Notification area | Toast messages | Slide in from right, fade after 3s, max 3 stacked |
| Milestone popup | Achievement earned | Center screen, dramatic, auto-dismiss 3s or click to dismiss |
| Fog warning | "⚠️ Low Torches!" | Appears when torches < 15% of capacity, pulses orange |
| Route blocked | "⚠️ Trade route blocked by fog!" | Appears when fog reclaims route tile, red flash |
**Toast Stack:** Max 3 simultaneous toasts, newest at bottom, slide in from right (300ms), fade out (3s), stack up if needed
**Milestone Popup:** Large centered modal, achievement icon (★), name, description, reward breakdown, "GOT IT" button
## Component Specifications
### Upgrade Card
```
+----------------------------------+
| [Icon] [Upgrade Name] [MAX]|
| | | |
| [Description text] |
| [Effect: +X% speed / +Y damage] |
| [Cost: 150 Gold] [BUY] |
+----------------------------------+
```
**States:**
- **Affordable**: Border #4CAF50 (success green), BUY button bright (#4CAF50 background, #e0e0d0 text), hover raises card slightly, click triggers purchase flash (200ms) → cost deducted → currency animates down → number ticks up → upgrade applies → entities affected show visible change (glow/size increase)
- **Maxed**: Border #4CAF50, "MAX" badge (red background, white text) upper-right, BUY button hidden, no hover effect
- **Locked**: Entire card dimmed (#2a2a4e with 50% opacity), lock icon (🔒) overlay center, no details visible, tooltip shows "???" + unlock condition, no interaction
- **Cannot afford**: Border #ff4436 (danger red), BUY button grayed out with red cost text (#ff4436), hover shows tooltip, click triggers card shake animation (200ms, ±5px x) → red flash on cost (300ms)
- **Affordable (hover)**: Card raises 2px, tooltip shows detailed stats (current/max, effect per level, total cost to max)
**Purchase Animation Sequence:**
1. Card flashes white (100ms)
2. Cost flies toward currency display (400ms) → currency decreases
3. Upgrade level ticks up (200ms) → card shows new level
4. Entities affected show visible change (glow/size/speed increase)
5. Card settles to new state
### Currency Display (HUD)
```
[🪙] 1,234.5 (+12.3/s)
```
**Number animation**: Count-up animation when value changes, duration 300ms, eases from old value to new
**Rate display**: Per-second rate in smaller text (12px, #a0a0a0), updates every second
**Large numbers**: When over 999,999, switch to K/M/B suffixes (1K = 1,000)
**Color**: Match accent color for currency (gold #d4a373, knowledge #4FC3F7)
**Earned by gameplay flash**: Brief glow/pulse (200ms) when currency earned from defeating enemies/merchant returns, distinct from passive income ticks (subtle)
**Suffix display**: Gold shows K/M/B, Knowledge shows K/M, Influence shows K/M, CP shows K/M (all 2 decimals)
**Layout per currency:**
```
┌─────────────────────────────────┐
│ [16px Icon] [20px Value][10px/suffix] │
│ [12px Rate] │
└─────────────────────────────────┘
```
### Milestone/Achievement Toast
```
+----------------------------------+
| ★ [Achievement Name]! |
| [+Reward breakdown] |
+----------------------------------+
```
**Appearance**: Slide in from right (300ms ease-in), high z-index above all
**Duration**: 3-5 seconds visible before auto-dismiss (varies by importance)
**Stack behavior**: Multiple toasts stack vertically (10px gap between), dismiss individually
**Milestone importance**: First discovery = 3s, prestige = 5s
### Prestige Panel
```
+----------------------------------+
| ⟳ [PRESTIGE TITLE] |
| |
| You will earn: [1,250 CP] |
| Current total: [2,500] |
| New total: [2,750] (after +1,250) |
| |
| RESETS: |
| • Gold (starts at 50) |
| • Knowledge (lost) |
| • Torches (starts at 20) |
| • Influence (persists 50) |
| • Cartographers (lost) |
| • Workers (lost) |
| • Towers (lost) |
| • Merchants (lost) |
| • Map territory |
| KEEPS: |
| • CP (persists all) |
| • Prestige upgrades (all kept) |
| • Unlocked specs (all kept) |
| |
| VISUAL CHANGE: |
| • [Crimson Peaks] → new terrain |
| • [terrain color shift +30] |
| • [fog color changes] |
| • [campfire becomes large brazier] |
| |
| [CANCEL] [PRESTIGE!] |
+----------------------------------+
```
**Layout**: Centered modal, 600px wide, sections side-by-side (loss vs keeps), confirm button prominent
**Section colors**: "Keeps" section has green border (#4CAF50), "Lost" section has red border (#ff4436)
**Prestige currency display**: Shows current, will earn, keeps, all line items with costs
**Visual change preview**: Small color swatches showing before/after terrain colors
**Warning state**: If progress > 90%, show warning "Maximize exploration before prestiging!" with yellow text
### Skill Tree Renderer
**Layout approach**: CSS Grid, 3 columns × 2 rows maximum, nodes centered on grid intersections
**Node size**: 64px × 64px per node (including icon + border + padding)
**Connection lines**: SVG elements drawn behind nodes, 2px stroke, #606060 color (60% opacity white), animated dash flow
**Node states**: Reference progression.md node states for visual treatment
**Grid Layout:**
```
┌───────┬───────┬───────┐
│ [Tier│ [Tier│ [Tier│ │
│ 1] │ 2] │ 3] │
├───────┼───────┼───────┤
│ [Tier│ [Tier│ [Tier│ │
│ 1a] │ 2a] │ 3a] │
│ Node] │ Node] │ Node] │
└────────┴─────────┴──────────┘
```
**Node Types:**
| Type | Appearance | Unlock State | Maxed State |
|---------|-------------|-------------|----------|
| Starting node | Filled with accent color | Available (normal brightness) | Empty, grayed out border |
| Upgrade node | Filled with accent color, level badge | Available | Filled, "MAX" badge |
| Choice node | Hollow circle with accent border | Available (player must choose one path) | Selected choice filled |
| Tier unlock | Large node with icon | Locked (dimmed, lock icon) | Unlocked (bright, glow) |
**Connection Animation**: SVG stroke-dasharray animates with offset (dash moves from start to end over 1s)
### Tooltip
```
+----------------------------------+
| [Upgrade Name] (Level X) |
| [Full description] |
| |
| Current: +Y damage |
| Next level: +Z damage |
| Cost: [amount] |
+----------------------------------+
```
**Trigger**: Hover (desktop) after 200ms delay
**Position**: Above cursor, clamped to viewport (never off-screen)
**Arrow**: Points toward node (if space available)
**Max width**: 240px (prevents overflow on small screens)
## UI Event Flow Diagrams
### Player Interaction → Canvas → UI Flow
```mermaid
sequenceDiagram
actor Player
participant Canvas as Canvas
participant Entities as Entity System
participant Events as EventBus
participant UI as HUD/Panels
participant Fog as FogSystem
Note over Player,Canvas: Player assigns worker to resource
Player->>Canvas: clicks revealed resource tile
Canvas->>Canvas: check: workerSystemUnlocked
Canvas->>Canvas: check: canAfford(25 gold)
Canvas->>Entities: createEntity('worker', resourceLocation)
Entities->>Canvas: worker spawn animation (scale 0→1, 300ms)
Entities->>Events: emit('worker-assigned', {type: 'gold', cost: 25})
Events->>UI: deductCost(25, 'gold')
Events->>UI: currency.countDown('gold', 300ms)
Events->>Canvas: placement flash effect (200ms, white at resource)
Canvas->>Canvas: worker walks to resource (visible movement)
Canvas->>Fog: check tile for fog reclaim
Fog->>UI: no fog reclaim threat (worker safe at this resource)
```
### Entity Death → Drops → Collection Flow
```mermaid
sequenceDiagram
actor Player
participant Canvas as Canvas
participant Entities as Entity System
participant Events as EventBus
participant UI as HUD/Panels
participant Currency as CurrencyManager
Note over Player,Canvas: Shadow dies → drops → player collects
Entities->>Entities: shadow.hp <= 0
Entities->>Canvas: death animation (fade 1→0, 500ms)
Entities->>Canvas: spark particles burst (5 particles, 400ms)
Entities->>Events: emit('shadow-killed', {type, level, rewards})
Events->>Canvas: spawnCollectible('influenceSparkle', deathPosition, reward)
Events->>Canvas: collectible bob animation (spawn)
Canvas->>Canvas: influence sparkle pulses (2s period)
Player->>Canvas: clicks collectible (within 24px)
Canvas->>Events: emit('collectible-collected', {type: 'influence', value})
Events->>Currency: currency.add('influence', reward)
Events->>Currency: currency.add('gold', goldReward)
Events->>UI: floatingText("+{value} ✨", deathPosition, 'purple')
Events->>UI: floatingText("+{gold} 🪙", deathPosition, 'gold')
Events->>UI: currency.countUp('influence', 300ms)
Events->>UI: currency.countUp('gold', 300ms)
Events->>Canvas: collectible burst particles (5 particles, 200ms)
Events->>Canvas: collectible fade out (removed)
```
### Upgrade Purchase → Visible Effect Flow
```mermaid
sequenceDiagram
actor Player
participant Canvas as Canvas
participant UI as Bottom Panel
participant Events as EventBus
participant Entities as Entity System
participant Currency as CurrencyManager
Note over Player,Canvas: Player buys cartographer speed upgrade
Player->>UI: clicks upgrade card (affordable)
UI->>Events: emit('upgrade-purchased', {type: 'cartographerSpeed', level: 1})
Events->>Currency: currency.deduct('gold', 30)
Events->>UI: currency.countDown('gold', 300ms)
Events->>Canvas: upgrade.flashEffect()
Canvas->>Entities: all cartographers show glow effect (300ms white flash)
Entities->>Canvas: cartographer walk animation speeds up (frame duration 200ms → 180ms)
Events->>UI: upgrade.showMaxed() if at new level
```
### Fog Reclaim → Territory Loss Flow
```mermaid
sequenceDiagram
actor Player
participant Canvas as Canvas
participant Fog as FogSystem
participant Entities as Entity System
participant UI as HUD/Panels
Note over Player,Canvas: Fog reclaims tile with worker
Fog->>Fog: tile.lastVisitedTime exceeds regrowthDelay (30s base)
Fog->>Canvas: fog overlay returns (opacity 0→70% over 2s)
Canvas->>Entities: check for worker on tile
Entities->>Entities: worker.hp <= 0 (worker destroyed)
Entities->>Canvas: worker death animation (fade out 400ms)
Entities->>Events: emit('worker-lost', {position, resourceType})
Events->>UI: toast("Worker lost to fog!", 'warning', 3s)
Events->>UI: fogWarning.pulse() if torches now low
Events->>Canvas: fog warning indicator flashes
```
### UI State Machine
```mermaid
stateDiagram-v2
[*] --> Loading: page load
Loading --> Playing: assets loaded, game initialized
state Playing {
[*] --> Active: game in progress
Active --> Paused: player pauses (esc key)
Active --> PreStige: player clicks prestige button (80% map)
Active --> GameOver: all cartographers dead (with no workers)
Active --> SettingsModal: player clicks settings
Active --> TutorialOverlay: player clicks help / first load
Paused --> Active: player resumes
Paused --> SettingsModal: settings accessible while paused
PreStige --> Active: player cancels
PreStige --> Prestiging: player confirms
Prestiging --> Active: new run starts
GameOver --> Active: player restarts
SettingsModal --> Active: modal closed
TutorialOverlay --> Active: overlay dismissed
}
```
**State Transitions:**
- Loading → Playing: Fade in (500ms), show Canvas, enable controls
- Playing → Paused: Blur canvas slightly, show "PAUSED" overlay, dim panels
- Playing → PreStige: Show prestige modal, blur Canvas
- Playing → GameOver: Show "DEFEAT" overlay, show restart button
- Playing → SettingsModal: Show settings overlay, pause game if not paused
- All states → Playing: Resume from state, close overlay, enable controls
## Feedback Systems
### Visual Feedback Catalog
| Action | Canvas Feedback | UI Feedback | Duration |
|--------|----------------|-------------|----------|
| Tile revealed (knowledge) | Fog fade animation (300ms), cyan ripple from tile | Knowledge counter pulses up (300ms) | 300ms |
| Tile revealed (first time bonus) | Gold sparkles on tile (5 particles, 400ms) | +Bonus text floats up, knowledge pulses | 400ms |
| Worker assigned | Worker spawns at camp (300ms fade in) | Gold counter animates down (300ms) | 300ms |
| Tower placed | Tower construct animation (2s rise), dust particles | Gold/Torch counters flash, card shakes | 500ms |
| Shadow defeated | Purple burst (5 particles), shadow fades | Influence + gold counters pulse up (300ms each) | 500ms |
| Shadow attacks cartographer | Cartographer flashes white (100ms) | Health bar drops (red flash) | 100ms |
| Merchant returns | Gold particles flow to camp (10 particles) | Gold counter pulses up (300ms) | 300ms |
| Route created | Cyan line animates along path (1s), merchant fades in | Toast "Trade route established" | 1s |
| Ruin investigated | Purple burst from ruin (8 particles) | Knowledge + influence counters pulse | 500ms |
| Prestige complete | White fade out (500ms), screen shakes | Prestige modal appears, currency carried over | 500ms |
| Upgrade purchased | Card flashes green (200ms) | Cost flies to currency (400ms), level ticks | 200ms |
| Cannot afford click | Card shakes (±5px, 200ms) | Cost flashes red (300ms) | 200ms |
| Collectible collected | Burst (5 particles, 200ms), number floats up | Currency pulses (300ms) | 200ms |
| Fog reclaim warning | Torch counter pulses red | Toast "⚠️ Low Torches!" (3s) | 3s |
### Number Formatting Rules
| Range | Format | Example |
|-------|--------|---------|
| 0 - 999 | Whole number | 742 |
| 1,000 - 999,999 | Comma separator | 12,345 |
| 1M - 999.9M | K suffix | 1.5M |
| 1B - 999.9B | B suffix | 42.3B |
| 1T+ | T suffix | 1.2T |
| Rates (/sec) | 1 decimal | +12.3/s |
| Damage numbers (Canvas) | Whole number, no suffix | -15 |
### Progress Bars
**Style**: Rounded corners (4px radius), filled portion has gradient (color to lighter variant by 20%), animation on change (300ms ease)
**Color**: Changes based on completion % (gradient from #ff4436 at 0% to #4CAF50 at 100%)
**Label**: Percentage only ("47.3%") in white text, centered
**Animation**: Smooth fill transition (300ms ease-out)
**Spark effect**: Subtle white particles at each 5% milestone
## Controls Panel (MANDATORY - Always Visible)
The game MUST have a permanently visible controls panel showing all player interactions. This is NOT optional.
### Controls Panel Layout
```
+--------------------------------------------------+
| CONTROLS: [Click tile to explore] | [Right-click: Cycle spec] | [Drag: Create route] |
+--------------------------------------------------+
```
**Position**: Bottom of screen, below Canvas, 40px from edge
**Always visible**: Never hidden behind a tab or menu
**Content**: Lists every player action with its trigger (click, hotkey, drag)
**Style**: Semi-transparent dark background (#16213e with 80% opacity), light text (#e0e0d0), compact single-line layout
**Responsive**: If space is tight, use icon + hotkey shorthand (e.g., "🖱️ Explore | ⛔️ Tower | Space: Pause")
### Controls Panel Content
| Action | Trigger | Canvas Effect | Description |
|---------|---------|---------------|----------|
| Click fog tile | Left-click adjacent fog | Cartographer walks to tile, reveals area |
| Click resource | Left-click revealed resource | Assign worker (if affordable) |
| Click ruin | Left-click revealed ruin | Investigate (if cartographer in range) |
| Click tower placement | Left-click with build mode | Place lantern tower (if affordable) |
| Right-click cartographer | Right-click on unit | Cycle specialization (Scout → Mapper → Explorer) |
| Drag route | Drag between two locations | Create trade route (if path exists) |
| Click collectible | Left-click within 24px | Collect currency (knowledge/gold/influence) |
| Collapse/expand panel | Click ▾/▲ button | Minimize/maximize bottom panel |
## Getting Started Overlay (MANDATORY - Shows on First Load)
The game MUST show a "How to Play" overlay on first load. This appears ONCE, centered on screen, over Canvas.
### Tutorial Overlay Layout
```
+----------------------------------+
| |
| HOW TO PLAY |
| |
| |
| • Click on dark fog tiles to send your |
| cartographer exploring and reveal the map |
| |
| • Discover resources and click them to assign |
| workers who gather gold |
| |
| • Build lantern towers to protect your |
| territory from the encroaching fog |
| |
| • Reach ancient ruins and investigate them |
| for powerful knowledge upgrades |
| |
| [ GOT IT! ] |
+----------------------------------+
```
**Trigger**: Shows automatically on first page load
**Dismiss**: "Got it!" button OR click anywhere outside
**Persistence**: Use localStorage to remember dismissal. Don't show again after first dismiss
**Content**: 3-4 concise bullet points from idea.md "Getting Started Tutorial" section
**Style**: Semi-transparent dark overlay (#1a1a2e with 90% opacity), centered modal, large readable text (18px), prominent dismiss button
**Z-index**: Above everything including Canvas (9999)
**Background blur**: Canvas blurred behind overlay (5px blur filter)
## Responsive Considerations
- **Minimum width**: 1280px (Canvas min 800px, panel min 280px = 1080px total)
- **Maximum width**: No cap (Canvas fills available width, panel max 400px)
- **Scaling approach**: Canvas scales to fit available width; bottom panel uses rem-based sizing (16px base)
- **Panel collapse behavior**: Bottom panel can be collapsed to 40px (just tab bar), giving Canvas more space on narrow viewports
- **Mobile considerations**: Touch targets minimum 44×44px for fog tiles, controls panel slides up from bottom on mobile
## Accessibility
- **Contrast ratios**: All text meets WCAG AA minimum 4.5:1 (foreground/background checked)
- **Focus indicators**: Visible focus outlines (2px #4FC3F7) for keyboard navigation, visible on all interactive elements
- **Screen reader**: Currency amounts have aria-live regions ("Gold, 123", updates announced), tooltips have aria-describedby
- **Reduced motion**: Respects prefers-reduced-motion media query — disables Canvas animations, uses static sprites, disables floating text animations
- **Keyboard navigation**: All panels accessible via Tab, upgrades purchasable via Enter, cartographers selectable via 1-5 keys
## Settings Panel
| Setting | Type | Default | Effect |
|---------|------|---------|--------|
| Number format | Dropdown (standard/scientific) | Standard | Changes 1,234,567.89K vs 1.23M, 567.9K |
| Animation speed | Slider (0.5x-2x) | 1x | Scales all animation durations and Canvas game speed |
| Auto-save interval | Dropdown (10s/30s/60s/off) | 30s | How often game state saves |
| Canvas quality | Toggle (high/low) | High | Low disables glow effects and particles for performance |
| Hard reset | Button (with confirmation) | — | Wipes all data, confirms via modal ("Reset all progress?") |
| Export save | Button | — | Copies save string to clipboard, shows "Copied!" toast |
| Import save | Button | — | Prompts for save string, parses and loads game state, shows "Loaded!" toast |
| Disable toasts | Toggle | Off | On to prevent distractions, hides collectible auto-collect until unlocked |
**Settings Modal**: Centered overlay, 500px wide, categories in collapsible sections, applies changes immediately
## CONFIG Spec: canvas, ui, and effects Sections
```javascript
// Cartographer's Fog - Canvas Configuration
CONFIG.canvas = {
// Dimensions
width: 1280, // max width, scales down based on viewport
minHeight: 500, // minimum canvas height
targetAspect: 16/9, // 1.778 ratio for fog tiles (16px) aspect
// Background
backgroundColor: '#0f0f1a', // Canvas background (fog base)
groundColor: '#1a1a2e', // Revealed terrain base
fogColor: '#16213e', // Fog overlay
fogOpacity: 0.7, // Fog overlay opacity (70%)
campfireColor: '#f59e42', // Center campfire glow
// Grid
tileSize: 16, // Pixels per tile (fog grid)
gridWidth: 60, // Tiles horizontally (960px)
gridHeight: 40, // Tiles vertically (640px base)
// Layers (drawn in order)
layers: ['background', 'fogOverlay', 'terrain', 'entities', 'effects', 'hudOverlay'],
// Camera
cameraFixed: true, // Fixed position, centered on camp
cameraPanMargin: 0.1, // Pan when cartographer within 10% of edge
};
CONFIG.ui = {
// Update rates
tickRate: 60, // UI updates per second (target)
renderRate: 60, // Canvas frames per second
autoSaveInterval: 30000, // ms (30 seconds)
theme: 'dark', // Always dark theme
// Dimensions
hudHeight: 50, // px
bottomPanelHeight: 250, // px (30% of 1080p viewport)
bottomPanelCollapsedHeight: 40, // px (just tab bar)
canvasMinHeight: 400, // px (guarantees playable area)
controlsPanelHeight: 60, // px (always visible below canvas)
// Tabs
tabs: [
{
id: 'upgrades',
label: 'UPGRADES',
icon: '🛠️',
unlockedAt: 'gameStart',
columns: 2, // cards per row
},
{
id: 'specialize',
label: 'SPECIALIZE',
icon: '🎭️',
unlockedAt: 'knowledge >= 20', // 20 Knowledge
columns: 3, // spec cards per row
},
{
id: 'routes',
label: 'ROUTES',
icon: '🛤️',
unlockedAt: 'mapPercent >= 10', // 10% map explored
columns: 1, // full-width route list
},
{
id: 'stats',
label: 'STATS',
icon: '📊',
unlockedAt: 'mapPercent >= 25', // 25% map explored
columns: 1, // full-width stats breakdown
},
{
id: 'settings',
label: 'SETTINGS',
icon: '⚙️',
unlockedAt: 'gameStart', // always available
columns: 1, // settings list
},
],
// Notifications
notifications: {
toastDuration: 3000, // ms
toastPosition: 'top-right', // corner of screen
toastMaxStack: 3, // max simultaneous
milestoneDisplayDuration: 5000, // ms
milestoneAutoDismiss: true, // auto-dismiss after duration
fogWarningThreshold: 0.15, // 15% torch capacity
},
// Currency displays
currencies: ['gold', 'knowledge', 'torches', 'influence', 'cartographyPoints'],
// Typography
fonts: {
primary: 'Cinzel, "Segoe UI", Tahoma, sans-serif',
monospace: '"Roboto Mono", "Courier New", monospace',
},
// Accessibility
accessibility: {
reducedMotion: false, // auto-detected
keyboardNavEnabled: true,
focusOutlineWidth: 2, // px
ariaLiveCurrencyUpdates: true,
},
};
CONFIG.effects = {
particles: {
spark: {
count: 5,
sprite: 'spark',
lifetime: 500, // ms
spread: 20, // px spread radius
fade: true,
},
deathBurst: {
count: 8,
sprite: 'spark',
lifetime: 600, // ms
spread: 25, // px
fade: true,
},
construction: {
count: 6,
sprite: 'spark',
lifetime: 400, // ms
spread: 15, // px
color: '#d4a373', // gold/brown dust
},
collect: {
count: 5,
sprite: 'spark',
lifetime: 200, // ms
spread: 10, // px
fade: true,
},
},
floatingText: {
duration: 800, // ms
riseSpeed: 30, // px/sec
fontSize: 14,
fontWeight: 'bold',
colors: {
gold: '#FFD700',
knowledge: '#4FC3F7',
influence: '#9b59c3',
damage: '#FF4444',
healing: '#44FF44',
},
},
screenFlash: {
waveComplete: { color: '#FFFFFF', opacity: 0.3, duration: 300 },
prestige: { color: '#FFFFFF', opacity: 1.0, duration: 500 },
bossSpawn: { color: '#000000', opacity: 0.2, duration: 300 },
},
placementFlash: { duration: 200, color: '#FFFFFF', opacity: 0.5 },
selectionPulse: { duration: 2000, color: '#FFD700' }, // 2s
fogRipple: { duration: 300, color: '#4FC3F7', spreadRadius: 48 }, // 3 tile radius
};
CONFIG.colorPalette = {
background: {
primary: '#0f0f1a',
secondary: '#1a1a2e',
tertiary: '#2a2a4e',
},
canvas: {
base: '#0f0f1a', // fog base
ground: '#1a1a2e', // revealed terrain
fog: '#16213e', // fog overlay (dark grey with 70% opacity)
grass: '#2d6a4f', // revealed grass tiles
forest: '#1a4a3a', // revealed forest tiles
water: '#0077b6', // revealed water tiles
mountain: '#6c757d', // revealed mountain tiles
ruins: '#d4a373', // ancient ruins
},
text: {
primary: '#e0e0d0',
secondary: '#a0a0a0',
muted: '#606060',
},
accent: {
gold: '#d4a373', // primary currency
knowledge: '#4FC3F7', // secondary currency
torches: '#f59e42', // fuel currency
influence: '#9b59c3', // strategic currency
prestige: '#E040FB', // prestige currency
},
success: '#4CAF50',
warning: '#ffb700',
danger: '#ff4436',
};
```
Adapt every value to the game's actual visual identity. Every color must be a hex value, every duration in milliseconds, every size in pixels.
## Engagement Self-Audit (MANDATORY)
Before finalizing your design, conduct this engagement audit. Since psychology-review agent no longer runs separately, YOU must verify these principles:
### Is This Actually A Game? (MOST CRITICAL)
- **Can you describe 30 seconds of gameplay without mentioning numbers, currencies, or upgrades?**
Yes. "Player's cartographer stands at edge of revealed grassland where it meets rolling fog. They click three tiles forward—cartographer walks, light spreading from lantern. Fog reveals a river glinting in darkness. Player clicks along riverbank, guiding explorer forward while keeping water in sight for navigation. Suddenly cartographer stops—iron deposit! Player quickly clicks to assign worker. Small figure appears from camp and begins marching toward iron. To south, fog ripples—shadow creature emerges! Player right-clicks cartographer to switch to combat mode, then clicks creature. Cartographer draws sword and charges."
- **Does player interact with Canvas directly (clicking, placing, directing) at least every 10 seconds?**
Yes. Player is constantly clicking fog tiles to explore (every 2-5 seconds per tile), assigning workers to resources (every 10-30 seconds), creating trade routes (every minute), right-clicking to cycle specializations, clicking collectibles. There is always a canvas action available.
- **If you removed all upgrade panels, is there still a recognizable game on Canvas?**
Yes. Even without UI, the Canvas shows: fog-covered grid with revealed terrain (grass, forest, water, mountains, ruins), animated cartographers walking and leaving light trails, workers marching to/from resources, merchants patrolling routes, shadows spawning and attacking, towers pulsing with light, campfire glow at center. The game is recognizable as "fog exploration cartographer game" from the Canvas alone.
- **Would a bystander watching over player's shoulder for 60 seconds understand what's happening?**
Yes. Bystander would see: humanoid figures walking on a map, darkness being pushed back by walking figures (revealing terrain), small particles and effects appearing when things happen, numbers floating up from entities, a central glow that seems to be a camp. The visual narrative of exploration and territory defense would be clear even without understanding the mechanics.
### Feedback Loop Completeness
Every player action must have BOTH Canvas feedback AND UI feedback:
| Action | Canvas Feedback (required) | UI Feedback (required) |
|--------|---------------------------|----------------------|
| Place tower (build mode) | Tower construct animation (2s rise), dust particles | Gold/Torch deducted, card shakes, cost flies to currency |
| Assign worker | Worker spawns at camp (300ms fade in) | Gold deducted, currency animates, resource shows assigned status |
| Kill shadow | Purple burst (5 particles), shadow fades | Influence + gold counters pulse up, floating numbers appear |
| Reveal tile (first time) | Fog fade animation (300ms), cyan ripple | Knowledge counter pulses, +bonus for new terrain type |
| Create trade route | Cyan line animates along path (1s) | Toast appears, merchant fades in |
| Investigate ruin | Purple burst from ruin (8 particles) | Knowledge + influence counters pulse |
| Prestige | White fade out (500ms), screen shakes | Prestige modal appears, currency carried over to new run |
| Cartographer dies | Fade out animation (500ms) | Toast "Cartographer lost!", 5s respawn timer |
| Collect collectible | Burst (5 particles, 200ms), number floats up | Currency pulses (300ms) |
| Fog reclaims tile with worker | Fog returns animation (2s fade in) | Toast warning, torch counter pulses red |
| Cannot afford (click upgrade) | N/A | Card shakes, cost flashes red |
All major actions have both Canvas and UI feedback specified.
### Reward Visibility Check
At any moment, player should see 2-3 things they're working toward:
- Next affordable upgrade (cost visible, progress shown, upgrade cards highlight when affordable)
- Next unlock threshold (progress bar or indicator, tab glow when unlocking soon)
- Current production rate (numbers/sec visible in HUD: gold, knowledge, torches)
- Map exploration progress (X% explored, with gradient bar)
- Cartographer count and specializations (always visible in stats)
- Fog warning indicator (pulses when torches < 15%)
### Variable Reward Check
Not all rewards are identical "+X gold":
- Tile knowledge varies by terrain type (grass=1, forest=2, water=3, ruins=5)
- Shadow rewards vary by level (base + per-level multiplier)
- Ruin rewards scale with tier
- Merchant yields vary by route length and road level
- Milestone rewards include diverse bonuses (new specializations, torch capacity, etc.)
Surprise elements:
- First ruin discovery provides large knowledge bonus
- Deep fog zones unlock after 50% explored (surprise high-value areas)
- Shadow spawn rate increases with territory (creates urgency)
- Random resource node quality varies (iron/gold/herbs with different yields)
## Quality Criteria
Before writing your output, verify:
- [✓] The Canvas game world is PRIMARY element, occupying 60-70% of screen
- [✓] Upgrade panels are SECONDARY, in a bottom panel (not whole screen)
- [✓] Currency displays are ALWAYS visible in HUD (never hidden behind tabs)
- [✓] Every entity type from idea.md has visual specs (sprite, scale, animation states)
- [✓] Canvas layers are specified (background, terrain, entities, effects, HUD overlay)
- [✓] Every UI element has specified states (locked, available, affordable, maxed)
- [✓] Feedback is specified for BOTH Canvas effects AND UI effects
- [✓] Floating damage/reward numbers are specified for Canvas
- [✓] The color palette has enough contrast for readability (dark theme)
- [✓] Tab unlock conditions match progression.md's unlock sequence
- [✓] Number formatting rules cover full range from 0 to 1T+
- [✓] The prestige UI shows visual transformation info
- [✓] The skill tree rendering approach is implementable in vanilla CSS/JS (CSS Grid)
- [✓] Accessibility basics are covered (contrast, keyboard, reduced motion)
- [✓] The design works at 1280×720 minimum resolution
- [✓] There is NO language about "the UI IS the game" — Canvas is the game
- [✓] Every entity type has a state machine diagram with all visual states
- [✓] Entity interaction diagram shows how all entity types relate
- [✓] UI event flow diagrams cover all major interaction paths (place, kill, collect, upgrade, fog reclaim)
- [✓] UI state machine shows game phases (loading, pre-wave, wave-active, prestige, game over)
- [✓] CONFIG.entities spec has every entity with sprite, scale, team, hp, states, healthBar
- [✓] CONFIG.canvas spec has width, height, backgroundColor, gridCellSize, layers
- [✓] CONFIG.ui spec has tab definitions with unlock conditions
- [✓] CONFIG.effects spec has particle, floatingText, and screenFlash definitions
- [✓] CONFIG.colorPalette has hex values for every UI color role
- [✓] Entity state definitions in CONFIG match state machine diagrams exactly
- [✓] A permanent controls panel is designed showing ALL player interactions (5 actions listed)
- [✓] A "How to Play" overlay is designed for first-load tutorial (4 bullet points)
- [✓] The controls panel is ALWAYS visible (not hidden behind tabs/menus)
- [✓] The tutorial overlay has a dismiss button and localStorage persistence
- [✓] 30-second gameplay description is entirely Canvas-based (no numbers/currencies mentioned)
- [✓] Player interacts with Canvas directly every 2-5 seconds (exploring tiles is constant action)
- [✓] Bystander would understand the game from Canvas visuals alone (clear exploration narrative)
- [✓] All major actions have both Canvas and UI feedback specified
- [✓] Multiple rewards visible at any time (upgrades, unlocks, production rates, map progress)
- [✓] Variable rewards implemented (tile knowledge varies, shadow rewards scale, ruin tiers exist)
- [✓] Currency displays always visible (all 4 currencies shown in HUD)
- [✓] Dark theme by default (all colors specified for dark background)
- [✓] Cartographer's Fog is the recognizable game name (not abstract poetry)