Docs Spielerweiterungen

RPG-Begleiter

Ein KI-Begleiter für RPG- und benutzerdefinierte Karten: Er folgt dir, kämpft mit, heilt dich bei niedrigen HP und plaudert mit dir. Vier Modi – eine Klasse erben, ein paar Attribute ändern, fertig ist dein eigener Begleiter.

Nicht nur für Melee-Partien. In RPG- und benutzerdefinierten Karten kannst du dir einen KI-Begleiter an die Seite stellen: Er folgt dir, hilft dir gegen Monster, heilt dich, wenn deine HP knapp werden, und plaudert mit dir, wenn gerade nichts los ist – die Sätze können auch von einem lokalen LLM kommen.

Wie du es nutzt, entscheidest du selbst. Das Ganze besteht aus drei API-Schichten, von unten nach oben; jede davon lässt sich direkt verwenden:

SchichtWas es istGeeignet für
JASS-Kanal g.jassDie 1291 JASS-Funktionen, die Kartenautoren zur Verfügung stehen, direkt per Name aufrufbar (Einheiten erstellen, Bündnisse setzen, Gegenstände geben, umbenennen, Text anzeigen, Helden wiederbeleben …)eigene Spielideen bauen
Komfort-APIsg.spawn, g.set_alliance, g.player_slots, g.show_text, g.map_data: die häufigsten Aufgaben fertig verpackteigene Hilfsskripte schreiben
Begleiter-Frameworkopenwar3.companion.Companion + openwar3.talk.Talk: erben, ein paar Attribute ändern – und du hast einen Begleiter, der folgt, mitkämpft, heilt und plauderteinfach einen Begleiter haben wollen

Nur für Offline-Spiele und selbst gehostete LAN-Spiele. Einheiten erstellen, Bündnisse setzen und Ähnliches verändert die Welt einseitig auf deinem Rechner: In Einzelspieler-Partien (gegen den Computer) ist das kein Problem; in Mehrspieler-Partien geraten die anderen Spieler dadurch aus dem Takt (Desync). Deshalb lässt der JASS-Kanal in Mehrspieler-Partien nur lesende Funktionen zu, und der Begleiter fällt automatisch auf „nur reden“ zurück.

Am schnellsten: in Farsight mit einem Klick starten

  1. Karte wählen: in Farsight auf der Seite „Instanzen & Start“ → „Einstellungen fürs nächste Spiel“ → Karte eine RPG-Karte wählen (alle Karten unter Scenario und Download im Ordner Maps des Spielverzeichnisses werden aufgelistet, z. B. (4)WarChasers).
  2. Schema wählen: auf der Instanzkachel im Dropdown „KI-Schema“ Begleiter-Beispiel (buddy) wählen → „Festlegen“.
  3. Test starten: Sobald das Spiel läuft, spielst du selbst im Spielfenster. Der Begleiter – ein Paladin namens „Lumi“ – erscheint neben dir.

Auch per Kommandozeile möglich:

python tools/play.py --bot brains/examples/buddy.py --inst 20 --rpg --map "<Spielverzeichnis>\Maps\Scenario\(4)WarChasers.w3m"

--rpg (im Schema-Manifest "judge": false) bedeutet, dass Sieg und Niederlage nicht nach Melee-Regeln entschieden werden: In RPGs lassen sich Helden wiederbeleben, und „alle Gebäude weg = verloren“ gibt es dort auch nicht. Viele RPG-Karten bleiben nach dem Laden bei „Beliebige Taste drücken, um fortzufahren“ stehen; erkennt das SDK „in der Partie, aber die Spieluhr steht dauerhaft bei 0“, drückt es selbst einmal die Leertaste (g.press_to_continue(); schickt nur eine Tastennachricht ans Spielfenster und stiehlt nicht den Fokus).

Einen eigenen Begleiter schreiben

from openwar3.companion import Companion
from openwar3.talk import Talk

class MyBuddy(Companion):
    mode = "ally"                        # Modus, siehe Tabelle unten
    unit = "Hpal"                        # was erstellt wird: jeder Vier-Zeichen-Code, auch von der Karte definierte
    nickname = "Lumi"
    heal = ("holybolt", "AHhb", 0.55)    # (Order-String, zu lernende Fähigkeit, heilen, wenn die HP des Meisters unter diesen Anteil fallen); None = nicht heilen
    follow_distance = 350
    talk = Talk(persona="Fröhlicher kleiner Paladin, der seinen Meister gern anfeuert")

Vier Modi

