Real-time combat · Clan warfare · Player-driven economy · One hostile 150×150 world
About · Quick Start · Systems · Controls · Development · Status
DarkFrame drops every player onto a shared 22,500-tile map — nine terrain types, no instancing. Gather metal and energy by day, defend what you've built by night, and remember one rule of the wasteland: if you can reach it, you can lose it.
| 🗺️ | 🎮 | ⚔️ | 🏰 |
|---|---|---|---|
| 150 × 150 persistent world | 8-direction movement | Server-resolved combat | Clans & alliances |
| 22,500 tiles · 9 terrain types · edge wrap-around | QWEASDZXC grid movement · reserved keys · zero misclicks |
battle engine · factories · flag warfare · WMDs | treasury · territory income · diplomacy |
| System | What it does | |
|---|---|---|
| ⛏️ | Gathering | Harvest metal & energy fields; auto-farm with live telemetry |
| 🏭 | Factories | Produce units through sequential build slots; honest scarcity curve (400 slots at L1 → 1,750 at L10) |
| 🎯 | Beer Bases | Weekly-respawning high-reward targets with power-band calibration, surfaced by the bot scanner (50-tile radius) — intel is earned, not given |
| 🚩 | Flag Warfare | Channel-and-flee steals (no HP battles); bearer bonus stack; 12h hold milestone |
| ☢️ | WMDs | Strategic weapons for clan-scale warfare (real damage engine, scheduled ticks) |
| 🏦 | Banking | Deposits, withdrawals, exchange, plus clan treasury with distributions |
| 🔨 | Auction House | Player-to-player trading with fee economics and real unit/money escrow |
| 🎓 | Progression | XP power curve · research points (census-anchored milestones) · doctrine specializations · mastery · achievements · VIP tiers |
| 💬 | Social | Global & clan chat, friends, DMs, bounties, referrals |
| 🛡️ | Moderation | Player inspection, session/activity tracking, flags & bans |
Node.js 20+ · PostgreSQL 14+ · (optional) Redis, Stripe CLI
git clone https://github.com/savant0x/DarkFrame.git
cd DarkFrame
npm installCreate .env.local (git-ignored — never commit real credentials):
# ── Required ────────────────────────────────────────
DATABASE_URL=postgresql://user:password@host:5432/darkframe
JWT_SECRET=change-me-to-a-long-random-string
# ── Owner account (created by db:setup) ─────────────
OWNER_USERNAME=yourname
OWNER_EMAIL=you@example.com
OWNER_PASSWORD=change-me
# ── Optional ────────────────────────────────────────
PORT=3000
REDIS_URL=redis://localhost:6379
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...npm run db:setupOne stop — generates the 22,500-tile map (idempotent) and creates your owner account.
npm run dev:serverOpen http://localhost:3000 and log in.
npm run devstarts Next.js alone — fine for UI work, but no realtime or world jobs.
📄 Full command reference
| Command | What it does |
|---|---|
npm run dev:server |
Full game server — Next + Socket.io + background jobs |
npm run dev |
Next.js dev server only |
npm run db:setup |
Generate map + owner account (idempotent) |
npm run map:rebuild |
--yes required) |
npm run test:ci |
Full test suite (Vitest, 865 tests) |
npm run lint |
ESLint (0 errors; no-console + import guards enforced) |
npx tsc --noEmit |
TypeScript check (0 errors, strict) |
npm run stripe:listen |
Stripe webhook forwarding (expects C:\stripe\stripe.exe) |
npm run validate-referrals |
Referral validation cron |
One key, one action. The movement keys are reserved — no panel or feature can ever fire when you press them. Every other action has exactly one binding; panel toggles use Shift + key. Rebind in-game via the admin Hotkey Manager.
| QWE ASD ZXC |
🧭 | Move — 8 directions (S holds position) |
| G / F | ⛏️ | Harvest field / harvest cave & forest |
| R | ⚔️ | Attack factory |
| ⇧Shift+E | 🍺 | Beer Bases panel |
| B · N · U | 🏛️ | Bank · Shrine · Unit build |
| M · T · H · V | 🛠️ | Factory mgmt · Tier unlock · Auction house · Achievements |
| O · J · Y | 🎯 | Bounty board · Bot magnet · Bot summoning |
| ⇧Shift+C / L / P | 👥 | Clan view / clan leaderboard / player leaderboard |
| ⇧Shift+X / ⇧Shift+F / ⇧Shift+S | 🤖 | Bot scanner / auto-farm toggle / auto-farm stats |
Full list with every binding (and rebind UI) in the admin Hotkey Manager.
DarkFrame/
├── app/ Next.js App Router — pages & 235 API routes
├── components/ Game canvas, panels, admin modals (NEON NOIR token system)
├── lib/ ~110 game services · Drizzle schema + connection · jobs · websocket
├── types/ Shared TypeScript contracts (single-source catalogs)
├── scripts/ Setup, E2E drivers & economy simulators (run the real engine)
├── docs/ Player + design docs (audited 2026-09-16; history in dev/archives/)
├── dev/ Working notes — sessions, FIDs + archive, audits, protocol
└── SCOPE.md Authoritative scope & audit trail
Stack: Next.js 16 (App Router) · React 19 · TypeScript strict · custom Node server hosting Next + Socket.io + scheduled jobs · PostgreSQL via Drizzle ORM · JWT auth (jose, bcrypt) · Stripe subscriptions · Redis rate-limiting · Sentry · Vitest
Deployment model (declared 2026-10-05 — HYBRID): the CRON_SECRET-gated cron
routes in app/api/cron/* (scheduled in vercel.json) are the authoritative
trigger for every background job; server.ts keeps Socket.io + boot migrations
and its in-process job intervals as an idempotent self-host optimization.
Every scheduler path runs through lib/jobs/tickGuard.ts — exactly once per
cadence window, claimed cross-process via Redis SET NX EX — so the two
registrations can never double-fire. On serverless, realtime degrades DB-only
(getIO() null: pushes are silent and honest) while the crons keep the world
moving. Runbook: dev/QUICK_START.md.
# verify your change before pushing — all three gates must pass
npx tsc --noEmit # types (0 errors)
npm run lint # style (0 errors)
npm run test:ci # behavior (865 tests)Workflow: direct to main — no PR flow. A pre-commit hook runs the
ladder-truth gate whenever game-math sources are staged; documented
game-math tables are CI-pinned (comment drift fails the suite).
Project docs live in dev/:
| Doc | Read it for |
|---|---|
SCOPE.md |
Every change — what, why, when — plus the open decision queue |
CHANGELOG.md |
Release-by-release record of what shipped |
dev/session-summaries/ |
Per-session engineering records |
dev/fids/archive/ |
Closed feature/bug records with evidence |
Player & operator guides live in docs/:
| Guide | Covers |
|---|---|
docs/ARCHITECTURE.md |
System design, stack, live API layout |
docs/DEV_SETUP.md |
Dev servers, scripts, Windows PATH fix |
docs/RP_ECONOMY_GUIDE.md |
Earning & spending research points |
docs/REFERRAL_SYSTEM_GUIDE.md |
Referral rewards & validation |
docs/MESSAGING_SYSTEM.md |
DMs, channels, Socket.io events |
docs/TUTORIAL_SYSTEM.md |
Tutorial quests & schema |
docs/STRIPE_LOCAL_TESTING.md |
Webhook testing with the Stripe CLI |
docs/TESTING_GUIDE.md |
Auth & gameplay test walkthroughs |
Note on the DB layer: Postgres (via Drizzle) is the only database. The Mongo stack and its compat shim were fully removed on 2026-09-19 — every route, service, script, and the server entry point ride drizzle/pg directly, and a pre-push gate refuses any reintroduction. Known rough edges are tracked openly in
SCOPE.md— nothing is silently broken.
✅ PLAYABLE — GATES GREEN
Combat rebalance shipped (sequential resolution, power-proportional HP, balance executes in-combat) · economy v2 live (census-anchored milestones, shared tech catalog, 600k WMD track, battle-RP pacing) · bot vaults regrow linearly · 0 open FIDs · tsc 0 / lint 0 / 865 tests green.
Honest, per-session progress in SCOPE.md — no marketing numbers.
DarkFrame — crafted by @savant0x
All rights reserved · reuse requires permission