Registrarse

[Otros] Usar la IA de combate correctamente

Samu

Usuario de Oro
Bueno, hace ya bastante tiempo que no posteo nada por aquí. Al menos nada tipo 'guía', fundamentalmente porque a veces me da la sensación de que no lo usa prácticamente nadie y hacerlo es un poco rollo, la verdad.

Pero vaya, el otro día estuve mirando "en profundidad" el código de la IA de combate en los juegos de gba. Porque ni he sido capaz de encontrar información fiable, ni nadie sabía decirme exactamente como funcionaba. Después de ver el código relacionado en pret, tengo una idea bastante más clara de como funciona la IA, y me temo que la mayor parte de la gente la configura de manera errónea.

Voy a explicar detenidamente como funciona la IA de combate y que opciones tiene, para que todos podamos configurarla de forma 'correcta', tanto aquellos que trabajan 'tradicionalmente' sobre roms, como lo que están actualmente compilando roms a partir de pret.





Configuración de la IA en GBA.

Varios de los que estáis leyendo esto, es posible que ya tengáis una idea aproximada de como funciona la IA, porque habéis visto esa casilla que sale en la configuración de los entrenadores (en editores como PGE y gen3tools).
Para los que no lo conozcáis, esa casilla nos permite establecer un número entre 0 y 255, es decir, que la información de la IA ocupa un byte (00-FF).

Algunos pensaréis: Hostia, pues cuanto más alto sea ese valor, más difícil será la IA. Este es el primero de los errores comunes o 'falsas creencias populares' sobre el funcionamiento de la IA. Aunque valores más altos de IA en ocasiones indican una mayor dificultad, esto no tiene porque ser así; ahora veremos el motivo.
He tenido muchos problemas para ver como explico esto a aquellas personas menos familiarizadas con la programación/informática, pero espero que se entienda así:
Como hemos dicho antes, el valor de la IA está formado por un número de un byte, ¿verdad? Bien, entonces podríamos decir que el valor de la IA lo forman un conjunto de 8 bits. Por ejemplo:
Código:
Para el valor 255 del número de IA:
    - Byte = 'FF'
    - bits = '1111 1111'
Sí vale, son 8 bits, ¿y eso que mierdas importa? ¿A qué viene todo esto?
Verás, las funciones del juego que controlan la IA no evalúan el 'valor del número' como tal, si no que evalúan el valor de cada uno de esos bits, si es 0 o 1.

Lo que quiero decir con esto es que en realidad ese número de 1 byte lo que contiene son 8 flags. Cada una de esas flags controla una serie de características de la IA dependiendo de si están activadas (su valor es 1) o si están desactivadas (su valor es 0).

Hasta aquí más o menos varios llegábamos y había constancia de ello en algunos de los foros 'especializados'. Donde ya había muchas más dudas es en: bueno, ¿y que mierda hace cada flag?. Y para eso estoy yo aquí, para haceros un breve resumen de como funciona cada flag.
Esta parte de la guía la apoyaré con código de pokeruby, para que veáis de que estoy hablando y que la gente que usa pret sepa donde están las funciones relacionadas y sus nombres, para poder editar las cosas con más facilidad. (Los que no entendáis el código no os asustéis, no es necesario para entender que hace cada flag).

En primer lugar, si revisamos la información que se almacena por cada trainer en el rom podemos ver lo siguiente.
Código en include/battle.h
Efectivamente, uno de los valores que se almacena en el rom se llama aiFlags, pero espera... ¿Qué es eso de u32...? Ese u32 quiere decir que el valor de las aiFlags se almacena como un número entero sin signo de 32 bits (4 bytes). ¡¿4 bytes?! Espera un momento, pero no habías dicho que el valor de la IA ocupaba 1 byte?.
Bueno, como podéis ver aquí, los desarrolladores del gen3 y PGE o bien no lo tuvieron en cuenta o decidieron pasarlo por alto, pero los iaFlags ocupan 4 bytes (32 bits) y no 1 byte (8 bits).

