Files
2026-09-24 17:57:54 +02:00

10 KiB
Raw Permalink Blame History

Game Design

Alle Werte stehen zentral in app/static/js/config.js. Die Tabellen hier geben den Stand zum Zeitpunkt des Schreibens wieder. Bei Abweichungen gilt config.js. Einheiten: Pixel (px), px/s, Millisekunden (ms), Lebenspunkte (LP).

Welt und Ton

  • Setting: Die fiktive „Vereinigte Erde“ wird von zwei außerirdischen Fraktionen angegriffen. Präsident Maximilian Valor verteidigt „den ewigen Frieden“ persönlich.
  • Satire: Durchsagen des „Ministeriums für Zuversicht“ zwischen den Wellen, Briefings, Game-Over-Texte. Der Spott gilt Militarismus und Propaganda im Allgemeinen, nicht realen Personen, Parteien oder Ländern. Namen und Begriffe sind eigenständig. Ein Test (tests/test_assets.py) verhindert Begriffe aus bekannten Vorbildern.
  • Arena: 2400 × 1600 px, größer als der Bildschirm (1280 × 720). Die Kamera folgt dem Präsidenten. Gegner außerhalb des Bildes zeigt das HUD als Randpfeile an.

Der Präsident

Wert
Leben 100 LP
Tempo 240 px/s (diagonal gleich schnell)
Hitbox Kreis, Radius 18 px
Unverwundbarkeit nach Treffer 500 ms (sonst tötet ein Schwarm in einem Frame)
Ausweichrolle 640 px/s für 320 ms, unverwundbar, Abklingzeit 1500 ms. Ohne Bewegung in Blickrichtung.
Heilung nach jeder Welle 15 LP

Treffer am Präsidenten beenden die Punkteserie. Gegnerprojektile fliegen während der Rolle hindurch, statt verschluckt zu werden.

Waffen

Karabiner »Zuversicht« Schrotflinte »Überzeugungskraft« Dienstpistole »Anstand«
Taste 1 2 3
Modus Dauerfeuer Einzelschuss Einzelschuss
Schaden 14 8 × 11 (Schrot) 16
Feuerpause 110 ms 650 ms 260 ms
Magazin / Reserve (Start, max.) 30 / 180, 270 6 / 24, 48 12 / unbegrenzt
Nachladen 1,5 s 1,9 s 1,1 s
Streuung 3° 24° Fächer 2°
Reichweite 820 px 420 px 700 px
Schaden/s (Feuerstoß / mit Nachladen) 127 / 88 135 / 91 62 / 45
  • Leeres Magazin lädt automatisch nach. Ein Waffenwechsel bricht das Nachladen ab.
  • Sind Magazin und Reserve leer, wechselt das Spiel automatisch zur Dienstpistole. Ohne Munition ist man also nie wehrlos.
  • Die Nachschubkapsel füllt die Reserve aller Waffen auf das Maximum.

Gegner

Die Schwärmer (insektoid, Nahkampf)

Krabbler (klein) Sprungkralle (mittel) Brutmutter (Elite)
Leben 20 60 450
Tempo 175 125 58
Kontaktschaden (Abklingzeit) 6 (700 ms) 14 (800 ms) 28 (1000 ms)
Punkte 10 30 250
Budgetkosten 1 3 15
Gruppengröße 4–8 1–3 1
Verhalten Umzingeln Sprungangriff Brüten
  • Umzingeln: Jeder Krabbler bekommt einen eigenen Anflugwinkel auf einem Kreis (130 px) um den Präsidenten. Ab 170 px Abstand greift er direkt an. Ein Rudel kommt dadurch von mehreren Seiten.
  • Sprungangriff: Verfolgen. Ab 260 px setzt die Sprungkralle 450 ms an: sie steht still, färbt sich rot und wird größer. Dann springt sie mit 560 px/s für 380 ms in die beim Ansetzen festgelegte Richtung. Wer auf die Vorwarnung reagiert, kann ausweichen. Abklingzeit 2,4 s.
  • Brüten: Langsames Verfolgen, alle 5 s schlüpfen bis zu 3 Krabbler, höchstens 6 gleichzeitig lebende Nachkommen.

Die Blechlegion (Roboter, Fernkampf)

