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 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
A soccer management sim that runs entirely in your browser, in the spirit of
Basketball GM. Take over a club and run it season
after season: pick the XI and the formation, work two transfer windows, develop
an academy, keep the books straight, and chase promotion, the league, a
continental cup and the World Cup.
Play it: worldsoccersim.org — no account, no
download, no server. Every save lives in your own browser's IndexedDB.檢視完整 README ↗A soccer management sim that runs entirely in your browser, in the spirit of Basketball GM. Take over a club and run it season after season: pick the XI and the formation, work two transfer windows, develop an academy, keep the books straight, and chase promotion, the league, a continental cup and the World Cup.
Play it: worldsoccersim.org — no account, no download, no server. Every save lives in your own browser's IndexedDB.
Math.random() in the sim.
The same seed gives the same world, which is what makes the balance audits in
scripts/ and the validation gates in test/validation/ possible at all.docs/eafc-import.md.)The game explains itself in-app at /manual, and /changelog lists every
player-visible change with dates.
Needs Node 20+.
npm install
npm run dev # Vite dev server
| Command | What it does |
|---|---|
npm run dev | dev server |
npm run build | production build (the worldsoccersim.org target) |
npm test | full vitest suite (164 files) |
npm run test:watch | vitest in watch mode |
npm run typecheck | tsc --noEmit |
npm run cli | headless sim harness, for audits |
There are two embedded build targets besides the default —
npm run build:itch and npm run package:crazygames — for platforms that host
the game inside an iframe at a path we don't control. docs/crazygames.md has
the runbook.
First npm test after a src/core change is slow. Generating a 320-club
world costs a few seconds and most test files want one, so worlds are cached on
disk and keyed by a hash of all of src/core. A core edit buys one rebuild
(~60s) and is free after that. SOCCER_GM_NO_FIXTURE_CACHE=1 skips the cache.
src/
engine/ the match sim — pure, no DOM, no storage
core/ league logic: season loop, progression, transfers, AI, cups, finance
db/ IndexedDB persistence + migrations + JSON export/import
worker/ web worker entry and its typed message protocol
ui/ React app (pages, components, LeagueContext)
test/
validation/ the Monte Carlo and multi-season gates
scripts/ audits, probes and one-off measurement tools (run with tsx)
engine/ and core/ import zero browser APIs, which is what lets the audit
scripts and CI run them in plain Node.
Two things are load-bearing and easy to break by accident:
rng
shifts every result downstream of it. New per-player traits and post-hoc
attribution must come off their own seeded stream.scripts/, not just a green test run.Both are covered properly in CLAUDE.md, which you should read before changing sim code.
CLAUDE.md is the current record — architecture, invariants, and a feature
ledger explaining what each system is, where it lives, and its non-obvious
traps. Everything else is narrower:
| Doc | What it is |
|---|---|
SOCCER_GM_SPEC.md | The original 2026-07 build brief. Historical — the engine spec and validation gates still hold; its world and roadmap sections describe a game that diverged. Its header box lists where. |
DESIGN.md / PRODUCT.md | The visual design system and the product brief. src/ui/styles.css is the source of truth for tokens. |
docs/finance-design.md | Design intent of the finance layer. |
docs/transfer-mobility.md | Postmortem: how the country strength ladder once inverted. |
docs/save-performance-plan.md | Why saves are split across IndexedDB stores. |
docs/player-save-findings.md | A live work queue built from real player saves. |
docs/eafc-import.md | The dev-only EA FC roster converter. |
docs/crazygames.md | Building and shipping the CrazyGames bundle. |
docs/analytics.md | PostHog pointers; src/ui/analytics.ts owns the event set. |
CI runs two jobs: a typecheck, and the suite sharded across 6 runners (the wall-clock is dominated by a handful of full-world multi-season sims, so sharding beats a single machine).
test/validation/ holds the realism gates — goals per game, draw rate, table
spread, top scorer, multi-season integrity. They are bands, not exact values,
and the standing rule when one fails is fix the statistic, not the band.
That lesson has been learned four separate times and each instance is written
up in CLAUDE.md.
No licence file, so default copyright applies: all rights reserved. The source is public to read, not to reuse.
The engine takes structural inspiration from ZenGM's hockey sim (the tick loop, the gate cascade, composite ratings), whose source is readable but not open source. Every line here is original, and it needs to stay that way — don't copy code, constants, structure or comments from that project.