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에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗A host-led quiz and games board for teams playing together in a room. Create the quiz, show it on a shared screen, and let the host run questions, challenges, scoring, and the final podium. Try it at kimquizak.com.
Quiz data is saved in the browser by default. File import/export works without an account; host login enables optional cloud snapshots and interactive Geoguesser when those services are configured.
The host runs KimQuizak on a shared TV or projector. Teams answer in the room; the host controls the pace, judges answers, and awards points.
sequenceDiagram
actor Host
participant TV as TV screen
actor Audience as Audience / teams
Host->>Host: Create teams and a quiz for the audience
Host->>TV: Open the game board on the shared screen
loop Each question or challenge
Audience->>Host: Choose a category and point value
Host->>TV: Show the question and explain the rules
Audience->>Host: Answer or complete the challenge
Host->>Host: Evaluate the answer and adjust the pace
Host->>TV: Reveal the answer and award points
TV-->>Audience: Show the updated scores
end
Host->>TV: Reveal the final podium
TV-->>Audience: Celebrate the winners!
Use Node.js 22.23.4 or newer within 22.x, as specified in package.json. .nvmrc pins the development version. The minimum includes Node.js security fixes released in October 2026.
If you use nvm, run nvm use first. Otherwise, install a compatible Node.js version before continuing.
npm install
npm run dev
The app uses Next.js 16 (App Router and TypeScript). npm run dev uses Turbopack; if development fails with a Turbopack error, stop the server and try npm run dev:webpack. The production build uses Webpack, as configured in package.json.
Open http://localhost:3000. A fresh browser starts without questions. Create your own in Questions, or use Questions → Local archive → Add example data. Loading examples replaces the current browser quiz, so download a backup first if you want to keep it. Supabase and Google Maps configuration are optional for local quiz editing and play.
| Type | How it plays |
|---|---|
| Standard | A question and answer, with optional images. The host judges the answer. |
| MCQ | 2–12 choices, with one or more correct answers. The host sets how many correct picks finish the question. Points are split across that target; with rollover enabled, a wrong pick passes play to the next team. |
| Text grid | One word or segment per line becomes one tile. Teams uncover the text to identify the answer. Red tiles pass the turn without reducing the question's value; the host can also pass after a wrong guess. An optional YouTube answer video accepts supported watch, share, or embed links. |
| Image reveal | Reveal an image by zooming out, clearing blur, or selecting areas. The host configures reveal stages or areas and whether extra reveals cost points. |
| Geoguesser | Start from a saved Street View location. Choose a fixed view with paid timed exploration, look-and-zoom without movement, free exploration, or a two-phase stage challenge: timed exploration followed by a timed map guess scored by distance. Requires host login and Google Maps setup. |
| Timeline | Place events in chronological order around a configured starting event. The host decides whether misses pass to the next team. |
| Audio | Identify a YouTube audio clip. Set the start time and clip length; an optional replay lowers the available points to the next lower board tier. |
| Trivia | A sequence of questions, followed by host review of the teams' answers. Each team can earn up to the full tile value, based on its number of correct answers. |
| Challenge | A host-authored task with an optional image and countdown or count-up timer. The host marks it completed for full points or not completed for zero. The timer does not award points automatically. |
| Joker high/low | Guess higher or lower on configurable number columns. Correct and wrong guesses move the reward up or down a six-level ladder; finding the hidden Joker jumps to the top level. |
| Connections | Find groups of four among 16 tiles. The host chooses a target of 1–4 solved groups, with points split across it. Wrong guesses can pass play to the next team. Defaults are 120 seconds per guess and four shared mistakes; both limits are configurable. Rules and setup. |
You can run the local quiz without cloud accounts. For an online copy with host login, Street View, and private cloud snapshots, this guide uses:
Use your own projects and configuration values. The blank .env.example lists the required variable names. The bundled players and relationships are fictional.
Interactive Geoguesser requires a configured Google Maps key and a signed-in host. There is no offline or image fallback. Players watching the shared screen do not need accounts. YouTube questions still need access to YouTube; browser-local quiz storage does not make external media available offline.
flowchart TD
A[Clone or fork KimQuizak] --> B[Google Cloud: billing and restricted Maps keys]
A --> C[Supabase: create project and host login]
C --> D[Apply migrations and enroll the host]
B --> E[Configure local environment and test]
D --> E
E --> F[Vercel: import repository and set production variables]
F --> G[Configure domain restrictions and deploy]
G --> H[Verify host login, Street View, and private archive]
Use Node.js 22.23.4 or newer within the 22.x release line. Fork the repository into your own GitHub account if you want Vercel to deploy your changes, then clone that fork. For a local evaluation:
git clone https://github.com/kimisak/kimquizak.git
cd kimquizak
npm install
npm run dev
Open http://localhost:3000 to try the local app. For the optional services below, copy .env.example to .env only if you do not already have that file, then fill in your own values. Keep existing environment files intact.
http://localhost:3000/* on the development key (add another exact local origin only if you use it).https://quiz.example.com/*, and your exact Vercel production hostname if you use it. Add www separately if needed. Do not allow every *.vercel.app deployment.The key identifies the Google project billed for Maps usage. It is sent to the signed-in browser to load interactive Street View. Storing it in Vercel keeps it out of Git, but does not make it invisible in browser developer tools. Host login and Google's website/API restrictions serve different purposes; use both. Signing in alone does not load Street View.
See Google's API setup, security guidance, usage and billing, and budget alerts.
See Supabase Auth configuration and API keys.
From the repository root, authenticate the CLI and link your project's reference (the identifier in its Supabase dashboard URL):
npx supabase login
npx supabase link --project-ref YOUR_PROJECT_REF
npx supabase migration list --linked
npx supabase db push --linked --dry-run
npx supabase db push --linked
This creates the private archive and its row-level security rules, including deletion. Next, enroll your app host. Replace YOUR_HOST_UUID with the UUID from Authentication → Users:
npx supabase db query --linked "insert into private.quiz_owners (user_id) values ('YOUR_HOST_UUID') on conflict do nothing;"
Use that same UUID in KIMQUIZAK_OWNER_USER_ID. The UI says Host; existing environment variables, function names, and database identifiers retain owner for compatibility. No schema rename is required.
CLI login is for project administration and migrations; app login is for the host session. Do not put CLI credentials in Vercel. For future schema changes, add migration files and run db push. If you applied SQL manually, reconcile migration history first. Re-running the initial migration resets table grants, and a remote db reset can remove data. See Supabase migrations.
Put local values in the ignored .env file. Add production values in Vercel → Project → Settings → Environment Variables → Production.
| Variable | Local development | Vercel production |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | Your Supabase project URL | Your Supabase project URL |
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY | Your publishable key | Your publishable key |
KIMQUIZAK_OWNER_USER_ID | Your host's UUID | Same host UUID enrolled in the database |
GOOGLE_MAPS_API_DEV_KEY | Restricted localhost key | Leave unset |
GOOGLE_MAPS_API_PROD_KEY | Usually leave unset | Restricted production key |
GOOGLE_MAPS_API_KEY | Optional override; usually unset | Optional override; usually unset |
A non-empty GOOGLE_MAPS_API_KEY takes precedence over both environment-specific keys. Otherwise development uses DEV_KEY, and production uses PROD_KEY without falling back to the development key. A local production build also uses PROD_KEY.
Restart local development after changing .env. Redeploy after changing Vercel variables; NEXT_PUBLIC_ values are embedded at build time. Keep .env, CLI credentials, and personal exports out of Git. The ignored private/ directory is convenient local storage, not encryption or login-protected storage.
npm run build build command. Vercel manages minor and patch updates within the selected major version; see its runtime version policy.Vercel deploys committed source from the selected Git revision. Unpushed local changes are not included when redeploying an existing Git deployment. Database migrations run separately through the CLI; Vercel builds do not apply them automatically.
See Vercel environment variables and Node.js versions.
/api/maps/config and /api/quizzes should return 401 without a host session.sequenceDiagram
actor Host
participant Browser
participant App as KimQuizak on Vercel
participant Auth as Supabase Auth
participant Google as Google Maps
Host->>Browser: Sign in with app email and password
Browser->>App: Submit login
App->>Auth: Authenticate
Auth-->>App: Session tokens
App-->>Browser: Set session cookies
Browser->>App: Open Street View and request Maps key
App->>Auth: Verify current user
Auth-->>App: User identity
alt Identity matches configured host
App-->>Browser: Restricted Maps key
Browser->>Google: Load Street View using key
Google-->>Browser: Interactive panorama
else No valid host session
App-->>Browser: 401 - login required
Browser-->>Host: Setup infobox and login link
end
Cloud snapshots are separate from the working quiz:
flowchart LR
A[Browser working quiz] -->|Save privately: host chooses| B[Supabase archive with RLS]
B -->|Open in editor: confirm replacement| A
B -->|Download| C[Local JSON file]
C -->|Upload backup| A
A -->|Download backup| C
For troubleshooting and the migration workflow, see host setup notes. An infobox after login can indicate a missing key, incorrect domain/API restrictions, disabled billing, a network failure, or unavailable panorama imagery; check the displayed error and browser console.
Quiz edits stay in this browser unless you export a file or deliberately save a cloud snapshot.
| Data | Default storage |
|---|---|
| Questions and their uploaded images | IndexedDB, in the browser |
| Teams, host profile, scores, settings, turn order, and supported round progress | localStorage, in the browser |
| Downloaded backups | JSON files saved to your device, including images |
| Explicitly saved private snapshots | Supabase, accessible through the configured host account |
The local storage implementation is in questionStorage.ts and usePersistentState.ts. Existing questions stored in localStorage are migrated to IndexedDB when read.
Cloud snapshots are separate copies, not automatic synchronization. Host → Save this browser’s quiz privately uploads a snapshot. Opening one asks before replacing the browser's quiz. Deleting one removes the cloud copy, not the local working quiz. The API accepts snapshots up to 3 MB and lists the latest 100; larger quizzes can use file backups.
Signing out does not erase browser-local quiz data. On a shared device, use Clear everything in the local archive when finished. Clearing browser storage also removes local quizzes, so export a backup if you need to keep them.
Add example data replaces the current browser quiz with default_questions.json. Its players and relationships are fictional. It includes examples of ten question types; Connections is supported by the app but is not included in this fixture. The zoom-reveal image is a CC0 photograph; its source and license are recorded separately.
Keep personal exports out of Git. The ignored private/ directory and kimquizak-backup-*.json filenames help prevent accidental commits; they do not encrypt or password-protect files.
npm run dev – start the Turbopack dev servernpm run dev:webpack – start the Webpack dev server as a fallbacknpm run build – production buildnpm start – serve the production build locallynpm test – regression checks for quiz rules, persistence, audio, and host accessnpm run test:browser – Playwright browser regression suite (see docs/regression-review.md for setup)npm run lint – lint with Next/ESLint defaultsnpm run audit:privacy -- --history – scan public files and local Git history for selected credential patterns, private file paths, and raster pictures (including those embedded in quiz JSON); see privacy review for findings and limits.public/team-animals/NOTICE.txt.