Underground 2 Revived
Chrome과 Firefox에서 Need for Speed Underground 2를 WebGPU로 두고 팬 프로젝트입니다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Read the machine. Wake the block. Crack the Underworld. Don't become it.
A cooperative game for 1–5 players about the hidden cost in every deal: the payday loan, the rent-to-own couch, the "free" first month. Learn to read the second number, teach your whole block to read it, and drag the one machine behind them all into the light. Set on the West Side of Dayton, Ohio, and built from Black American culture.
This repo holds everything: the website where you play it online, and the game itself (rules engine, rulebook, print-and-play kit, campaign and design docs).
| Where | What |
|---|---|
| (this folder) | The online game: a Next.js website. Play it in a browser on one device passed around the table. |
game/ | The game: the rules engine (Python, the source of truth), the rulebook, the balance tester, the terminal edition, the print-and-play PDFs, the campaign and the design docs. Start with game/README.md. |
You need Node.js 20 or newer.
npm install # first time only
npm run dev # then open http://localhost:3000
To run the production build instead: npm run build && npm start.
First time? Choose Learn to play on the home page. A four-panel comic tells the story in about 30 seconds (the block, the deals, the Machine, your mission); it opens before every guided game, the first time you play on a device, and any time from Story in the game's header. It starts a guided three-player Block Party (the 25-minute intro: 3 districts, 8 rounds, no roles) with the Coach: on every decision, the Coach glows on the move it would make and says why, and each rule is explained the first time it comes up. You can always choose your own move.
En español. The whole site plays in Spanish: the English / Español switch at the bottom of every page (kept on the device; a link with ?lang=es opens in Spanish, and each phone at a table can pick its own). Every card, chapter, the game log, the Coach, the teacher's guide and the rulebook are translated, with one glossary for every game word (game/i18n/GLOSSARY.md). Print: game/RULES.es.md, game/The_Second_Number_PRINT_AND_PLAY_ES.pdf, game/The_Second_Number_TEACHER_GUIDE_ES.pdf. How it works: the English string is the key; card text lives in game/i18n/es_*.json (python3 scripts/i18n_extract.py --check reports coverage; npm run content merges it), the site's own words in src/i18n/es/, and the log is translated line by line at display (src/i18n/log.ts), so the engine, saves and online play stay language-free. tests/i18n.test.ts fails if a card or a fixed site string has no Spanish. A native speaker's read before print is still on the list.
Hearing from players. At the end of every game an optional How did it go? card asks three taps and one sentence, and adds how the game went (no names). Answers go to a Google Sheet you own once you connect one (about 5 minutes: game/FEEDBACK.md, then set NEXT_PUBLIC_FEEDBACK_URL); until then they stay on the player's device.
Sound and access. The game has sound (made in the browser, no audio files; 🔊 in the game's header mutes it). It plays by keyboard alone (a Skip to your move link, visible focus everywhere), reads out each move for screen readers, and has Plain cards for anyone the red-lens effect doesn't work for. District colors pass a color-blindness check and each district has a symbol ($ ⌂ ⚒ ✚ ✎), so color is never the only cue. Every page passes an axe accessibility audit.
New players: game/The_Second_Number_HOW_TO_PLAY.pdf is the easy guide, the rules in plain words with examples and a cheat sheet (source: game/HOW_TO_PLAY.md; rebuild with python3 game/print_kit/build_guide.py). How to play on the home page has the short rules; game/RULES.md has the full rulebook. Prefer paper? Print game/The_Second_Number_PRINT_AND_PLAY.pdf. For the box, game/The_Second_Number_WHERE_NEXT.pdf is the Where it goes next card (English and Spanish, four to a sheet), with a QR code to getcivicarmor.com/next (rebuild with python3 game/print_kit/build_where_next.py). Endless deals on the home page rolls a fresh deal every press, for practice and classrooms; Read your own deal works out the second number of a real offer, on the device only; Your City editions set the game on your own side of town (your districts, gathering places, history and real help; see game/YOUR_CITY.md); the Teacher's guide (/teacher/guide, and game/The_Second_Number_TEACHER_GUIDE.pdf) fits a game into one class period with learning goals and questions for after; the Teacher's view adds up a class's games from the result codes tables copy at the end of a game (no accounts, nothing uploaded); ties the game to the novel and describes the School Edition.
How it connects: phones talk directly to the table device (WebRTC, through PeerJS). PeerJS's free public server only introduces them, so there's nothing to sign up for or run. The table device is the referee: phones send moves, it checks each one and passes it on, and every device replays the same moves (src/net/). Most home and phone networks connect fine; a few strict networks (some workplaces and schools) block direct connections, and then playing on one device still works. To use your own PeerJS server, add ?peer=host:port to the page address.
Every page is static (no server code, no database), so it runs on any free host. The plan is to serve it at play.getcivicarmor.com, beside the Civic Armor hub at getcivicarmor.com (hub/, see hub/README.md).
Cloudflare Pages (free, and allowed for a site that sells things):
npm run build:static. Build output directory out.SITE_URL = https://play.getcivicarmor.com (so shared links show the preview card). Optional: NEXT_PUBLIC_FEEDBACK_URL (game/FEEDBACK.md) and NEXT_PUBLIC_HUB_URL if the hub isn't at getcivicarmor.com yet.*.pages.dev link in a few minutes; every push to main updates it.play.getcivicarmor.com. With the domain's DNS on Cloudflare, it adds the record itself.npm run build:static writes the whole site to out/ as plain files, so any static host works (Netlify: same build command, publish directory out).
Vercel also works with no settings at all (import the repo, press Deploy), but its free plan is for non-commercial sites only; selling the book or the game from it needs Vercel Pro.
The links out of the game (the novel, The Third Option, the email list) all live in src/links.ts.
The build copies the PDFs in game/ into the site (scripts/copy_pdfs.mjs), so the print-and-play kit and the teacher's guide download from the live site at /The_Second_Number_PRINT_AND_PLAY.pdf and /The_Second_Number_TEACHER_GUIDE.pdf.
The Python engine (game/sn_engine.py) is the source of truth: the balance tester and rule checks run against it. The website uses a TypeScript port (src/engine/engine.ts) that must replay the Python engine's games exactly.
| Command | What it does |
|---|---|
npm run content | Re-export every card, place, scenario, chapter and tuning constant from game/ to src/content/content.json. |
npm run golden | Record 63 complete games from the Python engine (all modes, player counts, bot styles, scenarios and Owners) to tests/golden.json. |
npm test | Replay every golden game in TypeScript (each log line and the final state must match), 38 tests that drive the browser turn flow through whole games, and 5 Coach tests: it never changes the game or draws a card, never peeks at hidden layers, recommends only legal moves, and a table that follows it wins far more often than the default bot. |
npm run lint / npm run typecheck | ESLint and TypeScript. |
After any art change: with the site running, node scripts/render_art.mjs http://localhost:3000 captures the drawn art from the /art page into game/print_kit/art/ (needs Playwright), then python3 game/print_kit/build_print_and_play.py rebuilds the PDF.
After any rules or card change: edit the Python in game/, then run npm run content, npm run golden and npm test. If a test fails, mirror the change in src/engine/engine.ts.
| Path | What |
|---|---|
app/ | Website pages: home, /play, /learn (the guided game; ?seed= replays one), /join (a phone joining a room), /how-to-play, /teacher and /teacher/guide. |
src/engine/ | The rules engine (TypeScript port), its content types and the shared RNG. |
src/game/session.ts | The round-by-round flow: who acts next, and what the table is asked. |
src/net/ | Online play: the room's rules (who may make which move) and the PeerJS connection. |
src/game/moves.ts, save.ts | Every change to a game as a move; a game is its seed plus its moves, which is what a save holds. |
src/game/coach.ts | The Coach: the recommended move with its reason, and the lessons, all read-only. |
src/ui/ | The board, players, deal card and lens, action panels, the Coach box, the story comic, end screen. |
src/ui/art/ | The drawn district scenes and role portraits, and manifest.ts, where commissioned art drops in (brief: game/ART_BRIEF.md). |
scripts/ | Content export, golden-game recorder, the Python twin of the shared RNG. |
tests/ | Parity, session and Coach tests. |
game/ | The game itself (see above). |
game/ART_BRIEF.md), and Spanish versions of the chapter envelopes.Part of the Individual Democracy / Civic Armor universe.
game/BOOK_ONE.md