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를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A party/game-room web app: 14 standalone single-player tools plus a
Supabase-backed multiplayer room feature (chat, live participants, shared
activities synced in real time).
Every tool below works standalone (single-player, at /tools/) and as
a synced multiplayer activity inside a room (/room/[code]):
Two additional room modes bundle several of the above into one room:
Party Mode (all games unlocked) and Classroom (teacher-friendly picks/teams).
Beyond the games themselves, every multiplayer room includes:README 전문 보기 ↗A party/game-room web app: 14 standalone single-player tools plus a Supabase-backed multiplayer room feature (chat, live participants, shared activities synced in real time).
Every tool below works standalone (single-player, at /tools/<name>) and as
a synced multiplayer activity inside a room (/room/[code]):
| Game | Description |
|---|---|
| Team Maker | Build balanced teams instantly |
| Lucky Wheel | Physics-based 3D spinning wheel |
| Name Draw | Random winner picker, with elimination mode |
| Tournament | Single/double elimination and round-robin brackets |
| Coin Flip | Flip a coin, settle debates |
| Dice Roller | Roll custom dice sets |
| Guess Number | Number guessing game with live hints |
| Rock Paper Scissors | Classic showdown with synchronized reveals |
| Truth or Dare | Party question/dare draws |
| Would You Rather | Vote on impossible choices |
| Never Have I Ever | Icebreaker confessions |
| Trivia | Multiple-choice trivia, race to the top score |
| Bingo | Classic number bingo, call and mark |
| Word Scramble | Unscramble the word before anyone else |
Two additional room modes bundle several of the above into one room: Party Mode (all games unlocked) and Classroom (teacher-friendly picks/teams).
Beyond the games themselves, every multiplayer room includes:
@supabase/supabase-js) for multiplayer realtime sync — client-side only, no server/API routes@base-ui/react, vaul)npm install
cp .env.example .env.local # fill in your Supabase project URL + anon key
npm run dev
Open http://localhost:3000.
The multiplayer room feature needs a Supabase project. Without one
configured, the app still runs — rooms fall back to a same-browser-tab demo
mode via BroadcastChannel (see src/lib/supabase/client.ts), which does
not sync across different devices/users.
To enable real multiplayer:
.env.local (see .env.example).supabase/migrations/ in order (61 files as of
this writing) via supabase db push (or supabase link once, then
supabase db push) — this creates the full schema (rooms,
room_participants, chat_messages, moderation, scoring/XP, tournament
state, etc.), enables Row Level Security, and turns on realtime. On
main, .github/workflows/deploy.yml pushes any new migration files
automatically on every push that touches supabase/migrations/** — see
Deployment for the secrets it needs.Spintra uses Supabase Anonymous Auth: each client gets a real
auth.users row (no email/password), and RLS/trigger policies key off
auth.uid() rather than a client-supplied identity. See
supabase/migrations/0001_init_schema_and_rls.sql for the baseline policy
set and later migrations for the moderation/scoring/host-election hardening
built on top of it.
| Variable | Required | Description |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | For real multiplayer | Supabase project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY | For real multiplayer | Supabase anon public key |
NEXT_PUBLIC_SENTRY_DSN | Optional | Error monitoring. Without it, Sentry never initializes (see sentry.*.config.ts) — the app runs exactly the same |
SENTRY_ORG / SENTRY_PROJECT / SENTRY_AUTH_TOKEN | Optional | Only needed to upload source maps for readable production stack traces |
NEXT_PUBLIC_GA_MEASUREMENT_ID | Optional | Google Analytics (GA4). Without it, gtag.js never loads (see src/app/layout.tsx) and the CSP stays unchanged (see next.config.ts) |
| Command | Description |
|---|---|
npm run dev | Start the dev server. For the one preview link of a session use npm run dev -- -p 3200 -H 127.0.0.1 (http://127.0.0.1:3200): it follows the checked-out branch and reloads on every edit |
npm run build | Production build |
npm run start | Serve the production build |
npm run lint | ESLint |
npm run typecheck | tsc --noEmit |
npm run docs:check | Verify docs/ hasn't drifted from the real filesystem |
npm run verify:static | typecheck + lint + docs:check: the static checks that need no network |
npm run verify | verify:static + audit (the static gates CI runs first, so a red dependency audit shows up before the push; the audit needs the network, so it comes last; offline use verify:static and say the audit was not run) |
npm run verify:migration [name] | Confirms a migration's objects actually exist live in the linked Supabase project (not just tracked as "applied") — run after every supabase db push |
npm run test:smoke | Playwright smoke test (room create/join flow): the whole suite |
npm run test:related | Only the Playwright specs that cover the files changed since main (the whole suite for anything it cannot place: shared code, configuration, migrations, dependencies). -- --list shows the plan, -- --full forces everything, Playwright options go after a second --. It runs against this checkout's own preview server if one is running (found through .next/dev/lock), otherwise Playwright builds and starts its own. CI runs the whole suite on every pull request |
npm run test:city-regression | Spintra City release-blocker regression suite — asserts the fixed behaviour for each open blocker, so it stays red until the fix lands. Requires the local Supabase stack. |
npm run audit |
src/app/tools/* standalone single-player game/utility pages
src/app/room/[code]/ multiplayer room (chat, participants, header)
src/app/room/[code]/activities/ per-game room UI, one file per game
src/app/room/[code]/components/ moderation dashboard, scoreboard, room settings
src/app/create/ room creation flow
src/app/explore/ public room discovery / browse
src/app/settings/ user preferences (username, theme, etc.)
src/app/api/health/ liveness endpoint for uptime monitors / deploy checks
src/lib/games.ts single source of truth for the game catalog
src/lib/supabase/client.ts browser Supabase client (returns null if unconfigured)
src/lib/room-user.ts client-side identity, backed by Supabase Anonymous Auth
src/lib/moderation.ts moderation RPC client wrappers (kick/ban/dismiss)
src/lib/xp.ts XP/rank tier calculations
src/lib/tournament-engine.ts bracket generation for all 4 tournament formats
proxy.ts redirects /room?code=X to /room/X
supabase/migrations/ schema + RLS for the Supabase-backed tables
This Next.js version has breaking changes vs. older docs/training data — see
AGENTS.mdandnode_modules/next/dist/docs/before assuming an API works the way you remember. Notably, the routing hook file isproxy.ts(Next 16 renamedmiddleware.ts), notmiddleware.ts.
Playwright specs in tests/: smoke.spec.ts and comprehensive-smoke.spec.ts
(room create/join flow), multiplayer-loop.spec.ts (two genuinely distinct
participants — join, activity sync, moderation), comprehensive-tournament-audit.spec.ts
and tournament-double-elimination.spec.ts (bracket generation and scoring
across all formats).
.github/workflows/ci.yml runs two jobs once per pull request head (and once on main after a merge; a newer push to a pull request cancels the older run, and a branch without a pull request runs nothing): validate (dependency
security audit, typecheck, lint, docs drift check, build, and the Playwright
suite against the demo/BroadcastChannel fallback — no Supabase needed) and
db-integration (spins up an ephemeral local Supabase via Docker, applies
every migration fresh, and re-runs the suite against real RLS/triggers/realtime
instead of the demo fallback).
.github/workflows/db-backup.yml, deploy.yml) require repo secrets
that aren't configured yet — see Deployment.NEXT_PUBLIC_SENTRY_DSN configured yet).Any Next.js host works (e.g. Vercel). Set the
NEXT_PUBLIC_SUPABASE_* (and optionally NEXT_PUBLIC_SENTRY_DSN/SENTRY_*)
environment variables in your hosting provider's dashboard before deploying.
Two GitHub Actions workflows handle Supabase-side operations and need repo secrets to function:
| Workflow | Trigger | Required secrets |
|---|---|---|
deploy.yml | Push to main touching supabase/migrations/** (or manual dispatch) | SUPABASE_ACCESS_TOKEN, SUPABASE_DB_PASSWORD, SUPABASE_PROJECT_ID |
db-backup.yml | Twice a day, 03:00 and 15:00 UTC (+ manual dispatch) | SUPABASE_DB_URL, AWS_BACKUP_ACCESS_KEY_ID, AWS_BACKUP_SECRET_ACCESS_KEY, AWS_BACKUP_S3_BUCKET, AWS_BACKUP_R2_ENDPOINT |
db-backup.yml uploads to Cloudflare R2 (S3-API-compatible, free tier,
zero egress fees) rather than real AWS S3 — AWS_BACKUP_R2_ENDPOINT is the
bucket's R2 endpoint URL, and the region is hardcoded to auto in the
workflow itself (R2's documented value, not a real AWS region).
Without these secrets set (gh secret set <NAME>), both workflows run but
fail every time — migrations must then be pushed manually
(supabase db push) and no backups are retained.
All rights reserved. This repository is source-available for portfolio and reference purposes only — reuse, modification, or redistribution of this code is not permitted without the author's permission.
node scripts/audit-gate.mjs --audit-level=moderate: npm audit at that threshold, plus a short time-boxed allowlist (scripts/audit-allowlist.json) for advisories that have no fix yet — the one place this threshold is set; .github/workflows/ci.yml's CI gate calls this same script rather than hardcoding its own |
npm run ci | verify (which includes the audit) + build + test:smoke (the full CI gate, locally) |