Joder, ¿Y no hay mucha diferencia entre 4 bytes y 1 byte? Sí y no. Veamos el siguiente código:
data/battle_ai_scripts.s
Como se puede observar ahí, la mayor parte de los flags a partir del 9º no se usan para absolutamente nada, por lo que realmente perdemos poca funcionalidad utilizando solo los primeros 8 flags que permiten editar el PGE/gen3.
  • 1º flag. AI_CheckBadMove.
    Código:
    0000 000[B]1[/B]
    Con este flag la IA será capaz de comprobar si un ataque no va a ser efectivo (un ataque te tipo agua contra un pokemon con absorber agua, o un terremoto contra un pokemon volador, etc). Además también dará algo más de prioridad a los ataques que sean más efectivos (x2/x4).

  • 2º flag. AI_CheckMoveViability.
    Código:
    0000 00[B]1[/B]0
    Es probablemente el flag más importante de la IA. Comprueba un montón de cosas, y prácticamente cualquier IA que queramos que sea decente debe de tener este flag activado.
    Comprueba que no se tire un ataque que provoca un cambio de estado a un Pokémon que ya sufre uno, si se cumplen las condiciones para usar algunos movimientos (pesadilla, ronquido...), si nos subimos mucho la evasión intentará usar un ataque con precisión infinita... de verdad, comprueba muchísimas cosas.

  • 3º flag. AI_TryToFaint.
    Código:
    0000 0[B]1[/B]00
    Si un ataque va a debilitar al Pokémon enemigo en todos los casos, lo usará. También da prioridad al uso de ataques con <prioridad alta> si con ellos se consigue debilitar al rival.

  • 4º flag. AI_SetupFirstTurn.
    Código:
    0000 [B]1[/B]000
    Cuando esta flag este activada, durante el primer turno se dará prioridad a ataques de estado, que modifiquen estadísticas, muros tipo reflejo etc.
    Aquí tenéis la lista de ataques a los que se da prioridad:
    Código:
            .byte EFFECT_ATTACK_UP
    	.byte EFFECT_DEFENSE_UP
    	.byte EFFECT_SPEED_UP
    	.byte EFFECT_SPECIAL_ATTACK_UP
    	.byte EFFECT_SPECIAL_DEFENSE_UP
    	.byte EFFECT_ACCURACY_UP
    	.byte EFFECT_EVASION_UP
    	.byte EFFECT_ATTACK_DOWN
    	.byte EFFECT_DEFENSE_DOWN
    	.byte EFFECT_SPEED_DOWN
    	.byte EFFECT_SPECIAL_ATTACK_DOWN
    	.byte EFFECT_SPECIAL_DEFENSE_DOWN
    	.byte EFFECT_ACCURACY_DOWN
    	.byte EFFECT_EVASION_DOWN
    	.byte EFFECT_CONVERSION
    	.byte EFFECT_LIGHT_SCREEN
    	.byte EFFECT_SPECIAL_DEFENSE_UP_2
    	.byte EFFECT_FOCUS_ENERGY
    	.byte EFFECT_CONFUSE
    	.byte EFFECT_ATTACK_UP_2
    	.byte EFFECT_DEFENSE_UP_2
    	.byte EFFECT_SPEED_UP_2
    	.byte EFFECT_SPECIAL_ATTACK_UP_2
    	.byte EFFECT_SPECIAL_DEFENSE_UP_2
    	.byte EFFECT_ACCURACY_UP_2
    	.byte EFFECT_EVASION_UP_2
    	.byte EFFECT_ATTACK_DOWN_2
    	.byte EFFECT_DEFENSE_DOWN_2
    	.byte EFFECT_SPEED_DOWN_2
    	.byte EFFECT_SPECIAL_ATTACK_DOWN_2
    	.byte EFFECT_SPECIAL_DEFENSE_DOWN_2
    	.byte EFFECT_ACCURACY_DOWN_2
    	.byte EFFECT_EVASION_DOWN_2
    	.byte EFFECT_REFLECT
    	.byte EFFECT_POISON
    	.byte EFFECT_PARALYZE
    	.byte EFFECT_SUBSTITUTE
    	.byte EFFECT_LEECH_SEED
    	.byte EFFECT_MINIMIZE
    	.byte EFFECT_CURSE
    	.byte EFFECT_SWAGGER
    	.byte EFFECT_CAMOUFLAGE
    	.byte EFFECT_YAWN
    	.byte EFFECT_DEFENSE_CURL
    	.byte EFFECT_TORMENT
    	.byte EFFECT_FLATTER
    	.byte EFFECT_WILL_O_WISP
    	.byte EFFECT_INGRAIN
    	.byte EFFECT_IMPRISON
    	.byte EFFECT_TEETER_DANCE
    	.byte EFFECT_TICKLE
    	.byte EFFECT_COSMIC_POWER
    	.byte EFFECT_BULK_UP
    	.byte EFFECT_CALM_MIND
    	.byte EFFECT_CAMOUFLAGE
  • 5º flag. AI_Risky.
    Código:
    000[B]1[/B] 0000
    Esta flag favorece el uso de ataques 'arriesgados' como los 1 hit K.O. la autodestrucción, metrónomo, ataques con alto chance de crítico. Vaya, en general favorece que la IA intenta usar cosas arriesgadas (high risk - high reward).
    Aquí tenéis una lista de los efectos de ataques que son favorecidos por esta flag:
    Código:
    .byte EFFECT_SLEEP
    	.byte EFFECT_EXPLOSION
    	.byte EFFECT_MIRROR_MOVE
    	.byte EFFECT_OHKO
    	.byte EFFECT_HIGH_CRITICAL
    	.byte EFFECT_CONFUSE
    	.byte EFFECT_METRONOME
    	.byte EFFECT_PSYWAVE
    	.byte EFFECT_COUNTER
    	.byte EFFECT_DESTINY_BOND
    	.byte EFFECT_SWAGGER
    	.byte EFFECT_ATTRACT
    	.byte EFFECT_PRESENT
    	.byte EFFECT_ALL_STATS_UP_HIT
    	.byte EFFECT_BELLY_DRUM
    	.byte EFFECT_MIRROR_COAT
    	.byte EFFECT_FOCUS_PUNCH
    	.byte EFFECT_REVENGE
    	.byte EFFECT_TEETER_DANCE
  • 6º flag. AI_PreferStrongestMove.
    Código:
    00[B]1[/B]0 0000
    Da prioridad a los ataques más fuertes.

  • 7º flag. AI_PreferBatonPass.
    Código:
    0[B]1[/B]00 0000
    Da prioridad al uso de relevo (BatonPass).

  • 8º flag. AI_nothing
    No hace nada, está vacío.

  • 9º flag. AI_HPAware
    Código:
    [B]1[/B] 0000 0000
    Este flag hace que el IA tenga en cuenta la cantidad de HP de los pokemon en combate, fundamentalmente su utilidad radica en la elección de un objetivo al que atacar en combates dobles. También favorece el uso de movimientos como recuperación o explosión cuando el pokemon tiene poco HP y lo desfavorece cuando tiene mucho HP. (por resumirlo todo un poco).

  • 10º-29º flag. AI_Unused
    No se utilizan.

  • 30º flag. AI_Roaming.
    Código:
    00[B]1[/B]0 0000 [0x00 0x00 0x00]
    Si esta flag está activada el pokemon intentará escapar como lo hace un pokemon errante (latios, entei....).

  • 31º flag. AI_Safari.
    Código:
    0[B]1[/B]00 0000 [0x00 0x00 0x00]
    Este flag de IA es el utilizado en la zona safari. Los Pokémon te observan y huyen, pero no atacan.

  • 32º flag. AI_GoEasy.
    Código:
    [B]1[/B]000 0000 [0x00 0x00 0x00]
    Es el flag utilizado por el Poochyena/Zigzagoon del combate inicial. Si la vida de tu pokemon baja por debajo del 20%, el enemigo abandonará el combate.
