70 lines
3.9 KiB
Markdown
70 lines
3.9 KiB
Markdown
# NOTES.md — Project Brief (READ FIRST)
|
|
|
|
## 1. What you are building
|
|
**Emberfall**: a fantasy persistent browser-based game (PBBG). Players register
|
|
an account, create a hero, and spend regenerating **Energy** on actions. The
|
|
world keeps moving while they are offline (energy regenerates, expeditions
|
|
finish). All state lives in a database on the server.
|
|
|
|
You are the only developer. A human will play-test the result. Working,
|
|
simple, and correct beats ambitious and broken.
|
|
|
|
## 2. Hard constraints (do not violate)
|
|
1. **Stack is fixed:** Node.js (>= 20), Express, SQLite via `better-sqlite3`,
|
|
`bcryptjs` for password hashing, `express-session` + `better-sqlite3-session-store`
|
|
(or `connect-sqlite3`) for sessions, `helmet`, `express-rate-limit`,
|
|
`zod` for input validation. Tests with the built-in `node:test` runner.
|
|
2. **Frontend is vanilla HTML/CSS/JS.** No React, no build step, no bundler.
|
|
Static files in `public/`, talking to the JSON API with `fetch`.
|
|
3. **No new dependencies** without logging the reason in `docs/DECISIONS.md`.
|
|
4. **The server is the only source of truth.** The client never sends results,
|
|
damage, gold, XP, or timestamps. It only sends *intent* ("hunt in zone 2").
|
|
5. **No real-time ticks / cron loops for game logic.** Use *lazy evaluation*:
|
|
compute energy regen and finished timers when the player next makes a request
|
|
(see `docs/GAME_DESIGN.md` §Time).
|
|
6. **All SQL uses prepared statements with bound parameters.** Never build SQL
|
|
with string concatenation.
|
|
7. **Keep files small** (aim < 200 lines). Split by responsibility.
|
|
8. **Game rules live in `src/game/` as pure functions** (no DB, no Express).
|
|
They take data in and return data out, so they can be unit tested.
|
|
9. **Never store plaintext passwords.** Never log passwords or session secrets.
|
|
10. **Don't touch what isn't in the current step.** No drive-by refactors.
|
|
|
|
## 3. How to work (summary — details in docs/WORKFLOW.md)
|
|
1. Open `STATUS.md`. Find the first unchecked step in the lowest-numbered phase.
|
|
2. Read ONLY the docs that step references.
|
|
3. Implement the step in small pieces. Run the app / tests after each piece.
|
|
4. When the step's acceptance criteria pass, tick the box in `STATUS.md`,
|
|
add a Session Log line, and record any new Known Issues.
|
|
5. Stop and re-read `STATUS.md` before starting the next step.
|
|
|
|
If a doc is ambiguous or contradicts another doc, pick the simplest option,
|
|
and write it down in `docs/DECISIONS.md`. Do not stall.
|
|
|
|
## 4. Priority order when things conflict
|
|
Correctness & security > persistence works > game is playable > code tidy > fun extras.
|
|
|
|
## 5. Glossary
|
|
- **Hero / Character:** the player's in-game avatar. One per account (v1).
|
|
- **Energy:** action currency. Max 100. Regenerates over real time.
|
|
- **Gold:** soft currency. Earned from combat/expeditions, spent in shops.
|
|
- **Expedition:** a timed activity; started now, claimed later.
|
|
- **Zone:** an area with monsters, level range, and loot.
|
|
- **Lazy regen:** computing regen from `energy_updated_at` when needed.
|
|
|
|
## 6. Out of scope for v1
|
|
Real-money payments, email verification, password reset by email, websockets,
|
|
mobile apps, 3rd-party OAuth, admin web UI. (Stretch goals are in STATUS.md.)
|
|
|
|
## 7. Definition of "game is playable" (v1 target)
|
|
A new visitor can: register → log in → create a hero → see stats/energy →
|
|
hunt monsters → gain XP/gold/loot → level up → equip items → buy/sell in the
|
|
shop → start and claim an expedition → see the leaderboard → log out → log back
|
|
in and find everything exactly as left (plus offline energy regen).
|
|
|
|
## 8. Automated loop mode
|
|
This project may be driven by `scripts/run-agent-loop.sh`, which starts a fresh agent session per step.
|
|
In that mode: do exactly the one target step named in the prompt, never run commands that block forever,
|
|
never run `git commit`/`git reset` (the loop commits after it verifies `npm test`, and rolls back on failure),
|
|
and never delete or weaken tests (the loop rejects runs where the passing-test count drops).
|