Underground 2 Revived
Play Need for Speed: Underground 2 (2004) in Chrome and Firefox with WebGPU graphics, Web Audio, up to 120 fps widescreen, controller support, free roam and Online races with friends. Fan project, not
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
Form as many valid Hungarian words as you can from a set of scrambled letters
before the timer runs out. Longer words score more (points = word length²), and
finding every possible word clears the board.
When a game ends, every found or revealed word has a link to its entry in the
appropriate Wiktionary edition (Hungarian or English).檢視完整 README ↗Form as many valid Hungarian words as you can from a set of scrambled letters before the timer runs out. Longer words score more (points = word length²), and finding every possible word clears the board.
When a game ends, every found or revealed word has a link to its entry in the appropriate Wiktionary edition (Hungarian or English).
data/magyar-szavak.txt, ~161k in the source
file before non-letter entries are rejected on import) and ~270k English words
(data/english-words.txt) — see Word lists belowA batch-by-batch plan for where this project is headed (multiplayer, Google sign-in, Android) lives in
ROADMAP.md. The multiplayer design is indocs/multiplayer.md.
Requirements: Node 24 (pinned via engines in package.json, which also sets the Vercel function runtime; CI runs 24), the
Vercel CLI (npm i -g vercel,
then vercel login and vercel link once to connect this checkout to the Vercel project).
npm install # root tooling: API, migrations, tests
npm --prefix frontend install # frontend deps
./run_dev.sh # `vercel dev` — frontend + api/ on one origin
Frontend and API are same-origin under vercel dev (it runs the Vite dev server declared
as devCommand in vercel.json and proxies non-/api requests to it), so there is no
CORS or dev-proxy configuration to maintain. vercel dev also pulls the linked project's
Development environment variables automatically — set them in the Vercel dashboard
(or vercel env add ... development) rather than duplicating them locally.
See .env.example for DATABASE_URL (needed locally to run
db:migrate/db:import/db:verify directly, outside of vercel dev) and the contract
test's API_BASE_URL/VERCEL_AUTOMATION_BYPASS_SECRET.
The TypeScript API that replaces the Python backend (ROADMAP Batch 1.2). It is
server-authoritative and holds no in-process state: every game lives in the games
table and every scored guess in game_guesses, so any function instance can serve any
request and a redeploy mid-game loses nothing.
api/v1/[...path].ts — one catch-all dispatcher for the whole /api/v1 surface
(Vercel Hobby caps a deployment at 12 functions; routing on path segments in one file
costs zero functions per new endpoint). Every route is a thin call into lib/.lib/ — the logic: words.ts (board/letter rules), game.ts (the game), daily.ts
(daily puzzle), hints.ts, scores.ts, achievements.ts, players.ts, config.ts
(admin-editable knobs), admin-*.ts (admin panel), db.ts (Postgres), http.ts (the
Vercel adapter), auth.ts (anonymous cookie), neon-auth.ts (admin session
verification). The importer in scripts/ reads its rules from lib/words.ts too, so
the API and the dictionary can never disagree about what a word's letters are.vercel.json rewrites /api/v1/:path* onto the dispatcher and keeps the pre-1.2 aliases
(/api/game/…, /api/words/…) working.The Vercel project's Root Directory must be
./(the repo root), notfrontend. Vercel readsvercel.jsonfrom the Root Directory, and the functions inapi/and the shared code inlib/live abovefrontend/.
Possible-words is computed once at game start from the board's letters — enumerate the
sub-multisets of its signature (~99 for a 7-letter board) and do one indexed
signature = any(…) lookup, rather than scanning all 155k words.
npm test # unit tests (board/letter rules) — no database needed
npm run typecheck
# The full HTTP contract suite against a deployment (ports backend/tests/test_api.py):
API_BASE_URL=https://<preview>.vercel.app npm test
# ...and if Vercel deployment protection is on:
API_BASE_URL=… VERCEL_AUTOMATION_BYPASS_SECRET=… npm test
The target architecture (ROADMAP Batch 1) puts persistence on Neon serverless Postgres
(Neon's managed auth is used for the admin Magic-Link login; player identity is the
anonymous cookie). Schema lives as SQL migrations in
migrations/; the dictionary is loaded into the words table (each row
stores a signature — its letters sorted — so possible-words is one indexed query rather
than a full scan).
Status: the schema, importer and API were first built on Supabase (#9, #10) and re-pointed to Neon in ROADMAP Batch 1.5 — plain-SQL migrations in
migrations/, adb:migraterunner, and a singleDATABASE_URL(no Supabase CLI orSUPABASE_*vars). Live and verified against a Neon project (db:verifygreen; ~152k active Hungarian words after the 2026-07-30 non-letter purge, ~270k English).
npm install # repo-root tooling (importer, migration runner)
# Validate the importer's parsing/normalisation without any database:
npm run db:import -- --dry-run
# Apply migrations + import the wordlist to the CLOUD database (set DATABASE_URL to the
# Neon pooled connection string first — see .env.example):
npm run db:migrate # apply migrations/*.sql (tracked in schema_migrations)
npm run db:import
# Check the deployed database: schema, row counts, and that the signature lookup returns
# the right words via the index rather than a full scan.
npm run db:verify
Connection: put Neon's pooled connection string in
DATABASE_URL(...-pooler.<region>.aws.neon.tech, dual-stack) — samepostgres(postgres.js) driver as the Supabase build, no swap needed.prepare: falsestays required: Neon's pooler is also PgBouncer in transaction mode.
.github/workflows/backup.yml runs pg_dump every Monday and uploads the dump as a
90-day workflow artifact — encrypted to the public key in
.github/backup-public-key.asc, because artifacts of a public repository are
downloadable by any signed-in GitHub user. Only the project owner holds the matching
private key (never stored in GitHub). To restore:
gh run download <run-id> -n betuveto-db-backup-<run-id> # -> betuveto-backup.dump.gpg
export GNUPGHOME=$(mktemp -d) # throwaway keyring
gpg --import betuveto-backup-private-key.asc
gpg --output betuveto-backup.dump --decrypt betuveto-backup.dump.gpg
pg_restore --list betuveto-backup.dump | head # sanity check (pg_restore 18)
# restore into a Neon *branch*, never straight over production:
pg_restore --no-owner --dbname "$BRANCH_DATABASE_URL" betuveto-backup.dump
npm test # API unit tests (no database needed)
npm run typecheck
cd frontend && npm run lint && npm run build # frontend checks
cd frontend && npx playwright test # E2E smoke test (serves this build, proxies /api to production)
CI runs all of the above on every pull request (.github/workflows/ci.yml): an API job
(typecheck + unit tests), a frontend job (lint + build) and the E2E smoke test. The full
HTTP contract suite (tests/contract.test.ts) is not in CI — run it by hand against a
preview deployment before merging API changes (see the API section above).
Identity-mint throttle (ROADMAP 12.6): each client IP may mint at most
identity_mints_per_ip_per_hour(default 30) fresh anonymous players per hour. A full contract-suite run mints many fresh players from your one IP (100+ against a preview, where the pinned CI cookie isn't used; ~12 against production), so it will hit 429s. Before a run, set that config key to0(disabled) on the target database — admin config panel, or directly in a preview branch'sconfigtable — and restore it after.
Vercel builds and deploys the whole app (frontend + api/) from its GitHub integration on
every push — there is no separate backend deployment.
Two dictionaries as of ROADMAP Batch 6.1: data/magyar-szavak.txt (hu) and
data/english-words.txt (en), each imported with
npm run db:import -- <file> --code <code> --name <name>. Provenance and licence for
each are documented in data/README.md — the Hungarian list's remain
unverified (a pre-existing TODO, still open); the English list is MIT-licensed and fully
attributed there.
Code is released under the MIT License — see LICENSE. Word list licences
are tracked separately (see data/README.md).