IA — profils des adversaires ordinateur
Source : coreprime/kbot @ 0ab97bf · Modifier sur GitHub
Les fichiers
ai/*.txtsont 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
// commentdes fichiers d'origine sont sautées. Les mots qui suivent la valeur sont ignorés eux aussi : un// noteen 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 : leLimit CORFORT O(la lettre O) dukrogoth.txtd'origine interdit CORFORT, etLimit ARM DECOM 4limite toute la catégorie ARM à 0. - Les lignes situées avant la première ligne
plansont 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. Lekrogoth.txtd'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 toutplan— 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
UnitNamed'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 lignesWeightsuivantes (pour un poids) ou les lignesLimitsuivantes (pour une limite) ne la modifient plus. - Un mot de catégorie —
ARM,CORE,PLANT,CONSTR,LEVEL3,SPECIAL, … — comparé aux mots du champCategory=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.-1lè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
plandoit 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/*.fbide l'installation (nom etCategory=). 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 (
Ose 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.1ou0.10, ne l'est pas. - At game start (studio ;
kbot mountaffiche 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 |