Toutes les pages de formats ↓
Unités, scripts, configurations

IA — profils des adversaires ordinateur

Source : coreprime/kbot @ 0ab97bf · Modifier sur GitHub

Les fichiers ai/*.txt sont des profils d'adversaires ordinateur en texte brut. Chaque profil déclare, par niveau de difficulté, des priorités de construction et des plafonds d'unités ; le moteur les lit quand un joueur IA est configuré pour une carte. La clé aiprofile= de l'OTA choisit le profil avec lequel une carte démarre, mais l'utilisateur peut le changer dans le salon.

Tip

Essayez vous-même.

# Plain-text — just read them
ls $(kbot ctx path)/ai/
head -40 $(kbot ctx path)/ai/default.txt

Dans kbot. L'explorateur de ressources du studio affiche un profil dans son onglet AI Profile, et kbot mount l'affiche avec describe ai/<name>.txt (voir Ce que montre kbot).

Depuis Go. Utilisez formats/ai de kbot-io :

import "github.com/coreprime/kbot-io/formats/ai"

raw, _ := os.ReadFile("ai/default.txt")
profile, _ := ai.Parse(raw)
// profile.Preamble: lines before the first plan; profile.Plans: plan.Name,
// plan.Weights, plan.Limits; profile.Diagnostics: lines read unusually.
settings := ai.NewResolver(units).Apply(profile, ai.Easy) // per-unit result

Vue d'ensemble

Un profil est une suite de plans, un par niveau de difficulté. Chaque plan contient des directives Weight et Limit dont la cible est un nom d'unité unique (ARMCOM), un mot de catégorie (PLANT, LEVEL3, SPECIAL) ou ALL.

plan easy

Weight ARM      0.2
Weight CORE     0.2
Weight PLANT    2
Weight CONSTR   3
Weight ARMACK   2
Weight CORACK   2

Limit  ARMSILO  1
Limit  CORSILO  1


plan medium

Weight ARM      1.0
Weight CORE     1.0
...

Directives

Directive Syntaxe Signification
plan <word>… plan easy Ouvre un nouveau bloc de plan. Les lignes Weight/Limit qui suivent ne s'appliquent que si le plan correspond à la difficulté de la partie, jusqu'au plan suivant.
Weight <target> <value> Weight ARMCK 0.5 Multiplie la priorité de construction de la cible (voir comment les poids se combinent).
Limit <target> <value> Limit ARMSILO 1 Plafonne le nombre d'exemplaires de la cible que possède un joueur ordinateur : -1 signifie illimité, 0 ou toute autre valeur négative l'interdit.

Comment TA 3.1c lit le texte (le formats/ai de kbot-io fait de même) :

  • Une ligne est découpée en mots sur n'importe quel blanc — espaces, tabulations, CR, VT, FF — et # termine la ligne où qu'il apparaisse, même au milieu d'un mot.
  • Le premier mot est la directive, comparée sans tenir compte de la casse. Une ligne dont le premier mot est autre chose est ignorée : c'est ainsi que les lignes // comment des fichiers d'origine sont sautées. Les mots qui suivent la valeur sont ignorés eux aussi : un // note en fin de ligne ne fait donc aucun mal.
  • Une valeur est le préfixe numérique du troisième mot. Un poids est un nombre décimal (0.5, .5, 2, 1e1) ; une limite est un entier qui reboucle sur 32 bits. Un mot de valeur qui n'est pas un nombre se lit 0, et la directive s'applique quand même : le Limit CORFORT O (la lettre O) du krogoth.txt d'origine interdit CORFORT, et Limit ARM DECOM 4 limite toute la catégorie ARM à 0.
  • Les lignes situées avant la première ligne plan sont ignorées au démarrage d'une partie, puisqu'aucun plan n'a encore correspondu. Elles peuvent s'appliquer si le profil est rechargé en cours de partie. Le krogoth.txt d'origine commence par deux lignes de ce genre (weight cormakr 0.2, weight armmakr 0.2). Les fichiers d'IA de TA: Kingdoms n'utilisent pas du tout plan — voir TA: Kingdoms — profils sans plan plus bas.

Niveaux de difficulté

Les profils d'origine contiennent trois plans nommés easy, medium et hard. Un plan s'applique à une difficulté quand l'un de ses mots (sans tenir compte de la casse) nomme cette difficulté — plan medium hard couvre les deux — ou quand son premier mot est any. Un plan dont aucun mot ne nomme une difficulté (plan brutal, un plan seul) ne correspond à rien : les lignes qui le suivent sont ignorées jusqu'à la ligne plan suivante.


Noms d'unités et mots de catégorie

Weight comme Limit peuvent cibler :

  • Le UnitName d'une unité — par ex. ARMCOM, CORRAID (comparé sans tenir compte de la casse). La directive ne s'applique qu'à cette unité et la verrouille : les lignes Weight suivantes (pour un poids) ou les lignes Limit suivantes (pour une limite) ne la modifient plus.
  • Un mot de catégorie — ARM, CORE, PLANT, CONSTR, LEVEL3, SPECIAL, … — comparé aux mots du champ Category= de chaque unité. Il s'applique à toutes les unités correspondantes qui ne sont pas verrouillées.
  • ALL — toutes les unités qui ne sont pas verrouillées.

Chaque unité démarre avec une priorité de 100 % et sans limite. Un poids multiplie le pourcentage courant, le tronque à un nombre entier et le borne entre 0 et 100 % : un poids supérieur à 1 peut donc rétablir une unité réduite plus tôt, mais ne la fait jamais dépasser 100 %. Une limite remplace la limite courante. Dans le plan easy de default.txt, Weight ARM 0.2 laisse chaque unité Arm à 20 % ; le Weight ARMRAD 0.25 qui suit fait passer la tour radar Arm à 5 % et la verrouille ; Weight PLANT 2 fait remonter chaque usine Arm de 20 % à 40 %.

Important

Les alias de catégorie sont comparés à la liste de jetons Category= de l'unité, et non à un quelconque fichier de taxonomie. Un alias de catégorie n'« existe » que si au moins une unité le déclare. Écrivez LEVL3 par erreur et la directive ne fait rien, en silence (les visionneuses de kbot la marquent matches no unit).


Exemple commenté — extrait de default.txt

// DEFAULT PROFILE

//--------------------------- EASY

plan easy

Weight ARM 0.2          // Every Arm unit to 20%
Weight CORE 0.2

Weight ARMRAD 0.25      // Radar towers to 5%, locked
Weight CORRAD 0.25

Weight ARMMAKR .1       // …metal makers to 2%, locked
Weight CORMAKR .1

Weight PLANT 2          // Factories back up to 40%
Weight CONSTR 3         // Constructors to 60%

// encourages advanced units
Weight ARMACK 2         // Advanced Construction Kbots
Weight CORACK 2
Weight ARMACV 2
Weight CORACV 2
Weight ARMACA 2
Weight CORACA 2
Weight SPECIAL 2
Weight LEVEL3 2

Lecture : en difficulté easy, chaque unité Arm et Core tombe à 20 % de priorité ; les tours radar tombent à 5 % et les convertisseurs de métal à 2 % (et sont alors verrouillés) ; les usines (PLANT) et les constructeurs (CONSTR) remontent à 40 % et 60 %, et les lignes propres aux constructeurs avancés doublent leurs 60 % jusqu'au plafond de 100 % et les verrouillent.


Profils propres à une carte

Cavedog livre une poignée de profils réglés pour certaines cartes :

Profil Utilisé par
default.txt La plupart des cartes génériques
metal.txt Les cartes riches en métal (Metal Heck et consorts)
airbattle.txt Les cartes axées sur l'aviation
seabattle.txt Les cartes axées sur la marine
hover.txt Les cartes à forte présence d'aéroglisseurs
acid.txt Les cartes du monde acide
urban.txt Les cartes urbaines
waterwrld.txt Les cartes de monde aquatique
krogoth.txt La mission du boss Krogoth
missions.txt Les missions de campagne

Le .ota de la carte choisit le profil via aiprofile=, par ex. aiprofile=metal.


TA: Kingdoms — profils sans plan

Note

Cette section ne décrit que les écarts propres à TA:K. TAK utilise la même convention de nommage ai/*.txt et la même syntaxe de directives weight/limit, mais considère la directive plan comme facultative.

Chaque profil d'IA d'origine de TA: Kingdoms (ai/default.txt, la série ai/mission*.txt de la campagne) liste ses directives weight/limit sans aucune ligne plan : il n'y a qu'une difficulté implicite par fichier. La structure est un long bloc de poids suivi d'un long bloc de limites, regroupés par camp selon le préfixe du nom d'unité.

Exemple commenté — les 30 premières lignes de ai/default.txt

// Kingdoms Default AI Profile 3-28-99


weight araarch 5
weight araat 1
weight arabow 8
weight arabroad 5
weight arabuild 10
weight aracan 4
weight aracastl 10
weight araclay 5
weight aradrag 25      // Dragons: top priority
weight arafast 1
weight arakeep 10
weight araknigh 5
weight aralode 10
weight aramana 5
weight arangate 0      // 0 = never build
weight arapal 8
weight arapries 10
weight arapult 1
weight arasmith 8
weight araspy 4
weight arassh 1
weight arasword 5
weight aratre 1
weight arawall 0
weight arawar 1

Un examen des biais de poids de default.txt révèle les priorités de Cavedog :

  • aradrag 25 — le dragon d'Aramon est volontairement surpondéré : l'IA construira des dragons plus volontiers que n'importe quoi d'autre.
  • arabuild 10, aracastl 10, arakeep 10, arapries 10 — tous les types d'économie et de construction sont au poids 10.
  • arawall 0, arangate 0 — explicitement à zéro, jamais construits.
  • araat 1, arafast 1, arassh 1 — des unités de base que l'IA fait passer après des alternatives de niveau supérieur.

Le même schéma se répète plus bas dans le fichier pour les unités tar*, ver* et zon*.

Bloc des limites

Sous le bloc des poids vient un bloc des limites parallèle :

limit araarch 16
limit araat 8
limit arabow 16
limit arabroad 16
limit arabuild 10
limit aracan 3
limit aracastl 2       // Only 2 castles per game
limit araclay 3
limit aradrag 1        // ONE dragon, even though weight=25
limit arafast 4
limit arakeep 2
limit araknigh 16
…

Remarquez l'asymétrie : aradrag a un poids de 25 (priorité élevée) mais une limite de 1 (jamais plus d'un). C'est ainsi que l'IA de TA:K construit en vue d'une unité héroïque : un poids élevé la fait construire tôt, une limite basse garde une composition d'armée raisonnable.

Statistiques des profils

default.txt et les fichiers des missions de campagne suivent tous la même forme :

Profil Lignes de poids Lignes de limite Plans
ai/default.txt 104 104 0
ai/mission06.txt 104 104 0
ai/mission08.txt (mission d'Iron Plague) 161 162 0

Les fichiers des missions d'Iron Plague ont des tables de poids et de limites plus riches, car ils couvrent les unités Creon (préfixe CRE) que le default.txt du jeu de base omet.

Comment kbot gère les fichiers sans plan

L'ai.Parse de kbot-io place chaque ligne située avant la première ligne plan dans AIFile.Preamble, ce qui correspond à ce que TA en fait (voir plus haut) ; pour un profil de TA: Kingdoms, ai.ParseWith(data, ai.ParseOptions{DefaultPlan: true}) les lit dans un plan implicite unique qui correspond à toutes les difficultés. Les visionneuses de kbot les affichent dans leur propre onglet Before first plan et disent les deux choses : TA les ignore au démarrage d'une partie, et les profils de TA: Kingdoms, qui n'ont pas de lignes plan, les appliquent à toutes les difficultés. kbot ne modélise pas la façon dont TA: Kingdoms applique les poids supérieurs à 1.

ai.IsAIFile() examine le premier mot de chaque ligne : un fichier est un profil quand une de ses lignes commence par une directive écrite de la façon habituelle (une ligne plan qui nomme easy, medium, hard ou any, ou une ligne weight/limit dont la valeur commence par un nombre). Cela détecte les profils de TAK, qui n'ont pas de plan, et ceux séparés par des tabulations, tandis qu'un .txt qui se contente de mentionner « weight » ou « limit » dans sa prose n'est pas pris pour un profil.


Pièges

Warning

Le jeu ne signale rien. Un nom d'unité mal orthographié est lu comme une catégorie qui ne correspond à aucune unité et ne fait rien ; une valeur qui n'est pas un nombre se lit 0 (une limite interdit alors la cible) ; les lignes situées avant le premier plan sont ignorées au démarrage de la partie. Le premier signe d'un profil cassé est en général que « l'IA se comporte bizarrement ». Les visionneuses de kbot signalent chacun de ces cas (voir plus bas).

  • Limit 0, ou toute limite négative autre que -1, interdit à l'IA de construire la cible. -1 lève le plafond.
  • # termine une ligne n'importe où, même au milieu d'un mot ; il n'y a pas de commentaires de bloc. // ne fonctionne que parce qu'une ligne dont le premier mot n'est pas une directive est ignorée, et que les mots qui suivent la valeur sont ignorés.
  • Un poids supérieur à 1 ne fait jamais dépasser 100 % à une unité. Il ne peut que rétablir une unité qu'un poids de catégorie a réduite plus tôt.
  • La première ligne qui nomme une unité la verrouille. Placez les lignes propres à une unité après les lignes de catégorie qu'elles doivent affiner.
  • Les blancs entre les jetons ne comptent que comme séparateurs : tabulations, espaces, espaces multiples, tout fonctionne de la même façon.
  • Aucune prise en charge des sections imbriquées ou partagées. Chaque bloc plan doit redéclarer tous les poids et limites qui le concernent.

Ce que montre kbot

L'explorateur de ressources du studio (onglet AI Profile) et le describe de kbot mount lisent le profil comme le fait le jeu :

  • Before first plan — les lignes de préambule, signalées comme ignorées au démarrage d'une partie.
  • Un onglet par plan, chaque cible étant marquée unit, category ou all units d'après les units/*.fbi de l'installation (nom et Category=). Une catégorie qu'aucune unité ne possède — c'est ainsi que se lit un nom d'unité mal orthographié — est marquée matches no unit. Les poids sont affichés comme des multiplicateurs, avec une barre pour le pourcentage qui reste à une unité partie de 100 % ; les limites comme ∞ Unlimited, Disabled (0 ou toute valeur négative autre que -1) ou Max: N.
  • Lines the game reads differently — les diagnostics de kbot-io, comme un mot de valeur qui n'est pas un nombre (O se lit 0) ou des mots après la valeur. Un mot de valeur qui n'est pas le nombre lu par le jeu est affiché à côté de celui-ci (written "O") ; une autre écriture du même nombre, comme .1 ou 0.10, ne l'est pas.
  • At game start (studio ; kbot mount affiche les décomptes) — pour easy, medium et hard, chaque unité dont le profil modifie le poids ou la limite, avec 🔒 sur les valeurs qu'une ligne d'unité a verrouillées.

Tailles typiques

Mesure Plage observée dans les profils de Cavedog
Taille du fichier 1–4 Ko
Plans par fichier 3 (easy/medium/hard)
Directives de poids par plan 20–80
Directives de limite par plan 0–10

Voir aussi

  • TDF — les métadonnées de carte .ota qui choisissent un profil d'IA.
  • Glossaire — camp, catégorie.