En este apartado os voy a enseñar como pasar de un conjunto de flags/bits (0/1), a un número decimal que podáis introducir en el gen3/PGE. Puede que para algunos de nosotros esto último sea algo trivial, pero estoy seguro que para muchos otros no lo es.

Lo que yo recomiendo es que utilicéis la calculadora que viene instalada en vuestro equipo en modo "programador" o una calculadora online que pase de binario a decimal como esta.

Pongamos el siguiente caso: estoy haciendo un entrenador con un perfil algo defensivo y quiero que juegue más o menos safe. En este caso me interesa activar los flags 1-4 y el 6º, pero no el 5º flag (IA_Risky). Los bits quedarían así:
Código:
0010 1111
Los flags que están activados tienen el bit en '1', mientras que los desactivados tienen el bit en '0'. Esto no lo podemos escribir tal cual en el PGE/gen3, así que vamos a nuestra calculadora:
Ese 47 es lo que tenemos que escribir en el PGE/gen3.
Antes de terminar me gustaría hacer una pequeña reflexión por si hay alguien al que todavía no le haya convencido eso de no poner simplemente números grandes en la casilla de IA del PGE.
Código:
[list]
[*]Caso A: valor de IA = 15
[*]Caso B: valor de IA = 240[/list]
¿En cual de estos dos casos la IA será más difícil?
Billy: JAJA, obviamente en el caso B, ¡pareces tonto!
Joder Billy, mira que eres imbécil.

