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,即可驗證所有權並自行管理介紹。
一分鐘完成驗證ZENITH//UMBRA - original anime hero shooter: 10 heroes, rival counters, piloted mechs, co-op campaign vs space colossi. Browser + Windows.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
Ten heroes. Two oaths. One eclipse.
An original anime-inspired hero shooter for PC. The full game is the Windows app; the browser build is a light demo.檢視完整 README ↗Ten heroes. Two oaths. One eclipse.
An original anime-inspired hero shooter for PC. The full game is the Windows app; the browser build is a light demo.
One codebase, two editions (src/edition.ts):
Full: Windows app (download). Includes:
docs/BALANCE_PATCH.md): role passives (tanks build and give less ultimate, damage heroes cut healing on hit, everyone regenerates 20 HP/s after 5 s), sub-roles (Stalwart / Bruiser / Flanker / Sharpshooter / Medic / Tactician), 30% armor, half ult charge through temporary health, and ultimate costs in the Overwatch bands. The web demo shares the numbers.ANIMATION_NOTES.md), Stadium and the Starfall campaign.Lite: the website. You play vs AI on the original five arenas with the original ten heroes, using procedural animation and legacy single-round rules. npm run build runs scripts/lite-strip.mjs, which removes everything desktop-only from dist/. The URL can't switch the site to the full edition. On the dev server, ?edition=lite previews it.
10 heroes: the Zenith Vanguard (heroes) against the Umbra Syndicate (villains). Each side has one giant piloted mecha tank (Tenkai-Oh, piloted by Haruto Daimon; Gorgoth, piloted by Warlord Vorn), two supports (one of them flies), and two DPS.
Rival counters: every hero has a rival on the other team, and each of them carries an ability built to counter the other (Dawn Anchor vs Abyss Charge, Silence Aria vs Constellation Link, Warding Seal vs Severing Fang, Thunder Parry vs Chain of Oblivion, Revealing Dawn Arrow vs Stitched Decoy). The HUD calls out every counter as it happens.
5 story maps + Training Grounds: Amatsu Sky Shrine, Neo-Kurogane Rainport, Hangar Zero, Crimson Moon Cathedral, Eclipse Rift. The Zenith Academy Proving Grounds adds training dummies, sentry walkers and aerial drones.
Modes: Play vs AI in two flavours, as in Overwatch 2: Normal (first person, 5v5 on the capture point) and Stadium (third person, first to 4 round wins, with an Armory between rounds where you spend the cash you earned on weapon / ability / survival items and pick a hero power on rounds 1, 3, 5 and 7). Also Training, Watch AI vs AI, the AI Test Lab, and the Operation Starfall campaign.
Campaign: third person, 5 levels, 5 giant space-robot bosses, and the alien scientist Archon Qel'Varis as the final boss. Storyboard cinematics. Play solo with AI wingmates, or online co-op for up to 4.
Hero Viewer & Skins: rotate and zoom any hero, villain, pilot or boss, preview animations, and equip one of 5 skins per hero (Classic → Legendary).
Settings opens an Overwatch 2-style Options screen. Every change applies live and is saved; each tab has RESTORE DEFAULTS.
The ability bar shows the keys you actually bound.
WASD move · Space jump / hold to fly (Mirei, Nocturne) · F swoop to an ally (Mirei; Space mid-swoop = slingshot, Ctrl = superjump) · LMB fire · RMB secondary · Shift / E abilities · Q ultimate · R reload · V first/third person (Normal is always first person, Stadium always third) · Tab scoreboard / your stats · Esc pause · H switch hero (training)
npm i && npm run dev, then open /play.html. The landing page with the animatic is /.cd desktop && npm i && node build.mjs --installernode tests/e2e/audio_check.mjs 5199 gantetsu hanabi (bank loaded, which ids play recorded vs synth, threat mix), node tests/e2e/audio_glitch.mjs 5199 hibiki kagura 25 (the output meter counts clipped samples and clicks in a live match; it self-checks by injecting a click), node tests/e2e/vfx_wall.mjs 5199 gantetsu, node tests/e2e/hibiki_play.mjs 5199, node tests/e2e/tomoe_play.mjs 5199node tests/e2e/settings_ui.mjs 5199. It covers every tab, real key/mouse rebinding through input capture, per-hero overrides, the live-applied video/sound/accessibility options, persistence and restore defaults.node tests/e2e/hero_look.mjs tomoe e 0.25,0.45 30 (large viewer shots at chosen moments of a state)node tests/e2e/ui_tour.mjs 5199 (menus, a live match, Tab screen, Mikoshi Rush, results, every map, the lite title), node tests/e2e/lite_check.mjs 5199 (web edition)npm test (map / Control / Mikoshi Rush / health pack / rank rules in tests/unit/modes.test.ts, hero kits in kit.test.ts, headless 5v5 simulations of every map + campaign levels beaten by an AI squad), node tests/e2e/lab.mjs <url> (AI Test Lab report: animation states, foot sliding, wall penetration, physics, effects, sounds, perf)api/net.js is a Node function on Vercel. It handles presence, squad listing and WebRTC signalling for the campaign co-op, for both the web build and the Windows app. Gameplay traffic goes peer-to-peer over WebRTC data channels, with a host-authoritative simulation and client-side prediction. If a direct connection can't be made, traffic is relayed through the Vercel node at a reduced rate. Lobby state lives in the function's memory, or in Upstash Redis when KV_REST_API_URL / KV_REST_API_TOKEN are set. If the node can't be reached, the client falls back to public MQTT brokers.
The Windows app plays a recorded bank (public/sfx, about 14 MB): 138 sound effects and 507 voice lines. They are mixed the way Blizzard described Overwatch's "Play by Sound" design (GDC 2016):
Voice lines are stimulus-driven. Each stimulus has a category, and the category decides who hears the line:
Lines also follow priority, cooldown and interrupt rules. Mech pilots speak over cockpit radio, and an announcer calls the objective. With subtitles on, lines show on screen with the speaker's name.
Glitch safeguards. No crackles, no scratchy audio:
assetgen/audio_qa.py, which checks clipping, true peak, saturation, LPC click detection, edges, dropouts, DC and loop seams.How it was made:
assetgen/modal_sfx.py, audio/sfx_list.py, audio_finish.py).assetgen/modal_voice.py, audio/voice_lines.py). Newer heroes run the same pipeline on Kaggle (kagglevoice).assetgen/kagglesfx/kagglesfx.py).src/audio/Sfx.ts.assetgen/ is the whole pipeline:
kaggle_run.py concepts|models2|campaign).kaggle_run.py trellis|trellis2).blender/rig_hero.py):
blender/weights.py) when heat fails.src/render/Animator.ts) layers a mocap clip library over a procedural base:
public/anim/): Quaternius Universal Animation Library 1 & 2 (CC0) and Mixamo gap-fillers, retargeted on load onto every hero (see Animation library below): 8-way idle/walk/jog/sprint blend space, jumps, deaths, hit reactions, melee combos one hit per swing, punches, rolls, parkoursrc/render/FirstPerson.ts): each hero's own model as a viewmodel, with Blender-authored per-hero clips where they exist and a procedural personality per hero otherwisebuild_assets.py / publish_2d.py produce the web tier (Draco, WebP) and the desktop tier.The hero-shooter rebuild (current heroes): every hero was rebuilt for a polished stylized team-shooter look - adult heroic proportions, clean bevelled shapes, painted colour blocks, expressive faces:
modal_restyle.py re-renders each hero's concept with Qwen-Image-Edit-2511 (Apache-2.0) on a Modal A100: same
character, outfit, colours and weapon, in a clean A-pose for rigging (--seeds N candidates, picks go in work/ow/pick).modal_trellis2.py: TRELLIS.2 at its highest setting (1536 cascade, bf16, 4K PBR bake, remeshed) on a Modal A100.ow_finish.py: the face from the 4x Real-ESRGAN concept (modal_upscale.py) projected onto the head (facebake.py),
then blender/owpaint.py bakes occlusion, painted edge highlights and a head-to-toe value gradient into the albedo.build_assets.py --unirig: MediaPipe rig (rig_hero.py, 45k tris / mechs 70k), then UniRig (MIT) skin weights
predicted for that skeleton on Modal (modal_unirig.py -> blender/apply_skin.py), then web (2K) / desktop (4K) GLBs.bake_fp.py: every hero's Overwatch-style first-person clip set (blender/fp_choreo.py -> blender/fp_arms.py).Handoff notes, including measured data, open work and pitfalls: ANIMATION_NOTES.md.
The clips aren't in the repo. Download them yourself (itch.io / Adobe login), pack them, and the game picks them up:
Get UAL1 and UAL2 from quaternius.itch.io/universal-animation-library(-2) (glTF). Optionally add Mixamo clips as FBX Binary, Without Skin, 30 fps, In Place in one folder.
blender -b -P assetgen/blender/anim_pack.py -- --ual1 UAL1.glb --ual2 UAL2.glb --mixamo mixamo_fbx/ --out public/anim removes the meshes, writes UAL1.glb / UAL2.glb / mixamo.glb and adds them to public/anim/manifest.json. Use --only "Idle|Jog|..." to trim the set.
That's all. On load, src/render/Retarget.ts maps any humanoid skeleton by bone name and hierarchy: UAL, Mixamo, Rigify, Biped, old Quaternius; T-pose or A-pose; any units, facing or up axis. It bakes each clip to rig-independent poses: bone directions plus torso rotations, in leg lengths. src/render/ClipLibrary.ts then sorts them into slots by name. Locomotion is sorted by the direction and speed it actually travels, measured from the planted feet, so pack naming doesn't matter. Mirroring and time reversal fill in missing strafe and backpedal directions. Pin or exclude clips with "slots" / "exclude" in the manifest. ?anim=procedural turns the library off.
Hero first-person arms (the part that gives each hero personality): blender -b -P assetgen/blender/fp_arms.py -- --hero raijin --model public/models/raijin.glb --setup work/fp_raijin.blend builds an authoring scene on the hero's rig. The camera is the in-game eye, and IK hand/elbow controls come with a starter fp_idle / fp_fire / fp_alt / fp_melee / fp_reload / fp_ability1 / fp_ability2 / fp_ult / fp_hit / fp_land set. Polish the actions in Blender, then blender -b work/fp_raijin.blend -P assetgen/blender/fp_arms.py -- --hero raijin --export public/anim bakes them onto the arm bones and registers fp_raijin.glb.
Broken auto-rigged arms: if a hero's arm joints landed inside the chest (a held weapon or long sleeves confuse the detector), blender -b -P assetgen/blender/fix_arms.py -- --glb <hero>_plain.glb --out fixed.glb --hero <id> --test work/<id> moves the shoulder/elbow/wrist joints from assetgen/blender/arm_fixes.json (front-view x/z). It re-weights only the arms, binds a held weapon fused into the mesh rigidly to the hand, keeps every other weight, and renders deformation tests. Publish with npx @gltf-transform/cli optimize fixed.glb public/models/<id>.glb --compress draco --texture-compress webp --texture-size 1024 --simplify false. Raijin's arms were fixed this way.
Credits when shipping clips: Universal Animation Library 1 & 2 by Quaternius (CC0); Mixamo clips are free to use in games under Adobe's terms (don't redistribute them as raw animation files).
Tests: npm test covers retargeting accuracy across rig styles, clip analysis, the blend space and slots, plus foot sliding in a 60 fps bot match with clips against procedural. npm run anim:fixtures writes GLB test packs, and node tests/e2e/anim.mjs http://localhost:5199/ checks the library, the AI Lab and the first-person arms in the browser.
Sound is fully procedural WebAudio. No audio files are used.
Third-party models used in the pipeline: SDXL (CreativeML Open RAIL++-M), Qwen-Image-Edit-2511 (Apache-2.0), TRELLIS / TRELLIS.2 (MIT), UniRig (MIT), Real-ESRGAN (BSD-3), BiRefNet via rembg (MIT), MediaPipe Pose (Apache-2.0), rembg isnet-anime (MIT), DINOv3 via timm (DINOv3 License).