Progress / Phase 4
Phase 4: Accounts and Characters
Players create an account, log in, make a character and come back later to find it where they left it.
Phase 40 / 32 · 0%
This phase is still ahead.
4.1 Database
0 of 6 done- PostgreSQL on the host through the bootstrap script: pinned major version, local connections only, separate roles for migrations and the app.
- Decision Database access: pgx with sqlc for typed queries and goose for migrations (recommended).
- Migrations in
server/migrations/, run bymake migratelocally and as a deploy step in production. - Local dev database with Docker Compose (
make db-up,make db-reset) and a Postgres service container in CI. - Schema: accounts, sessions and characters (name, appearance, zone, position, facing, timestamps).
- A bounded connection pool, a context timeout on every query, and no database call on a zone goroutine: zones hand saves to persistence workers through a bounded queue.
4.2 Authentication
0 of 6 done- Registration: username rules, password of at least 10 characters checked against a common-password list, Argon2id hashing with parameters recorded in an ADR.
- HTTPS endpoints
POST /api/auth/register,/loginand/logoutreturning an opaque session token, stored only as a hash. - The WebSocket handshake carries the session token; invalid or expired tokens are rejected; a new login ends any older game session for that account.
- Rate limits and lockouts on login and registration per IP and per account, proven by tests.
- Password hashing on a bounded worker pool, so a login storm queues instead of starving tick loops;
make loadtest SCENARIO=stormmeets the scaling.md login-storm target ondev-m5. - Owner Decide on account recovery for v1 (no email, or optional email with an SMTP provider). An agent writes the options up as an ADR first.
4.3 Characters
0 of 6 done- Character creation: name rules (unique, allowed characters, length, reserved and offensive words filtered) and appearance chosen from the Batch 04 variants.
- Character select: up to four characters per account, with delete behind a typed confirmation (soft delete).
- Position and state saved on logout, on disconnect and every 60 seconds, and restored on login.
- A failure in the middle of a save (connection killed, transaction aborted, server killed) leaves the last committed state intact, tested against a real Postgres.
- Session resume: a client that reconnects within a grace window with its session token returns to its character without logging in again;
make loadtest SCENARIO=reconnectmeets the scaling.md reconnect-storm target ondev-m5. - Client login, registration, character select and creation screens with clear errors; the token lives in memory unless “remember me” is chosen.
4.4 Backups
0 of 4 done- Nightly
pg_dump, compressed and encrypted, keeping 7 daily and 4 weekly copies. - Owner Choose an off-site backup destination and put its credentials on the host.
- Every backup copied off-site automatically, with an alert if a backup fails.
- Restore drill: restore the latest off-site backup into a scratch database and verify it, documented in
docs/ops/backups.md.
4.5 Website
0 of 2 done- Privacy policy page (what’s stored, why, for how long, how to delete an account) and terms of use with a player code of conduct.
- Owner Review and approve the privacy policy and terms.
4.6 Walkthrough
0 of 2 done-
docs/walkthroughs/phase-04-accounts.md: password hashing, sessions, migrations, transactions and backups. - Devlog draft, release notes, tag
v0.4.0and publish builds.
Acceptance criteria
0 of 6 done- A new player can register, create a character, play, quit, and log back in at the same spot.
- Passwords exist only as Argon2id hashes and session tokens only as hashes.
- Brute-force login attempts are rate limited (integration test).
- A backup was restored successfully from the off-site copy.
- CI runs the database integration tests against a real Postgres.
- The login-storm and reconnect-storm targets in scaling.md are met on
dev-m5, with results indocs/perf/.
