Docs Anleitungen

Debugging & Performance

Warum ein Tick langsam ist, warum ein Befehl nicht greift, warum das Spiel steht: nach Symptom eingrenzen, dann mit den mitgelieferten Live-Prüfskripten bestätigen.

Quittungen lesen

Die Quittung jedes Befehls ist die erste Spur:

r = g.cast(hero, "blizzard", x=tx, y=ty)
if not r:
    print(r.reason, r.verdict)     # rejected(…) und der Reason-Code
print(r.exec_us, r.engine_us)      # Mikrosekunden auf dem Spiel-Thread / davon in der Befehlsfunktion der Engine selbst

Normalerweise kostet ein Befehl auf dem Spiel-Thread einige bis einige hundert Mikrosekunden. Nach einem Batch-Block enthält g.last_receipts die Quittung jedes einzelnen Befehls dieses Batches.

Im Spiel beobachten

g.say(unit, "Rückzug")         # Chat-Blase über der Einheit (beeinflusst das Spiel nicht)
g.message("Creepen beginnt")   # eine Zeile im Nachrichtenbereich unten links (nur lokal sichtbar)

Ausgaben von print landen im Terminal, in dem der Bot läuft. Die wichtigsten Entscheidungen jedes Ticks ausgeben und dazu die Sprechblasen nutzen – das geht viel schneller, als den Code zu lesen.

Ein Tick ist langsam

Prüf zuerst, ob einer dieser Fälle vorliegt:

UrsacheLösung
Befehle einzeln gesendet, jeder wartet einen FrameIn with g.batch(): packen – Dutzende Befehle warten nur einmal
g.visible() / g.can_do() einzeln aufgerufen (jeder Aufruf geht über die Schnellspur und wartet einen Frame)Sichtbarkeit per u.visible_to() aus dem Snapshot; Machbarkeit gebündelt per g.can_do_many([...])
sleep oder Warten in on_tickSpielzeit merken und im nächsten Tick erneut prüfen
Teures in jedem Tick neu berechnen (Wegfindung, Scans der ganzen Karte)Ergebnisse cachen, nur alle paar Ticks neu rechnen. g.grid() hat einen eigenen 2-s-Cache, die Technologiestufen in g.stats() werden 5 s gecacht

Spiel steht / Bot wartet ewig auf Spielbeginn

SymptomMeistens
Hängt dauerhaft bei „warte auf Spiel“Falsche Instanznummer; oder das Spielfenster ist minimiert – minimiert steht die Spielsimulation (die Uhr läuft nicht)
Spiel läuft, Bot-Befehle bewirken nichtsBefehle an fremde Einheiten (Quittung not_owner); oder der Bot ist als observer verbunden (forbidden)
Befehl ist heldDie Einheit wird von einer höher priorisierten Schicht gehalten (Reflex-Schicht des Referenz-Brains, manueller Befehl aus der Konsole) und der Befehl nicht gesendet
Nach einer Pause gehen Befehle noch durchNormal: In der Pause steht die Engine-Uhr, aber Event-Dispatch und Befehlsausführung laufen weiter

Verbinden und Status prüfen

python -m openwar3 status --inst 5

Gibt den Verbindungsstatus aus: Spiel-PID, Veröffentlichungsintervall der Welt und Dauer jeder Erfassung, Zähler der Schnellspur, ob ein Spiel läuft, Einheitenzahl, Spieluhr.

Live-Prüfskripte

Starte eine Testinstanz und prüfe Punkt für Punkt, ob die SDK-Fähigkeiten auf deinem Rechner funktionieren:

python tools/sdk_live_check.py --inst 20                 # alles
python tools/sdk_live_check.py --inst 20 --only prod     # nur einen Abschnitt prüfen

Abschnitte: Batch, Zeit, Produktion, Befehle mit Warteschlange, Kampfwerte, Wegfindung, Fair-Modus. Jeder Abschnitt erteilt in einem echten Spiel Befehle, liest die Wirkung zurück und gibt die Zahl der bestandenen Prüfungen aus.

Offline-Tests brauchen kein laufendes Spiel:

python tools/run_tests.py

Typische „sieht aus wie ein Bug“-Fälle

  • Bau-Quittung angenommen, aber nie ein Fundament: Auch einen Punkt im Wald nimmt die Engine sofort an; scheitern tut der Befehl erst, wenn der Arbeiter ankommt. build_near verfolgt das und sperrt fehlgeschlagene Punkte eine Zeit lang.
  • Fähigkeit angenommen, aber nicht gewirkt: Unterbrochen, oder kein Mana. Im Tick danach prüfen, ob g.cooldown() läuft.
  • Angriff angenommen, aber die Einheiten greifen etwas anderes an: Für ein konkretes Ziel g.attack(units, enemy) verwenden (Rechtsklick-Semantik). Der rohe Angriffsbefehl ändert bei einem Ziel nur die Order, merkt sich das Ziel aber nicht und greift dann etwas anderes in der Nähe an.
  • Arbeiterzahl stimmt nicht: Arbeiter in der Goldmine fehlen im Snapshot.
  • Toter Held lässt sich nicht ausbilden: Helden sind einzigartig, du brauchst g.revive(altar); Wiederbeleben kostet Nahrung und geht erst etwa 3 Spielsekunden nach dem Tod.