modeWer der Begleiter istBeschreibung
ally (Standard)belegt einen freien Spielerplatz als dein VerbündeterHat eigene Farbe und eigenen Namen (Punktetafel und Verbündeten-Fenster zeigen nickname); du kannst ihn nicht steuern, er kämpft selbstständig. Das Framework setzt automatisch Bündnis + geteilte Sicht
ownwird unter deinem Namen erstelltDu kannst ihn jederzeit selbst befehligen; wenn du dich nicht um ihn kümmerst, steuert ihn die KI für dich
adoptübernimmt eine vorhandene Einheit der Karteadopt(g) überschreiben und diese Einheit zurückgeben (ein Haustier oder Gefolgsmann, den die Karte dir gibt)
voiceerstellt keine Einheit, redet nurGesellschaft und Hinweise; verändert die Welt nicht, funktioniert auch in Mehrspieler-Partien

Ohne freien Platz fällt ally automatisch auf own zurück; in Mehrspieler-Partien oder wenn sich keine Einheit erstellen lässt, auf voice.

Ein Begleiter im Modus ally hält sich an „die beste Einheit, die dieser Platz gerade hat“ (Helden zuerst), nicht stur an eine bestimmte Einheit. Im Test hat eine Karte den Begleiter für einen echten Spieler gehalten, den Paladin gelöscht und stattdessen einen Kartenhelden ausgegeben – der Begleiter übernimmt diesen Helden dann einfach und lernt auch die Fähigkeiten, die die Karte für ihn vorsieht. Stirbt der Held, wird er möglichst an Ort und Stelle wiederbelebt; belebt ihn die Karte selbst wieder, macht der Begleiter mit ihm weiter.

Was in jedem Tick passiert

Die Regeln werden der Reihe nach geprüft; die erste zutreffende wird ausgeführt:

ReihenfolgeVerhaltenBedingungEinstellbar
1RückzugEigene HP unter 25 % und Gegner in der Nähe: hinter den Meister zurückziehenretreat_at
2HeilenHP des Meisters unter dem eingestellten Wert, Fähigkeit bereit, Entfernung höchstens 900heal (None schaltet es ab)
3MitkämpfenGegner in der Nähe des Meisters: wer den Meister angreift > wen der Meister angreift > der nächsteassist_radius, oder pick_target überschreiben
4FolgenZu weit vom Meister entfernt: aufschließen; ab einer gewissen Entfernung direkt zurücklaufen, ohne sich in Kämpfe verwickeln zu lassenfollow_distance, leash
5PlaudernKeine Gegner in der Nähe: alle 1–2.5 Minuten ein SatzSprüche

„Gegner“ richtet sich nach den Bündnissen im Spiel (alle 20 Sekunden aktualisiert). RPG-Karten haben oft mehrere verbündete Parteien; man kann also nicht einfach „alle Spieler außer mir“ als Gegner behandeln.

Überschreibbare Hooks: find_master (wer der Meister ist; Standard: der Held mit der höchsten Stufe des lokalen Spielers), adopt, pick_target, on_poke (der Meister hat den Begleiter mit Rechtsklick angeklickt) sowie die Bot-Hooks on_start / on_tick / on_event / on_end. Wie oft geheilt, mitgekämpft, getötet, gefolgt, zurückgezogen, gesprochen und wiederbelebt wurde, steht in self.stats und wird am Ende ausgegeben.

So sprichst du ihn an

  • Chat-Befehle: im Chatfeld -follow (folge mir), -stay (bleib hier und halte die Stellung), -heal (sofort heilen) oder -hi (begrüßen) eintippen. Die Befehlsliste änderst du in commands, die Reaktionen durch Überschreiben von on_command.
  • Rechtsklick auf den Begleiter: löst on_poke aus. Im Beispiel heilt er den Meister einmal, falls dieser nicht volle HP hat, sonst sagt er etwas.
  • Porträt-Dialog: Begrüßung, Meister gefallen, Meister steigt auf, Begleiter wieder da – diese Sätze laufen über den Porträt-Dialog des Spiels (unten erscheint das Porträt des Begleiters, auf dem Bildschirm ein Untertitel); alles andere als Sprechblase über dem Kopf.
  • Statusanzeige: ein Panel links am Bildschirmrand mit HP-Balken des Begleiters, was er gerade tut, Stimmung (fröhlich / aufgeregt / angespannt / ängstlich / traurig), Kills und Heilungen. Es wird mit dem Canvas gezeichnet und ist auch in Mehrspieler-Partien sicher.

Sprechen – und lokale LLMs

Talk wählt Sprüche passend zum Ereignis und zeigt sie als Sprechblase über dem Kopf; im Modus voice oder wenn keine Sprechblase möglich ist, unten links auf dem Bildschirm. Jeder Satz landet außerdem im Schema-Log, sodass du später nachlesen kannst, was der Begleiter gesagt hat.

