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。 以下為已儲存的摘錄。
Play it now: https://shengji.fly.dev — solo vs bots or share a room code
with friends (phones: landscape).
Full-stack implementation of the classic Chinese partnership trick-taking game:
Python rules engine + a learned-model-guided Monte Carlo AI + FastAPI
multiplayer server + React web UI with Mandarin voice announcements.
The production bot — release 28 (2026-09-16)
One checkpoint, JS-M1 (a5248cc5, served as the NumPy package
js-m1-0d17fd03.npz), does two jobs on every play decision:檢視完整 README ↗Play it now: https://shengji.fly.dev — solo vs bots or share a room code with friends (phones: landscape).
The classic Chinese partnership trick-taking game: Python rules engine, Monte Carlo AI guided by a learned model, FastAPI multiplayer server, and React web UI with Mandarin voice announcements.
Live: release 48 (since 2026-10-24 10:18 ET): release 46 with the S58 belief package, dtrx and the
guarded greedy-finished value leaf (lgf, lgfx, lgfd2000). Release 46 is the combo: belief-model worlds + exact
endgame at 7 cards + every-chance first-round value declaration, on release 45. Release 45 is the SMV3
outcome-head package smv3out-491ee4bf.npz in the one-ply policy/value search (64 worlds,
8 candidates) with five search rules (div, rc, tb, la, dtr), the value-guided trump declaration
(release 44) and the wide value-only bury (release 45). The model owns declaration, bury and card
play; the heuristic is the anchor and the fallback. Colour marks what release 46 added: violet belief,
berry exact endgame, blue declaration.
Rule tokens used in the figures and tables:
Served results (signed levels per round, 95% CI; indirect contrasts through a common MC-LCB control):
| change | against | result | reading | vs Sol, actor-only | vs PT-Sol |
|---|---|---|---|---|---|
| S58 belief + dtrx + guarded greedy finish (release 48) | release 46 | +0.0765 [+0.0571, +0.0958]; confirmation +0.0843 [+0.0575, +0.1111] | POSITIVE and CONFIRMED (r48cloud, r48confirm) | — | — |
| the combo (belief worlds + D7/X7 exact endgame + vdef) | release 45 | +0.2167 [+0.1923, +0.2412]; confirmation +0.2284 [+0.2046, +0.2521] | POSITIVE and CONFIRMED (v92combo45, v92c) | +0.55 [+0.25, +0.90] (S47) | pending (S47-PT) |
| wide value-only bury K=64 (release 45) | release 44 | +0.0488 [+0.0286, +0.0690] | POSITIVE, one ten-window screen on first-round deals, not confirmed (v76bwv44) | — | — |
| value-guided declaration (release 44) | release 43 | +0.0497 [+0.0379, +0.0615] first-round; +0.0352 [+0.0233, +0.0471] later-round | POSITIVE in both populations, ten windows each (v70vd43, v71vd43lr) | — | — |
| doomed-throw swap / re-select (releases 42, 43) | release 38 / 42 | interval spans zero | correctness fixes, no strength claim | — | — |
| div + rc + tb | release 36 | +0.0461 [+0.0242, +0.0681] | CONFIRMED, ten fresh windows (#676) | — | — |
| + la | div + rc + tb | +0.0106 [+0.0006, +0.0205] | POSITIVE incremental (not a confirmation): small, ten windows, lower bound near zero (#676) | — | — |
| SMV3 outcome head (release 36) | release 30 | +0.0393 [+0.0033, +0.0752] | predeclared confirmation (#663) | +0.45 [0.00, +0.80] (#355); 0.00 [−0.40, +0.35] (S47) | +0.30 [−0.20, +0.80] (#355) |
| policy/value search (release 29) | release 28 | +0.049 [+0.003, +0.095] | five windows; card play +0.086 [+0.042, +0.131] | +0.50 [+0.15, +0.90] (#355) | +0.45 [−0.10, +0.95] (#355) |
The two Sol columns come from a separate instrument. The release's recipe plays card play only against the GPT-5.6 Sol LLM opponent, on 10 deals × 2 mirrored roles. Actor-only Sol sees one seat's hand; PT-Sol sees every hand. Each cell is bot minus Sol in signed levels per round, with a deal-cluster 95% CI. These numbers are not on the screen scale and do not rank the releases (details).
The exact contract, the caveats on these reads, what was tried and not taken, and every earlier release: AI_POLICIES.md and its ladder. Rollback and gates: DEPLOY.md. Every screen: Atlas v2. Open work: the board issue (see AGENTS.md) and RL_PLAN.md.
The screen never plays the candidate against the release directly: both play the same fixed MC-LCB control on the same deals, and the result is the difference. That puts the two arms of one screen on one scale; rows of the ladder come from different eras and instruments, so read each alone. Confirmation runs when Jerry or the packet requires it.
# 1. Build the frontend (once, or after UI changes)
cd web && npm install && npm run build && cd ..
# 2. Run the server (serves the built UI at http://localhost:8000)
cd server && uv sync && uv run shengji-server
Open http://localhost:8000, create a room, add 3 bots (or share the room code
with friends on your network), and start. For frontend development, run
npm run dev in web/ (Vite on :5173, talks to the server on :8000).
Tests: cd server && uv run python scripts/test_checkout.py --engine pure -- -q.
The entrypoint anchors imports to its own checkout, prints the source and engine,
and checks both before pytest starts. It also works with a shared environment's
Python from another working directory; pass the absolute script path. Use
--engine compiled after building that checkout's extension; missing native
code fails instead of silently counting pure coverage. Pure mode unsets
SHENGJI_FAST (setting it to 0 is not sufficient).
For a small, model-free producer-to-consumer diagnostic rehearsal:
uv run python scripts/test_checkout.py --engine pure -- -q tests/test_m9_readout_persistence_roundtrip.py.
This exercises synthetic collection, persisted panels and final summarization;
it is not a real-model qualification or scientific run. Frontend checks:
cd web && npm ci && npm run lint && npm test && npm run build (from repo root).
Headless bot-vs-bot evaluation: uv run python -m shengji.ai.env.
House rules (v1): throws are checked against all three other hands with no 10-point penalty; pair obligations for multi-component throws use the pair-count rule.
server/shengji/engine/ cards, combos (tractor decomposition), legality, round, game
server/shengji/ai/ policies: heuristic.py, smart.py + memory.py (card-counting
heuristic), mcbot.py (the Monte Carlo search), cwv_numpy.py
(the Torch-free package runtime), refusal.py (refusal-aware
world sampling), registry.py (SHENGJI_BOT names are derived
from the fly.toml env, never hand-written)
server/shengji/train/ pv_search_policy.py + policy_value_search.py (the served play
search, value declare and wide bury), cwv_bury_policy.py (hybrid
bury), the shortlist-era bots, screens
server/shengji/rl/ encoders, action enumeration, the value/policy model, trainer
server/shengji/harvest/ self-play trajectory corpora (the training data)
server/shengji/eval/ diagnostic panels, readers and the tactical fixture runner
server/shengji/api/ FastAPI WebSocket server (rooms, bots, per-seat state)
server/scripts/ export_cwv_numpy.py, cwv_serving_gate.py, cwv_serving_smoke.py,
replay.py, xray.py
server/tests/ unit tests + randomized self-play soak tests
web/ React + TypeScript UI (Vite)
PROTOCOL.md WebSocket protocol contract
The engine is authoritative and UI-free; the server maps card instance ids to codes per seat so hidden information never leaves the server.
mc-s0-report-lcb: the bare MC-LCB search; the common control of every served screen and
the deep rollback.smart and heuristic: the hand-written baselines.Closed lanes (PUCT with the heads, root allocation, the BELIEF and privileged-teacher teachers, direct-Q, Suphx O0) are lessons in AI_POLICIES.md and RL_PLAN.md, not policies. The G1 grid trunk, a served null in gen 4, is back as the C14 training run (RL_PLAN "Planned work").
scripts/replay.py — render any room log (logs/<ROOM>.jsonl) as a full
transcript with all hands.scripts/xray.py / the in-game X-ray (press x; needs
SHENGJI_DEBUG_TOKEN) — what the bot sees and would play from any position,
on an isolated snapshot (the live bot's RNG is untouched). It decodes
shortlist-era records (W32 nominations, MC selection estimates, the report-gap
decision). For the pv-search bot it shows the pick and the bot's memory, not
the admitted candidates' value means.scripts/fetch_fly_logs.sh — stage, validate, refresh and hash prod logs.python -m shengji.rl.human_shards — build a replay-audited human play/bury
corpus (raw human choices are proposal data until counterfactually validated).| file | what it holds |
|---|---|
AI_POLICIES.md | production contract, measured policies, evidence and lane rules |
RL_PLAN.md | research plan, key learnings, measurement rules |
DEPLOY.md | release records, rollbacks, gates |
| GitHub issue #707 + topic issues | the live investigation board and work queue |
docs/atlas_v2/ | every screen since release 29 (registry.json) |
docs/scaling_log/ | every model with its offline metrics; engine and search speed (with issue #208) |
docs/EXTERNAL_SSD.md | what lives on the external SSD (corpora, backups) and its rules |
incidents/ / server/tests/ | postmortems; the validation suite |
AGENTS.md | execution discipline and agent orchestration |
HANDOFF_REVIEW.md | frozen authority markers (#674) |
PROTOCOL.md / web/README.md | wire protocol; client architecture |
BACKLOG.md | deprecated; see #707 |
docs_archive/ | compacted history: closed lanes, old designs, rotated ledgers |
Top-level documents hold only current project, operational or durable contract
surfaces. Completed one-off specs are summarized in their owner and moved to
docs_archive/.