Todas las páginas de formatos ↓
Unidades, scripts y configuración

IA: perfiles del oponente controlado por el ordenador

Fuente: coreprime/kbot @ 0ab97bf · Editar en GitHub

Los archivos de ai/*.txt son 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 clave aiprofile= 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 // comment de la versión comercial. Las palabras que siguen al valor también se ignoran, así que un // note al 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: el Limit CORFORT O (una letra O) del krogoth.txt de la versión comercial prohíbe CORFORT, y Limit ARM DECOM 4 limita toda la categoría ARM a 0.
  • Las líneas anteriores a la primera línea plan se 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. El krogoth.txt de 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 usan plan en 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 UnitName de una unidad: p. ej., ARMCOM, CORRAID (comparado sin distinguir mayúsculas). La directiva se aplica solo a esa unidad y la bloquea: las líneas Weight posteriores (en el caso de un peso) o las líneas Limit posteriores (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 campo Category= 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. -1 elimina 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 plan tiene 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/*.fbi de la instalación (nombre y Category=). 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 (O se lee como
    1. 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 .1 o 0.10, no.
  • At game start (studio; kbot mount imprime 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

Véase también

  • TDF: los metadatos de mapa .ota que eligen un perfil de IA.
  • Glosario: side, category.