IA: perfiles del oponente controlado por el ordenador
Fuente: coreprime/kbot @ 0ab97bf · Editar en GitHub
Los archivos de
ai/*.txtson perfiles en texto plano del oponente controlado por el ordenador. Cada perfil declara, por dificultad, las prioridades de construcción y los topes de unidades; el motor los lee cuando se configura un jugador de IA para un mapa. La claveaiprofile=del OTA elige con qué perfil empieza cada mapa, pero el usuario puede cambiarlo en el lobby.
Tip
Pruébalo tú mismo.
# Plain-text — just read them
ls $(kbot ctx path)/ai/
head -40 $(kbot ctx path)/ai/default.txt
En kbot. El explorador de recursos del studio muestra un perfil en
su pestaña AI Profile, y kbot mount lo imprime con
describe ai/<name>.txt (consulta Qué muestra kbot).
Desde Go. Usa 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
De un vistazo
Un perfil es una secuencia de planes, uno por nivel de dificultad.
Cada plan contiene directivas Weight y Limit cuyo objetivo es un
único nombre de unidad (ARMCOM), una palabra de categoría (PLANT,
LEVEL3, SPECIAL) o 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
...
Directivas
| Directiva | Sintaxis | Significado |
|---|---|---|
plan <word>… |
plan easy |
Empieza un bloque de plan nuevo. Las líneas Weight/Limit que siguen solo se aplican cuando el plan coincide con la dificultad de la partida, hasta el siguiente plan. |
Weight <target> <value> |
Weight ARMCK 0.5 |
Multiplica la prioridad de construcción del objetivo (consulta cómo se combinan los pesos). |
Limit <target> <value> |
Limit ARMSILO 1 |
Limita cuántas unidades del objetivo puede tener un jugador de ordenador: -1 es ilimitado, y 0 o cualquier otro valor negativo lo prohíbe. |
Cómo lee el texto TA 3.1c (el
formats/ai
de kbot-io hace lo mismo):
- Una línea se divide en palabras por cualquier espacio en blanco
(espacios, tabuladores, CR, VT, FF), y
#termina la línea allí donde aparezca, incluso dentro de una palabra. - La primera palabra es la directiva, comparada sin distinguir
mayúsculas de minúsculas. Una línea cuya primera palabra sea cualquier
otra cosa se ignora; así es como se saltan las líneas
// commentde la versión comercial. Las palabras que siguen al valor también se ignoran, así que un// noteal final no hace ningún daño. - Un valor es el prefijo numérico de la tercera palabra. Un peso es
un número decimal (
0.5,.5,2,1e1); un límite es un entero que da la vuelta a 32 bits. Una palabra de valor que no es un número se lee como 0 y la directiva se sigue aplicando: elLimit CORFORT O(una letra O) delkrogoth.txtde la versión comercial prohíbe CORFORT, yLimit ARM DECOM 4limita toda la categoría ARM a 0. - Las líneas anteriores a la primera línea
planse ignoran al empezar una partida, porque todavía no ha coincidido ningún plan. Pueden aplicarse si el perfil se vuelve a cargar durante la partida. Elkrogoth.txtde la versión comercial empieza con dos de esas líneas (weight cormakr 0.2,weight armmakr 0.2). Los archivos de IA de TA: Kingdoms no usanplanen absoluto: consulta Perfiles sin plan de TA: Kingdoms más abajo.
Niveles de dificultad
Los perfiles originales traen tres planes llamados easy, medium y
hard. Un plan se aplica en una dificultad cuando una de sus palabras
(sin distinguir mayúsculas) nombra esa dificultad (plan medium hard
cubre las dos) o cuando su primera palabra es any. Un plan cuyas
palabras no nombran ninguna dificultad (plan brutal, un plan a
secas) no coincide con nada: las líneas que tiene debajo se ignoran hasta
la siguiente línea plan.
Nombres de unidad frente a palabras de categoría
Tanto Weight como Limit pueden tener como objetivo:
- El
UnitNamede una unidad: p. ej.,ARMCOM,CORRAID(comparado sin distinguir mayúsculas). La directiva se aplica solo a esa unidad y la bloquea: las líneasWeightposteriores (en el caso de un peso) o las líneasLimitposteriores (en el de un límite) ya no la cambian. - Una palabra de categoría:
ARM,CORE,PLANT,CONSTR,LEVEL3,SPECIAL, …, que se compara con las palabras del campoCategory=de cada unidad. Se aplica a todas las unidades que coincidan y no estén bloqueadas. ALL: todas las unidades que no estén bloqueadas.
Todas las unidades empiezan con una prioridad del 100 % y sin
límite. Un peso multiplica el porcentaje actual, lo trunca a un número
entero y lo limita al rango 0–100 %, así que un peso mayor que 1 puede
recuperar una unidad que se había reducido antes, pero nunca la sube por
encima del 100 %. Un límite sustituye al actual. En el plan easy de
default.txt, Weight ARM 0.2 deja todas las unidades de Arm en el
20 %; el Weight ARMRAD 0.25 posterior lleva la torre de radar de Arm al
5 % y la bloquea; Weight PLANT 2 devuelve cada fábrica de Arm del 20 %
al 40 %.
Important
Los alias de categoría se comparan con la lista de tokens de
Category= de la unidad, no con ningún archivo de taxonomía. Un alias
de categoría solo «existe» si al menos una unidad lo declara. Escribe mal
LEVL3 y la directiva no hará nada, sin avisar (los visores de kbot lo
marcan como matches no unit).
Ejemplo desarrollado: fragmento 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
Cómo leerlo: en la dificultad easy, todas las unidades de Arm y de Core
bajan a una prioridad del 20 %; las torres de radar bajan al 5 % y los
conversores de metal (metal makers) al 2 % (y las dos quedan
bloqueadas); las fábricas (PLANT) y los constructores (CONSTR) vuelven
a subir al 40 % y al 60 %, y las líneas propias de los constructores
avanzados duplican su 60 % hasta el tope del 100 % y los bloquean.
Perfiles específicos de un mapa
Cavedog distribuye unos cuantos perfiles ajustados para ciertos mapas:
| Perfil | Lo usan |
|---|---|
default.txt |
La mayoría de los mapas genéricos |
metal.txt |
Mapas ricos en metal (Metal Heck y compañía) |
airbattle.txt |
Mapas centrados en el combate aéreo |
seabattle.txt |
Mapas centrados en el combate naval |
hover.txt |
Mapas con mucho aerodeslizador |
acid.txt |
Mapas del mundo ácido |
urban.txt |
Mapas urbanos |
waterwrld.txt |
Mapas de mundo acuático |
krogoth.txt |
La misión del jefe Krogoth |
missions.txt |
Misiones de campaña |
El .ota del mapa elige cuál mediante aiprofile=, p. ej.,
aiprofile=metal.
Perfiles sin plan de TA: Kingdoms
Note
Esta sección recoge solo lo que cambia en TA:K. TAK usa la misma
convención de nombres de archivo ai/*.txt y la misma sintaxis de
directivas weight/limit, pero la directiva plan es opcional.
Todos los perfiles de IA de TA: Kingdoms de la versión comercial
(ai/default.txt y el conjunto ai/mission*.txt de la campaña) enumeran
directivas weight/limit sin ninguna línea plan: hay una única
dificultad implícita por archivo. La estructura es un bloque largo de
pesos seguido de un bloque largo de límites, agrupados por bando según el
prefijo del nombre de unidad.
Ejemplo desarrollado: las 30 primeras líneas 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 repaso de los pesos de default.txt deja ver las prioridades de
Cavedog:
aradrag 25: el Dragón de Aramon tiene a propósito un peso excesivo; la IA construirá dragones con más ganas que cualquier otra cosa.arabuild 10,aracastl 10,arakeep 10,arapries 10: todos los tipos de economía y construcción tienen peso 10.arawall 0,arangate 0: cero explícito, no se construyen nunca.araat 1,arafast 1,arassh 1: unidades básicas a las que la IA quita prioridad en favor de alternativas de nivel superior.
El mismo patrón se repite más abajo en el archivo para las unidades
tar*, ver* y zon*.
Bloque de límites
Debajo del bloque de pesos viene un bloque paralelo de límites:
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
…
Fíjate en la asimetría: aradrag tiene peso 25 (prioridad alta) pero
límite 1 (nunca más de uno). Así es como la IA de TA:K va hacia una
unidad heroica: el peso alto hace que se construya pronto y el límite bajo
mantiene razonable la composición del ejército.
Estadísticas de los perfiles
default.txt y los archivos de las misiones de campaña siguen todos la
misma forma:
| Perfil | Líneas de peso | Líneas de límite | Planes |
|---|---|---|---|
ai/default.txt |
104 | 104 | 0 |
ai/mission06.txt |
104 | 104 | 0 |
ai/mission08.txt (misión de Iron Plague) |
161 | 162 | 0 |
Los archivos de las misiones de Iron Plague tienen tablas de pesos y
límites más ricas porque cubren las unidades de Creon (prefijo CRE) que el
default.txt del juego base omite.
Cómo trata kbot los archivos sin plan
ai.Parse de kbot-io pone todas las líneas anteriores a la primera línea
plan en AIFile.Preamble, que es lo que hace TA con ellas (ver arriba);
para un perfil de TA: Kingdoms, ai.ParseWith(data, ai.ParseOptions{DefaultPlan: true}) las lee en un único plan implícito que coincide con todas las
dificultades. Los visores de kbot las muestran en su propia pestaña
Before first plan y dicen las dos cosas: TA las ignora al empezar una
partida, y los perfiles de TA: Kingdoms, que no tienen líneas plan, las
aplican en todas las dificultades. kbot no modela cómo aplica TA:
Kingdoms los pesos mayores que 1.
ai.IsAIFile() mira la primera palabra de cada línea: un archivo es
un perfil cuando alguna línea empieza con una directiva escrita de la
forma habitual (una línea plan que nombra easy, medium, hard o
any, o una línea weight/limit cuyo valor empieza por un número).
Así se detectan los perfiles de TAK, que no tienen plan, y los
separados por tabuladores, mientras que un .txt que solo menciona
«weight» o «limit» en la prosa no se confunde con un perfil.
Escollos
Warning
El juego no informa de nada. Un nombre de unidad mal escrito se lee
como una categoría que no coincide con ninguna unidad y no hace nada; un
valor que no es un número se lee como 0 (así que un límite prohíbe el
objetivo); las líneas anteriores al primer plan se ignoran al empezar
la partida. La primera señal de un perfil roto suele ser que «la IA se
comporta de forma rara». Los visores de kbot señalan cada uno de estos
casos (ver más abajo).
Limit 0, o cualquier límite negativo que no sea-1, impide a la IA construir ese objetivo.-1elimina el tope.#termina una línea en cualquier punto, incluso dentro de una palabra; no hay comentarios de bloque.//funciona solo porque se ignora una línea cuya primera palabra no es una directiva, y también se ignoran las palabras que siguen al valor.- Un peso mayor que 1 nunca sube una unidad por encima del 100 %. Solo puede recuperar una unidad que un peso de categoría redujo antes.
- La primera línea que nombra una unidad la bloquea. Pon las líneas específicas de una unidad después de las líneas de categoría que deben afinar.
- El espacio en blanco entre tokens solo importa como separador: tabuladores, espacios y varios espacios seguidos funcionan igual.
- No se admiten secciones anidadas ni compartidas. Cada bloque
plantiene que volver a declarar todos los pesos y límites que le interesan.
Qué muestra kbot
El explorador de recursos del studio (pestaña AI Profile) y el
describe de kbot mount leen el perfil igual que el juego:
- Before first plan: las líneas del preámbulo, marcadas como ignoradas al empezar una partida.
- Una pestaña por plan, con cada objetivo marcado como unit,
category o all units según los
units/*.fbide la instalación (nombre yCategory=). Una categoría que no tiene ninguna unidad, que es como se lee un nombre de unidad mal escrito, se marca como matches no unit. Los pesos se muestran como multiplicadores, con una barra para el porcentaje con el que se queda una unidad que estaba al 100 %; los límites, como ∞ Unlimited, Disabled (0 o cualquier valor negativo distinto de -1) o Max: N. - Líneas que el juego lee de otra manera: los diagnósticos de
kbot-io, como una palabra de valor que no es un número (
Ose lee como- o palabras después del valor. Una palabra de valor que no es el
número que lee el juego se muestra a su lado (written "O"); otra forma
de escribir el mismo número, como
.1o0.10, no.
- o palabras después del valor. Una palabra de valor que no es el
número que lee el juego se muestra a su lado (written "O"); otra forma
de escribir el mismo número, como
- At game start (studio;
kbot mountimprime los recuentos): para easy, medium y hard, todas las unidades cuyo peso o límite cambia el perfil, con 🔒 en los valores que bloqueó una línea de unidad.
Tamaños habituales
| Métrica | Rango observado en los perfiles de Cavedog |
|---|---|
| Tamaño del archivo | 1–4 KB |
| Planes por archivo | 3 (easy/medium/hard) |
| Directivas de peso por plan | 20–80 |
| Directivas de límite por plan | 0–10 |