# TRXTD – Tower Defense im Browser Ein vollständiges Tower-Defense-Spiel, gebaut mit **Vue 3 + TypeScript + Vite**. Die Spiellogik läuft in reinem TypeScript auf einem HTML-Canvas (60 FPS), Vue kümmert sich um HUD, Menüs und Panels. Enthält **Solo-Kampagne**, **2-Spieler-Coop** und **1v1-Duell** (Online/Lokal per WebSocket). ## Schnellstart 1. Abhängigkeiten installieren: ```bash npm install ``` 2. Frontend (Vite) und Multiplayer-Server starten: ```bash # Terminal 1: Dev-Server npm run dev # → http://localhost:5173 # Terminal 2: Multiplayer-Relay (nur für Coop / 1v1 nötig) npm run server # → ws://localhost:3001 ``` 3. Browser öffnen unter `http://localhost:5173`. --- ## 🐳 Docker Das Spiel gibt es als **All-in-One-Container**: Frontend (statisch) und Multiplayer-Server teilen sich **einen Port** – ideal für Self-Hosting. ```bash # Image bauen (Multi-Stage-Build: Build → schlankes Runtime-Image) docker build -t trxtd:latest . # Container starten docker run -d --name trxtd -p 3001:3001 trxtd:latest # Oder mit Docker Compose (empfohlen) docker compose up -d ``` Danach läuft das komplette Spiel inkl. Online-Multiplayer unter **http://localhost:3001**. **Enthaltene Härtung:** - Multi-Stage-Build (kein Build-Tooling im Runtime-Image) - Läuft als unprivilegierter Nutzer (`node`) - `HEALTHCHECK` über `/health` - `/assets/` mit immutablen Cache-Headern, SPA-Fallback für alle anderen Routen - WebSocket-Sicherheit: Payload-Limit (4 KB), Rate-Limiting (30 Aktionen/s), Schema-Validierung, Ping/Pong-Heartbeat **Nützliche Umgebungsvariablen:** | Variable | Default | Bedeutung | | --- | --- | --- | | `PORT` | `3001` | HTTP- und WebSocket-Port | | `DIST_DIR` | `./dist` | Ordner mit den statischen Dateien | | `ALLOWED_ORIGINS` | – | Zusätzlich erlaubte WebSocket-Origins (Komma-Liste, z. B. `https://spiel.example.com`) | **Öffentliches Hosting hinter Reverse Proxy (Nginx Proxy Manager / NPMplus):** 1. Container **nur im internen Netz** erreichbar machen (Port 3001 **nicht** am Router freigeben!), z. B.: ```yaml # docker-compose.yml — gemeinsames Netzwerk mit dem Proxy services: trxtd: build: . restart: unless-stopped expose: ["3001"] # intern, kein ports:-Mapping nach außen # networks: proxy_net ... ``` 2. In NPM/NPMplus einen **Proxy Host** anlegen: - **Domain:** `spiel.example.com` (DNS-A-Record auf den Server) - **Scheme:** `http` · **Forward Hostname:** Containername (gemeinsames Docker-Netz) oder Server-LAN-IP · **Port:** `3001` - **Websockets Support: ✔ aktivieren** (zwingend erforderlich für Multiplayer!) - Block Common Exploits: ✔ · Cache Assets: ✘ (der Server setzt eigene Cache-Header) - **SSL-Tab:** Let's-Encrypt-Zertifikat anfordern, *Force SSL* + *HTTP/2* aktivieren 3. Fertig – das Spiel (inkl. Coop/1v1 über `wss://`) läuft unter `https://spiel.example.com`. **Serverseitige Härtung (aktiv):** CSP-/Frame-/Referrer-Header · Origin-Check gegen Cross-Site-WebSocket-Hijacking · `X-Forwarded-For`-Auswertung nur aus privaten Proxy-Netzen · max. 500 WebSocket-Verbindungen total / 20 pro IP · max. 300 Räume · Payload-Limit 4 KB · Rate-Limit 30 Aktionen/s · Schema-Validierung · Ping/Pong-Heartbeat · Raum-Timeout 30 min. **Manuell ohne Docker im Produktionsmodus starten:** ```bash npm run build npm run server # serves dist/ + ws auf :3001 ``` ### 🛡️ Admin-Dashboard (`/admin`) Live-Übersicht über den Server: wer gerade **Solo spielt** (Karte, Schwierigkeit, Welle — angemeldete Spieler senden dazu alle 20 s einen Heartbeat), offene **Multiplayer-Räume**, Account-**Statistiken** und die **Nutzerliste**. Aktualisiert sich alle 5 s automatisch. Freischalten über die Umgebungsvariable `ADMIN_USERS` (Komma-getrennte Benutzernamen): ```yaml environment: - ADMIN_USERS=deinaccount ``` Dann als eines dieser Konten unter `https://deine-domain/admin` anmelden. Solo-Spiele laufen zwar lokal im Browser, aber angemeldete Spieler melden ihren Spielstatus an den Server; Gäste bleiben unsichtbar. --- ## Spielmodi ### 1. Solo-Kampagne Verteidige deine Basis gegen 20 handgetunte Wellen (Leicht: 30 Leben, Normal: 20 Leben, Schwer: 12 Leben). Nach Welle 20 geht es auf Wunsch im **Endlos-Modus** weiter. ### 2. 🤝 2-Spieler-Coop - **Gemeinsame Basis & gemeinsames Gold** – Sprecht euch ab! - **Eigene Türme:** Deine Türme haben einen **blauen Ring**, die deines Partners einen **orangenen Ring** (jeder kann nur seine eigenen Türme upgraden oder verkaufen). - Gegner haben 70 % mehr Leben, um der doppelten Feuerkraft standzuhalten. - Wellen starten automatisch nach Countdown oder per Klick auf „Nächste Welle" (beide können klicken). ### 3. ⚔ 1v1-Duell (Tower-Battles-Prinzip) - Jeder Spieler verteidigt sein **eigenes Spielfeld**. - Über ein **Live-Miniaturfenster (PiP)** siehst du in Echtzeit das Spielfeld deines Gegners mit allen Türmen und Gegnern. - **Rush-Mechanik:** Schicke gegen Gold (`60 🪙 + 8 🪙/Welle`) eine Welle schneller Läufer auf die Basis des Gegners! - **Siegbedingungen:** - Basis des Gegners fällt auf 0 Leben → Sofortsieg! - Nach 20 Wellen gewinnt, wer mehr Leben übrig hat (bei Gleichstand entscheiden die Punkte). ### Multiplayer-Raum-System - Klicke auf dem Startbildschirm auf **„Coop-Raum erstellen"** oder **„1v1-Raum erstellen"**. - Gib deinem Mitspieler den **4-stelligen Raum-Code** (z. B. `5SK7`). - Der Mitspieler tippt seinen Namen + den Code ein und klickt auf **„Beitreten"**. - Der Host startet das Spiel, sobald beide in der Lobby sind. - Funktioniert im lokalen Netzwerk (LAN / WLAN) – für Freunde über das Internet einfach Port 3001 freigeben oder über ngrok/Tailscale leiten. --- ## 🌟 9-Level-Evolutionssystem Jeder Turm hat **9 Ausbaustufen**, aufgeteilt in **3 Evolutions-Stufen**: | Tier | Level | Farbe | Bedeutung | | --- | --- | --- | --- | | **Basis** | 1–3 | 🟡 Gelb | Höherer Grundschaden, Reichweite & Feuerrate | | **Evolution I** | 4–6 | 🟠 Orange | Neue Spezialfähigkeit schaltet sich frei | | **Evolution II** | 7–9 | 🔵 Blau | Finale Evolutionsstufe mit verheerenden Effekten | ### Die Evolutionen im Detail | Turm | 🟡 Basis (L1–3) | 🟠 Evolution I (L4–6) | 🔵 Evolution II (L7–9) | | --- | --- | --- | --- | | 🏹 **Bogenturm** | Schneller Einzelschuss | **Mehrfachschuss:** Feuert 2–3 Pfeile gleichzeitig auf verschiedene Ziele | **Giftpfeile + 4-Fach:** Bis zu 4 Pfeile + starker Gift-DoT (28 Schaden/s) | | 🧨 **Kanone** | Flächenschaden | **Brandgeschosse:** Hinterlässt brennenden DoT an allen getroffenen Gegnern | **Flak-Geschütz:** Trifft ab L7 auch **Flugeinheiten** mit voller Explosionskraft! | | ❄️ **Eisturm** | Verlangsamender Puls | **Permafrost:** Jeder 3. Puls **friert alle Gegner komplett ein** (Bewegung = 0) | **Zerbrechlichkeit:** Eingefrorene Ziele nehmen **+50 % Schaden aus ALLEN Quellen**! | | ⚡ **Teslaturm** | Kettenblitz | **Betäubungs-Schock:** Kettenblitze betäuben getroffene Ziele kurzzeitig | **Gewittersturm:** Jeder 4. Schuss schlägt bei **ALLEN Gegnern in Reichweite** gleichzeitig ein! | | 💫 **Laserturm** | Soforttreffer | **Prisma-Brechung:** Der Laserstrahl bricht und springt auf 2–3 Nebenziele über | **Durchschlag:** Der Strahl durchdringt ALLES in einer Linie bis zum Rand der Reichweite | Türme ab Level 4 erhalten im Spiel eine pulsierende **Evolutions-Aura** (orange ab L4, blau ab L7) und die Sterne im Turm-Panel zeigen die jeweilige Tier-Farbe. --- ## Gegner - **🟢 Kriecher:** Standard-Einheit, gut für frühes Gold - **🟡 Läufer:** Sehr schnell – Bogentürme oder Eisturm nötig - **⬜ Panzer:** Zäh, kostet **2 Leben** bei Durchbruch - **🟣 Flieger:** Ignorieren den Weg und fliegen auf halber Höhe geradeaus (nur Bogenturm, Eisturm, Tesla, Laser!) - **🔴 Boss:** Riesige Lebensleiste, kostet **5 Leben** (Wellen 10, 15, 20 …) --- ## Hindernisse Bäume (60 🪙) und Felsen (40 🪙) blockieren strategisch wichtige Bauplätze. - **Klick auf das Hindernis** → „⛏ Entfernen" öffnet sich oben rechts. - Nach dem Entfernen wird das Feld sofort bebaubar. --- ## Steuerung - **1–5** – Turm zum Bauen auswählen, Klick auf freies Feld platziert ihn - **Klick auf Turm** – Details, Upgrade, Verkauf, Zielmodus - **Klick auf Hindernis** – Entfernen gegen Gold - **Leertaste** – nächste Welle früh starten (Frühstart-Bonus!) / Pause (nur Solo) - **U** Upgrade · **V** Verkaufen · **T** Zielmodus wechseln - **P** Pause (nur Solo) · **M** Ton an/aus · **Esc** Abbrechen - **Rechte Maustaste** – Bauauswahl aufheben --- ## Technische Details - **Client-Side Simulation:** Determinister Lockstep-Tick-Loop (30 Hz) – beide Clients berechnen den exakten Spielverlauf parallel; der Server (`server/server.mjs`) vermittelt nur die Räume und leitet Aktionen weiter (minimaler Traffic, kein Lag bei der Bewegung). - **Renderer:** Offscreen-gepufferter HTML-Canvas mit dynamischer Vollbild-Skalierung, Retina-DPR-Support, Partikelsystem und Mündungsfeuer. - **Sound:** Web Audio API mit synthetisierten Klängen (keine externen Audio-Dateien). - **Automatisierte Tests:** - `npm run sim` – Headless-Bot spielt die Solo-Kampagne zur Balancing-Prüfung durch - `npx tsx scripts/test-mp.mts` – Lockstep-Determinismus-Test (3600 Ticks, byte-identischer Zustand auf beiden Seiten) - `npx tsx scripts/test-obstacle.mts` – Feature-Test: Hindernis-Entfernung