Files
slop-game-opus5.5/README.md
T
2026-09-24 17:57:54 +02:00

219 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Glory Defense
**Für Freiheit und Frieden!** – Ein satirischer 2D-Browser-Shooter in Draufsicht.
Als *Präsident Maximilian Valor* verteidigt man die „Vereinigte Erde“ gegen
außerirdische Invasoren, begleitet von pathetischen Durchsagen des „Ministeriums
für Zuversicht“. Der Humor richtet sich gegen Militarismus und Propaganda im
Allgemeinen. Alle Figuren und Organisationen sind frei erfunden (siehe
[Disclaimer](#disclaimer)).
![Hauptmenü](docs/images/menu.png)
![Spielszene](docs/images/gameplay.png)
- **Frontend:** Phaser 3.90 (lokal eingebunden, kein CDN), native ES-Module, kein Build-Schritt
- **Backend:** Flask (monolithisch), SQLite, kleine JSON-API für Highscores
- **Hosting:** läuft auf cPanel über „Setup Python App“ (Phusion Passenger)
## Inhalt
- [Spielprinzip](#spielprinzip)
- [Steuerung](#steuerung)
- [Lokales Setup](#lokales-setup)
- [Starten](#starten)
- [Tests](#tests)
- [Projektstruktur](#projektstruktur)
- [Konfiguration](#konfiguration)
- [Weitere Dokumentation](#weitere-dokumentation)
- [Disclaimer](#disclaimer)
## Spielprinzip
- **Wellen-Modus:** endlose Angriffswellen mit steigender Schwierigkeit, dazwischen
kurze Pausen mit Propaganda-Durchsage, Wellenbonus und etwas Heilung.
- **Zwei Fraktionen mit je drei Gegnertypen:**
- *Die Schwärmer* (insektoid, schnell, Nahkampf): Krabbler, Sprungkralle, Brutmutter
- *Die Blechlegion* (Roboter, langsam, Fernkampf): Nieter-Drohne, Blechsoldat, Walzmeister
- **Gegner-KI:** verfolgen, umzingeln, Abstand halten, flankieren, Sprungangriff mit
Vorwarnung, Mörser mit Bodenmarkierung.
- **Drei Waffen:** Karabiner »Zuversicht«, Schrotflinte »Überzeugungskraft« und die
Dienstpistole »Anstand« mit unbegrenzter Munition.
- **Orbital-Befehle** per Tastenkombination (Q halten): Orbitalschlag »Morgenröte«,
Nachschubkapsel »Fürsorgepaket« und Geschütz »Wachsamer Nachbar«. Alle mit
Abklingzeit und Bodenmarkierung bis zum Einschlag.
- **Punkte:** Abschüsse in schneller Folge bauen eine Serie auf (Multiplikator bis ×4).
Treffer am Präsidenten beenden sie.
- **Ehrentafel:** Top 10 werden auf dem Server gespeichert (mit Plausibilitätsprüfung
und Rate-Limit).
Details und alle Balancing-Werte: [docs/GAME_DESIGN.md](docs/GAME_DESIGN.md).
## Steuerung
| Taste | Aktion |
|---|---|
| **W A S D** | Bewegen (8 Richtungen) |
| **Maus** | Zielen |
| **Linksklick** | Schießen (Karabiner: gedrückt halten) |
| **R** | Nachladen |
| **1 / 2 / 3**, **Mausrad** | Waffe wechseln |
| **Leertaste** | Ausweichrolle (kurz unverwundbar, 1,5 s Abklingzeit) |
| **Q halten + Pfeiltasten oder WASD** | Orbital-Befehl eingeben, Ziel ist der Mauszeiger |
| **Esc** | Pause mit Lautstärkereglern |
| Orbital-Befehl | Code | Abklingzeit |
|---|---|---|
| Orbitalschlag »Morgenröte« | ↑ → ↓ ↓ | 30 s |
| Nachschubkapsel »Fürsorgepaket« | ← ← ↓ → | 45 s |
| Geschütz »Wachsamer Nachbar« | → ← → ↑ ↑ | 60 s |
Warum **Q** als Halte-Taste: Mit gehaltener **Strg** würde **W** den Browser-Tab
schließen (lässt sich nicht abfangen), und fünfmal **Shift** öffnet unter Windows die
Einrastfunktion.
## Lokales Setup
Voraussetzungen:
- **Python 3.10 oder neuer** (für Server und Python-Tests)
- optional **Node.js 22 (ab 22.13) oder 24** (nur für JavaScript-Unit-Tests und ESLint)
- optional **Microsoft Edge oder Google Chrome** (für die End-to-End-Tests)
Fürs Spielen und für den Server-Betrieb ist Node nicht nötig: Phaser liegt bereits
unter `app/static/js/lib/`.
**Windows (PowerShell):**
```powershell
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements-dev.txt
Copy-Item .env.example .env
```
Blockiert Windows `Activate.ps1` („Die Ausführung von Skripts ist auf diesem System
deaktiviert“), gibt es zwei Wege:
- die Ausführungsrichtlinie nur für den eigenen Benutzer lockern:
`Set-ExecutionPolicy -Scope CurrentUser RemoteSigned`, oder
- ohne Aktivierung arbeiten und jeden Befehl über den Python der venv aufrufen:
`.\.venv\Scripts\python.exe -m pip install -r requirements-dev.txt`,
`.\.venv\Scripts\python.exe -m flask run`, `.\.venv\Scripts\python.exe -m pytest`.
**Linux/macOS:**
```bash
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements-dev.txt
cp .env.example .env
```
In `.env` einen eigenen `SECRET_KEY` eintragen, zum Beispiel erzeugt mit:
```bash
python -c "import secrets; print(secrets.token_hex(32))"
```
Bleibt `SECRET_KEY` leer, erzeugt die App beim ersten Start automatisch
`instance/secret_key`. Für die JavaScript-Werkzeuge (optional):
```bash
npm install
```
## Starten
Bei aktivierter venv:
```bash
flask run
```
Dann <http://127.0.0.1:5000> öffnen. Mit `flask run --debug` lädt der Server bei
Codeänderungen neu. Die Datenbank (`instance/glory_defense.sqlite3`) wird beim
ersten Start automatisch angelegt. Nachträglich geht das auch mit `flask init-db`.
Weitere Adressen:
- `/disclaimer`: Disclaimer als eigene Seite (auch ohne JavaScript lesbar)
- `/api/highscores`: Top 10 als JSON
- `/healthz`: Funktionstest für das Deployment
## Tests
Kurzfassung. Die Details stehen in [docs/TESTING.md](docs/TESTING.md).
```bash
pytest # Backend, Assets, Passenger-Import und End-to-End im Browser
pytest -m "not e2e" # ohne Browser-Tests
npm test # JavaScript-Unit-Tests (Vitest)
ruff check .
ruff format --check .
npm run lint # ESLint
```
## Projektstruktur
```
passenger_wsgi.py Einstiegspunkt für Phusion Passenger (cPanel)
app/
__init__.py App-Factory, Security-Header, Fehlerbehandlung
config.py Konfiguration aus Umgebungsvariablen, Plausibilitätsgrenzen
routes.py Seiten: /, /disclaimer, /healthz
api.py JSON-API: /api/highscores, /api/runs
models.py SQLite: Schema, Highscores, Rate-Limit, Run-Tokens, CLI (flask scores …)
validation.py Namensbereinigung und Plausibilitätsprüfung
templates/ HTML (Disclaimer-Text liegt nur einmal vor)
static/
css/site.css
js/main.js Start: Dienste bauen, Phaser konfigurieren
js/config.js ALLE Balancing-Werte
js/content/texts.js Alle Texte (Durchsagen, Briefings, Credits …)
js/logic/ Reine Spiellogik ohne Phaser (per Vitest getestet)
js/scenes/ Boot, Menü, Disclaimer, Briefing, Spiel, HUD, Pause, Game Over …
js/entities/ Präsident, Gegner, Projektile, Geschütz, Kapsel
js/systems/ Orbital-Befehle, Effekte, Audio, Assets, Overlays, API-Client …
js/lib/phaser.min.js Phaser 3.90.0 (MIT)
assets/ Grafiken und Klänge (siehe docs/ASSETS.md)
tests/ pytest (Backend, Assets, Passenger), tests/js (Vitest), tests/e2e (Playwright)
docs/ Architektur, Game Design, Deployment, Assets, Testing
scripts/vendor-phaser.mjs kopiert Phaser aus node_modules nach app/static/js/lib
scripts/build_deploy_zip.py baut das Upload-Paket für cPanel (dist/glory_defense.zip)
```
## Konfiguration
| Umgebungsvariable | Standard | Bedeutung |
|---|---|---|
| `SECRET_KEY` | automatisch (`instance/secret_key`) | signiert Run-Tokens, hasht IP-Adressen für das Rate-Limit |
| `GLORY_DB_PATH` | `instance/glory_defense.sqlite3` | SQLite-Datei; relative Pfade gelten ab Projektordner |
| `GLORY_RATE_LIMIT_MAX` | `5` | Highscore-Einreichungen pro Client … |
| `GLORY_RATE_LIMIT_WINDOW` | `600` | … innerhalb dieser Sekunden |
| `GLORY_TRUST_PROXY` | `0` | `1` nur hinter einem vertrauenswürdigen Reverse-Proxy |
| `GLORY_NAME_BLOCKLIST` | `instance/name_blocklist.txt` | optionale Sperrliste für Namen auf der Ehrentafel |
Spielwerte (Leben, Schaden, Wellen, Abklingzeiten …) stehen zentral in
`app/static/js/config.js`.
## Weitere Dokumentation
- [docs/DEPLOYMENT_CPANEL.md](docs/DEPLOYMENT_CPANEL.md): Schritt-für-Schritt-Anleitung für cPanel
- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md): Aufbau von Backend und Frontend, Szenenfluss
- [docs/GAME_DESIGN.md](docs/GAME_DESIGN.md): Gegner, Waffen, Orbital-Befehle, Balancing
- [docs/ASSETS.md](docs/ASSETS.md): Quellen und Lizenzen aller Grafiken und Klänge
- [docs/TESTING.md](docs/TESTING.md): Tests ausführen und erweitern
## Disclaimer
Glory Defense ist **Satire und reine Fiktion**. Alle Figuren, Staaten, Organisationen
und Fraktionen sind frei erfunden. Ähnlichkeiten mit realen Personen, lebend oder
verstorben, sind nicht beabsichtigt und rein zufällig. Das Spiel vertritt keine
politische Position und richtet sich nicht gegen reale Parteien, Politikerinnen und
Politiker oder Länder. Die übertriebenen Durchsagen sind Gegenstand der Satire, nicht
ihre Botschaft.
Grafiken und Klänge stammen aus eigenen Entwürfen (CC0) und von
[Kenney](https://kenney.nl) (CC0). Schriften sind Systemschriften und werden nicht
mitgeliefert. Phaser steht unter der MIT-Lizenz. Details in
[docs/ASSETS.md](docs/ASSETS.md).