Código:
Caso A: 15 -> 0000 1111
Esta IA ajustará los ataques que usa para que sean lo más efectivos posibles, no dejará de debilitar a tus pokemon si puede y utilizará los primeros turnos para preparar el combate. Es una IA bastante decente.

Código:
Caso B: 240 -> 1111 0000
Esta IA dará preferencia a los ataques más poderosos y a los arriesgados,
así como a relevo. Sin embargo, no comprobará que el ataque pueda ser
poco o nada eficaz, pudiendo usar un terremoto contra un crobat y
prácticamente no evaluará nada. Es una IA bastante poco inteligente.

En definitiva, la IA 240 es mucho peor (en casi cualquier caso) que la IA 15. Ah, y Billy es imbécil. No sé si lo había dicho ya. Tú no quieres ser como Billy ¿Verdad?.
Bueno, lo puedes hacer, pero hasta donde yo se no hay ningún programa actualmente que te permita meterlas (si lo hay decídmelo), así que tendrás que hacerlo 'a mano' desde el HxD.

Esta es la información del primer entrenador del juego en Esmeralda 'Sawyer', aparecen marcados los 4 bytes de la IA, que como se puede ver vale 7.(Sí, los bytes están permutados).


Si por lo que sea queremos que el trainer se comporte como un pokemon errante le ponemos estos flags:




PD: Sé que la mayor utilidad de esto es poner el flag IA_HPAware, pero creo que se veía mejor que funcionaba con esto(?).
Bueno, para vosotros asignar los valores que queráis para los aiFlags es bastante sencillo, simplemente vais al fichero .h en el que están definidos los entrenadores y ponéis el valor que os de la gana.

No obstante, me gustaría recalcar que desde pret se puede hacer prácticamente lo que te de la gana con los flags de AI. No se si alguno se ha dado cuenta ya, pero hay 20 aiFlags que no se utilizan, es tan fácil como definir esos flags y asignarles un script de AI que hagáis vosotros mismos. Lo que pueda salir de ahí solo lo limita vuestra imaginación.

PD: Creo recordar que Alien (el editor de scripts de cosarara tenía también un editor de AI_scripts por si a alguien le sirve de algo).


En fin, espero que esto sirva de algo, al menos para no ver entrenadores semi deficientes mentales por tener cifras altas de IA puestas a boleo.
 

Annatar

A la luz del quinto día, mira al este
Re: [GBA] Usar la IA de combate correctamente

Que brutal tío!

