Docs Grundlagen

Die 15 Regeln

Jede einzelne stammt aus echten Spielen. Prüf deinen Bot beim Schreiben dagegen – das spart den Großteil der Fehlersuche.

Gib diese Seite zusammen mit api.json an dein LLM – der Bot, den es schreibt, erspart dir viele Umwege.

Zustand lesen

1. Nicht lesbar heißt None, nicht 0

resources(), time_of_day(), production() und cooldown() können alle None zurückgeben (Ladebildschirm, Einheit ohne Detaildaten, Gebäude produziert gerade nichts …). Erst prüfen, dann verwenden:

res = g.resources()
if res is None:
    return

2. Einheiten per Handle erkennen, nicht per Adresse

Adressen werden für neue Einheiten wiederverwendet: Eine alte Adresse kann auf eine frisch erschienene Einheit zeigen. Um dir eine Einheit über mehrere Ticks zu merken, speichere u.handle und hol sie mit g.unit(handle) zurück.

3. Der Event-Stream ist global

In production.done und unit.died stecken auch Events von Gegnern und Creeps. Filtere nach ev.owner (oder dem Gebäude-Handle):

if ev.kind == "production.done" and ev.owner == g.me():
    ...

4. Arbeiter in der Goldmine fehlen im Snapshot

In dem Moment, in dem ein Arbeiter die Goldmine betritt, verschwindet er aus dem Snapshot (unit.removed, nicht tot). Um zu zählen, wie viele an jeder Mine arbeiten, führ selbst Buch und streich keine Einträge anhand des Snapshots – sonst schickst du zusätzliche Arbeiter an volle Minen.

Befehle erteilen

5. „Angenommen“ ≠ erledigt

Auch einen Bauplatz im Wald nimmt die Engine sofort an; scheitern tut der Befehl erst, wenn der Arbeiter ankommt. Fähigkeiten können unterbrochen werden. Die Wirkung siehst du in Snapshot und Events: Zum Bauen build_near (verfolgt, ob das Fundament erscheint), bei Fähigkeiten prüfen, ob g.cooldown() läuft.

6. Unsichtbare Ziele kannst du nicht angreifen

Zielbefehle auf Gegner im Nebel werden mit Reason-Code 1001 abgelehnt. Um einen Gegner im Nebel zu verfolgen, schick attack_move an seine zuletzt gesehene Position.

7. Nur untätigen Einheiten Befehle geben

Denselben Befehl in jedem Tick erneut an dieselbe Einheit zu senden, unterbricht sie: Soldaten zucken auf der Stelle, der Abbauzyklus der Arbeiter beginnt von vorn. Ob eine Einheit untätig ist, prüfst du mit g.order_of(u) (enthält auch die Befehle, die du in diesem Tick gerade erteilt hast), nicht mit u.order aus dem Snapshot (der hinkt noch hinterher).

8. Shift heißt nur „direkt hinter den aktuellen Befehl“

Die Engine kennt kein „ans Ende anhängen“: Sendest du nacheinander B und C mit queue='after', bekommst du A, C, B. Für eine Reihe von Punkten in fester Reihenfolge nimm g.path(units, points), für mehrere Gebäude mit einem Arbeiter g.build_queue(worker, plan) – beide fügen in umgekehrter Reihenfolge ein und erledigen das für dich.

9. Alle Befehle eines Ticks als Batch

Dutzende Befehle einzeln gesendet heißt dutzendmal auf den Spiel-Thread warten; in with g.batch(): verpackt nur einmal.

Wirtschaft & Produktion

10. Maximal 5 Arbeiter pro Goldmine

Mehr bringt kein Einkommen. Das Arbeiterziel richtet sich nach der Zahl der Minen: 5 für Gold pro Mine, plus ein paar für Holz.

11. Nur 1 Einheit in der Ausbildungswarteschlange

Eine volle Warteschlange (7 Plätze) bindet Geld (gemessen: 4 Bauern im Hauptgebäude eingereiht, 300 Gold gebunden, die Eröffnung deutlich langsamer). Erst nachlegen, wenn g.queue(b) leer ist.

12. Bei Nahrungsengpass in die Produktionstabelle schauen

g.production(b).blocked = etwas steht in der Warteschlange, hat aber nicht begonnen – meistens fehlt Nahrung. Das ist einen Schritt früher als „bauen, wenn die Nahrung fast voll ist“: Verlierst du im Kampf viele Einheiten und stockt beim Nachbauen die Warteschlange, weißt du es sofort.

13. Helden sind einzigartig; kein Tier-Up bei belegter Warteschlange des Hauptgebäudes

  • Ein toter Held lässt sich nur mit g.revive(altar) zurückholen; erneutes Ausbilden wird abgelehnt (221). Auch Wiederbeleben kostet Nahrung (ein Held belegt 5).
  • Solange noch etwas in der Warteschlange des Hauptgebäudes steht, kann es nicht aufgewertet werden (Reason-Code 185, „Gebäude beschäftigt“).

Zeit & Raum

14. Bei 2× Geschwindigkeit nicht nach der Wanduhr warten

Willst du 3 Spielsekunden warten, warte, bis g.clock() um 3 gestiegen ist – nicht sleep(1.5). Bei erhöhter Geschwindigkeit läuft die Engine-Uhr schneller als die Wanduhr.

15. Auf Insel- und Waldkarten keine Luftlinie

Für Creep-Lager und Expansionen g.path_distance(a, b) verwenden (A* am Boden, um Wald, Klippen und Gebäude herum); ist ein Ort unerreichbar, kommt None zurück. Der Punkt mit der kürzesten Luftlinie liegt womöglich auf der anderen Seite des Meeres.

Und noch eine: Schreib für den Fair-Modus

Mit --fair siehst du nur Einheiten, Gegenstände, Produktion und Events in deiner Sicht – genau die Regel der Arena. Schreib schon jetzt für den Fair-Modus, dann musst du für die Arena nichts ändern. Mehr dazu unter Fair-Modus.