Files
Emberfall/docs/GAME_DESIGN.md
T
2026-10-20 20:33:35 +11:00

90 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.