# GAME_DESIGN.md — Emberfall ## Setting & tone The Ashen Realm: an old kingdom whose great Ember-Throne has gone dark. Monsters creep out of the wilds, and heroes gather at the border town of **Cindergate** to rekindle the Throne. Tone: classic high fantasy, slightly wry. Keep flavour text short (1–2 sentences). Names should feel Tolkien/D&D-ish but original. ## Core loop (target session: 5–10 min, several times a day) 1. Log in → see energy (regenerated while away) and any finished expedition. 2. Spend energy: hunt monsters, or start an expedition. 3. Collect XP, gold, loot → level up → equip/upgrade → unlock harder zones. 4. Spend leftover gold in shop. Check leaderboard. Log out. Energy limits session length; timers give reasons to return. ## Time (lazy evaluation — IMPORTANT) - **Energy**: max 100, +1 per 180 s (3 min). Stored as `(energy, energy_updated_at)`. On any request that needs energy: `computeEnergy()` → write back the new pair. At max, regen stops (timestamp resets to now so no "banked" regen). - **Expeditions**: stored with `ends_at`. "Finished" is just `now >= ends_at`. Nothing runs at that moment; the player claims it later. - **HP**: stored as `hp_current`. Natural regen: +1% max HP per minute, computed lazily the same way as energy (add `hp_updated_at` column if you implement it; otherwise HP fully restores on level-up and via Rest/potions — v1 acceptable). - No `setInterval` for game logic. Ever. ## Classes (pick one at creation; permanent in v1) | Class | Fantasy | Starting STR/AGI/INT/VIT | Bonus | |---|---|---|---| | Warrior | Armoured frontliner | 8 / 4 / 2 / 8 | +10% defense | | Mage | Glass-cannon spellcaster | 2 / 4 / 9 / 5 | +15% damage vs. high-defense foes | | Ranger | Fast skirmisher | 5 / 9 / 3 / 5 | +8% crit chance | Primary stat for attack: Warrior→STR, Mage→INT, Ranger→AGI. Each level grants **3 unspent stat points** (player allocates via API). ## Stats - **STR** physical power, **AGI** speed & crit, **INT** magic power, **VIT** health. - Derived stats formulas: see BALANCE.md §Derived. ## Combat (auto-resolved, server-side, turn based) - Hero vs one monster. **Each round BOTH sides attack once**; the higher `speed` side attacks first (hero wins ties). If the first attacker kills the target, the second does not act. - Max 20 rounds; if no one dies, the one with higher HP% wins. - Each hit: damage formula in BALANCE.md, small random variance, crit chance. - Output a **round-by-round log** (array of `{round, actor, damage, crit, targetHpAfter}`) for the UI to replay. - Win: XP + gold + loot rolls. Lose: lose 10% of carried gold (min 0), HP set to 1, no XP; deaths +1. (Never lose items in v1.) - Hero HP persists between fights (`hp_current`). Hunting with HP < 20% of max is blocked: `HP_TOO_LOW` (422) → player must Rest or use a potion. - Combat resolution takes an injected `rng` so tests are deterministic. ## Zones (v1: 3 required, add more if time permits) | Zone | Level | Energy | Theme | |---|---|---|---| | Whispering Meadows | 1+ | 5 | goblins, wolves, giant rats | | Gloomroot Forest | 5+ | 8 | spiders, bandits, treants | | Ashfang Crags | 10+ | 12 | drakes, fire imps, stone golems | Optional: Sunken Catacombs (15+), Emberthrone Ruins (20+, boss). ## Items Types: `weapon`, `armor`, `trinket` (equippable, one per slot), `consumable` (stackable), `material` (stackable, sell-only in v1). Rarity: common → uncommon → rare → epic → legendary (colour-coded in UI). Items give flat stat/attack/defense bonuses. Class restrictions: none in v1. Starter gear: new heroes get one common weapon appropriate to class (auto-equipped) and 2 Minor Healing Potions. ## Economy - Gold sources: monster drops, expeditions, selling items. - Gold sinks: shop purchases, Rest (heal to full), (stretch) market tax. - Sell price = 40% of `buy_price` (items with `buy_price` 0 sell for rarity default: see BALANCE). - Prices must make the 1st hour feel rewarding but not trivialise gear. See BALANCE. - Gold can never go below 0; enforced by DB CHECK and service checks. ## Expeditions (the "offline" mechanic) - Choose one of 3–4 definitions (e.g. "Scout the Old Road" 10 min, "Raid the Bandit Camp" 1 h, "Delve the Hollow" 4 h). - Costs energy up-front. One active at a time. Hero cannot hunt while on expedition? **No** — hunting is still allowed (keeps it simple). - Claim after `ends_at`: grants XP + gold (+ a loot roll for 1h+ ones). Double-claim impossible (`claimed_at` set inside the same transaction). ## Leaderboards Top 50 by: level (tie-break xp), gold, kills. Public. Query on indexed columns. Optionally cache 30 s in memory. ## Names & content rules - Hero names: 3–16 chars `[A-Za-z0-9 '-]`, unique case-insensitive, trimmed, no double spaces. - Basic profanity blocklist: small array in `src/game/constants.js` (keep it short; log extension as a TODO). ## Balance targets (sanity check when testing) - Level 1 → 5 in roughly 40–60 hunts (~2–3 energy refills). - A fresh Level-1 hero should win ≈ 80% of Meadow fights and lose ≈ 90% against a Crag monster. - No single item should raise power by > 25% at its tier.