Nieter-Drohne (klein) Blechsoldat (mittel) Walzmeister (Elite)
Leben 30 90 700
Tempo 95 78 44
Wunschabstand 220–340 px 200–380 px 260–460 px
Angriff Einzelschuss 7, alle 1,5 s 3er-Salve à 8, alle 2,3 s Fächer aus 7 × 10 (50°), alle 2,7 s + Mörser
Projektiltempo 330 400 290
Punkte 20 50 400
Budgetkosten 2 4 18
Gruppengröße 2–3 1–3 1
Verhalten Abstand halten Flankieren Belagern
  • Abstand halten: Zu weit weg → annähern, zu nah → zurückweichen, dazwischen seitlich ausweichen. Die Richtung wechselt zufällig alle 1,4–3,2 s. So sind Fernkämpfer kein stehendes Ziel.
  • Flankieren: Ziel ist ein Punkt, der gegenüber der Linie Präsident→Gegner um 70° gedreht ist (Abstand 290 px). Der Blechsoldat schwenkt also seitlich ein, statt frontal anzulaufen. Dort angekommen, hält er Abstand.
  • Mörser (Walzmeister): Alle 5,2 s zielt er auf die aktuelle Position des Präsidenten. Eine rote Bodenmarkierung (Radius 90 px) füllt sich 1,4 s lang, dann folgt der Einschlag (26 Schaden). Stehenbleiben ist keine Option.
  • Frisch gespawnte Gegner schießen frühestens nach etwa 0,5–1,6 s. Das ist fair, weil sonst Salven aus dem Nichts kämen.

Allgemeine KI

Alle Bewegungen sind Steuerungsvektoren (logic/steering.js), die sich überlagern. Eine Separation (Radius 34 px + Gegnerradius) schiebt Gegner auseinander und verhindert Klumpen. Die Geschwindigkeit wird weich nachgeführt (18 % pro Frame), damit Richtungswechsel nicht ruckeln. Nahkämpfer bleiben am Rand des Präsidenten stehen, statt sich auf seinen Mittelpunkt zu drängen.

Orbital-Befehle

Eingabe: Q gedrückt halten und die Richtungsfolge mit Pfeiltasten oder WASD eingeben. Während der Eingabe steht der Präsident still. Das Ziel ist die Mausposition, begrenzt auf 560 px Entfernung und die Arena. Falsche Eingaben leeren den Puffer, man kann sofort neu ansetzen. Keine Folge ist der Anfang einer anderen, und jede beginnt mit einer anderen Richtung (wird getestet). Die Codes sind eigene Erfindungen. Der Orbitalschlag-Code ↑ → ↓ ↓ stammt aus der Projektvorgabe. Ein Test stellt sicher, dass keiner der Codes einem Code aus einem bekannten Spiel mit ähnlicher Mechanik entspricht.

Befehl Code Verzögerung Abklingzeit Wirkung
Orbitalschlag »Morgenröte« ↑ → ↓ ↓ 2,5 s 30 s Radius 150 px, 260 Schaden an Gegnern, 40 am Präsidenten, falls er im Radius steht
Nachschubkapsel »Fürsorgepaket« ← ← ↓ → 3 s 45 s Einschlag: Radius 70 px, 120 Schaden (20 am Präsidenten). Danach liegt 30 s eine Kapsel: +50 LP, volle Reserve.
Geschütz »Wachsamer Nachbar« → ← → ↑ ↑ 3 s 60 s Einschlag: Radius 60 px, 80 Schaden (15 am Präsidenten). Danach 25 s Geschütz: zielt auf den nächsten Gegner (480 px), 12 Schaden alle 150 ms

Bis zum Einschlag zeigt eine Bodenmarkierung den genauen Wirkungsradius, einen Strahl aus dem Orbit und einen Countdown. Kapsel und Geschütz blinken in ihren letzten 3 Sekunden.

Wellen

  • Budget: B(n) = 8 + 5 · (n − 1)^1,15, gerundet. Gegner „kosten“ Budget (Tabellen oben).
  • Fraktionen: Wellen 1–2 nur Schwärmer, 3–4 nur Blechlegion, ab 5 gemischt.
  • Eliten: jede 5. Welle, Anzahl = Welle / 5 (max. 4). Die erste Elite ist eine Brutmutter, danach wechselt die Fraktion.
  • Zusammenstellung: Zuerst werden Eliten gekauft (mindestens 30 % des Budgets bleiben für Fußvolk). Dann gehen 10 % + 4 % · (n − 1) des Restbudgets (max. 50 %) in mittlere Gegner, der Rest in kleine. Gruppengrößen je Typ.
  • Ablauf: Gruppen erscheinen nacheinander (1,3–3 s Abstand, in späten Wellen bis zu 55 % dichter) an zufälligen Arenarändern, nie näher als 420 px am Präsidenten. Leben mehr als 60 Gegner, wartet der Spawner.
  • Skalierung ab Welle 6: +7 % Leben und +1,2 % Tempo pro Welle (Tempo max. +30 %).
  • Pause: 8 s zwischen den Wellen mit Propaganda-Durchsage (ohne direkte Wiederholung), Wellenbonus und Heilung.
