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,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗the search for sunrise in 2049 Mumbai
Mumbai, 2049. Hundreds of towers, thousands of flyovers and walkways, stacked so densely that the ground never sees the sun. On the morning of a festival of lights, a five-level flyover collapses onto the slum beneath it. Setu, eight years old and asthmatic, who has never seen a sunrise, falls with the maintenance lift into the metro tunnels. His sister Mithi is eighteen and blind. She carries his pills and inhaler, and she hears the city the way other people see it.
Grahan is a real-time, first-person search-and-survival game that runs in a browser. You play Mithi. Find Setu before his breath runs out, survive the city (feral dogs, drones and police, collapsing walkways, smog, the dark), learn what the deep construction under the city has done to the water table, warn the authorities, and bring Setu to the Sunrise Bridge on the east edge for dawn.
It is based on Grahan (Children of the Sun), a story by Sarat T. Rao, and a concept deck by Sarat Talluri Rao and Mohammed Ali Rukadikar. The sources are in docs/.
Sound is how Mithi sees. Headphones are recommended.
The in-game "How to play" screen has the same cards with pictograms.
| Keyboard and mouse | Touch | |
|---|---|---|
| Move | W A S D | left thumb: floating stick (push it to the edge to sprint) |
| Sprint | Shift | stick to the edge |
| Look | mouse (pointer lock) | drag anywhere on the right |
| Jump | Space | jump button |
| Use, talk, read (hold to dig) | E | E button, or tap the prompt |
| Sing / second sight | Q (hold 2 s) | Q button (hold) |
| Switch character | Tab | switch button (after Jeetu joins) |
| Third person | V | V button |
| Map (full city map, pauses the game) | M (Esc or M closes it; 1-5 or the arrows change level; + - zoom; C centres on you) | tap the little map, or the map button when the minimap is off |
| Pause | Esc | pause button |
Conversation answers and cards are clickable and tappable. The touch layer appears on touch devices (or after the first touch).
Pause menu or title screen, saved in localStorage: master, music, effects and voice volume; PA voice; captions for sounds; mouse and touch sensitivity; invert Y; field of view; quality (resolution and draw distance); reduce flashing (also on by default when the OS asks for reduced motion); the minimap (on or off); default view; run length (24, 30, 45 or 60 minutes, applied on the next run).
There is no build step and no dependency to install. Serve the repository root with any static server and open index.html:
python3 -m http.server 8000
# then open http://localhost:8000/
It needs a browser with WebGL 2 and Web Audio: any current Chrome, Edge, Firefox or Safari, including iPad and iPhone (iOS/iPadOS 15 or later). Touch controls turn on automatically on touch screens. Nothing is loaded from the network (three.js is vendored in vendor/, all sound is synthesised, all textures are procedural), so it also runs offline from a static host.
| Parameter | Effect |
|---|---|
seed=N | Seed for the run (dangers, vendor offers, Setu's route, unstable walkways). The map is always the same. Default: random. |
minutes=N | Total real minutes of the run, first light to the flood. Overrides the run-length setting. |
autostart=1 | Skip the title and the pointer-lock requirement and start playing at once (headless tests need it). The opening cutscene is skipped too, unless intro=1. |
intro=1 | Play the opening collapse cutscene even with autostart. |
debug=1 | Expose window.__grahan (state, teleport, set time, spawn things, ...) and the corner readout. |
arena=1 | Load the small test arena instead of the city. |
hazards=0 | Switch every hazard off (dogs, drones, guards, smog, flood, collapses). |
mute=1 | Start with the sound muted. |
touch=1 / touch=0 | Force the touch controls on or off. |
For example index.html?seed=7&minutes=45&debug=1.
index.html entry: the static title screen, the HUD container, a boot watchdog
src/main.js boot, system registration, the fixed-step loop
src/game.js the shared Game object (scene, camera, events, rng, systems, modes)
src/debug.js the debug / test API (window.__grahan with ?debug=1)
src/core/ events, rng, params, input (keyboard, mouse, pointer lock, touch), physics, player
src/world/ the city as data (map.js) and everything that builds it: structures, props, rail (the Harbour Line's tracks, platforms, fence), sky, sea,
lifts (capsules: solo, family, public and freight classes, solar battery), the flyover network (network.js is the data, netcheck.js its
self-check, network-build.js its piers, footpaths and vaulted undersides), gates, sunlight, fx
src/characters/ procedural low-poly people
src/systems/ clock, health, Setu, vendors, hazards/, audio/ (a procedural Web Audio engine), senses/ (sing, ripples,
visions), story/ (cast, dialogue, objectives, fragments, cinematics), endings,
transit/ (the Harbour Line trains), crowds/ (instanced pedestrians and traffic), lifts/ (floor panels and charge, the capsule fleet,
capacity: who fits in the car and who waits for the next one)
src/ui/ HUD, messages, dialogs, screen effects, title screen, pause menu, settings, how to play, touch controls, the minimap, the full map and the warmth cue
(map.js, minimap.js, fullmap.js, maprender.js, mapdata.js, warmth.js)
src/styles.css the whole stylesheet (OK Computer language: pale blue-white thin type, safety-card pictograms, scrawls)
tools/smoke.mjs headless test runner (Playwright) tools/shots*.json screenshot tours with assertions
tools/audio-check.mjs offline render of every synthesised sound tools/check-network.mjs self-check of the flyover network (no browser)
docs/PLAN.md the design spec and the per-phase progress log
docs/*.pdf the story and the pitch deck
vendor/ three.js r160 (MIT)
The smoke tool serves the repository, opens the game in headless Chromium (software WebGL), runs the steps of a "shots" file, saves a screenshot per step into shots/ (git-ignored), and fails on any console error, page error or failed request. Steps can run JS in the page (eval, mostly through the debug API), click, tap, press keys, drive raw touch points, resize the viewport and reload.
npm i -g playwright && npx playwright install chromium # once
node tools/smoke.mjs --shots tools/shots.json --wait 6000 # the city tour (about 12 minutes under SwiftShader)
Playwright is found through NODE_PATH or the global npm root.
| Flag | Meaning |
|---|---|
--shots file.json | the steps to run |
--wait ms | wait after the page loads |
--query "seed=1&..." | extra URL parameters |
--out dir | screenshot folder (default shots) |
--no-autostart | open without autostart=1, so the title screen shows |
--mobile | phone emulation (touch, 844x390; --orientation portrait for 390x844, or --viewport WxH) |
The tours: tools/shots.json (the whole city, level by level), shots-arena.json (the Phase 1 arena, --query "seed=1&arena=1"), shots-phase3.json (core loop), shots-phase4.json (hazards), shots-phase5.json (senses and sound), shots-phase6a.json and shots-phase6b.json (cast, objectives, fragments, cinematics; shots-phase6b-intro.json with --query "seed=1&intro=1"), shots-phase9a.json (the flyover web and the capsule lifts: money shots from the streets, the triple stack, traffic on the flyovers, a long walk over the skywalks, each capsule class, the seat rule, the maps and the draw-call and triangle worst cases; built by tools/build-phase9a.mjs), shots-phase8b.json (Mumbai signage, the Harbour Line, crowds, lifts and the draw-call worst case; built by tools/build-phase8b.mjs), shots-phase8a.json (the minimap and the full map on every level and on phone-sized screens, the warmth cue and its bearing, sun beacons, painted arrows and signs, the minimap setting; built by tools/build-phase8a.mjs) and shots-phase8a-mobile.json (real touch: tapping the minimap, the tabs, zoom and pan; run with --mobile --query "seed=1&touch=1"), shots-objective-map.json (where the current objective is: the HUD line, the minimap marker and rim arrow, the full map's star, ghost and "Where to go" card, on desktop and phone-sized screens), shots-phase7a.json (title, how to play, settings, pause, HUD, dialogs and endings on desktop; run with --no-autostart) and shots-phase7a-mobile.json (touch controls and the phone layouts in both orientations; run with --mobile --query "seed=1&touch=1"). Most steps assert with ok(condition, message), so a broken behaviour fails the run, not just the picture.
node tools/audio-check.mjs renders every synthesised sound offline and flags silence, NaN and clipping (--wav dir writes WAV files to listen to).