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를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Prompt-driven 2D physics combat. You pilot a mechanical goblin ragdoll in an industrial arena against a mechanical spider. Type what you want ("give my goblin giant rocket boosters") and an LLM compiles it into a validated mutation plan built from a fixed library of physical components. The plan then plays as a cinematic: a schematic appears, parts fly in and bolt on, and the boosters ignite. A second model acts as the AI Director: it watches combat summaries and triggers countermeasures and arena events.
Stack: TypeScript · Phaser 4 (Matter.js physics) · three.js (lazy-loaded cinematic) · Vite · Node/Express · Anthropic SDK · Zod.
Four original fighters on one shared active-ragdoll rig, each with its own proportions, physics profile and special (F):
| Fighter | Profile | Special |
|---|---|---|
| Mech Goblin | balanced | Scrap Bomb |
| The Diva | fast, double jump | Sonic Shockwave (also shatters lasers) |
| Gadget Gremlin | tiny, armored | Pop-Up Dome (invulnerable, reflects) |
| Industrial Menace | huge, slow, 160 HP | Ground Pound |
Arena mode vs. the Arachnotron, with 5 challenges: Standard, Glass Cannon, Beat the Clock, Enraged Arachnotron, Factory Settings.
Character Lab: a passive, regenerating training dummy, a spec sheet with the live loadout, lab prompt chips, and a "take this build to the arena" button.
Mutation roulette: a slot-machine reveal of a curated, supported prompt, which then goes through the normal mutation pipeline.
Mutation components: rocket boosters (1–6), chain hammer (optional rocket assist), spring boxing glove (optional rocket assist), energy shield, spring legs, armor plating.
Three.js Mutation Chamber: a 3D cinematic of the validated plan, with the real executor running at its climax (see below).
AI Director with three personalities: Tactical Analyst, Engineering Inspector, Chaos Commentator.
Victory card and fast rematch: R rematch, B rematch with build, Esc fighters.
npm install
cp .env.example .env # optional: add ANTHROPIC_API_KEY for live AI
npm run dev # client on :5173 (proxies /api) + server on :8787
Open http://localhost:5173.
No API key? It still plays. Without credentials (or when a model call fails, times out, or returns invalid output) the server uses a deterministic keyword compiler and a rule-based director (shared/fallback.ts). If the browser can't reach the server at all, it runs the same fallback in-page. The HUD shows which path was used: SONNET, FALLBACK or CONSOLE on each timeline card, and OPUS · LIVE or LOCAL FALLBACK on the director ticker.
The LINK: line under the logo reports the server's verified state. At startup the server makes a no-token authenticated call (models.retrieve) and then updates the state after every AI request:
| Shown | Meaning |
|---|---|
LIVE AI · <models> | an authenticated API call has succeeded |
VERIFYING API KEY… | key present, startup check still running |
NO API KEY · LOCAL FALLBACK | no key configured |
AUTH FAILED (HTTP 401) · LOCAL FALLBACK | key rejected (401/403) |
AI ERROR · LOCAL FALLBACK | last call failed for another reason (timeout, 5xx, invalid output) |
SERVER OFFLINE · IN-BROWSER FALLBACK | the browser can't reach /api |
npm run build # typecheck + vite build -> dist/
PORT=8080 npm start # Express serves dist/ and /api on one port
Deploy anywhere that runs Node 20+ (Render, Railway, Fly.io, a VM): build command npm install && npm run build, start command npm start, and set ANTHROPIC_API_KEY as a secret env var. The key is only ever read server-side and is never sent to the browser.
| Input | Action |
|---|---|
| A / D | move |
| W | jump (springs boost it) |
| SPACE / SHIFT | rocket thrust (with boosters) |
| Mouse | aim arm / whirl the chain hammer |
| Left click | punch |
| Q / Right click | hammer slam (with chain weapon), the arena-shaking set piece |
| F (or E) | character special |
| Enter | focus the prompt console · Esc to leave |
| Esc (in game) | back to fighter select |
| L | toggle reduced effects |
| B (on result card) | rematch keeping your build |
| R | restart after a win or loss |
Demo prompts (also one-click chips under the console):
Give my goblin giant rocket boostersAttach a massive chain hammer to my right armGive me a shieldMake my weapon heavierManual console commands go through the same action handlers as LLM plans:
/attach shield size=2 color=red, /modify chain_weapon mass=2, /remove rocket_booster.
src/game/abilities.ts implements abilities for three imported characters. They are registered against the stable ids kratos, doraemon and hulk in IMPORTED (characters.ts) and are independent of any model files.
The models are not in the repo yet. Until they are, these characters use a clearly labelled neutral prototype rig and appear only in the select screen's Prototype Bay, not in the main roster. All abilities use the existing Matter world, damage and impact paths, and effects. They are bounded and clean up after themselves.
| Key | Kratos | Doraemon | Hulk |
|---|---|---|---|
| 1 / F | Leviathan Axe: a sensor projectile that damages on collision with knockback, lodges in walls and platforms, then recalls along an arc and can hit again on the way back. Only one axe at a time, with a 3.2 s hard lifetime cap. | Air Cannon: a compressed-air blast with large knockback and light damage. At most 3 in flight. | Hulk Smash: a bounded, steered leap toward the cursor (≤ 520 px), then a slam down through the existing ground-slam impact. Huge shockwave, and a spider caught nearby is launched. 2 s hard cap. |
| 2 | Spartan Rage: 6 s. Enters with a ground slam; punches become shockwave hits; 1.4× damage dealt, half damage taken, 1.25× speed. Everything is restored exactly on expiry. | Bamboo Copter: up to 5 s of controlled hover (hold W or Space to climb), then a capped safe-landing fall. Stops on defeat. | Thunderclap: a forward cone shockwave (420 px, ±38°): damage, big knockback and a 1 s stun on the spider. It shatters lasers and blows crates away. |
| 3 | – | Anywhere Door: door opens, the fighter is hidden and frozen, the real physics bodies (including equipped weapons) are teleported to a validated safe spot, then the door closes. The spot is on a platform, in bounds, not under a catwalk, clear of bodies and away from the spider. Unsafe use (mid-air, or no valid exit) is rejected without charging the cooldown. | – |
The HUD ability strip shows clickable buttons with cooldowns and active states (axe in flight, rage running, copter battery). Mutations still work on these characters.
src/chamber/Chamber.ts is lazy-loaded (a separate ~146 KB gzipped chunk) the first time a mutation plays. Once a plan has been validated, the sequence is:
count, hammer, glove, shield, springs, armor) flying in and snapping together.dispatch) runs at the climax. Each plan row shows the actual ✓ MOUNTED or ✗ FAULT result, and the ignition only fires if something actually mounted.forceContextLoss), and removes event listeners.Click or Esc skips the animation but still applies the plan for real.
Disabling it: the 3D button toggles it (the setting persists). It is always off in reduced-effects mode. If WebGL or three.js fails before execution, the original 2D cinematic plays instead (verified by simulating a WebGL failure).
Physics runs at a fixed 60 Hz step with catch-up, so game speed stays correct at 30–45 FPS. Logic runs per step; visuals update per frame.
Static vector layers are baked into textures once. Full-screen flash and alarm quads are hidden when idle. Particles, debris and bodies are capped.
Reduced effects (FX button or L; switches on automatically if the frame rate stays below ~40 FPS for 3 s) does the following:
Cinematic zoom, letterbox, blueprint and explosions are kept.
Open /?perf for an overlay showing FPS, worst frame, update/render ms, bodies, particles and FX mode. Use it to profile on the target laptop.
player prompt ──► POST /api/mutate ──► Sonnet (structured JSON output, schema = MUTATION_JSON_SCHEMA)
│ fail / no key / invalid
▼
fallbackCompile()
Zod MutationPlanSchema (clamps numbers, snaps illegal sockets, rejects unknown components)
▼
browser re-validates ─► cinematic ─► dispatch(op) ─► handler registry ─► Goblin.attach/modify/remove
combat events ─► every ~12-16 s, non-blocking ─► POST /api/director ─► Opus ─► {commentary, action, intensity}
└► fallbackDirect() on failure
MUTATION_MODEL, default claude-sonnet-5-5. It can only pick from 6 components (rocket_booster, chain_weapon, shield, spring_legs, armor_plating, boxing_glove), 5 sockets, 3 ops (attach, modify, remove), bounded numeric params (size, power, mass, length, count 1–6, rocket 0–3) and a fixed colour palette. It never produces code.DIRECTOR_MODEL, default claude-opus-5-5. It picks one of 8 actions: laser barrage, leap slam, enemy shield, enrage, crane drop, steam vent, crate rain, or none. It speaks in the selected personality and must reference real events. In the lab, the scene only executes arena events. The fallback builds its commentary deterministically from the latest real event. Calls are asynchronous; the game never waits on them, and a server-side lock prevents overlapping calls.output_config.format JSON-schema structured outputs at effort: "low", with a 20–25 s timeout. Every response is re-validated with Zod before it touches the game.shared/mutations.ts component library, sockets, bounds, Zod + JSON schemas (shared by client and server)
shared/fallback.ts deterministic compiler + director
server/index.ts Express API + Anthropic calls + static hosting
src/main.ts Phaser boot + DOM HUD wiring
src/api.ts fetch wrappers (never throw; fall back locally)
src/game/ArenaScene.ts game loop, collisions, mutation cinematic, impacts, director actions
src/game/Goblin.ts self-righting active ragdoll (parameterised by CharacterDef) + component builders
src/game/characters.ts 4 character definitions, their procedural textures, portrait composer
src/game/challenges.ts challenge presets
src/game/quality.ts reduced-effects mode + 3D chamber preference
src/chamber/Chamber.ts Three.js Mutation Chamber (lazy-loaded)
src/menu.ts select screen, lab panel, roulette, personalities, victory card
src/perf.ts ?perf overlay
src/game/Spider.ts spider body, procedural 2-bone IK legs, attack loop
src/game/Arena.ts layered industrial arena, lamps, vents, crane, crates
src/game/Fx.ts particles, shockwaves, flashes, debris, floating text
src/game/actions.ts shared action registry + console command parser
src/game/textures.ts all art, generated procedurally at boot
RoomEnvironment for reflections.AUTH FAILED; with the server offline the in-browser fallback runs./?perf on the target machine.