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.