slop game oder so
This commit is contained in:
@@ -0,0 +1,218 @@
|
||||
# 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)).
|
||||
|
||||

|
||||

|
||||
|
||||
- **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).
|
||||
Reference in New Issue
Block a user