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,即可验证所有权并自行管理介绍。
一分钟完成验证MixMash Studio: free browser games, including the MIXMASH DJ platform fighter
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
The studio hub at mixmash.games, served from this repo's gh-pages branch (the live default branch — GitHub Pages "legacy" build, not an Actions deploy).查看完整 README ↗The studio hub at mixmash.games, served from this repo's gh-pages branch (the live default branch — GitHub Pages "legacy" build, not an Actions deploy).
| Path | What it is |
|---|---|
/ (index.html, home.html) | Studio homepage — brand tokens, game lineup |
/play/ | MIXMASH — a DJ-powered platform fighter (the flagship game; see docs/PLAYER_GUIDE.md) |
/mars/ | MarsScape — canvas-backed isometric client with a server-authoritative backend (see below). No longer a build snapshot of the marsscape source repo — the two have diverged; do not overwrite one with the other. |
/empires/ | EMPIRES (aka "Age of Dave") — WebAssembly build of the real aoe2-clone RTS (7 civs, combat, AI opponent; local skirmish only — no multiplayer in-browser) |
/garden/ | Full-viewport iframe embed of the live Garden OS story mode (davehomeassist.github.io/garden-os/story-mode/) — never drifts |
/pitch/ | PITCH RIOT — a self-contained arcade soccer game (single index.html, canvas + vanilla JS). One outfielder vs a CPU (auto keepers) across two halves; at halftime you play a built-in cover-ops minigame (a mini homage to FIFA Pitch Crew from the system-by-dave repo) — show quality earns a timed "HYPED" boost for the second half. Difficulty select, keyboard + touch. No build step, no backend. |
/front-of-house/ | Front of House: an early playable concert-promotion management game (Lot Night: book a band, build a parking-lot venue, promote, survive show night, settle the money). Rules engine, balance simulator and design docs live in the folder; see front-of-house/README.md. Dave approved the Early playable hub listing on 2026-10-05; noindex and sitemap exclusion remain. |
/horseshoes/ | Backyard Horseshoes: an unlisted Phase 1 physics practice prototype built with Three.js and Rapier. One compound-collider shoe, fixed 120 Hz simulation, desktop and touch throws, immediate retry, close camera, and collider diagnostics. The source remains in DaveHomeAssist/curling-simulator; this route is its static deployment build. |
/zelda2mario/ | Evidence-bound public status dashboard for the source-only Zelda2MarioCoop project. The game itself is not yet published as a playable route. |
/admin/ | Admin index — every tracked file and reference in this repo, organised by game (one tab each) and purpose (docs, decisions, roadmaps and logs, evidence, art, tests, tooling, source, API, builds, config), with search, category filters and copyable paths. Rendered from the generated admin/catalog.json; noindex, not in the sitemap, and never links local paths, Notion or private source. |
ROADMAP.md | Production roadmap for the MIXMASH fighter specifically — phased DoD/checkpoints/verification standards |
src/kit/ | MixKit, the shared game layer: nav.js (hub, mute all, fullscreen), input.js, lifecycle.js, viewport.css, stage.js, save.js, pwa.js. See "MixKit" below. |
src/combat.js | Canonical, tested knockback math for the fighter (finite() guard + calcKnockback) |
mars/engine.mjs, mars/server.mjs | Shared MarsScape game engine + the Node authority server (SQLite locally) |
mars/commissioned-art.mjs, mars/golden-scene.html | DEC-79 validated commissioned-art cache and in-renderer golden-scene review surface |
api/ | Vercel serverless functions — the production authority API (Blob-backed sessions) |
test/*.test.{js,mjs}, mars/test-*.mjs, mars/parity/parity.test.mjs | Node's built-in test runner (node --test) — fighter combat math, the inline combat parity guard, public roster/arena count guard, extracted play modules, MixKit save, MarsScape engine/API/handler/art/parity tests |
.github/workflows/ci.yml | CI — on pull requests, manual dispatch, and pushes to gh-pages touching any game route, api/, src/, test/, the hub pages, the PWA shell, or package files: runs npm test, vercel-build, the DEC-79 art validation/report/contact-sheet drift gates, sim, then the Playwright rails (art:visual, smoke:play, smoke:catalog, smoke:landing, smoke:zelda2mario, smoke:front-of-house, smoke:admin, smoke:mobile), plus the Front of House balance baseline drift gate (sim:front-of-house) |
npm install # once
npm test # node --test — fighter combat/parity/count guards, play modules, MarsScape engine/API/handler/art/parity tests, Front of House engine, admin index coverage
npm run smoke:play # fighter resume/snapshot smoke test
npm run smoke:catalog # catalog runtime smoke tests
npm run smoke:landing # five-width landing, keyboard, motion, hit targets, screenshots
npm run smoke:zelda2mario # status scope, mobile/ultrawide, themes, keyboard tabs, filters and complete printing
npm run smoke:front-of-house # Lot Night end to end, reload, save codes (including version 1 conversion), keyboard building, reduced motion, phone width, contrast
npm run sim:front-of-house # regenerate front-of-house/docs/BALANCE_BASELINE.md (CI fails on drift or a FAIL verdict)
npm run admin:index # regenerate admin/catalog.json after adding, removing or renaming any tracked file
npm run smoke:admin # admin index: no page scroll at six widths, themes, keyboard tabs, filters, search, privacy
npm run smoke:mobile # MixKit mobile and tablet touch rail: 12 touch configs (WebKit and Chromium) across every game plus the kit itself
npm run start:mars # run the MarsScape authority server locally (SQLite) — http://localhost:8787/mars/
npm run vercel-build # syntax-check all api/ and mars/ server files (what Vercel's build runs)
npm run art:validate # validate DEC-79 and verify the runtime index plus strict-report parity
npm run art:report # refresh normal, paid-test, and full-golden machine evidence
npm run art:visual # capture game, fallback, contract, contact-sheet, and golden-scene evidence
npm run art:approve # strict paid-test gate: 4 assets, 8 PNGs, 4 editable sources
Windows note:
mars/test-vercel-handler.mjscan fail withEBUSY: resource busy or lockeddeleting a temp.sqlite-shmfile — a Windows file-locking quirk in test teardown (node:sqliteWAL mode), not a real defect. All assertion-level tests pass; only the cleanup hook is affected.
There is no build step for the static site itself — index.html, home.html, /play/, and /empires/ are served as-is by GitHub Pages. /mars/ is a static client too, but talks to a separate live backend.
The landing smoke rail checks 320, 390, 768, 1024, and 1440px. It writes screenshots
and report.json into a temporary directory printed on completion. Set
LANDING_SCREENSHOT_DIR to keep them in a specific evidence directory. For
post-deployment readback, run
LANDING_BASE_URL=https://mixmash.games/ npm run smoke:landing.
Gameplay-preview provenance and refresh guidance live in
assets/previews/README.md.
zelda2mario/index.html is an exact public-safe copy of the game's canonical
docs/status/zelda2mario-project-status.html, not a separate status source.
Edit the canonical embedded status-data block, validate its eleven phases and
six M2 actions against the implementation plan, then copy the complete reviewed
HTML here. Preserve the source baseline and evidence timestamp; never infer game
completion from a documentation deployment. Reconcile the project-owned Notion
records through targeted dated updates, keeping private links out of this file.
Publish through a scoped PR into gh-pages after applicable CI succeeds.
Legacy Pages deploys independently, so do not bypass the pre-merge CI gate.
Verify canonical/published SHA-256 parity, Pages success, the slash redirect,
and live rendering. The browser check covers 320, 390, 768, 1440 and 2560x720,
all work fields, keyboard tabs, light/dark persistence, filters and full printing.
Screenshots and a JSON report go to the temporary directory printed at exit.
Use ZELDA2MARIO_SCREENSHOT_DIR to retain a chosen evidence location; use
ZELDA2MARIO_BASE_URL=https://mixmash.games/zelda2mario/ npm run smoke:zelda2mario
for live verification. Roll back a faulty route with a scoped revert PR; do not
alter other game routes, the authority API, hosting configuration or ROM data.
/admin/ lists every tracked file once. admin/build-catalog.mjs classifies
each path by rules (project, then category), takes its title and summary from
the file's own heading, <title>/meta description or leading comment, and
merges the hand-authored projects, references and notes in
admin/catalog-sources.mjs. After adding, removing or renaming a file, run
npm run admin:index and commit admin/catalog.json; npm test
(test/admin-catalog.test.mjs) fails while the catalog and the tree disagree.
Summaries are snapshots from generation time and are not compared. The page
records where each game's status lives, never the status itself. It is public
like every Pages route, so keep it public-safe: no local paths, no Notion links,
and the private Zelda2MarioCoop source named but not linked. For live readback,
run ADMIN_BASE_URL=https://mixmash.games/admin/ npm run smoke:admin.
src/kit/ is the one shared layer every game uses; there are no mobile-only forks. Scripts load before the game's own scripts (as nav.js always has). A page that loads the shared nav declares viewport-fit=cover in its viewport meta (the hub pages load only pwa.js and have no safe-area padding yet, so they do not). Touch capability is matchMedia('(pointer: coarse)').matches || navigator.maxTouchPoints > 0; it is never a screen-width test.
| File | Use it for | API and events |
|---|---|---|
nav.js | The shared bar: hub, mute all, fullscreen (only where requestFullscreen exists), source. 44 px targets; idle state is one 44 px handle, not a faded bar; positioned from the safe-area variables. | window.__mixmashNav: element, isMuted(), setMuted(), audioContexts, expand(), collapse(), isCollapsed(), setSlot(name, {top,right,bottom,left}), getSlot(), setCollapsible(bool). A game with HUD in the top-left declares another slot (top-left default, top-right, bottom-left, bottom-right) with data-nav-slot="..." on the script tag or setSlot(); data-nav-collapse="off" keeps the bar open. Event mixmash:mute. |
input.js | Touch capability, the player's current input mode, and gestures: tap, long-press as the secondary action, two-finger pan. | MixKit.input.touchCapable(), .mode() (touch, mouse, keyboard), .gestures(el, {onTap, onSecondary, onPanStart, onPan, onPanEnd}, opts) returning {destroy()}. Sets data-input-mode on <html>; event mixkit:input-mode {mode, previous, touchCapable}. |
lifecycle.js | One source for visibilitychange, pagehide/pageshow, freeze/resume, window blur/focus. Suspends every AudioContext nav.js tracks on pause and resumes only the ones it suspended, never while Mute All is on. | MixKit.lifecycle.isPaused(), .reasons(), .onPause(fn), .onResume(fn). Events mixkit:pause {reason, reasons} and mixkit:resume {reason}. |
viewport.css | Locked root (overflow: hidden, overscroll-behavior: none), --safe-top/right/bottom/left from , the 100dvh stage (its content box is the safe area), and , a menu overlay that scrolls instead of clipping. |
Every added kit file goes into the sw.js precache list, and VERSION is bumped. test/kit-layer.test.mjs unit-tests the logic; test/mobile-touch-smoke.mjs exercises it in real browsers.
npm run smoke:mobile loads every game at 12 touch configs: WebKit at 390x844, 430x932, 768x1024, 820x1180 and 1024x1366, and Chromium with an Android user agent at 360x800, each in both orientations (hasTouch and isMobile). Per game and config it asserts no vertical page scroll, no horizontal overflow, 44 px targets (shared nav, then everything else) and a nav that stays clear of the device safe-area insets (simulated through --safe-*, since a headless browser reports none). For MIXMASH and Pitch Riot it also asserts that touch alone reaches active play from a fresh load (reaches-play: MIXMASH render_game_to_text mode=playing with the touch pad on screen, Pitch Riot ?debug __pitch.game.state === 1), scrolling only the one container a player can scroll if a control sits below the fold. Per config it also drives the kit on a blank page: viewport locking and scrolling overlays, input and gestures, lifecycle and audio suspension, stage fit, DPR and rotate prompt, and the nav handle, slots and contrast.
The configs, games and checks are exported tables in the file: later phases add a config, a game or a check there instead of adding a rail. A check that a game does not yet pass is listed in EXPECTED_FAIL with the audit finding it waits on and the exact configs it applies to (there are no "partial" entries); it still runs and still has to fail there, a failure at any other config is a plain failure, and a listed config that starts passing is reported as XPASS so it gets removed. Run it locally with SMOKE_CHROMIUM_CHANNEL=chrome to use the installed Chrome for the Chromium config (CI installs chromium webkit), and against the live site with SMOKE_BASE_URL=https://mixmash.games/ npm run smoke:mobile. SMOKE_ENGINE, SMOKE_CONFIGS, SMOKE_GAMES, SMOKE_REPORT_DIR and SMOKE_STRICT_XPASS=1 narrow, relocate or tighten a run.
/mars/ stopped being a build snapshot of the marsscape source repo — it was rebuilt in place as a server-authoritative game:
mars/index.html + mars/game.js (canvas isometric board) + mars/styles.css. Valid commissioned PNGs are discovered only through mars/assets/commissioned/index.json, decoded to cached ImageBitmap objects, and fall back through code-owned maps and procedural rendering without blocking play.mars/render-contract.mjs v3 owns geometry, states, animation, lighting, accessibility, and performance values. /mars/golden-scene.html renders the eight-beat DEC-79 review sequence. Deterministic strict reports bind every PNG and structurally valid layered source by SHA-256 and prove runtime-index readiness. Full approval also requires all 24 canonical beat/zoom/lighting tuples, the four 1.0x lighting profiles, 1.0x fallback and reduced-motion reviews, and 300 commissioned 1.0x performance samples before Dave can attest and create a package-bound receipt in the final 1.0x view. Its client integrity digest detects drift but does not authenticate a reviewer; canonical approval requires the exported receipt plus external Git/review identity in the repo decision record.mars/engine.mjs (shared game rules) served two ways — mars/server.mjs (Node/SQLite, for local dev via npm run start:mars) and api/*.mjs (Vercel functions, for production). The client picks the API base from a <meta name="marsscape-api-base"> tag in mars/index.html, currently pointed at https://mixmash-marsscape-authority.vercel.app/api/.gather, build, smelt, craft, research, startStorm) are applied server-side.mixmash-marsscape-authority, backed by a private Vercel Blob store (env: BLOB_READ_WRITE_TOKEN, MARSSCAPE_SECRET, MARSSCAPE_ALLOW_ORIGIN). See mars/README.md for full operating limits (256 KB/5s request caps, per-session write locks, in-memory rate limiting).This means the old redeploy recipe (marsscape repo → npm run build → copy dist/index.html into mixmash/mars/) is obsolete and would destroy this architecture if run. The marsscape GitHub repo continues to exist as an independent single-file-build project; the two /mars/ implementations have diverged and are not currently reconciled.
/empires/ is a manual Emscripten build snapshot copied in from the aoe2-clone repo (tools/build_web.sh there produces aoe2-clone.js/.wasm/.data (sprite atlases); copy all three into mixmash/empires/assets/ alongside the existing index.html/shell.js). /garden/ needs no redeploy — it's a live iframe.
gh-pages is the real default branch and the only one served at mixmash.games. There is no main branch. The other branches are work branches that aren't part of the live site: dec79-paid-test-candidate (draft PR #11, the MarsScape DEC-79 paid-test art awaiting in-game review) and claude/mars-art-roadmap (an Aug 2026 docs branch whose MarsScape art roadmap has since landed on gh-pages). Check with git branch -r before relying on this list.src/combat.js (tested, canonical) and an inline copy inside play/index.html (the shipped game). Keep them hand-synced until the game imports the module directly (tracked in ROADMAP.md Phase 1).mixmash_opts in localStorage persists match options (volume, music, hitbox display, stage hazards, both players' control binds) — don't reset it casually.dist/index.html from the marsscape repo into mars/) — see "MarsScape's architecture" above. /mars/ is now its own multi-file app with a live backend, independent of the marsscape source repo.env(safe-area-inset-*).mixkit-stage.mixkit-overlay| CSS classes and custom properties. |
stage.js | Fits a canvas inside the safe area at its base aspect ratio, sizes the backing store to devicePixelRatio (cap dprCap, default 2), sets touch-action: none, and shows one shared rotate prompt when a game declares a preferred orientation and the fitted canvas covers under 50% of the screen. | MixKit.stage.attach(canvas, {width, height, container, dprCap, orientation, touchAction, onFit}) returning {fit, info, setBase, setDprCap, destroy}; pure helpers fitRect, backingSize, needsRotate; event mixkit:stage-fit. |