Sin duda es un buen aporte y te confieso que yo ni idea tenía de todo esto de las flags de la IA. Y puedo asegurarte que esto sirve de mucho a la hora de personalizar los combates de la forma que nosotros queramos (incluso da trasfondo a los personajes a la hora de plasmar sus características en combate).

Nada que objetar, buen trabajo Samu ;)
 

Naren Jr.

Puto amo
Usuario de Platino
Respuesta: [GBA] Usar la IA de combate correctamente

Eres mi DIOS SAMUCITO

Fuera de coñas, me parece un gran tutorial, demasiado documentado y bastante solido, eres de esos RHrs que sabe donde buscar la información y como utilizarla.

Recientemente me llamo la atención de ello más cuando en el Gimnasio de Norman en RUBY o EMERALD los entrenadores se enfocan en cierto tipo de cosas, como que cada uno tiene su propio estilo, ahora queda al descubierto el porque es así.

Muchas gracias por esto bro!

TKM
 

Fran Agustín

L'amor està en l'aire
Respuesta: [GBA] Usar la IA de combate correctamente

¡Brutal! ¡Qué buen tutorial! No sólo por el tema que trata, que es poco conocido, sino por la forma en que lo hace. Se nota que le has puesto muchísimo empeño, Zyx, como de costumbre. ¡Gran trabajo!

La verdad es que has pensado en todo y lo explicas muy clarito, no quedan dudas.
Esto explica muchísimo sobre el comportamiento de los trainers y vaya que nos hemos tardado en explicarlo.

¡Gracias! ¡Eres un grande!
 

Dr._Seuss

Average RomHacker
Respuesta: [GBA] Usar la IA de combate correctamente

Agregaré alguna información adicional acerca de la IA de batalla que tiene que ver con el post original.

Algo que muchos no toman en cuenta al momento de insertar un tipo elemental nuevo a sus hackroms y/o poner parches que agregan ataques y tipos nuevos es el comportamiento de la IA. Debido a que insertan un tipo y/o un efecto que no estaba programado si le dan a un entrenador un Pokémon con un tipo/ataques nuevos, la IA va a actuar de manera un tanto errática al no saber como reaccionar a un tipo no programado, haciendo que esta misma ejecute ataques al azar en vez de uar una lógica. Sin importan que tanto le indiquemos a la IA del entrenador que use combinaciones lógicas.

El mejor ejemplo de lo que digo es el famosísimo parche de MrDollSteak, el cual agrega el tipo hada y un puñado de movimientos y efectos nuevos. Si a un entrenador con IA en 7 o 15 (Que es una IA que piensa lo que hace) le pones un Pokémon con ataques con efectos nuevos y entre ellos pones detección/protección, la IA va a spamear ese movimiento como si no hubiese mañana, ya que es el único al cual sabe como actuar. El resto lo usará de manera aleatoria o si el tipo del movimiento es super efectivo contra el rival, sin chequear si el movimiento hará daño o no (Como usar Trampa Venenosa a un rival no envenenado o usar salmuera en un enemigo con habilidad absorbe agua)

Es posible actualizar la IA para que reconozca nuevos movimientos y/o tipos. Aquí un tema en Pokeco con información al respecto.

https://www.pokecommunity.com/showthread.php?t=409111

Combinado lo de arriba con el tema original de @Samu nos dará una IA completamente mejorada y capaz de armar combos imteresantes junto a movimeintos nuevos.
 
Literalmente solo me registre para felicitarte por la guia.
Te juro que no encontraba en ningun lado que me explicaran esto, revise un monton de foros y sitios en ingles y una persona en Reddit QUE NO HABLA ESPAÑOL me recomendó este hilo y me lo pasó traducido por Google Translate, a lo que le dije "Bueno, por suerte hablo español como primer idioma xD" y me vine aqui.
También tengo mucha curiosidad de como podriamos forzar a un entrenador a usar movimientos climáticos sin usar pret ya que tengo un hack rom muy avanzado y no quisiera tener que empezar de nuevo desde un dissasembly.
 
Arriba