90 lines
5.0 KiB
Markdown
90 lines
5.0 KiB
Markdown
# 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, alternating attacks. Higher `speed` acts first each round.
|
||
- 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.
|