miércoles, 12 de agosto de 2026

Página 230: Apuntes de "Pawn AI - Task System in Godot 4"

Lista de reproducción completa del tutorial How to make Rimworld de Real Robots

https://www.youtube.com/playlist?list=PLOb5IPYDOceDIeNvojEYIUeHbHTZShtc- 


En este capítulo comenzamos a desarrollar el sistema de IA que controlará a nuestros colonos. En lugar de programar comportamientos específicos, construiremos una arquitectura basada en tareas y subtareas reutilizables. Empezaremos con una tarea sencilla, buscar comida y comer, que servirá como base para crear comportamientos mucho más complejos en el futuro.

Empezamos creando el script Task.

 

Agregamos el nodo TaskManager(Node) en la escena World(Node2D).

Actualizamos el script de TaskManager agregando la función RemoveItemFromWorld.

Ahora en la escena Pawn(CharacterBody2D), vamos actualizar el script,agregar el nodo PawnIA(Node) con un script nuevo y un progressbar que representara el hambre.

 

 

Y ahora creamos el script para PawnAI(Node).

 

En teoria aqui acaba la cosa, pero como no me gusta tener la sensación de que he copiado codigo sin entender como funciona, voy revisar el recorrido del codigo.

Todo empieza en el script del nodo PawnAI (Node). Si el Pawn no está realizando ninguna tarea, solicitará una nueva al TaskManager. En este ejemplo, como el TaskManager solo genera tareas para alimentarse, el Pawn únicamente pedirá una tarea cuando tenga hambre.

El TaskManager devuelve un objeto de tipo Task

 

Puede decirse que Task es un "manual de instrucciones" que describe cómo realizar una tarea. En lugar de contener toda la lógica en un único bloque, la tarea se divide en varias subtareas que se ejecutarán en orden. 

 

Ahora que PawnAI ha recibido su tarea, entrara en la función DoCurrentTask para realizar los pasos que le indica Task.

 

Primero que hara PawnAI es ver cual es la instrucción que le toca, GetCurrentSubTask.

SubStaks es el array con todos pasos.

currentSubTask es el indice, ira aumentando a medida que se vaya progresando. 

 

 

 PawnAI empieza con el estado Idle, asi que entrara en el primer if.

 

La primera tarea es FindItem, en esta instrucción pedirá al itemManager el item mas cercano, si no hay item devolvera Null.  

 

En caso de no encontrar ningún objeto, el índice avanzará hasta la última subtarea, marcando la tarea como finalizada

 

En caso de que si encuentre algo, aumentaremos el indice  CurrentSubTask y guardaremos el item objetivo en la subtarea Task, nota, el item se guarda en esa subtarea en especifico, si avanzamos de tarea y revisamos el targetItem actual dara nulo.

 

Como el estado actual de PawnAI sigue en Idle, volveremos a entrar en la función StartCurrentSubStack.

Como la siguiente tarea es  Walkto, asi entrara en Task.TaskType.WalkTo, en esta condición moverá a Pawn hasta el objetivo y cambiaremos el estado de PawnAI de Idle a DoingSubStack.

 

Ahora con estado actual de PawnAI cambiado, pasaremos al else en DoCurrentTask.

El script entrara en WalkTo ya que no ha pasado a la siguiente subtarea.

Pasaremos a la siguiente tarea si hemos llegado al objetivo. 

 

 

Terminamos la subtarea actual y copiamos el targetItem en la proxima subtarea. 

 

Y con esta subtarea terminada, volvemos a poner el PawnAI a Idle

 

Si no hay mas trabajos, pondremos el CurrentTask a nulo, aquí el PawnAI empezaría a buscar otro trabajo al TaskManager.

 

Aceleramos el paso, la siguiente tarea es Pickup, en este paso, guardamos el item en PawnAI y lo quitamos del mapa. 

 

 

Y finalmente queda comer, asignamos el estado DoingSubTask y procedemos hacer que Pawn se lo coma, aumentando la nutrición.

 

 

 En resumidas cuentas, la relación entre las tres clases queda de esta forma, no es la forma mas precisa pero si la mas compresible.

 


Al fin terminé. Menudo trabajo, y no me extraña que abandonara este tutorial en su día. Es un no parar de saltar entre clases, por lo que es muy fácil perderse.

Ahora lo suyo sería empezar un proyecto nuevo e intentar implementarlo desde cero, consultando el tutorial lo mínimo posible. En su momento, el sistema de inventario se me hizo difícil de entender y, al igual que ahora, tuve que hacer diagramas para comprender mejor cómo funcionaba.

También hay que decir que algunos nombres de variables y funciones pueden resultar confusos. Por ejemplo, el índice currentSubTask de Task: es fácil olvidar que realmente es un índice. Yo le habría puesto un nombre como currentSubTaskIndex o currentIndexSubTask, ya que deja mucho más claro cuál es su función.

Se acabaron los OP de Bleach, ahora toca OP de Naruto.
 

No hay comentarios:

Publicar un comentario