# Gameplay-Mods

> Ein Schema ist nicht nur eine KI, die für dich spielt – es kann auch ein Regelwerk sein: Du spielst selbst im Spielfenster, die Mod richtet den Start ein, schickt Gegnerwellen, verteilt Belohnungen, gibt dir Buttons und Auswahlkarten auf dem Bildschirm und entscheidet über Sieg und Niederlage. Von openwar3.Mod erben – eine Datei ist ein ganzes Spielprinzip.

Quelle: https://war3ai.com/de/docs/mods/

[KI-Schemata](https://war3ai.com/de/docs/schemes/) gibt es in zwei Arten: `kind: bot` ist eine KI, die für dich spielt; `kind: mod` ist **ein Regelwerk** – du spielst selbst im Spielfenster, und die Mod stellt die Aufgaben: wie der Start aussieht, wann nach Zeit oder Event Gegner erscheinen, welche Belohnungen es gibt, welche Buttons und Auswahlkarten du auf dem Bildschirm bekommst und wann du gewonnen hast.

Eine Mod nutzt ausschließlich vorhandene Fähigkeiten: [Oberfläche & Eingabe](https://war3ai.com/de/docs/ui-input/) (klickbare Buttons, Karten, Hotkeys, Klicks auf den Boden), [Canvas](https://war3ai.com/de/docs/canvas/) (Panels, Fortschrittsbalken, Routen), [JASS-Kanal](https://war3ai.com/de/docs/jass/) (Einheiten erzeugen, Werte ändern, Gegenstände vergeben) und den Event-Stream (Tode, Stufenaufstiege, gewirkte Fähigkeiten, Chat).

## Zwei Beispiele

In Farsight unter „KI-Schemata“ → „Eingebaut“ auswählbar:

| Mod | Spielprinzip | Genutzte Fähigkeiten |
|---|---|---|
| **Helden-Roguelike** `builtin/hero-roguelike` | Du hast nur einen Paladin, und Welle um Welle rücken Gegner von allen Seiten an; bei jedem Stufenaufstieg wählst du in der Bildschirmmitte eine von drei Verstärkungen (das Spiel pausiert während der Wahl); überstehst du 10 Wellen, gewinnst du, stirbt der Held, verlierst du | `g.ui.choice` (klickbare Karten + Pause), Events `hero.levelup` / `killed` / `spell.cast`, Chat `-help`, Heldenwerte per JASS ändern, Gegenstände vergeben |
| **Endlose Verteidigung** `builtin/endless-defense` | Gegner laufen vom gegenüberliegenden Startpunkt entlang der roten Linie am Boden auf dein Hauptgebäude zu; für jede abgewehrte Welle gibt es Gold; per Button auf dem Bildschirm oder mit F7 rufst du die nächste Welle früher, Belohnung ×1.5; F8 und dann Linksklick auf den Boden setzt einen kostenlosen Wachturm (Rechtsklick bricht ab) | `g.ui.button`, `g.ui.hotkey`, `g.ui.mouse` (Klicks auf den Boden abfangen), Canvas-Panel / Fortschrittsbalken / Route, Gegner erzeugen und Gold geben per JASS |

Beide Beispiele haben je etwa 150 Zeilen; der Code liegt in `brains/examples/mod_hero_roguelike.py` und `brains/examples/mod_endless_defense.py`.

```bash
python tools/play.py --bot brains/examples/mod_hero_roguelike.py --inst 9     # Spiel starten, die Mod übernimmt, du spielst im Spielfenster
```

## Eine Mod schreiben

```python
from openwar3 import Mod

class Survive(Mod):
    name = "survive"

    def on_start(self, g):
        super().on_start(g)                        # Einzelspieler-Prüfung + Computergegner ruhigstellen
        self.foe = self.wave_player(g)             # ein leerer Slot als „Wellenspieler“: mit niemandem verbündet, keine Computer-KI
        self.every(30, self.wave)                  # alle 30 Spielsekunden eine Welle (steht während der Pause)
        g.ui.hotkey("F7", lambda g, ev: self.wave(g))

    def wave(self, g):
        self.spawn_ring(g, self.foe, "ugho", 6, self.home(g), 1400, attack_to=self.home(g))

    def on_event(self, g, ev):
        if ev.kind == "unit.died" and ev.type == "htow":
            self.finish("loss", "Hauptgebäude zerstört")
```

`Mod` bietet zusätzlich zu `Bot`:

| Methode / Attribut | Beschreibung |
|---|---|
| `on_start / on_tick / on_event / on_end` | wie beim Bot; wenn du `on_start` / `on_tick` überschreibst, zuerst `super()` aufrufen |
| `every(Sekunden, fn, first=)` / `after(Sekunden, fn)` | Timer nach **Spielzeit**, der Callback ist `fn(g)` |
| `finish(result, reason)` | beendet die Partie (`'win'` / `'loss'` / `'unknown'`): Der Runner stoppt im nächsten Tick, in der Bildschirmmitte erscheint ein Ergebnis-Panel, und das Ergebnis des Schemas wird entsprechend erfasst |
| `wave_player(g)` | erster leerer Spieler-Slot, als Wellenspieler gedacht |
| `spawn_ring(g, Spieler, Einheit, Anzahl, Mitte, Radius, attack_to=)` | erzeugt Einheiten auf einem Kreis, auch Dutzende pro Welle ohne Ruckeln; gibt JASS-Handles zurück |
| `alive_of(g, Spieler)` / `attack_move_all(g, Spieler, Punkt)` | lebende Einheiten eines Spielers / alle per Angriffsbewegung dorthin schicken (alle paar Sekunden aufrufen, dann verfolgen die Gegner dich) |
| `home(g)` / `hud(g, Titel, Zeilen)` | Position deines Hauptgebäudes / Info-Panel oben rechts |
| `neutralize_ai = True` | stellt den Computergegner beim Start ruhig: Seine Einheiten werden alle 5 Sekunden angehalten, Gold und Holz auf null gesetzt. Auf Melee-Karten gibt es immer einen Computergegner – wenn die Mod eigene Regeln macht, soll er nicht dazwischenfunken |
| `single_player_only = True` | verweigert den Start, wenn weitere menschliche Spieler da sind (JASS, das die Welt verändert, würde bei anderen einen Desync auslösen) |
| `linger_s = 6` | wie viele Sekunden der Ergebnisbildschirm nach der Entscheidung stehen bleibt, bevor die Partie endet |

`finish()` gibt es auch auf `Bot`: Auch ein normaler Bot kann das Ende selbst verkünden.

## Als Schema verpacken und teilen

In `scheme.json` `"kind": "mod"` eintragen und in der Einstiegsdatei eine Unterklasse von `Mod` definieren:

```json
{"id": "survive", "name": "10 Wellen halten", "kind": "mod", "entry": "survive.py", "class": "Survive"}
```

Eine Mod läuft grundsätzlich **nicht im Fair-Modus** (sie ist der Schiedsrichter, der die Aufgaben stellt, und muss die ganze Karte sehen und die Welt verändern) und entscheidet **Sieg und Niederlage nicht nach Melee-Regeln** (das Ergebnis meldet `finish`); `fair` / `judge` im Manifest haben keine Wirkung. zip-Export, Import, Vertrauen und Ergebnisse funktionieren genau wie bei Bot-Schemata, siehe [KI-Schemata](https://war3ai.com/de/docs/schemes/). Auch eine Mod ist Code: Fremde Mods müssen vor dem ersten Start ebenfalls als vertrauenswürdig bestätigt werden.

## Gemessen

2026-09-25, auf der Testinstanz:

- **Helden-Roguelike**: Die erste Welle erscheint, das Panel oben rechts läuft mit; Held auf Stufe 3 gebracht → Karten erscheinen in der Bildschirmmitte, die Spieluhr steht; zweimal eine Karte angeklickt → beide Verstärkungen wirken (Stärke 22 → 27), die Uhr läuft weiter.
- **Endlose Verteidigung**: Panel, Route am Boden und Buttons sind da; F8 + Klick auf den Boden → neben dem Hauptgebäude steht ein Turm mehr; Button geklickt, bevor die Welle erledigt ist → Hinweis „Diese Welle ist noch nicht erledigt“.

## Grenzen

- **Nur Einzelspieler**: Einheiten erzeugen und Werte ändern läuft über den JASS-Kanal und führt im Multiplayer zu Desyncs. Das folgt aus dem Lockstep-Modell; Multiplayer-Spielprinzipien müssen auf einen Synchronisationskanal warten (siehe [Roadmap](https://war3ai.com/de/roadmap/)).
- Eine Mod sieht die ganze Karte – sie stellt die Aufgaben, sie ist kein Spieler.
- Der Computergegner auf Melee-Karten wird nur „ruhiggestellt“, nicht entfernt (ein Entfernen würde nach Melee-Regeln einen Sieg auslösen).