EreignisWannEreignisWann
hellogerade angekommenmaster_lowMeister hat kaum noch HP
pokeMeister klickt ihn mit Rechtsklick anmaster_levelupMeister steigt eine Stufe auf
fightKampf beginntmaster_died / master_backMeister fällt / ist wiederbelebt
killMonster getötet (nennt den Namen des Monsters)buddy_low / buddy_died / buddy_backBegleiter selbst kaum noch HP / gefallen / wieder da
healedMeister geheiltidle / itemPlaudern / etwas aufgehoben

In den Sprüchen kannst du die Platzhalter {master}, {me}, {map}, {enemy}, {level} und {item} verwenden; die Sprüche selbst änderst du direkt in talk.lines, die Abklingzeit in talk.cooldown.

Lokales LLM anbinden: Talk(llm=LocalLLM(url, model)) – jede OpenAI-kompatible API funktioniert (LM Studio, Ollama …). Das Modell antwortet in einem Hintergrund-Thread, gesprochen wird erst, wenn die Antwort da ist; läuft es nicht, gibt es ein Timeout oder einen Fehler, kommt ein fester Spruch – das Spiel hängt nie. Anfragen gehen nur an die lokale Adresse, die du angibst; Inhalt ist, was im Spiel passiert (wie der Meister heißt, gegen welche Monster gekämpft wurde).

Einheitennamen in benutzerdefinierten Karten

Einheiten, Gegenstände und Helden in RPG-Karten sind meist von der Karte selbst angelegt (Vier-Zeichen-Codes wie HC07, I00A) und stehen nicht in der eingebauten Namenstabelle. g.map_data liest direkt die Kartendatei der aktuellen Partie:

md = g.map_data
md.name_of("HC07")        # 'Optimus Primo' – von der Karte geänderte Namen haben Vorrang
md.hero_names("HC07")     # Liste der Heldentitel
md.hero_skills("OC10")    # Fähigkeiten, die die Karte für diesen Helden vorsieht
md.tooltip("I00A")        # Beschreibungstext

Geschützte oder optimierte Karten (viele beliebte RPGs) enthalten keine Standard-Objektdatendateien; die Namen werden dann aus den Textdaten der Karte gelesen. Im Test wurden alle 38 RPG- und benutzerdefinierten Karten auf dem Rechner erfolgreich geparst, bei 37 davon kamen Einheitennamen heraus.

Als Schema teilen

Ein Begleiter ist einfach eine Unterklasse von openwar3.Bot und lässt sich als KI-Schema mit anderen teilen. Im Manifest stehen zwei zusätzliche Einträge:

{"id": "my-buddy", "name": "Mein Begleiter", "entry": "my_buddy.py", "fair": false, "judge": false}

"fair": false: nötig für den JASS-Kanal (Einheiten erstellen, Bündnisse setzen); "judge": false: Sieg und Niederlage nicht nach Melee-Regeln entscheiden.

Testprotokoll

2026-09-24, Testinstanz, Karte WarChasers, 2× Geschwindigkeit:

  • JASS-Kanal: alle 18 Prüfungen bestanden – Spielerplätze, Umrechnung zwischen Einheit und Handle hin und zurück, Rückgabewerte vom Typ real, String-Parameter, Einheit für einen freien Platz erstellen, Bündnis setzen, umbenennen, Einheit löschen; Aufrufe über eine Spieler-Spur und eine falsche Parameteranzahl wurden korrekt abgelehnt.
  • Begleiter: bestätigt „Beliebige Taste drücken“ selbst → erscheint neben dem Meister und grüßt → folgt in den Kreis der Macht zur Heldenwahl, bekommt von der Karte einen Helden und übernimmt ihn → folgt (200–400 vom Meister entfernt) → kämpft gegen Monster und sagt beim Kill „Sauber!“ → zieht sich bei wenig HP zurück → wird nach dem Tod von der Karte wiederbelebt und folgt weiter.

Was noch fehlt

  1. Beliebiger Chattext des Spielers lässt sich nicht lesen. Feste Chat-Befehle funktionieren bereits; damit der Begleiter wirklich frei mit dir plaudern kann, muss erst der Text selbst ausgelesen werden.
  2. Der Begleiter kennt die Spielmechanik einer bestimmten Karte nicht (Quests, Läden, Story). Er kann allgemein folgen, mitkämpfen und heilen; soll er eine bestimmte Karte verstehen, schreibst du das für diese Karte in die Unterklasse – g.map_data liefert Namen, g.jass ruft jede Funktion auf. Genau dieser Teil bleibt dir überlassen.