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
A free speedcubing timer with official WCA scrambles, real stats and a competition simulator. Works in any browser, no download.
GamesTypeScript · CSSGitHub @prizeficryptoOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗A free speedcubing timer and WCA competition simulator. Open the site and you're on the timer; the simulator lets you solve the real scrambles from a real WCA round and see where you'd have placed against the people who were there. Supported by ads (Google AdSense); no paid plans.
/app, the front door) — csTimer-class practice timer:
sessions per puzzle (all WCA events + "no scramble"), real random-state WCA
scrambles (cubing.js) with history and your own scrambles, hold-to-start,
WCA inspection (+2 after 15 s, DNF after 17 s) with spoken 8 s / 12 s calls
(choose a male/female/system voice, volume, or a beep), multi-phase splits,
focus mode, OK/+2/DNF and comments per solve, csTimer's keyboard shortcuts,
typed times, StackMat (audio jack) and GAN Smart Timer (Bluetooth,
beta) input, full stats (mo3/ao5/ao12/… current + best, csTimer trimming,
WCA rounding), a time list that stays fast at 10k+ solves, tools (scramble
image, trend, distribution, scramble generator, metronome), and
import/export (csTimer JSON + CSV, Twisty Timer, Cubic Timer, plain lists)./app/competitions) — pick any past WCA competition
(a "Just published" list surfaces new ones automatically), an event and a
round, solve its official scrambles, and get placed by WCA ranking rules.client/ React + Vite + TS SPA
server/ Express API: WCA data proxy, accounts, social, feedback
api/ Vercel serverless entry (wraps the bundled Express app)
Server routers live in server/src/routes/ (data, account, social,
feedback); server/src/index.ts composes them.
Cache-Control: s-maxage so Vercel's CDN serves repeat
requests without running the function. Public data requests carry no
Authorization header (that would bypass the CDN).client/src/lib/timer/storage.ts);
signed-in users sync them in hashed 200-solve chunks so only changed chunks
upload (client/src/lib/cloudSync.ts, server/src/social/).client/src/lib/cubing.ts — simulator scoring per WCA Regulations: attempts
truncated to the hundredth (whole seconds at 10:00+), Ao5 drops one best and
one worst, mean of 3 for 6x6/7x7, averages rounded (to the second at 10:00+),
placement by average then best single, ties share a position, DNF averages
ranked after every valid average by best single.client/src/lib/timer/stats.ts — practice stats with csTimer's definitions
(5% trimming, DNF rules) and WCA rounding.client/src/lib/timer/engine.ts — the timer state machine (pure, tested).Server (server/.env, see server/.env.example):
| Variable | Needed for |
|---|---|
DATABASE_URL | Required. Supabase transaction-pooler URL (port 6543) |
APP_URL | Public URL (WCA sign-in redirect) |
GOOGLE_CLIENT_ID | Google sign-in |
WCA_CLIENT_ID, WCA_CLIENT_SECRET | WCA sign-in / connect |
ADSENSE_PUBLISHER_ID | Serves /ads.txt (e.g. pub-123…) |
CRON_SECRET | Protects the daily database keep-alive |
Client (client/.env, see client/.env.example): VITE_GOOGLE_CLIENT_ID,
VITE_ADSENSE_CLIENT (ca-pub-…) and VITE_ADSENSE_SLOT_* ad-unit ids.
Anything unset simply stays off (no fake buttons, no empty ad boxes).
server/schema.sql once in the Supabase SQL editor (it's
idempotent). Upgrading an existing database only needs
server/migrations/2026-10-26-social.sql. Until it's run, social features
hide themselves.<APP_URL>/auth/wca and scope public (sign-in also asks for email).vercel.json schedules a daily /api/cron/keepalive to prevent
that (set CRON_SECRET).Node 22.18+ (the server runs TypeScript directly via type-stripping).
cd server && npm install && npm start # API on :4000
cd client && npm install && npm run dev # app on :5173, proxies /api
cd client && node src/lib/cubing.test.ts # WCA scoring + placement
cd client && node src/lib/timer/stats.test.ts # practice stats
cd client && node src/lib/timer/engine.test.ts # timer state machine
cd client && node src/lib/timer/typing.test.ts # typed-time parsing
cd server && node src/social/social.test.ts # sync codec, handles, scoring
cd server && node src/wcaOauth.test.ts # WCA OAuth state signing
cd server && npm run verify # real WCA fetch sanity check
cd client && npm run build # typecheck + production build