Écrire un Bot avec un LLM
Pas besoin de savoir programmer : vous expliquez clairement comment il doit jouer, le LLM écrit le code. Copiez le modèle de prompt, décrivez votre stratégie, lancez-le, puis demandez des corrections.
Cette page s’adresse aux joueurs de Warcraft qui ne savent pas programmer, mais aussi aux développeurs qui veulent gagner du temps. Tout le processus est une conversation : vous décrivez la stratégie → le modèle écrit le code → vous jouez une partie → vous décrivez au modèle ce que vous avez observé → il corrige.
Installez d’abord l’environnement en suivant le Démarrage rapide, et faites tourner hello_bot jusqu’au bout (les paysans partent récolter). Ainsi, en cas de problème, vous saurez distinguer un problème d’environnement d’un problème de Bot.
1. Préparer les documents pour le modèle
La qualité du code produit dépend à 80 % du fait que le modèle a lu les bons documents. Choisissez la méthode selon votre outil :
| Vous utilisez | Comment fournir les documents |
|---|---|
| Un agent de code capable de lire le dépôt (Claude Code, Cursor, Codex, etc.) | Ouvrez-le dans le dossier du dépôt et demandez-lui de lire d’abord docs/BOT_HANDBOOK_ZH.md, docs/api.json et un exemple (brains/examples/macro_bot.py pour l’économie, micro_bot.py pour le combat) |
| Un modèle conversationnel avec accès à Internet | Demandez-lui de lire d’abord https://war3ai.com/llms-full.txt : toute la documentation du site tient dans ce seul fichier |
| Une conversation web sans accès à Internet | Collez le manuel, api.json et un fichier d’exemple à la suite du prompt |
| Un modèle local (LM Studio, Ollama) | Même chose. Prévoyez une fenêtre de contexte d’au moins 32K tokens, sinon le manuel et le catalogue de l’API n’y tiennent pas |
Pour une technique pro précise, collez en plus la recette correspondante des Recettes des joueurs pros.
2. Copier ce prompt
Remplacez la dernière partie, « La stratégie que je veux », par vos propres mots, en étant le plus précis possible :
Tu dois écrire une IA (en Python) pour Warcraft III 1.27. Utilise uniquement les méthodes de Game listées dans api.json,
n'invente aucune méthode qui n'existe pas. Inspire-toi de rush_bot.py : hérite de openwar3.Bot, implémente on_start(g) et on_tick(g).
Règles :
- on_tick est appelé environ 5 fois par seconde et doit être rapide (pas de sleep dedans).
- Une valeur illisible vaut None, pas 0 : vérifie-la avant de l'utiliser.
- Une commande renvoie un reçu (Receipt) ; `if r:` signifie "le moteur l'a acceptée" ; sinon `r.reason` en donne la raison
(nourriture insuffisante, or insuffisant, cible invisible, ce héros existe déjà…) : réessaie au tick suivant ou change d'approche.
- Pour attaquer un ennemi précis, utilise g.attack(unités, ennemi) ; l'ennemi doit être dans le champ de vision, sinon l'ordre est rejeté.
- Un héros mort se ressuscite avec g.revive(autel), on ne peut pas en entraîner un autre.
- Pour construire, utilise g.build_near(ouvrier, code_bâtiment, x, y) : il trouve seul un emplacement libre, suit le résultat et ne fait rien si l'argent manque.
- Pour savoir "ce qui vient de se passer" (qui est mort, qui a perdu des PV, un héros qui monte de niveau, un objet qui tombe), implémente on_event(g, ev).
- Ne redonne pas le même ordre à la même unité à chaque tick (cela interrompt ce qu'elle fait) ; donne des ordres aux unités "inactives".
- N'affecte à la récolte que les ouvriers de idle_workers(). 5 ouvriers au maximum par mine d'or.
- Une seule unité à la fois dans une file d'entraînement (relance quand g.queue(bâtiment) est vide) ; si la nourriture bloque, regarde g.production(bâtiment).blocked.
- Quand un tick doit envoyer beaucoup de commandes, regroupe-les dans with g.batch(): (une seule attente du thread du jeu).
- Pour choisir qui attaquer, utilise g.time_to_kill(mon_groupe, ennemi) (contres et armure compris) ; pour choisir où aller, g.path_distance (renvoie None si inaccessible).
- En mode équitable, seul ce qui est dans le champ de vision est visible ; pour les ennemis déjà aperçus, utilise g.last_seen().
- Les unités sont désignées par un code à quatre caractères (Paysan humain hpea, Fantassin hfoo, Caserne hbar…), les sorts par leur nom d'ordre (thunderbolt Éclair de tempête,
blizzard Blizzard, holybolt Lumière sacrée…, la liste complète est dans data/order-ids.txt), l'apprentissage des compétences par un code à quatre caractères (AHtb, AHbz…).
La stratégie que je veux :
<Écris-la ici en langage courant, par exemple :
"Humains, au départ 5 paysans à l'or et 1 au bois ; l'Archimage en premier ; deux casernes pour des fantassins et des fusiliers ;
à 12 unités, partir avec le héros attaquer l'expansion adverse ; si le héros passe sous 30 % de PV, rentrer à la base ;
en creeping, attaquer d'abord les camps proches de la base.">
Comment bien décrire votre stratégie
Ce que le modèle redoute le plus, ce sont les consignes floues. Plutôt que « jouer plus agressif », ces informations sont bien plus utiles :
- Race et héros : quel héros en premier, dans quel ordre monter ses compétences (par exemple pour l’Archimage : Élémentaire d’eau, Blizzard, Élémentaire d’eau…).
- Ordre de construction : à quel paysan construire la caserne, quand passer de tier, combien de casernes.
- Composition de l’armée : fantassins + fusiliers ? À partir de combien d’unités sortir ?
- Conditions d’attaque et de repli : à combien d’unités attaquer, sous quel niveau de PV le héros se replie, rentrer reconstituer l’armée après de lourdes pertes.
- Creeping : creeper ou non, quand (à la tombée de la nuit ?), uniquement les camps à votre portée ?
- Équitable ou non : si vous comptez passer un jour sur l’Arène, précisez « n’utiliser que les ennemis visibles dans le champ de vision ».
3. Le lancer
Enregistrez le code fourni par le modèle dans brains/my_bot.py, puis :
python tools/play.py --bot brains/my_bot.py --race 1 --difficulty 2
Pour voir le résultat plus vite, ajoutez --speed 200 (vitesse ×2).
4. Le faire corriger
- En cas d’erreur : recollez l’intégralité du message d’erreur tel quel au modèle et dites « corrige ».
- S’il joue mal : décrivez ce que vous voyez en jeu, pas la cause que vous supposez. Par exemple « le héros reste planté dans la base », « les unités arrivent une par une et se font tuer », « les paysans s’entassent sur une seule mine ».
- Pour ajouter une stratégie : une seule chose à la fois, jouez une partie pour vérifier que rien n’est cassé, puis passez à la suivante.
Un agent de code capable d’exécuter des commandes peut aussi prendre en charge les étapes 3 et 4 : jouer une partie, lire les journaux et les reçus, corriger le code, relancer. Pour lui donner assez d’informations, voir Itération autonome d’un agent.
5. Problèmes fréquents
| Symptôme | Cause probable |
|---|---|
| Rien ne bouge | Mauvais numéro d’instance (--inst), ou la partie n’a pas encore commencé |
| Les paysans ne récoltent pas | Des ordres sont donnés à des paysans déjà occupés ; n’affectez que ceux de idle_workers() |
| Aucune ferme n’est jamais construite | Utilisez build_near au lieu de coordonnées en dur ; vérifiez si le reason du reçu indique un manque d’argent |
| Le héros ne sort pas | Regardez le reçu de train : nourriture insuffisante ? Ou le héros est mort (il faut revive) ? |
| Le héros ne lance pas ses sorts | Compétence non apprise (learn) ou mana insuffisant ; après le lancement, vérifiez avec cooldown() que le sort est en recharge |
| Les unités tressautent à chaque tick | Les ordres sont redonnés à chaque tick ; ne donnez des ordres qu’aux unités inactives |
| Aucune unité ne sort, l’argent s’accumule | La nourriture bloque : regardez g.production(caserne).blocked |
| Le modèle utilise des méthodes inexistantes | Insistez à nouveau dans le prompt sur « uniquement les méthodes de api.json », et collez api.json en entier |
Pour aller plus loin
- Toutes les méthodes et le mécanisme sous-jacent de chacune : catalogue de l’API ;
- Le cerveau de référence (
brains/xwar3/strategy) est une IA complète qui prend des expansions, creepe et attaque. Vous pouvez faire lire sa logique au modèle, mais il utilise des interfaces de plus bas niveau : ne le recopiez pas tel quel ; - Sur l’Arène, vous ne verrez que les ennemis présents dans votre champ de vision : ajoutez dès maintenant
--fairpour vous imposer cette contrainte, vous n’aurez rien à modifier plus tard.