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).
- 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
- Steuerung
- Lokales Setup
- Starten
- Tests
- Projektstruktur
- Konfiguration
- Weitere Dokumentation
- 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.
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):
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:
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:
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):
npm install
Starten
Bei aktivierter venv:
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.
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: Schritt-für-Schritt-Anleitung für cPanel
- docs/ARCHITECTURE.md: Aufbau von Backend und Frontend, Szenenfluss
- docs/GAME_DESIGN.md: Gegner, Waffen, Orbital-Befehle, Balancing
- docs/ASSETS.md: Quellen und Lizenzen aller Grafiken und Klänge
- 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 (CC0). Schriften sind Systemschriften und werden nicht mitgeliefert. Phaser steht unter der MIT-Lizenz. Details in docs/ASSETS.md.

