Esta charla se adentrará en cómo construir una IA para un juego de estrategia por turnos desde cero. Cuando comencé a construir Athena Crisis, no tenía idea de cómo construir una IA. Todos los recursos disponibles eran demasiado complejos o confusos, así que simplemente comencé a construirlo basándome en cómo jugaría el juego. ¡Si quieres aprender cómo construir una IA, no te pierdas esta charla!
This talk has been presented at JS GameDev Summit 2023, check out the latest edition of this JavaScript Conference.
FAQ
Athena Crisis es un juego que se está construyendo utilizando JavaScript, React y CSS. Está diseñado para ser jugado en múltiples dispositivos, incluyendo el Steam Deck, y utiliza estructuras de datos persistentes inmutables para manejar el estado del juego.
Nakazawa Tech, una startup ubicada en Tokio, ofrece una variedad de servicios que incluyen la construcción de videojuegos, coaching de liderazgo y soluciones para mejorar la velocidad de desarrollo y la productividad en proyectos basados en JavaScript.
La IA para Athena Crisis se construyó sobre abstracciones sólidas y primitivas, necesarias para manejar los algoritmos de búsqueda y las decisiones matemáticas del juego. La IA es rápida, sin estado, determinista y componible, actuando bajo el mismo conjunto de reglas que un jugador humano.
Los requisitos incluyen tener buenas abstracciones de programación, conocer los algoritmos de búsqueda para la localización de objetos dentro del juego, y tener conocimientos matemáticos para la toma de decisiones estratégicas.
Athena Crisis utiliza una arquitectura basada en acciones y respuestas, donde cada acción del jugador se valida contra el estado del juego y genera una respuesta que confirma la aplicabilidad de la acción dentro de las reglas del juego.
El sistema de niebla de guerra en Athena Crisis oculta partes del estado del juego que están fuera del rango de visión de las unidades del jugador, lo cual añade una capa estratégica al no revelar toda la información a todos los jugadores simultáneamente.
La comunicación se optimiza mediante el uso de estructuras de datos inmutables y codificadores/decodificadores automáticos para las acciones del juego, asegurando que solo los cambios necesarios sean transmitidos y manteniendo la sincronización entre cliente y servidor.
El juego utiliza algoritmos como A* para decisiones de ruta, y combina esto con un sistema que evalúa la acción óptima basada en el contexto de la unidad, como atacar, moverse hacia objetivos estratégicos o suministrar recursos, siempre dentro de las reglas del juego.
Únete a Christoph de Nakazawa Tech en la construcción de la IA para Athena Crisis, un juego donde la IA realiza acciones como un jugador. Aprende sobre la importancia de las abstracciones, primitivas y algoritmos de búsqueda en la construcción de una IA para un videojuego. Explora la arquitectura de Athena Crisis, que utiliza estructuras de datos persistentes inmutables y actualizaciones optimistas. Descubre cómo implementar comportamientos de IA y crear una clase para la IA. Averigua cómo analizar unidades, asignar pesos y priorizar acciones basadas en el estado del juego. Considera los próximos pasos en la construcción de la IA y explora la posibilidad de construir una IA para un juego de estrategia en tiempo real.
1. Introducción a la construcción de IA para Athena Crisis
Short description:
¡Hola! Únete a mí en mi charla sobre la construcción de la IA para Athena Crisis. Soy Christoph de Nakazawa Tech. Si no has oído hablar de Athena Crisis antes, te recomiendo ver mi charla anterior. Tengo experiencia en la gestión de equipos de infraestructura de React Native y JavaScript en Facebook. Ofrecemos coaching de liderazgo y resolución de problemas de JavaScript en Nakazawa Tech. Contáctanos en nakazawa.dev.
¡Oh, hola! Estoy jugando a Athena Crisis en mi Steam deck. Muchas gracias por unirte a mí en mi charla sobre la construcción de la IA para Athena Crisis. Soy Christoph y dirijo una pequeña startup en Tokio llamada Nakazawa Tech. Si no has oído hablar de Athena Crisis antes, recientemente en la React Summit hace unos meses, di una charla que explica cómo se está construyendo el juego, y todo está construido con JavaScript, React y CSS. Recomiendo encarecidamente que si no lo has visto, vuelvas y veas esa charla. Si retrocedemos aún más, si nunca has trabajado conmigo antes o si no me conoces, solía gestionar los equipos de infraestructura de React Native y JavaScript en Facebook, y construí un framework de pruebas llamado JustJavaScript. Hacemos muchas cosas en Nakazawa Tech, incluyendo la construcción de videojuegos, pero también ofrecemos coaching de liderazgo, y podemos ayudarte con tus problemas de JavaScript, con la velocidad de desarrollo, la productividad o ayudarte con cualquier problema que puedas encontrar al construir aplicaciones basadas en JavaScript. Por favor, trabaja con nosotros, contáctanos en nakazawa.dev.
2. Understanding Athena Crisis and Building an AI
Short description:
Antes de sumergirnos en la construcción de una IA para Athena Crisis, comprendamos qué es Athena Crisis. En el juego, puedo entrar en una partida desde el menú y jugar. Después de mi turno, la IA toma el control y realiza todas las acciones necesarias, como un jugador. Puede atacar, moverse y capturar edificios. Ahora, exploremos cómo construir una IA así.
Primero, antes de adentrarnos en la construcción de una IA para Athena Crisis, dediquemos un poco de tiempo a comprender qué es Athena Crisis. Estoy aquí en el juego en el menú, y puedes ver la página de descripción general en este momento, y puedo entrar en una partida desde aquí mismo. Y así, puedo jugar el juego. Aún no todos los ataques tienen sonido, pero algunos sí lo tienen. Pero lo interesante es que, una vez que termino mi turno, déjame construir algunas unidades. Cuando termino mi turno, la IA toma el control y se encarga de su turno. Realiza ataques, se mueve, puede capturar edificios, puede hacer todo lo que un jugador haría.
3. Building an AI with Abstractions
Short description:
Veamos cómo construir una IA así. Hablaremos sobre código, abstracciones, primitivas, algoritmos de búsqueda y matemáticas. Construir una IA para un videojuego puede ser desafiante, pero al tener abstracciones básicas y abordarlo como si estuvieras jugando el juego, se vuelve más manejable.
también puede hacerlo. Apaga la música de nuevo. Así que veamos cómo podríamos construir realmente una IA como esa. La advertencia aquí es que esta es una charla centrada en código. Hablaremos mucho sobre código, pero al mismo tiempo, será apta para principiantes. Así que por favor, acompáñame mientras repaso todas las piezas. Los requisitos previos que encontré para construir una IA son que necesitas tener buenas abstracciones. Necesitas tener primitivas sólidas, necesitas conocer los algoritmos de búsqueda para saber dónde están las cosas en el juego, y necesitas conocer matemáticas para decidir qué acción tomar. La forma en que abordé esto fue que mi problema era que nunca antes había construido una IA para un video juego. Así que no tenía idea de cómo hacerlo. Leía artículos en internet sobre cómo construían una IA para tipos específicos de video juegos, y simplemente no me parecía lógico porque siento que estas cosas son realmente difíciles de entender cuando solo las lees o cuando solo ves a alguien más hacer eso. La mejor forma que encontré para construir una IA es teniendo todas estas abstracciones básicas en su lugar y luego construyéndola como si imaginara qué haría si estuviera jugando el juego.
4. Supuestos y Abstracciones para Construir una IA
Short description:
Quiero construir una IA que sea rápida, sin estado, determinista y componible. Si estoy construyendo una IA que se comporte como un jugador humano, necesito tener abstracciones en el juego que pueda proporcionar al código de la IA que sean básicamente las mismas que le doy a un jugador.
Y así, los supuestos que hice son que quiero construir una IA que sea rápida, sin estado, determinista y componible. Así que te he lanzado muchas palabras. Y la forma en que lo veo es que si estoy construyendo una IA que se comporte como un jugador humano, de la misma manera que estoy jugando, necesito tener abstracciones en el juego que pueda proporcionar al código de la IA que sean básicamente las mismas que le doy a un jugador. Por supuesto, es un poco diferente porque el jugador ve un mapa, se renderiza en un navegador y todo eso, pero debajo de eso, debe haber un nivel
5. Construyendo una IA sin estado para Athena Crisis
Short description:
Para construir una IA sin estado para Athena Crisis, se necesitan primitivas sólidas como un estado de mapa y acciones. La IA debe ser rápida, sin estado y determinista. La composabilidad también es importante, permitiendo que los módulos sean reutilizables en todo el sistema. La arquitectura de Athena Crisis utiliza estructuras de datos persistentes inmutables, asegurando cambios declarativos en el estado del juego. La IA se ejecuta en el servidor, comportándose como otro jugador, y comunica sus acciones al cliente. Las actualizaciones optimistas garantizan que el cliente y el servidor tomen acciones simultáneamente.
de abstracciones con las que puedes trabajar si eres humano o si eres una IA. Y para eso, necesitas primitivas sólidas, necesitas tener un estado de mapa, necesitas tener acciones. Y luego, si volvemos a la suposición, es que quería que la IA fuera súper rápida. Quería que fuera sin estado. Así que toma una acción, no tiene memoria, descubre cuál es la siguiente acción que puedo tomar para maximizar mis posibilidades de ganar. Obviamente, una IA más inteligente tendría memoria o planificaría y descubriría cuál es la mejor manera de ganar durante todo el tiempo del juego. Pero por ahora y para este ejemplo hoy, solo vamos a pensar en cómo podemos hacer una IA sin estado que solo haga una acción a la vez. En cuanto a hacerla determinista, lo que me importa es que no haya aleatoriedad involucrada. Obviamente, en el juego real de Athena Crisis, hay cierta aleatoriedad en la IA para que las cosas se mezclen. Porque si le dices a la IA, `oye, ve y construye la unidad que creas que es la más útil para construir`, entonces terminas construyendo la misma unidad cada vez, en cada turno, muy probablemente, ¿verdad? Así que quieres tener algo de variedad en el juego. Así que podrías agregar algo de aleatoriedad. No vamos a hacer eso hoy. Y en cuanto a la composabilidad, es realmente útil que la IA... que todos los módulos sean reutilizables en todo el sistema. Entonces, si estás haciendo algo para buscar caminos, o si estás descubriendo cuál es la unidad a la que debo atacar que me aporta más valor como jugador, debes abstraer eso para poder componerlos de otras formas. Y si observamos la arquitectura de Athena Crisis, naturalmente llegué a algo que era una base sólida para construir una IA. En primer lugar, y nuevamente, puedes volver a esa charla en la cumbre de React para aprender más sobre la configuración básica de Athena Crisis. Pero todo utiliza estructuras de datos persistentes inmutables. Entonces tienes un estado de mapa , lo transformas y obtienes un nuevo estado. Por lo tanto, no estás realizando cambios imperativos en el mapa o en el estado del juego. Todo es declarativo. Solo estás diciendo, aquí está el estado del juego que me gustaría ejecutar. Aquí está el cambio que me gustaría ejecutar en un estado del juego, y obtienes un nuevo estado del juego y este tipo de arquitecturas también funcionan muy bien en una relación servidor-cliente porque Athena Crisis será un juego que se puede jugar con muchas personas en Internet. Y naturalmente, gran parte del código se ejecuta en el servidor. Por ejemplo, la IA que te mostré antes se ejecutaba completamente en el backend y no se envía al cliente en absoluto. Solo te dice los comportamientos o las acciones que está tomando la IA. Y en ese sentido, funciona exactamente igual que otro jugador. Porque cuando juegas un juego en Internet contra otra persona, no conoces el proceso de toma de decisiones por el que están pasando mientras toman acciones. Y la IA funciona de la misma manera, excepto que se ejecuta en un servidor y te dice las decisiones que tomó al final. En cuanto a las actualizaciones optimistas, la idea es que el cliente siempre toma
6. Transformadores de acciones y arquitectura
Short description:
Los transformadores de acciones y la arquitectura de acción-respuesta son la pieza central en la que estamos trabajando. Los jugadores realizan acciones, que se ejecutan en el estado del juego. Las acciones visibles se calculan en función de la niebla de guerra y la visibilidad individual de los jugadores. El generador de código automatiza los codificadores y decodificadores de acciones. Ejecutar una acción implica obtener unidades, asegurarse de los oponentes y verificar la elegibilidad para el ataque.
Al mismo tiempo que el servidor, el jugador realiza una acción. Y, como no hay aleatoriedad en ello, eso debería funcionar idealmente y toda la experiencia del usuario debería sentirse bien. Permíteme explicarte los transformadores de acciones y la arquitectura de acción-respuesta, porque esa es la pieza central en la que vamos a trabajar mientras construimos una IA. La forma en que funciona es que cuando un jugador juega el juego, realiza una acción. Por ejemplo, antes estaba moviendo mi unidad. Mover o atacar, esas son acciones. Luego las ejecutamos en el estado del juego y obtenemos una respuesta de acción. Básicamente, eso solo confirma, okay, el jugador quiere mover esta unidad de aquí a allá. Ejecutamos esa acción. Y si obtenemos una respuesta de acción, significa que esa acción realmente es aplicable al estado del juego. Por ejemplo, valida que realmente puedas mover esa unidad. Valida que puedas moverla a ese lugar y si eso es aceptable dentro de las reglas del juego. Y luego, en función de cada jugador, calculamos las acciones visibles. Antes solo te mostré un mapa básico del juego, pero también hay un sistema llamado niebla de guerra, donde cada unidad tiene un rango de visión y no puedes ver más allá de eso. Entonces hay muchas partes del estado del juego que están ocultas para el jugador según lo que tus unidades pueden ver. Y el único lugar que tiene el estado completo del juego es el servidor. ¿Correcto? Y así, puedes mover una unidad de un lugar a otro y otros jugadores solo pueden ver una de esas casillas. Y luego, cuando calculas las acciones visibles, se eliminarán todas las partes del movimiento que el jugador no está autorizado a ver. Después de calcular esas acciones, obtienes respuestas de acción para cada jugador individualmente, luego en el cliente, las animas y luego las aplicas al estado del juego. Permíteme mostrarte el código aquí, en realidad. Como te mostré antes, hay una acción de ataque a una unidad. Si la ejecutas, puedes obtener una respuesta de acción de ataque a una unidad. Y luego esto se comprime en una tupla donde se eliminan todos los elementos innecesarios al enviarlo a través de la red. Hay un generador de código que genera estos codificadores y decodificadores de acciones para todas las acciones del juego. Así que todo es automático. Y esto es lo que parece ejecutar una acción. Por ejemplo, para atacar a una unidad, recibes la estructura de datos del mapa. Obtienes las unidades de esa estructura. Te aseguras de que cuando atacas a una unidad, no sean del mismo jugador y no estén en el mismo equipo. Te aseguras de que la unidad que está atacando realmente pueda ejecutar un ataque y que aún no esté completado.
7. Implementando Comportamientos de IA y Creando una Clase
Short description:
La arquitectura funciona aplicando respuestas de acción al estado del juego, actualizando unidades con nuevos datos. Este enfoque simplifica la construcción de una IA al generar acciones válidas para el estado actual del juego. La arquitectura proporciona una capa de abstracción común, evitando el fraude de la IA y asegurando que todos los jugadores jueguen según las mismas reglas. Implementemos comportamientos de IA describiendo el comportamiento más básico y creando una pequeña clase.
Y luego realizas una serie de cálculos de daño. Y luego devuelves las estadísticas para las nuevas unidades. Y luego, cuando estás buscando, cuando tienes niebla de guerra, tienes que, como dije, calcular si esas acciones son visibles o no. Entonces hay una definición que uso, básicamente dice que si ambos campos son visibles, entonces puedes recibir la respuesta de acción regular de ataque a la unidad. Si solo la fuente, solo la unidad que está atacando es visible, entonces transforma esa respuesta de acción en un ataque a una unidad oculta. Y si solo el objetivo es visible, lo transforma en un ataque de una fuente oculta a una unidad. Obviamente, estos se invierten, porque si solo el objetivo es visible, entonces la fuente del ataque es visible. Así que es un ataque de fuente oculta. Y luego, más adelante, hay muchas animaciones involucradas aquí. No las mostraré hoy porque no son relevantes para construir la IA, pero aplicamos esas respuestas de acción. Así que observamos todas las respuestas de acción y si está atacando a una unidad, recibimos todos los nuevos datos de la unidad. Obtenemos las unidades existentes y luego, según el estado, actualizamos la unidad con los nuevos datos. Todo aquí es inmutable. Y descubrí que esta arquitectura funciona muy bien para construir una IA. Aquí tienes un ejemplo rápido. Simplemente estoy moviendo y atacando al tanque rosa. Primero, aplicamos la respuesta de acción desde esta posición aquí arriba y la movemos al puente, y luego usamos esa unidad que está en el puente para atacar a la unidad que está junto a ella. Y así es como funciona la arquitectura. Entonces, todo lo que realmente necesitamos si estamos construyendo una IA es generar un montón de estas acciones que sean válidas para el estado actual del juego. Esto simplifica significativamente el problema del proyecto. Porque imagina, no tienes una abstracción como esta donde estás aplicando acciones a un estado de juego y para cada acción del jugador, estás modificando manualmente el estado del juego. Dices, OK, atacar, y luego simplemente vas y tienes código imperativo que cambia todo en un solo lugar. Y luego, si intentas construir una IA, tienes que copiar todo eso a tu IA y luego tienes problemas. Pero también proporciona esta capa de abstracción común donde no le das a la IA acceso para hacer cosas como hacer trampa. Si estás realizando un ataque o ejecutando un ataque con este tipo de abstracción, la IA no puede tener un ataque que sea el doble de efectivo o algo así si eso tampoco está permitido para el jugador. Por supuesto, es posible que desees tener un sistema así. Pero en un juego como Athena Crisis, quieres que todos los jugadores jueguen según las mismas reglas. Finalmente, implementemos comportamientos de IA. Lo hacemos simplemente describiendo el comportamiento más básico.
8. Agregando Comportamientos y Movimientos de IA
Short description:
La primera versión de nuestra IA solo puede finalizar el turno. Ejecutamos la acción Fin de Turno en el estado del juego y agregamos un método auxiliar llamado actuar. Usamos la función de acción para encadenar los comportamientos de la IA. Cuando la IA está ejecutando un Fin de Turno, devolvemos nulo. Para agregar un movimiento, intentamos mover una unidad. Si no se pueden mover más unidades, finalizamos el turno. Implementamos la función de movimiento utilizando funciones auxiliares para obtener las unidades disponibles y determinar hacia dónde deben ir según el estado del mapa.
El primer comportamiento que la IA podría tener. Vamos a armar una pequeña clase. No es necesario usar clases aquí, pero es un poco más fácil. La primera versión de nuestra IA solo puede hacer una cosa. Cuando la IA comienza su turno, finaliza el turno. Y esa es una buena manera de asegurarse de que la IA deje de jugar, porque de lo contrario, el juego se bloquea rápidamente. En este caso, simplemente vamos a agregar una única acción llamada Fin de Turno. Ejecutamos la acción Fin de Turno en el estado del juego. Y vamos a agregar aquí un método auxiliar que será útil más adelante. Básicamente, estamos agregando este método, actuar. Si ejecutamos una acción aquí, la agregamos a esta matriz de respuestas, y luego podemos recuperarlas más tarde y enviarlas al jugador. Y luego, lo interesante aquí, usaremos esta función llamada acción para encadenar todos nuestros comportamientos de IA juntos. Y una vez que esta función devuelve nulo, significa que la IA ha terminado. En este caso, cuando la IA está ejecutando un Fin de Turno, simplemente devolvemos nulo. Y así es como podríamos usar esta IA. Así que simplemente creamos una nueva instancia, y mientras el jugador actual sea un bot, simplemente actuamos en el mapa y luego reemplazamos, lo importante es también reemplazar el mapa con el nuevo estado del juego. Y luego, al final, recibimos todas las respuestas y podemos transmitirlas al cliente. Entonces, en este caso, simplemente devolvería una respuesta de acción de Fin de Turno y luego se la enviaría al jugador. Como puedes ver aquí, el juego está en un bucle. Cada vez que termino mi turno, la IA termina el suyo. Entonces, ahora, ¿cómo agregamos un movimiento? Por ejemplo, vimos esta función de acción anteriormente. Entonces, ahora, la forma en que lo estamos ampliando es que, en primer lugar, siempre intentaremos mover una unidad. Y si no hay más unidades que podamos mover, es decir, esta función devuelve nulo, entonces finalizaremos el turno. Y así, la forma en que podemos implementar una función de movimiento es a través de un conjunto de funciones auxiliares diferentes. En primer lugar, simplemente obtendremos la primera unidad disponible que podamos mover. Así que supongamos que hay una función auxiliar aquí que nos permite extraer eso. Y luego, ¿cómo jugaría un humano, verdad? Y así es como pensé en cómo jugaría. Es como si fuera a mirar lo que es interesante en el mapa, como, ya sabes, según la situación actual, según esta unidad, según el estado del mapa, ¿dónde tiene más sentido que vaya esa unidad? Una vez que tengo esta lista de posiciones, averiguo cuáles son los grupos de a dónde debo ir. Entraré en detalles más adelante. Pero básicamente, puedo tener, como, cien posiciones interesantes, pero necesito averiguar a dónde ir realmente. Y así, la forma en que funciona esta función de agrupación es que tomará todas esas posiciones y las reducirá a una cantidad menor de grupos donde tiene más sentido buscar a dónde ir realmente. Y luego, en función de eso, miramos, ya sabes, a qué objetivo deberíamos ir realmente. Entonces,
9. Moviendo Unidades y Comportamientos de las Unidades
Short description:
Solo tenemos unos pocos grupos y encontramos un objetivo. Si tenemos una ubicación, ejecutamos una acción de movimiento; de lo contrario, una acción completa. Cada función debe devolver una acción o modificar el estado del juego. La función de movimiento evita el recomputo cuando no hay a dónde ir. Se utiliza el algoritmo A estrella para optimizar el movimiento en la cuadrícula 2D. Las unidades tienen diferentes comportamientos basados en sus habilidades, como capturar edificios o atacar a otros. El comportamiento de la unidad se determina por las posiciones interesantes en el mapa y sus capacidades.
si observas esto como, como, ya sabes, podríamos tener muchas posiciones. Solo tenemos, como, unos pocos grupos. Y luego solo encontraremos un objetivo. Y luego, si tenemos una ubicación a la que ir, ejecutaremos una acción de movimiento. De lo contrario, y aquí es donde se vuelve realmente importante, ejecutaremos una acción completa. Entonces, lo importante aquí es que cada una de estas funciones siempre debe devolver una acción. O lo siento. Siempre debe modificar el estado del juego. Entonces, ya sea que la unidad se mueva o complete, lo que significa que no tomará ninguna otra acción.
Porque el problema al que te enfrentas, de lo contrario, si ejecutas esta función de acción en un bucle, entrará en la función de movimiento y luego siempre intentará recomputar todo esto, solo para darse cuenta de que no hay a dónde ir. Entonces, siempre debes asegurarte de que cada una de estas funciones, cuando no haya más acciones que tomar, devuelvan nulo o modifiquen el estado del juego para que puedas volver a esa función para mover la siguiente unidad. Entonces, idealmente, a medida que ejecutas acciones de juego aquí, el número de unidades disponibles disminuye a cero para que puedas ingresar a la función de fin de turno aquí.
Muy bien, ahora, descubramos todo esto sobre cómo moverse realmente. Hay un algoritmo muy común . Hay muchos algoritmos para buscar, buscar en una cuadrícula 2D hacia dónde vas. Me decidí por A estrella, funciona muy bien para este tipo de juego. Y lo único aquí es que básicamente estás haciendo una búsqueda en profundidad en una cuadrícula 2D para averiguar dónde deberías ir y estás tratando de hacerlo de la manera más rápida posible con el menor costo. Si solo miramos el mapa del juego, esta unidad no puede ir a las montañas y cuesta más ir al bosque que quedarse en la calle. Entonces, estamos tratando de optimizar cómo llegar desde esta casilla verde, desde esta unidad hasta aquí. En este caso, solo hay un camino, ¿verdad? Pero aún así necesitamos averiguar, está bien, ¿es este el camino a seguir? o deberíamos pasar por el río. Pero ya sabes, esta unidad no puede pasar por el río, así que una vez que haces esta búsqueda de ruta, tienes paredes o tienes un costo de movimiento más alto que ciertas casillas. Y luego, una vez que tienes este radio y esta capacidad para averiguar dónde puede ir esta unidad, entonces podemos averiguar, está bien, ¿cuáles son las posiciones interesantes en un mapa y luego averiguar si la unidad realmente puede viajar allí. Entonces, esto es obviamente una versión simplificada, pero aquí hay tres cosas en las que podrías fijarte. La implementación real en Athena Crisis es de unas cientos de líneas, dependiendo del estado del juego y la unidad sobre la que estás preguntando qué hacer. Entonces, por ejemplo, las unidades pueden capturar edificios, las unidades pueden atacar a otras, las unidades pueden suministrar combustible y munición a otras unidades. Entonces, por ejemplo, podrías tener un sistema aquí donde una unidad que puede suministrar a otras pensará en otras unidades si tienen poca munición, ¿verdad? O en este caso, si la unidad no tiene un ataque o se queda sin munición, está en peligro. Entonces, si está en la primera línea, realmente pensará que las posiciones interesantes son los edificios de vuelta donde están mis bases. Y a través de eso, si alimentamos eso en el sistema que describí, esa unidad intentará retirarse. Y aquí, por ejemplo, si la unidad tiene la capacidad de capturar otros edificios, entonces el lugar más interesante para ir es a otros edificios que son propiedad del oponente. Y finalmente, si la unidad tiene ataques regulares, lo más probable es que encuentre interesante ir a otras unidades, como unidades oponentes
10. Building AI: Encontrar Objetivos y Agregar Ataques
Short description:
En el lado izquierdo, tenemos todo el mapa con unidades amarillas y rosas. Utilizamos un algoritmo de K-means para encontrar posiciones interesantes y reducirlas a grupos. Luego, encontramos el objetivo más cercano basado en el radio de movimiento y posicionamos la unidad junto a él. Finalmente, ejecutamos una acción de movimiento hacia el puente. Agregar ataques es similar a moverse. Primero analizamos los ataques, luego nos movemos a lugares interesantes y terminamos el turno. Elegimos el mejor ataque basado en el resultado para el jugador actual. Si es necesario, nos acercamos al objetivo antes de atacar.
para ir. Entonces, ahora pensemos en todo esto con los grupos. Entonces, en el lado izquierdo, tenemos todo el mapa, ¿verdad? Y así, tienes las unidades amarillas aquí y tienes las unidades rosas allí. Entonces, una vez que obtenemos las posiciones interesantes a las que esta unidad debe ir, el mapa se verá así para la IA. Será como, okay, creo que hay uno rosa aquí y una unidad rosa allí. ¿A cuál debería ir realmente? Y hay una función muy útil. Esta es una de las pocas veces en las que estoy feliz de usar una biblioteca de terceros porque es un montón de matemáticas que se simplifican al empujarlas hacia otra biblioteca. Básicamente, podrías tener 100 puntos en el mapa. En este caso, sé que solo tenemos dos. Así que este es un ejemplo muy simple. Pero simplemente estamos usando un algoritmo de K-means y hay un paquete de NPM llamado sk-means que es bastante rápido, donde podemos proporcionar un montón de posiciones y luego decirle, aquí está qué algoritmo usar y cuántas iteraciones debes tomar y cuántas ubicaciones o grupos debes devolver como máximo, y luego reducirá esos y los agrupará según su interés. Y luego, finalmente, simplemente alimentaremos esos grupos en una función llamada encontrar ruta hacia objetivos donde en realidad solo vamos a mirar, okay, esta unidad solo puede moverse de un lugar a otro en este turno. Así que simplemente encontremos el objetivo más cercano.
Y luego simplemente podemos, tal vez en este caso, usar la distancia en la cuadrícula. Pero la implementación real, la forma en que funciona, es que en realidad se verá el radio de movimiento, porque es posible que tengas una unidad que esté muy cerca de otra, pero hay una montaña en medio, por lo que no puede acceder a esa unidad. Entonces, en realidad debes mirar el radio, el radio de movimiento de esa unidad para ver cuál es el más fácil de alcanzar. Y una vez que sepamos cuál es la unidad más cercana, averiguaremos cómo llegar allí realmente. Y luego intentaremos posicionar la unidad justo al lado del objetivo. Entonces, en este caso, objetivo.padre, esta función devuelve una lista de rutas donde cada... lo siento, una lista de campos y donde cada campo tiene un padre, para que puedas navegarlo. Y no podemos mover la unidad encima de otra, así que tenemos que moverla al padre de esa unidad. Y finalmente, podemos unirlo todo y nuestra unidad se mueve hacia el puente. Como dije, buscamos las posiciones interesantes, las reducimos a grupos, encontramos una ruta hacia un objetivo y luego ejecutamos una acción de movimiento. Una vez que hemos terminado con la acción de movimiento, terminamos el turno. Muy bien, y luego lo otro que quiero mostrar es cómo construir un ataque. Por ahora, todo lo que hacemos es que la unidad se mueve, pero ¿cómo agregamos ataques? Y en realidad es muy similar a moverse. Entonces, ¿qué tal si cada vez que la IA comienza, primero miramos los ataques? Si no hay ataques para hacer, entonces nos movemos a lugares interesantes, y finalmente terminamos el turno. La forma en que he implementado esto es que en cada punto del juego, miro cuál es el mejor ataque que tiene el mejor resultado para el jugador actual. Y si hay un ataque disponible, entonces nos aseguramos de que debemos movernos allí. Y si es así, si la distancia es mayor que uno, entonces primero nos acercamos a esa unidad y luego atacamos a esa unidad. Muy bien, ¿cómo averiguamos cuál es el mejor ataque? Aquí hay una implementación básica para averiguar el mejor ataque.
11. Analizando Unidades y Asignando Pesos
Short description:
Analizamos las unidades y sus capacidades de ataque, asignando pesos al daño probable. Priorizamos las acciones en función del estado del juego y la importancia de derrotar ciertas unidades. En lugar de maximizar el daño, consideramos la cantidad mínima de daño necesaria para eliminar una unidad del campo. Evitamos acciones de bajo daño para prevenir contraataques. Priorizamos la defensa de edificios y unidades con habilidades especiales. Finalmente, observamos cómo nuestra unidad se mueve y ataca al objetivo.
En primer lugar, analizamos todas las unidades que tiene el jugador. Luego, determinamos, okay, anteriormente les mostré el algoritmo A estrella, y podemos extenderlo para no solo proporcionar el radio de movimiento, sino también el radio de ataque, que generalmente es el radio de movimiento más un campo a cada lado, algo así. Luego, para cada unidad a la que esa otra unidad puede atacar, determinamos cuál es el daño probable que podemos infligir, y luego le asignamos un peso. Y, ya saben, acompáñenme por un momento, suponemos que el daño máximo tiene el peso más alto. Luego, lo agregamos a una lista de posibles ataques. Y luego simplemente devolvemos el que tiene el peso más alto. En este caso, el daño más alto. Pero puede que no sea ideal pensar siempre en hacer la mayor cantidad de daño. Por lo tanto, es necesario introducir pesos. Y en este caso, dependiendo del estado del juego, puede ser más valioso atacar ciertas unidades en cierto estado que atacar otras unidades. Por ejemplo, si estás derrotando a esa unidad, es mucho más importante ejecutar esa acción que si solo estás reduciendo un poco su salud. Y este es un cálculo ligeramente más complejo porque lo que he descubierto es que no quieres tener el daño máximo a una unidad que ya está dañada. En realidad, quieres encontrar la unidad que puede hacer la menor cantidad de daño a una cierta unidad para sacarla del campo porque eso reserva otras unidades más fuertes para hacer ataques más fuertes a otras unidades más adelante. Y otra cosa que he descubierto es que, quieres evitar acciones de muy bajo daño porque puede que solo tengas una unidad que se encuentre con otra unidad y no haga ningún daño pero luego el contraataque es tan fuerte que esa unidad es eliminada del campo. Por lo tanto, es posible que desees evitar eso también. Y luego se vuelve mucho más interesante aquí en este lado también dice, okay, ¿qué pasa si hay un edificio aquí y luego hay una unidad oponente en ese campo y esa unidad está tratando de tomar tu edificio eso probablemente es mucho más importante que eliminar una unidad aleatoria que está en otro lugar del campo. Y luego, hay varios casos en los que, si esta unidad está transportando otras unidades o si el edificio en cuestión es el... Si el edificio donde se encuentra esa unidad es tu propia sede, es muy probable que pierdas. Por lo tanto, le daremos prioridad. O en algunos casos, algunas unidades tienen la capacidad de atacar y otras solo tienen otras habilidades especiales. La mayoría de las veces, es más importante atacar esas unidades. Y luego, juntamos todo eso y luego, veremos cómo nuestra unidad se mueve y ataca a esa otra unidad. Muy bien.
12. Building AI: Next Steps and Conclusion
Short description:
Para continuar construyendo la IA, debemos admitir todas las capacidades de las unidades y edificios, eliminar la información no visible para la IA y considerar comportamientos de IA personalizables. Las IA reales en los videojuegos se optimizan para predecir acciones futuras, pero esto puede ralentizar la IA. Esta visión general es útil para construir una IA de juego de estrategia por turnos en 2D. A continuación, consideremos construir una IA para un juego de estrategia en tiempo real. La charla fue diseñada con React y MDX, y el código fuente está disponible en GitHub. Si estás interesado, ponte en contacto con Nakazawa Tech para colaborar.
Entonces les mostré cómo agregar una IA a un juego de video, cómo moverla, cómo ejecutar ataques. ¿Cuál sería el siguiente paso? En primer lugar, debes admitir todas las capacidades de las unidades y edificios que tiene el juego, para que la IA tenga las mismas capacidades que un jugador humano. No hemos pensado en la niebla de guerra en absoluto en esta IA. De hecho, debemos asegurarnos de que la IA no obtenga información que el jugador no tenga. Por lo tanto, debemos eliminar toda la información que no sea visible para la IA.
Una cosa que encontré muy divertida y que pensé que iba a ser muy difícil, pero resultó ser relativamente fácil, es agregar comportamientos de IA personalizables. Puedes hacer que una IA sea más agresiva, defensiva o pasiva, o puedes adaptar su estilo según el estado del juego, cuando es atacada, cambiará de defensiva a agresiva, algo así. Si has estado siguiendo esto y estás interesado en construir una IA, te recomiendo encarecidamente que construyas tu primera versión y luego pienses en cómo hacerla defensiva o más agresiva. Es realmente divertido experimentar con eso y ver qué tipo de resultados tiene al ajustar el pequeño peso de priorizar una cosa sobre otra.
Finalmente, como dije al principio, solo queremos que esta IA sea rápida, sin estado y componible, y no haga ningún tipo de planificación. No mira hacia atrás. No tiene memoria. No piensa en cinco turnos adelante, en cuál es el movimiento más inteligente que podría hacer ahora que me preparará para el éxito más adelante. Las IA reales en los videojuegos probablemente hagan algún tipo de optimización para predecir lo que va a suceder en el futuro. Planifican cuál es la mejor acción, no solo ahora, sino también si pensamos en el futuro, según cómo pueda evolucionar el juego. El problema con eso es que tiende a volverse muy lento porque la IA tiene que pensar mucho. Por ejemplo, ¿qué pasa si me muevo de esta manera y luego el jugador contrario tiene cinco opciones y puede tomar una de esas cinco, lo que luego genera siete opciones para mí y luego tienes esta explosión en términos de toma de decisiones? Por lo tanto, se vuelve muy lento. Pero espero que esta visión general te haya sido útil si nunca has construido una IA desde cero para entender cómo construir una IA para un juego de estrategia por turnos en 2D. Ahora, el siguiente paso podría ser, ¿cómo construir una IA para un juego de estrategia en tiempo real que tal vez también esté construido en una cuadrícula o algo así?
Otra cosa que quería compartir es que toda esta charla fue diseñada con React y MDX. Construí un sistema llamado reMDX que puedes usar para hacer presentaciones de diapositivas y puedes encontrar el código fuente de toda esta presentación en GitHub también. Y nuevamente, trabajo en Nakazawa Tech, una pequeña startup en Tokio. Si te gustaría trabajar con nosotros, por favor ponte en contacto. Muchas gracias.
The Talk discusses React Forget, a compiler built at Meta that aims to optimize client-side React development. It explores the use of memoization to improve performance and the vision of Forget to automatically determine dependencies at build time. Forget is named with an F-word pun and has the potential to optimize server builds and enable dead code elimination. The team plans to make Forget open-source and is focused on ensuring its quality before release.
Mishko, the creator of Angular and AngularJS, discusses the challenges of website performance and JavaScript hydration. He explains the differences between client-side and server-side rendering and introduces Quik as a solution for efficient component hydration. Mishko demonstrates examples of state management and intercommunication using Quik. He highlights the performance benefits of using Quik with React and emphasizes the importance of reducing JavaScript size for better performance. Finally, he mentions the use of QUIC in both MPA and SPA applications for improved startup performance.
Suspense is a mechanism for orchestrating asynchronous state changes in JavaScript frameworks. It ensures async consistency in UIs and helps avoid trust erosion and inconsistencies. Suspense boundaries are used to hoist data fetching and create consistency zones based on the user interface. They can handle loading states of multiple resources and control state loading in applications. Suspense can be used for transitions, providing a smoother user experience and allowing prioritization of important content.
Tom Pressenwurter introduces Redwood.js, a full stack app framework for building GraphQL APIs easily and maintainably. He demonstrates a Redwood.js application with a React-based front end and a Node.js API. Redwood.js offers a simplified folder structure and schema for organizing the application. It provides easy data manipulation and CRUD operations through GraphQL functions. Redwood.js allows for easy implementation of new queries and directives, including authentication and limiting access to data. It is a stable and production-ready framework that integrates well with other front-end technologies.
State management in React is a highly discussed topic with many libraries and solutions. Jotai is a new library based on atoms, which represent pieces of state. Atoms in Jotai are used to define state without holding values and can be used for global, semi-global, or local states. Jotai atoms are reusable definitions that are independent from React and can be used without React in an experimental library called Jotajsx.
Today's Talk discusses the importance of managing technical debt through refactoring practices, prioritization, and planning. Successful refactoring requires establishing guidelines, maintaining an inventory, and implementing a process. Celebrating success and ensuring resilience are key to building a strong refactoring culture. Visibility, support, and transparent communication are crucial for addressing technical debt effectively. The team's responsibilities, operating style, and availability should be transparent to product managers.
En esta masterclass, discutimos los méritos de la arquitectura sin servidor y cómo se puede aplicar al espacio de la IA. Exploraremos opciones para construir aplicaciones RAG sin servidor para un enfoque más lambda-esque a la IA. A continuación, nos pondremos manos a la obra y construiremos una aplicación CRUD de muestra que te permite almacenar información y consultarla utilizando un LLM con Workers AI, Vectorize, D1 y Cloudflare Workers.
En esta masterclass, construiremos un juego utilizando el motor WebGL de PlayCanvas desde el principio hasta el final. Desde el desarrollo hasta la publicación, cubriremos las características más cruciales como la escritura de scripts, la creación de UI y mucho más. Tabla de contenido:- Introducción- Introducción a PlayCanvas- Lo que vamos a construir- Agregando un modelo de personaje y animación- Haciendo que el personaje se mueva con scripts- 'Falsa' carrera- Agregando obstáculos- Detectando colisiones- Agregando un contador de puntuación- Fin del juego y reinicio- ¡Resumen!- Preguntas Nivel de la masterclassSe recomienda familiaridad con los motores de juegos y los aspectos del desarrollo de juegos, pero no es obligatorio.
El conocimiento de las herramientas de AI es fundamental para preparar el futuro de las carreras de los desarrolladores de React, y la suite de herramientas de AI de Vercel es una vía de acceso accesible. En este curso, examinaremos más de cerca el Vercel AI SDK y cómo esto puede ayudar a los desarrolladores de React a construir interfaces de transmisión con JavaScript y Next.js. También incorporaremos APIs de terceros adicionales para construir y desplegar una aplicación de visualización de música. Temas:- Creación de un Proyecto de React con Next.js- Elección de un LLM- Personalización de Interfaces de Transmisión- Construcción de Rutas- Creación y Generación de Componentes - Uso de Hooks (useChat, useCompletion, useActions, etc)
Construye Aplicaciones Modernas Utilizando GraphQL y Javascript
Featured Workshop
2 authors
Ven y aprende cómo puedes potenciar tus aplicaciones modernas y seguras utilizando GraphQL y Javascript. En este masterclass construiremos una API de GraphQL y demostraremos los beneficios del lenguaje de consulta para APIs y los casos de uso para los que es adecuado. Se requiere conocimiento básico de Javascript.
Aprovechando LLMs para Construir Experiencias de IA Intuitivas con JavaScript
Featured Workshop
2 authors
Hoy en día, todos los desarrolladores están utilizando LLMs en diferentes formas y variantes, desde ChatGPT hasta asistentes de código como GitHub CoPilot. Siguiendo esto, muchos productos han introducido capacidades de IA integradas, y en este masterclass haremos que los LLMs sean comprensibles para los desarrolladores web. Y nos adentraremos en la codificación de tu propia aplicación impulsada por IA. No se necesita experiencia previa en trabajar con LLMs o aprendizaje automático. En su lugar, utilizaremos tecnologías web como JavaScript, React que ya conoces y amas, al mismo tiempo que aprendemos sobre algunas nuevas bibliotecas como OpenAI, Transformers.js
Únete a Nathan en esta sesión práctica donde primero aprenderás a alto nivel qué son los modelos de lenguaje grandes (LLMs) y cómo funcionan. Luego sumérgete en un ejercicio de codificación interactivo donde implementarás la funcionalidad de LLM en una aplicación de ejemplo básica. Durante este ejercicio, adquirirás habilidades clave para trabajar con LLMs en tus propias aplicaciones, como la ingeniería de indicaciones y la exposición a la API de OpenAI. Después de esta sesión, tendrás una idea de qué son los LLMs y cómo se pueden utilizar prácticamente para mejorar tus propias aplicaciones. Tabla de contenidos:- Demostración interactiva de la implementación de funciones básicas impulsadas por LLM en una aplicación de demostración- Discutir cómo decidir dónde aprovechar los LLMs en un producto- Lecciones aprendidas sobre la integración con OpenAI / descripción general de la API de OpenAI- Mejores prácticas para la ingeniería de indicaciones- Desafíos comunes específicos de React (gestión de estado :D / buenas prácticas de UX)
Comments