Welle Budget Eliten Leben × Tempo × Ø Gegner
1 8 0 1,00 1,00 8
3 19 0 1,00 1,00 9
5 33 1 1,00 1,00 14
10 71 2 1,35 1,06 23
15 112 3 1,70 1,12 37
20 156 4 2,05 1,18 52

(Ø Gegner ohne ausgebrütete Krabbler, gemittelt über 50 Zufalls-Seeds.)

Punkte

  • Abschuss: Punkte des Gegnertyps × Multiplikator
  • Serie: Jeder Abschuss innerhalb von 3 s nach dem letzten setzt die Serie fort. Alle 5 Abschüsse steigt der Multiplikator um 0,5, bis maximal ×4.
  • Ein Treffer am Präsidenten beendet die Serie.
  • Wellenbonus: 100 × Wellennummer (ohne Multiplikator)

Plausibilitätsgrenzen im Backend

app/config.py (GAME_RULE_DEFAULTS) lehnt Einreichungen ab, wenn

  1. die gemeldete Spieldauer länger ist als die Zeit seit Ausgabe des Run-Tokens (+30 s Toleranz). Pausen zählen nicht zur Spieldauer, daher darf sie kürzer sein.
  2. die Welle in der Spieldauer nicht erreichbar ist: Dauer ≥ (Welle − 1) · 5 s, denn jede Pause dauert 8 s.
  3. die Punkte über 2000 + 200 · Dauer in s liegen.

Herleitung der 200 Punkte/s: Testläufe (Bot mit perfektem Zielen) liegen bei etwa 15–20 Punkten/s. Eine grobe Abschätzung für eine sehr starke Runde (Welle 25 nach 20 Minuten, Multiplikator dauerhaft hoch) ergibt 80–120 Punkte/s im Schnitt. 200/s im Durchschnitt über die ganze Runde lässt also Luft, schneidet aber Fantasiewerte ab. Der Sockel von 2000 deckt kurze Runden mit Glückstreffern ab. Wer Punktwerte in config.js stark erhöht, muss diese Grenze mit anpassen.

Wie jede Prüfung im Backend verhindert das kein gezieltes Cheaten (die Spiellogik läuft im Browser). Für Ausreißer gibt es die Moderationsbefehle (siehe docs/DEPLOYMENT_CPANEL.md).

Schwierigkeit

Ein Testbot (perfektes Zielen, weicht nur zurück, ohne Rolle, Orbital-Befehle und Nachschub) erreicht Welle 5 nach etwa 2 Minuten. Die erste Elite-Welle mit Brutmutter ist bewusst die erste echte Hürde. Wer Rolle, Orbitalschlag und Nachschub nutzt, kommt deutlich weiter. Stellschrauben, wenn das Spiel zu schwer oder zu leicht wirkt:

  • WAVES.budgetGrowth / budgetExponent: Größe der Wellen
  • WAVES.hpScalePerWave: Zähigkeit in späten Wellen
  • PLAYER.waveClearHeal, ORBITAL.commands[supply].heal: Heilung
  • ENEMY_TYPES.*.contactDamage / attack.damage: Schaden der Gegner

Rückmeldung (Feedback)

  • Trefferblitz (weiß), Funken in Fraktionsfarbe, Punkte als schwebender Text
  • neue Multiplikatorstufe als „SERIE ×2“ über dem Präsidenten
  • Explosionen mit Feuer, Rauch, Lichtblitz, Brandspur und Wirkungsring (zeigt den Radius)
  • Bildschirmwackeln bei Treffern und Explosionen, rote Vignette bei Schaden, pulsierender Rand unter 30 % Leben
  • Ausweichrolle mit Nachbild
  • Randpfeile für Gegner außerhalb des Bildes (Eliten in Gold)
  • Ton: Kenney-Klänge mit leichter Tonhöhenstreuung, synthetischer Ersatz, Marschmusik (in der Pause gedämpft), Jingles für Wellenstart, Wellenende, Elite-Alarm und Game Over