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。 以下為已儲存的摘錄。
Ein Fantasy-Quartett im Browser mit taktischem Kniff – gegen den Computer (Leicht/Normal/Schwer) oder zu zweit online an zwei Geräten. Keine Installation nötig – index.html im Browser öffnen, oder:檢視完整 README ↗
Ein Fantasy-Quartett im Browser mit taktischem Kniff – gegen den Computer (Leicht/Normal/Schwer) oder zu zweit online an zwei Geräten.
Keine Installation nötig – index.html im Browser öffnen, oder:
python3 -m http.server 8765 # dann http://localhost:8765
Als App und offline: Über HTTPS (z. B. GitHub Pages) lässt sich das Spiel auf den Homescreen legen
(Android/Chrome: „App installieren“, iPhone: Teilen → „Zum Home-Bildschirm“). Nach dem ersten Besuch hält ein
Service Worker (sw.js) alle Dateien bereit – das Spiel startet dann sofort und läuft auch ohne Netz, nur der
Online-Modus braucht natürlich eine Verbindung. Die Cache-Version aus index.html gilt auch für den Service Worker:
Hochzählen genügt, dann lädt er beim nächsten Besuch alles neu. Auf localhost ist er nur mit ?sw in der Adresse
aktiv, damit beim Entwickeln keine alten Dateien aus dem Cache kommen.
Direkt von Browser zu Browser (WebRTC), ohne eigenen Server. Wer „Spiel eröffnen“ wählt, bekommt einen
Einladungslink, einen QR-Code und einen kurzen Raumcode (z. B. K7M-Q2P). Der Mitspieler tippt
auf den Link, scannt den QR-Code mit der Handykamera oder gibt den Code unter „Beitreten“ ein – fertig.
Zusammengeführt werden die beiden über öffentliche Nostr-Relays (Bibliothek Trystero,
lokal in js/vendor/). Die Relays sehen nur verschlüsselte Verbindungsdaten, das Spiel selbst läuft direkt
zwischen den Geräten; ein öffentlicher STUN-Server hilft beim Finden der Adressen. Die Seite muss über HTTPS
oder localhost laufen (z. B. GitHub Pages). In sehr strengen Netzen (manche Mobilfunkanbieter) kommt keine
Direktverbindung zustande – dann hilft ein WLAN.
Notlösung ohne Relays: „Klappt nicht? Ohne Vermittlung verbinden“ – dann tauschen die Spieler zwei lange Codes von Hand aus.
Beide Geräte rechnen dieselbe Partie mit demselben Startwert (der Gast spiegelverkehrt), übers Netz gehen
nur die Züge. Beide müssen dieselbe Spielversion geladen haben (geprüft wird die Cache-Version aus index.html);
nach jedem Duell vergleichen beide eine Prüfsumme des Spielstands, damit Abweichungen sofort auffallen.
Reißt die Verbindung mitten in der Partie ab (Handy gesperrt, kurz kein Netz), warten beide eine Minute und
suchen sich über den Raum neu; die verpassten Züge werden dann nachgeschickt. Bei den Codes von Hand geht das nicht.
Gedacht ist der Online-Modus für Partien unter Freunden: Beide Geräte kennen den ganzen Spielstand, ein
veränderter Browser könnte also die gegnerische Hand auslesen.
Lässt der Gegner länger als 30 Sekunden auf seinen Zug warten, zeigt ein Zähler das an; nach zwei Minuten
kann man die Partie dort direkt verlassen. Gezogen wird nie für ihn.
1–3 Karte wählen, H Schlachtruf, Enter ausspielen/weiter, Z Karte groß zeigen, Esc Fenster schließen;
mit Tab lassen sich die Handkarten ansteuern, Leertaste wählt.| Datei | Inhalt |
|---|---|
sw.js, manifest.webmanifest | Service Worker (offline, schneller Start) und App-Beschreibung zum Installieren; Icons in art/icons/ (aus dem Wappen der Kartenrückseite) |
js/cards.js | Völker, Karten und Schlachtfelder (hier lässt sich alles balancen) |
js/engine.js | Regeln und Spielzustand, ohne DOM (läuft auch in Node) |
js/net.js | Online-Verbindung: Raum über Nostr-Relays (Link, QR, Raumcode) oder Codes von Hand, WebRTC-Datenkanal |
js/vendor/ | Trystero und QR-Code-Generator (MIT, siehe LIZENZ.md), werden erst in der Online-Lobby geladen |
js/ai.js | Computergegner: Siegchance × Wert der Beute gegen Verlustrisiko; „Schwer“ zählt Karten und rechnet mit der wahrscheinlichen Gegnerkarte |
js/audio.js | Soundeffekte und Hintergrundmusik, live mit der Web-Audio-API erzeugt (keine Audiodateien) |
js/ui.js | Menü, Rundenablauf, Karten, Animationen, Fenster; ruckelt es, schaltet watchFrames die Bildeffekte stufenweise ab. Teilt sich mit den folgenden Dateien das Objekt CG.UI (dort UI.s = aktueller Spielstand) |
js/ui-duel.js | Duell zum Mitverfolgen: Schritte, hochzählende Werte, automatisches „Weiter“ |
js/ui-input.js | Maus, Tastatur und Touch im Spiel, Spielmenü |
js/ui-online.js | Online-Partie: Züge, Prüfsummen, Abrisse, Revanche, Lobby |
js/art-fx.js | ART_FX legt die bewegten Bildeffekte je Karte fest (Glut, Funken, Leuchten, Nebel …) |
art/src/**/*.svg | Handgezeichnete SVG-Illustrationen (32 Helden, 14 Schlachtfelder, Kartenrückseite) – die Quellen |
art/src/textures/*.webp | Graue Strukturkarten (Stein, Metall, Stoff, Holz, Haar, Schuppen …, CC0), die beim Bauen über die Illustrationen gelegt werden. In einem SVG markiert man Flächen mit data-tx="stone" am Verlauf oder filter="url(#tx-metal)" an Form/Gruppe (Varianten -soft, -fine) – Details in |
tools/texturize.pyart/cards, art/terrains | Daraus erzeugte WebP-Bilder (groß + .thumb für kleine Darstellungen), die das Spiel lädt: nach Änderungen an einem SVG tools/build-art.sh ausführen |
art/cursors/*.svg | Eigene Mauszeiger (Pfeil, Panzerhandschuh, Lupe, Info) |
tools/texturize.py | Setzt die Material-Texturen in ein SVG ein (von build-art.sh und render-svg.sh aufgerufen) |
tools/emoji-font.py | Baut die Emoji-Ersatzschrift (art/fonts/noto-emoji-subset.woff2) nur mit den Emojis des Spiels – nach neuen Emojis ausführen |
tools/render-svg.sh | Rendert ein SVG per Headless-Chromium als PNG (zum Prüfen von Illustrationen) |
test/simulate.js | KI-gegen-KI-Partien mit Invarianten-Prüfung und Grenzen für die Spielstärke der Stufen (EXPECT): node test/simulate.js 400 |
test/online.js | Online-Partien im Gleichschritt: Host und Gast müssen bei jeder Zugreihenfolge gleich rechnen (inkl. Prüfsumme und ungültiger Züge): node test/online.js 500 |
test/balance.js | Balance-Analyse (Karten, Fähigkeiten, Schlachtruf, Schwierigkeitsstufen): node test/balance.js 3000 |
package.json, .github/workflows/test.yml | npm test startet simulate.js und online.js (knapp eine Minute, ohne Installation); GitHub führt das bei jedem Push aus |