Full text
Producción de un Videojuego de Acción Táctica con Personajes Controlados mediante Planificación Automática Production of a Tactical Action Video Game with Characters Controlled by Automated Planning Trabajo de Fin de Grado Curso 2021–2022 Autores Brais Santiago Morgade Valcárcel Daniel Gil Aguilar Director Prof. Dr. Federico Peinado Gil Grado en Desarrollo de Videojuegos Facultad de Informática Universidad Complutense de Madrid
Producción de un Videojuego de Acción Táctica con Personajes Controlados mediante Planificación Automática Production of a Tactical Action Video Game with Characters Controlled by Automated Planning Trabajo de Fin de Grado Departamento de Ingeniería del Software e Inteligencia Artificial Autor Brais Santiago Morgade Valcárcel Daniel Gil Aguilar Director Prof. Dr. Federico Peinado Gil Convocatoria: Septiembre 2022 Grado en Desarrollo de Videojuegos Facultad de Informática Universidad Complutense de Madrid 16 de septiembre de 2022
Agradecimientos Gracias a nuestras familias, amigos y a todos los participantes de los experimentos. Especialmente agradecidos de las contribuciones de Daniel Sánchez, Diego López, Miguel Beneyto-Guillamas, mi amigo Borja Bayón y mi hermano Adrián Morgade cuyas aportaciones han sido de un inmenso valor. v
Resumen Los videojuegos son un campo de aplicación que goza de un gran éxito económico y aceptación social. A la hora de producirlos, los estudios más pequeños y los desarrolladores independientes cuentan a día de hoy con herramientas potentes y bastantes asequibles como las que proporcionan plataformas como Unity o Unreal Engine. Estas herramientas suelen actualizarse con frecuencia y en general suelen incorporar muchas novedades interesantes, lo que se traduce en una mayor facilidad para crear nuevos y mejores videojuegos. Sin embargo, en algunas áreas como la Inteligencia Artificial, la existencia de herramientas estándar hace que muchos desarrolladores recurran siempre a los mismos conceptos y las mismas técnicas que ya llevan bien instaladas en la industria desde hace décadas. El objetivo de este proyecto es aplicar un producto de inteligencia artificial preexistente que actualmente permite desarrollar personajes no jugadores definiendo su comportamiento mediante un sistema de planificación automática sobre un proyecto real de producción de un videojuego. Esta herramienta, llamada GOAP NPC, nunca había sido utilizada anteriormente para desarrollar un juego, y en este trabajo es puesta a prueba en la producción de un corte vertical de videojuego para ordenador con un género y un estilo definidos: sigilo y acción táctica en formato 3D retro, típico de los años 90 y la primera Playstation. En este proceso el producto ha sido mejorado pensando en aquellos que van a trabajar con él, compartiendo una nueva versión de código libre y publicándola en el mercado más habitual para llegar a desarrolladores de Unreal Engine. Para probar tanto el resultado del videojuego creado, como indagar acerca de la eficacia percibida en esta nueva herramienta, se ha utilizado un experimento de prueba A/B con dos pequeños grupos de jugadores que arroja luz sobre las posibilidades de este cambio de paradigma en la inteligencia artificial de los videojuegos. Palabras clave Desarrollo de Videojuegos, Inteligencia Artificial, Herramienta de Desarrollo, Sigilo, Comportamiento Inteligente, Personaje No Jugador, Unreal Engine. vii
Abstract Video games are a field of application that enjoys great economic success and social acceptance. When it comes to producing them, smaller studios and independent developers nowadays have powerful and quite affordable tools such as those provided by platforms like Unity or Unreal Engine. These tools tend to be updated frequently and generally incorporate many interesting new features, which translates into greater ease in creating new and better video games. However, in some areas such as Artificial Intelligence, the existence of standard tools means that many developers always resort to the same concepts and techniques that have been well established in the industry for decades. The objective of this project is to apply a pre-existing artificial intelligence product that currently allows the development of non-player characters by defining their behavior through an automatic planning system on a real video game production project. This tool, called GOAP NPC, has never been used before to develop a game, and in this work it is tested in the production of a vertical cut of a computer game with a defined genre and style: stealth and tactical action in retro 3D format, typical of the 90’s and the first Playstation. In this process the product has been improved thinking about those who are going to work with it, sharing a new open source version and publishing it in the most common market to reach Unreal Engine developers. To test both the result of the video game created, and to inquire about the perceived effectiveness of this new tool, an A/B test experiment with two small groups of players has been used to shed light on the possibilities of this paradigm shift in artificial intelligence in video games. Keywords Video Game Development, Artificial Intelligence, Development Tool, Stealth, Character Behavior, Non-player Character, Unreal Engine. ix
5.12. Gestión del input de movimiento y cálculo de la velocidad del jugador .............................. 46 5.13. Usando un switch se implementa la funcionalidad de cada estado 47 5.14. Un pequeño vistazo a algunos de los estados . . . . . . . . . . 47 5.15. Funcionalidad del estado de voltereta . . . . . . . . . . . . . . 47 5.16. Un ejemplo de la función de generación de ruido para los disparos 48 5.17. Estructura de información de los objetos . . . . . . . . . . . . 48 5.18. Tabla de objetos. Cada fila representando un objeto tiene un ID, que se usará para identificar los objetos en el inventario . 49 5.19. Las variables de mundo, con un mundo deseado de patrullar atrue ............................... 55 5.20. Delegado del componente AIPerception, llamado cuando se actualiza la percepción. El NPC capta el sonido y llama a la función Noise Heard donde tomará decisiones en base al sonidopercibido ......................... 56 5.21. Se actualiza el investigate indicando que el NPC tiene intención de investigar y se pone como objetivo eliminar esa necesidad 56 5.22. Delegado del cono de visión que actualiza el valor de playerOnSight.............................. 56 5.23. Enemigo HellComms investigando tras estar expuesto suficiente tiempo al jugador. El círculo señala la barra blanca que indica la detección del enemigo. Cuando esta se llena por completo, el enemigo detecta al jugador . . . . . . . . . . . . 57 5.24. Ejemplo de las órdenes enviadas al cuerpo desde la cabeza . . 58 6.1. Respuestas a las preguntas 1 y 2 de la primera sección . . . . 71 6.2. Respuestas a las preguntas 3 y 4 de la primera sección . . . . 72 6.3. Respuestas a la preguntas 5 de la primera sección . . . . . . . 72 6.4. Respuestas a las preguntas 6 y 7 de la primera sección . . . . 73 6.5. Respuestas a las preguntas 1 y 2 de la segunda sección . . . . 74 6.6. Respuestas a las preguntas 3 y 4 de la segunda sección . . . . 75 6.7. Respuestas a las preguntas 5 y 6 de la segunda sección . . . . 76 6.8. Respuestas a las preguntas 1 y 2 de la tercera sección . . . . . 77 6.9. Respuestas a las preguntas 3 y 4 de la segunda sección . . . . 78
Índice de tablas xvii
Capítulo 1 Introducción Como estudiantes del Grado en Desarrollo de Videojuegos, consideramos lógico que como Trabajo de Fin de Grado realicemos un videojuego. Nos hemos querido centrar en Inteligencia Artificial, una de las facetas que lleva acompañando al sector durante mucho tiempo y así seguirá siendo. 1.1. Motivación La industria de los videojuegos lleva en constante crecimiento desde sus inicios. Cada año se convierte en la opción de ocio preferida para más gente. Al igual que cada vez hay más consumidores el coste de producción ha ido aumentando significativamente con el paso de los años. Son muy pocas las desarrolladoras que se pueden permitir motores y frameworks específicos para sus videojuegos. Esto provoca que el resto de empresas del sector se vean obligadas a pagar por motores y otras herramientas de terceros, ya que el ahorro económico es muy grande. Motores como Unreal Engine, Unity 3D o CryEngine entre otros, dan la posibilidad de desarrollar videojuegos con los principales sistemas como los de render, físicas o sonido ya programados e implementados. Gracias a ello se puede ahorrar mucho tiempo y dinero. Para resolver problemas específicos que los motores no cubren, ya que tienen un enfoque más generalista, multitud de empresas y usuarios desarrollan herramientas disponibles en la tienda de los motores. Por otro lado, la Inteligencia Artificial lleva décadas teniendo una importancia capital en el sector de los videojuegos. Los avances en IA en otros ámbitos suelen acabar viéndose reflejados en el mundo de los videojuegos de alguna forma. Del mismo modo a avances de IA en el mundo de los videojuegos se le acaba encontrando siempre alguna utilizad en otros sectores. Por tanto, es justo decir que el sector del desarrollo de videojuegos a tenido un importante papel en los avances en Inteligencia Artificial de las últimas décadas. 1
2Capítulo 1. Introducción Cuando los ordenadores y consolas no tenían suficiente potencia como para poder renderizar unos gráficos realistas, gran parte del peso de los videojuegos recaía en su jugabilidad. Tener una Inteligencia Artificial más interesante o más realista que los demás era un factor de peso a la hora de desarrollar los videojuegos. Destacan los juegos de sigilo. En este género es muy importante tener una buena IA, ya que el jugador debe ser capaz de reconocer patrones de los NPCs manteniendo cierta nivel de dificultad para pasarse el nivel. 1.2. Propósito Uniendo los conceptos anteriores, hay multitud de herramientas para motores de videojuegos que, de alguna forma, ayudan a la creación de NPCs. Para lograr de una experiencia más inmersiva normalmente se necesita que los NPCs no sean simplemente sprites o modelos que se ponen en la parte de atrás de la escena. Ahí es donde entra la Inteligencia Artificial. En nuestro caso hemos elegido GOAP NPC, una herramienta de Unreal Marketplace que ayuda a desarrollar IA para NPCs desde un enfoque muy interesante y novedoso: Goal-Oriented Action Planning. Para poder comprobar el uso práctico de esta herramienta, o de cualquier otra, es necesario realizar una demo o una prueba de concepto. Esto es importante ya que nunca sabes bien del todo qué tal va a funcionar hasta que lo pruebas. 1.3. Alcance Queremos partir de GOAP NPC, herramienta ya preexistente. Arreglaremos los problemas que tiene y realizaremos alguna mejora. Con esa nueva versión desarrollaremos un prototipo para probar su utilidad en la producción de un videojuego y ver de primera mano los inconvenientes que van surgiendo. El prototipo será un juego de sigilo con estilo retro similar a los juegos de PlayStation 1. No pretendemos convertir GOAP NPC en una herramienta sofisticada al nivel de las desarrolladas por empresas especializadas en este tipo de productos cuyo precio supera los 100 euros. Tampoco tenemos como objetivo desarrollar un videojuego completo listo para sacar al mercado. 1.4. Asignaturas relacionadas Principalmente haremos uso de los conocimientos adquiridos en la asignatura de Inteligencia Artificial para Videojuegos. Ahí aprendimos las bases
1.5. Estructura del trabajo 3 de la IA para videojuegos y las principales técnicas. También es importante lo aprendido en Motores de Videojuegos, dada su clara relación con el tema del TFG aunque no aprendiéramos a usar Unreal Engine en específico. Con menos peso pero que cabe mencionar, lo visto en asignaturas como Sonido en Videojuegos, Modelado en 3D y Técnicas de Animación en 3D ayudó a la hora de producir assets para el juego. Por último, son básicas todas las asignaturas en las que aprendimos a programar. Especial mención a Fundamentos de la Programación, ya que aprendimos la base y la lógica de la programación, y a Tecnologías de Programación en Videojuegos, donde aprendimos C++. 1.5. Estructura del trabajo El trabajo se divide en una serie de capítulos: Capítulo 1: Se presentan las ideas principales que motivan este trabajo, así como el propósito que tenemos a la hora de trabajar con GOAP NPC Capítulo 2: Se revisa el estado de la cuestión de los campos mas importantes que guardan relación con este proyecto, como por ejemplo distintas técnicas de Inteligencia Artificial que se usan en la actualidad. Capítulo 3: Se presentan los principales objetivos del proyecto y se especifican las formas concretas en las que se planea alcanzarlos. Capítulo 4: Se explican todas las herramientas utilizadas, así como el proceso de desarrollo software utilizado. Capítulo 5: Se explica con detalle el armazón software diseñado, su desarrollo e implementación como una extensión de un proyecto precedente, y los detalles de su funcionamiento interno. Capítulo 6: Se presentan los resultados obtenidos en el experimento con probadores de la demostración que utiliza el armazón propuesto. Capítulo 7: Finalmente se describen las conclusiones obtenidas de todo el trabajo y se esbozan algunas líneas de trabajo futuro.
Capítulo 2 Estado de la cuestión A lo largo de este capítulo analizaremos de dónde partimos en el Trabajo de Fin de Grado y la situación actual de la industria de los videojuegos y del área de la Inteligencia Artificial. 2.1. Producción de videojuegos La industria de los videojuegos está en constante crecimiento desde sus inicios. Este crecimiento ha hecho que en los últimos años se convierta en la principal industria en el sector del entretenimiento como se puede ver en 2.1. Figura 2.1: Ingresos del sector del videojuego comparado con el cine y la música 5
6Capítulo 2. Estado de la cuestión Al igual que los ingresos, los costes de producción no han dejado de ascender. En los inicios de la industria las desarrolladoras eran capaces de cubrir las pérdidas de varios videojuegos que fracasaron en ventas con las ganancias de un videojuego que fuera un éxito. En la actualidad hay videojuegos con un coste de producción de decenas de millones de euros, como se puede ver en 2.2. Esto hace que un fracaso en ventas de un juego así puede suponer la bancarrota de una gran empresa. Los estudios más pequeños y desarrolladores independientes, para reducir los costes de producción y poder ajustarse a un presupuesto más limitado cuentan con herramientas potentes y bastantes asequibles como las que proporcionan plataformas como Unity o Unreal Engine. Estas herramientas suelen actualizarse con frecuencia y en general suelen incorporar muchas novedades interesantes, lo se traduce en una mayor facilidad para crear nuevos y mejores videojuegos. Figura 2.2: Coste de producción de algunos de los videojuegos con mayor coste en millones de dólares El entorno de desarrollo escogido para la producción de videojuego en este trabajo es Unreal Engine. Se trata de un entorno de desarrollo creado por Epic Games que actualmente incorpora uno de los motores más punteros para la visualización realista, la vegetación y la creación de terrenos. Unreal tiene un sistema Blueprint para programar de una forma muy visual sin necesidad de conocer c++ ni ningún otro lenguaje de programación. Los blueprints se ven en forma de grafos formados por bloques interconectados. Estos bloques y conexiones representan la lógica del juego reemplazando a lo que sería el código. Unreal ha sido desarrollado en C++, lo que ofrece a
2.2. Inteligencia artificial en videojuegos 7 los desarrolladores un gran control sobre el motor tanto durante la creación de videojuegos como a la hora de programar herramientas y librerías para Unreal. La principal competencia de Unreal es Unity. Está más enfocado a gente principiante ya que utiliza C# que es más sencillo de aprender que C++. Por otro lado tiene una menor potencia gráfica y suele ser menos eficiente en grandes proyectos. 2.2. Inteligencia artificial en videojuegos Uno de los pilares en el mundo de los videojuegos es la IA para personajes no jugadores (PNJ o NPC por sus siglas en inglés). Existe una tendencia constante a hacer agentes inteligentes cada vez más realistas y complejos. Un agente inteligente es cualquier cosa que puede percibir su entorno a través de sensores y actuar sobre él mediante actuadores (Guerrero, 2010). Para conseguir dotar de inteligencia a estos agentes se han investigado y desarrollado multitud de técnicas. Una de las más populares son los árboles de comportamiento (o BT por sus siglas en inglés). Se caracterizan por ser modulares, flexibles y reutilizables. El objetivo es que los PNJ tengan un comportamiento reactivo, es decir, que reaccione a eventos externos. Se representan en forma de árbol de nodos. Los nodos extremo representan acciones que el PNJ puede hacer, mientras que los nodos intermedios deciden qué nodo es el siguiente a seguir. Figura 2.3: Ejemplo de árbol de comportamiento Otra técnica muy popular son las máquinas de estado finitas (o FSM por sus siglas en inglés).Es una abstracción que permite codificar un diagrama
Capítulo 3 Objetivos y especificación En esta sección definiremos los objetivos principales de este trabajo. Como uno de los objetivos más importantes, también hablaremos en profundidad del diseño inicial del juego que luego contrastaremos con la versión final del prototipo en el Capítulo 5: Contribución. 3.1. Objetivos Analizando este proyecto como un trabajo definitivo de la carrera de desarrollo de videojuegos, aunando todas las distintas facetas y competencias que se aprenden durante los cuatro cursos, solo es natural pensar que su fruto sea un videojuego, desarrollado desde cero y poniendo en práctica todo lo aprendido. GOAP NPC fue exitoso, pero si queríamos mejorar una herramienta cuyo propósito es ayudar a la creación de agentes inteligentes en futuros videojuegos qué mejor manera que ser nosotros mismos quienes se embarcan a desarrollar un videojuego haciendo uso de GOAP NPC para ver realmente lo que funciona y lo que no, ver que cosas se pueden añadir y mejorar mientras en el proceso analizamos como de viable y útil es puesto en práctica. Así que el objetivo estaba definido, realizar un videojuego con GOAP NPC que sirva tanto de ejemplo de un videojuego real hecho gracias a esta herramienta como de campo de pruebas sobre su utilidad y robustez en un ambiente práctico, con el objetivo de sacar conclusiones sobre añadidos que pueden hacerla aún mejor. Más concretamente presentamos 3 objetivos principales: Revisar y actualizar GOAP NPC para la nueva versión de Unreal. Desde su lanzamiento original, GOAP NPC sufrió un cierto abandono. Numerosos comentarios de usuarios en la marketplace pedían una actualización para usar en la última versión de Unreal Engine 4 (4.27). Es por esto que el primer objetivo propuesto fue actualizar el 15
16 Capítulo 3. Objetivos y especificación plugin a la nueva versión, junto con ciertos cambios de nomenclatura internos para evitar errores. Desarrollar un prototipo de videojuego donde se use GOAP NPC. Con el siguiente objetivo surgió la pregunta de cuál sería el mejor juego para ilustrar lo que queríamos conseguir. La IA en videojuegos se diferencia en que usualmente no quieren comportarse de manera perfecta, su propósito es dar vida a los personajes de su mundo. Se vuelve más importante que sepan transmitir lo que quieren hacer o como se sienten, no sólo para darles carácter pero también para que el jugador sepa leer sus intenciones y poder jugar con su comportamiento. Esto nos orientó hacia los juegos de sigilo, ya que la principal característica de este tipo de videojuegos es que el jugador está constantemente poniendo su atención sobre los NPCs y aprendiendo cómo se comportan. Realizar pruebas del juego y reunir feedback de desarrolladores y jugadores. Como último paso, cerramos una pequeña demostración de concepto del videojuego para que prueben desarrolladores y jugadores, reuniendo su feedback a través de un cuestionario con el que demostraremos si el juego ha sido efectivo en cuanto a ejemplificar el valor de GOAP NPC y ver si hay un mayor interés tras descubrir que ha sido desarrollado usando este plugin. Además reuniremos feedback sobre el juego y su estilo de cara a una futura versión completa. 3.2. Especificaciones Desde el principio se tenía claro que el género del juego iba a ser infiltración, pero la especificación de las mecánicas e IA fue cambiando sustancialmente a lo largo de varias presentaciones. Gracias al feedback de nuestro director, finalmente se consiguió encontrar un punto diferenciador interesante. A estas alturas ya se había concebido la estética del juego. Como homenaje a Metal Gear Solid, fuente de inspiración de gran cantidad de juegos de sigilo, y una cierta curiosidad sobre el estilo de los juegos de su era, decidimos tratar de imitar el apartado gráfico y efectos de los videojuegos 3D de la PlayStation original. En cuanto al punto diferenciador del juego, los enemigos que el jugador encontrará a lo largo de su camino serían no muertos, soldados traídos directamente del infierno que tendrán una segunda oportunidad para dominar el mundo, pero esta vez con nuevas capacidades. Estas nuevas habilidades traerían novedades en cuanto a como el jugador debe lidiar con sus enemigos si no quiere ser visto y como estos pueden arrinconar o atacar al intruso.
3.2. Especificaciones 17 Con estas ideas claras, se escribió un documento1 de diseño de juego (Game Design Document o GDD, en inglés) donde se especifican todos los apartados del diseño del juego que se comenzaría a desarrollar. Nótese que debido a la naturaleza del documento de diseño (un documento que se escribe previo al desarrollo) ciertos aspectos que se describen en el GDD pueden no coincidir con la versión desarrollada ya que esta es un prototipo, una pequeña parte del juego donde no todos los conceptos que se tratan en el documento se ven reflejados. Eventualmente, el juego adquirió el nombre ”Salamander´s Nightmare”. 3.2.1. Concepto Salamander´s Nightmare es un juego de sigilo con perspectiva principalmente top down, es decir que la cámara sigue al personaje desde las alturas enfocando directamente hacia abajo. Nos decidimos por este tipo de cámara en parte por la influencia de Metal Gear Solid que a menudo usa esta perspectiva pero también porque una cámara que siempre tenga la misma perspectiva y ofrezca una buena imagen de los alrededores del jugador nos parecía una buena combinación con las dinámicas del sigilo. En el juego Little Salamander se infiltra en el corazón de una base militar plagada de soldados no muertos. El objetivo es eliminar a los cabecillas de la base que aparecerán en cada nivel. Estos son los puntos más importantes sobre las ideas y el concepto del juego: Estética PS1. El juego imita el apartado gráfico de la PS1, con shaders, efectos, texturas de baja resolución y modelados de bajo poligonado. Dividido en niveles En cada nivel el objetivo es eliminar al jefe, un NPC especial rodeado de mucha seguridad. Distintos tipos de enemigos. Cada tipo de enemigo nuevo tiene una serie de habilidades y debilidades únicas que producen comportamientos variados. Muchos de los enemigos son inmortales. Con lo que se vuelve vital sabotear el entorno y las facilidades de la base para poder acabar con ellos. Los enemigos se comunican con el jefe. Al exponerse a actividad sospechosa o detectar al jugador los enemigos hablan con el jefe, que es otro NPC real que está en el nivel, capaz de recordar reportes de sus aliados y tomar decisiones para incrementar la seguridad. 1https://docs.google.com/document/d/1y1Yw-iqUNYMpZ3rKauYV4d9yC_iTBmKuo9Mz06z9Xc0/edit?usp=sharing
18 Capítulo 3. Objetivos y especificación 3.2.2. Influencias Dos franquicias fueron las principales influencias en la creación de este juego. Por un lado tenemos a Metal Gear Solid con su estética y mecánicas en el funcionamiento básico del jugador y enemigos. Por el otro lado están Hitman y sus misiones centradas en eliminar a un objetivo valioso que deambula por el nivel con mucha seguridad tras de sí. 3.2.2.1. Metal Gear Solid Metal Gear Solid es un juego de acción-aventura y sigilo desarrollado por Konami en 1998. Es a menudo descrito como uno de los juegos más importantes de la historia por ser uno de los primeros juegos en utilizar el lenguaje del cine en sus numerosas cinemáticas donde los personajes ya actuaban con su limitada animación. Pero también fue de los títulos con mayor influencia en la popularización del género de sigilo. El jugador comienza desarmado en medio de una base militar tomada por un grupo terrorista. A lo largo del juego se adquieren diversos objetos como armas y llaves para abrir paso a zonas de la base nuevas. Para avanzar sin ser visto Snake puede agacharse y moverse reptando para hacer menos ruido o incluso pasar por debajo de ciertas partes del escenario. En cuanto a estructura comparte menos con sus secuelas ya que tiene un cierto punto de metroidvania. En ciertas ocasiones se recorren de vuelta las mismas zonas de la base para esta vez abrir una puerta de la que antes no se tenía la llave. Los enemigos de Metal Gear Solid actúan todos de manera similar. Patrullan por una zona hasta que ven o escuchan algún ruido generado por el jugador (puede ser un paso o un disparo por ejemplo) entonces investigan la zona, si no ven nada vuelven a la patrulla. Si detectan finalmente al jugador la base entra en alerta y todos los enemigos se disponen a atacar a Snake, incluso pueden llegar refuerzos para apoyar a los guardias de la zona. Las piezas que más influyen en nuestro juego son: Gráficos y estética. Uno de nuestros objetivos haciendo el juego es imitar el estilo gráfico de PS1, esto incluye realizar modelos con muy pocos polígonos y texturas de no más de 256x256 píxeles. La estética del juego recuerda a Metal Gear Solid en particular por la temática: base militar, sigilo, semi-futurista. Objetos e inventario. El juego comienza con el jugador desprovisto de objetos. Estos los encontrará por el juego y podrá usarlos en niveles posteriores. Cámara. Aunque en Metal Gear Solid el ángulo de cámara varía frecuentemente dependiendo de la sala y la zona por donde nos movamos, en muchas ocasiones la cámara se coloca encima del personaje de una
3.2. Especificaciones 19 Figura 3.1: Metal Gear Solid (PlayStation, 1998) Figura 3.2: La principal perspectiva que usaremos en nuestro juego manera similar a como lo hará en nuestro juego. También, al igual que en Metal Gear Solid, podremos cambiar la vista a primera persona. A parte, mecánicas como poder agacharse para hacer menos ruido o el funcionamiento básico de los enemigos también se ven reflejadas en nuestro juego, pero se tratan de características que ya no son propias de Metal Gear si no que es algo que se puede encontrar en casi cualquier juego con tintes de sigilo. 3.2.2.2. Hitman Hitman es una saga de sigilo con su primer juego lanzado en el 2000. En esta saga el agente 47, un asesino a sueldo, es encargado de asesinar a obje-
20 Capítulo 3. Objetivos y especificación tivos concretos en cada nivel del juego. Lo que lo diferencia de otros juegos de sigilo es su acercamiento a este y la infiltración, además de la manera organizada en la que se mueven las distintas piezas de los niveles, compuestos por distintos NPCs con funciones distintas y una cierta jerarquía y en lo alto de todo, el objetivo que debes eliminar. El agente 47 utiliza el sigilo a plena vista, usando disfraces para hacerse pasar por distintos NPCs que tienen ciertos privilegios y acceso a zonas del nivel de mayor seguridad. Es mediante esta táctica que el jugador debe ir acercándose cada vez más a su presa, estudiar su comportamiento y tender una trampa para cumplir el encargo idealmente haciendo parecer que la muerte ha sido consecuencia de un accidente. Los niveles son muy grandes y llenos de posibilidades, rutas alternativas y objetos interactuables. Cada objetivo de cada nivel tiene un patrón distinto. Puede pasar cierto tiempo en un sitio rodeado de sus guardias, en determinado momento decidir salir y pasar por otra zona del nivel o en respuesta a algún acontecimiento causado por el jugador. Es la prioridad del jugador entonces observar los movimientos de su objetivo para saber de antemano como va a reaccionar y eliminarlo exitosamente. Figura 3.3: Agente 47 disfrazado como chófer en Hitman: Codename 47, 2000 Lo que influye más sobre nuestro juego es el funcionamiento de los niveles. En cada nivel Little Salamander deberá eliminar a un objetivo, un cabecilla del ejército de no-muertos que tendrá unas rutas y patrones específicos. Con la suficiente información, el jugador podrá explotar una brecha de seguridad en los movimientos de su enemigo para eliminarlo y poder avanzar al siguiente nivel.
3.2. Especificaciones 21 3.2.3. Estética y estilo PS1 En Salamander´s Nightmare nos adentramos en una base militar, de aquí la influencia clara de Metal Gear Solid en la estética, pero también nos enfrentamos a soldados no-muertos y experimentos que tienen que ver con invocaciones y portales al infierno. Nunca nos planteamos el tono del juego como algo serio. Siguiendo la estética retro de PS1 nos parecía natural que el juego tuviese un punto algo tonto y siguiendo los concepts originales que la estética pudiese recordar un poco a cómic. Durante el desarrollo contamos con ayuda de dos artistas: Diego López y Daniel Sánchez (información sobre sus contribuciones en el capítulo Contribución). Para dirigir el estilo del juego en una misma dirección creamos un documento2donde se detallan objetivos y referencias para el diseño de personajes. 3.2.4. Historia y worldbuilding Mundo alternativo, en una especie de años 30, ocurrió el alzamiento del Imperio Erináceo, surgido del país Erinacea, que arrasasaba con toda etnia y cultura distinta, proclamando la pureza de la raza y el alzamiento de aquellos individuos considerados como los más preparados o más talentosos por encima de todos los demás, que estarían destinados al trabajo pesado. Su éxito en combate se debía en parte a que poseían tecnología bastante avanzada, pero también se contaba a menudo que los soldados peleaban con una fuerza casi inhumana. Ante el avance del imperio, numerosos países se aliaron y combatieron en una cruenta guerra en la que finalmente el imperio cayó derrotado. Con el fin del imperio, los diferentes estados se volvieron a separar, desarrollándose de manera independiente. Con el paso del tiempo y debido a roces de intereses y conflictos ideológicos entre ellos poco a poco se fue formando un miedo a posibles futuros conflictos de mayor magnitud incentivando un fuerte desarrollo militar. La historia se desarrolla en New Caudata en una época actual, concretamente en la base-laboratorio militar New Caudata Underground Labs, donde se está investigando y desarrollando nueva tecnología y armas de manera secreta frente al resto del mundo, y que de la misma manera, contiene cabezas nucleares y otras potentes armas. El jefe a cargo de la base, Gordon Chocus, propone estudiar los avances e investigaciones realizadas por el Imperio Erináceo a espaldas de sus superiores, ya que ellos no lo permitirían. Descubren que el antiguo imperio realizó una extensa investigación sobre la comunicación con el infierno. Chocus da la orden de continuar esa investigación, para la sorpresa de sus inferiores, que lo veían como una investigación estúpida e imposible. Sin embargo, éste consigue convencer a sus compañeros y proceden. Tiempo más tarde llegan a una revelación: realmente es posible lo que 2https://docs.google.com/document/d/1uKiulxuTr2toNsuMMoF9amhCnD09nQMjygpt3mqWHD4/edit?usp=sharing
22 Capítulo 3. Objetivos y especificación Figura 3.4: Primer boceto de los enemigos del juego Figura 3.5: El primer jefe del juego Figura 3.6: Boceto de la protagonista: Little Salamander investigaba el antiguo imperio, y probablemente tuviese que ver con su éxito. Asustados por el descubrimiento que acababan de hacer, gran parte del personal de la base exigió al jefe que se notificase al resto de la armada del descubrimiento y que se cesase la investigación. Ante cada vez más exigencias del personal, Gordon Chocus decide tomar las armas y reprimir a todos los que estaban en su contra. Ya librados de posibles detractores, continuaron
3.2. Especificaciones 23 con su plan. Fracasaron numerosas veces, intentando replicar lo que hicieron. Aun así, descubrieron un patrón, según utilizaban métodos más parecidos a los antiguos, más se acercaban a su objetivo. Así acabaron desarrollando una tecnología de aspecto antiguo pero a la vez moderna. Una mezcla con la que consiguieron crear un puente entre este mundo y las almas atrapadas en el infierno. Gordon ( un admirador del antiguo ejército que idealizaba los valores del imperio ) y su personal, que lo seguían ciegamente convencidos por su palabrería y las consecuencias de ir en su contra, idearon un plan para traer de vuelta el imperio, sacando las almas del ejército que ahora yacían en el infierno y devolviéndolas a sus cuerpos. Así, renombraron el laboratorio y el equipo a su cargo como Hell Communications. El jefe sabía que era cuestión de tiempo que el estado descubriese lo que estaba pasando en esa base y tomase medidas, así que se adelantó amenazando con hacer pública la existencia de cabezas nucleares en esa base ante el mundo, lo que pondría a los demás en su contra y probablemente daría lugar a una guerra debido a todas las tensiones que se habían acumulado entre los distintos estados, e incluso llegar a usarlas si el estado decidía intervenir. Es por esto que el estado envía secretamente a Little Salamander, veterana en operaciones encubiertas, a descubrir lo que está sucediendo y detener el plan que se está llevando a cabo en el laboratorio, con ayuda de su nuevo compañero Funky Axolotl, que se comunicará por radio con ella durante la misión. Durante el juego, Little Salamander se enfrentará a los miembros de Hell Communications y a los soldados resurgidos del Imperio, derrotando a los altos mandos del ejército Erináceo, que se presentarán como no muertos dotados de la capacidad de resucitar una y otra vez. A medida que se adentra en la base se encuentra con más fuerzas sobrenaturales: soldados esqueleto capaces de separar sus miembros, no muertos prácticamente inmortales equipados con armadura y armas avanzadas y fantasmas capaces de poseer cadáveres. El entorno también irá cambiando, desde el de una base tecnológica moderna a una cada vez más antigua pero a la vez imbuida en un aura maligna que dota de energía a una maquinaria progresivamente más misteriosa. 3.2.5. Estructura del juego La estructura del juego lo divide en niveles. Antes de cada nivel, elegimos los objetos con los que comenzamos la misión. Cada nivel cuenta con un objetivo a eliminar. Este objetivo es el jefe del lugar, el NPC que está al otro lado cuando un guardia reporta algo por radio. Siendo un juego de sigilo, deberemos infiltrarnos en la base y avanzar hasta encontrar dónde se esconde el jefe. En el camino haremos uso de objetos y armas para derribar enemigos, distraerlos e incluso abrir puertas a zonas antes inaccesibles. El conocimiento del nivel será de gran ayuda, ya que para eliminar a nuestro objetivo de manera permanente debemos sabotear una máquina localizada en algún punto del nivel, el comunicador infernal. Este saboteo es sólo tempo-
30 Capítulo 3. Objetivos y especificación guir tramamos un plan. Podemos destruir el comunicador, dándonos mucho más tiempo para eliminar al objetivo antes de que lo reparen, distraer a los guardias de la puerta justo antes de que el objetivo vuelva a abandonar su escondite y alinear un disparo a la cabeza cuanto esté abandonando la sala. Llevamos a cabo el plan, eliminamos al objetivo y terminamos el nivel. Tras el fin del nivel, una pantalla de puntuación analiza qué tal lo hemos hecho. Nada mal pero se podría hacer mejor, se puede pasar totalmente inadvertido, se puede eliminar al objetivo mucho más rápido, hay más rutas y objetos que no hemos encontrado y un mayor desafío si lo intentamos en un nivel de dificultad mayor. Nuestro rendimiento nos recompensa con nuevos objetos para equipar en la siguiente misión además del acceso a esta.
Capítulo 4 Metodologia y herramientas En este capítulo analizaremos cómo nos hemos organizado el trabajo y qué herramientas hemos utilizado para ello. 4.1. Organización del trabajo Al comienzo del del TFG decidimos que lo más conveniente en nuestro caso era realizar una metodología de trabajo similar a Scrum. Scrum es un conjunto de técnicas para desarrollo ágil de software. En nuestro caso acordamos reuniones cada 2 semanas. En estas reuniones Federico Peinado actuaba de Scrum Master. Una reunión típica consistía en ver qué habíamos hecho en esas dos semanas y proponernos objetivos para la siguiente reunión. 4.2. Planificación y Seguimiento A la hora de organizarnos el trabajo decidimos que Brais sería el encargado de desarrollar el juego en Unreal liderando a los colaboradores que nos han ayudado a sacar el juego adelante. Mientras que Daniel se encargaría de arreglar y mejorar GOAP NPC además de realizar las investigaciones y configuraciones necesarias para el uso de otras herramientas. Hemos tenido la suerte de poder contar con la colaboración de varias personas en el proyecto. Diego López Martín y Daniel Sánchez Cuenca han sido nuestros artistas y se han encargado del arte del juego. También hemos contado con la colaboración de Miguel Beneyto-Guillamas en el apartado de sonido del juego. Gracias a su ayuda nos hemos podido centrar en el desarrollo del juego y de la herramienta, ahorrando bastante tiempo en aspecto no tan centrales en nuestro grado. A lo largo del año teníamos reuniones de seguimiento cada dos semanas 31
32 Capítulo 4. Metodologia y herramientas para comprobar el estado del proyecto y asignar tareas para la siguiente reunión. Estas reuniones forman parte de la metodología de trabajo previamente explicada. 4.3. Herramientas utilizadas A lo largo del proyecto hemos utilizado multitud de herramientas. Las principales han sido Unreal Engine y Goap NPC, de las que ya hemos hablado anteriormente. En esta sección hablaremos de otras herramientas que hemos utilizado. Perforce. Perforce es un desarrollador estadounidense de software utilizado para desarrollar y ejecutar aplicaciones. Destaca su software de control de versiones con el mismo nombre. Tras muchas pruebas e investigaciones decidimos utilizar Perforce como repositorio por encima de GitHub. Esta decisión se debió a que, incluso utilizando la extensión para archivos de gran tamaño, GitHub no nos permitía tener un repositorio con archivos tan pesados como necesitábamos. Tras ver que GitHub no se adaptaba a nuestras necesidades buscamos otras opciones. Fue ahí cuando decidimos apostar por Perforce como software de control de versiones. Slack. Slack es una aplicación de mensajería creada para la gestión de proyectos y grupos de trabajo. Está enfocada principalmente al mundo empresarial. Hemos usado esta aplicación como método principal de comunicación y organización entre todos los que hemos participado en el Trabajo de Fin de Grado. Google Meet. Google Meet es un servicio de videotelefonía desarrollado por Google. Ha sido la aplicación elegida para realizar las reuniones que teníamos programadas cada dos semanas para comprobar el estado del proyecto. Discord. Discord es un servicio de mensajería instantánea, chat de voz y videollamadas. Hemos utilizado Discord para realizar reuniones en las que resolvíamos problemas o dudas que surgían en el día a día. FMOD Studio. FMOD es un motor de efectos de sonido . Es capaz de reproducir y mezclar sonidos de diversos formatos en muchos sistemas operativos. Hemos usado FMOD Studio para los sonidos y música del juego. Todo ello ha sido añadido al juego mediante su extesión en Unreal Engine. Visual Studio. Microsoft Visual Studio es un entorno de desarrollo integrado para Windows y macOS. Es compatible con múltiples lenguajes de programación, tales como C++, C# o Visual Basic. Como
4.3. Herramientas utilizadas 33 GOAP NPC es una herramienta programada en C++ elegimos Visual Studio como IDE a la hora de tocar el código fuente de GOAP NPC. Mixamo. Mixamo vende servicios basados en web para la animación de personajes en 3D. Mixamo ha sido la fuente de la base de muchas animaciones que se utilizan en el juego. Una vez obteniamos las animaciones de Mixamo las modificábamos y adaptábamos a nuestro juego. Retroshader. Desde el principio tuvimos claro que queríamos una estética similar a la de PS1. Utilizamos Retroshader para recrear esta estética. Audacity. Audacity es una aplicación informática multiplataforma libre que se puede usar para grabación y edición de audio. Es el editor de audio y sonido más difundido en las distribuciones Linux. Hemos utilizado Audacity para poder editar las pistas de audio que más tarde formarían parte del juego. Photoshop. Adobe Photoshop es un editor de fotografías usado principalmente para el retoque de fotografías y gráficos. Las texturas que hay en el juego fueron creadas en PhotoShop. Blender. Blender es un programa informático multiplataforma, dedicado especialmente al modelado, iluminación, renderizado, la animación y creación de gráficos tridimensionales. También de composición digital utilizando la técnica procesal de nodos, edición de vídeo, escultura y pintura digital. Utilizamos Blender para el modelado 3D de todos los elementos del juego. Además lo hemos usado para crear las animaciones.
Capítulo 5 Contribución Durante este capítulo hablaremos del desarrollo del juego en profundidad, así como los cambios hechos a GOAP NPC. Comenzaremos comentando desde donde partimos, el estado inicial de GOAP NPC y seguiremos con un análisis de algunas de las características del hardware de PS1 clave para entender su particular estética que intentaremos imitar. 5.1. Investigación y análisis 5.1.1. Análisis de la situación del proyecto El proyecto de nuestro videojuego se creó de cero para este trabajo, a parte de usar GOAP NPC como base para la IA, inspirándonos en el proyecto demo que dejó GOAP NPC a disposición de todo el mundo. En este proyecto se demuestra algunas de las capacidades de GOAP en una escena de prueba con dos personajes. Uno de los dos es controlado por el jugador, mientras el otro lo controla una IA que utiliza GOAP NPC. En la escena hay varios elementos: un par de llaves, una puerta y una moneda. El jugador puede alternar el objetivo del NPC entre seguir al jugador y obtener la moneda. La moneda se encuentra detrás de la puerta cerrada, con lo que el NPC debe trazar un plan para llegar hasta ella, el cual cambia dependiendo de la situación del mundo. Normalmente, el NPC irá a por una llave para abrir la puerta, la abrirá y recogerá la moneda. El jugador puede recoger las llaves. Si el NPC se queda sin llaves decidirá romper a la fuerza la puerta. Cómo funciona esto: El NPC tiene asignadas una serie de posibles acciones: Seguir al jugador, Coger llave, Abrir puerta, Romper puerta, Obtener Moneda y Esperar. Al pulsar Z o X se cambia el objetivo del NPC, que es satisfacer una de los estados del mundo. 35
36 Capítulo 5. Contribución Figura 5.1: Variables de mundo y Acciones del controller Figura 5.2: Asignación de objetivos al pulsar cada botón Al tener el objetivo asignado, el NPC busca la acción de menor coste que pueda satisfacer su objetivo, analizando los prerrequisitos y bus-
5.1. Investigación y análisis 37 cando acciones que cumplan los prerrequisitos, trazando así el plan. Si el plan no se puede ejecutar, elige la siguiente acción de menor coste que pueda satisfacer sus requisitos. Con el plan asignado, lo va ejecutando mientras se asegura de que el plan sigue siendo válido. Figura 5.3: Acción de romper puerta, con un coste de 5000 Figura 5.4: Acción de abrir puerta, con un coste de 2 La acción abrir puerta tiene menor coste que romper puerta, sin embargo, para abrir la puerta necesita una llave. Por tanto en el caso de que no puede
38 Capítulo 5. Contribución recoger una llave, elimina abrir puerta como posible acción para el plan. Su otra alternativa es la acción de coste mucho mayor pero sin requisitos: romper puerta. Esta demo da una buena idea inicial de cómo funciona no sólo GOAP NPC si no la técnica GOAP en general. No obstante, la simplicidad del ejemplo deja muchos asuntos sin resolver que van dando cara cuando uno se enfrenta al desarrollo de un videojuego completo. Cosas como la intención de crear un Go To genérico, maneras de priorizar objetivos o cómo resolver acciones temporizadas fueron algunos de los asuntos con los que tuvimos que lidiar durante el desarrollo e intentar buscar soluciones alternativas. 5.1.2. Sobre las limitaciones y la estética retro Los videojuegos de la PlayStation original, una de las primeras consolas en soportar juegos completamente en tres dimensiones, tienen unos gráficos muy reconocibles. Esto se debe a varias razones que tienen que ver con cómo la consola renderizaba los polígonos y sus limitaciones técnicas. Aspectos como la falta de z-buffer, mipmaps o la falta de soporte de números en coma flotante derivaron en el aspecto tan carácteristico que seguimos reconociendo hoy en día. En esta sección hablaremos de que significan estos términos y qué aspectos de la PlayStation 1 conseguimos replicar. Ausencia de MipMaps. Los Mip Maps son secuencias de texturas, cada una de la mitad de resolución que la anterior, que se utilizan para incrementar la velocidad de renderizado y reducir el aliasing. Las versiones de mayor resolución se utilizan cuando la cámara está cerca de la textura y se va cambiando a las versiones de menor resolución conforme la cámara se aleja. Esto previene tener que calcular la posición de cada pixel de textura que correspondería con cada pixel de pantalla. La ausencia de mip-mapping en PlayStation por un lado hace que las texturas aparezcan más limpias que en consolas de su época como N64 que sí utilizaba mip-maps, pero a menudo genera más artefactos de aliasing y una imagen más pixelada. Falta de z-buffer El z-buffer se encarga de gestionar las coordenadas de profundidad de imágenes en un escenario en 3D. Básicamente es lo que decide qué triángulos se muestran ya que los que están cubiertos por otros se optan por no renderizar, optimizando recursos. Esto no significa que en los juegos no se usase esta técnica, si no que el uso de z-buffer quedaba en manos de los desarrolladores, que tendrían que programar ellos mismos qué triángulos se renderizarían y cuales no. El problema viene con las texturas, que al no recibir información de la coordenada de profundidad, estas se pintaban con una perspectiva incorrecta. A este efecto se le llama texture Warping.
5.1. Investigación y análisis 39 Figura 5.5: Los mip-maps son secuencias de texturas precomputadas de cada vez menor resolución Figura 5.6: El mip-mapping causa texturas más borrosas en N64 pero previene el aliasing que se ve en la PlayStation Falta de números decimales. Los números con los que trabajaba el hardware de PlayStation eran enteros, los gráficos no se podían colocar en posiciones sub-píxel, dando lugar a ”snaps” de los vértices a la siguiente posición entera cuando se animaba un modelo o se movía la cámara. A este efecto se le llama vertex snapping. Dithering. El dithering o tramado es una técnica usada para crear ilusión de profundidad de color cuando se tiene una paleta limitada. Los colores no disponibles se aproximan realizando entramado de los colores más cercanos, haciendo que el ojo humano perciba la fusión de ambos colores. PlayStation utilizaba en la práctica una profundidad de color de 15 bits, con lo que el uso de tramado se veía en casi cualquier juego.
46 Capítulo 5. Contribución Figura 5.12: Gestión del input de movimiento y cálculo de la velocidad del jugador 5.2.2.2. Máquina de estados del jugador En el juego existen dos máquinas de estados: la del jugador y la de los enemigos. La implementación de esta difiere considerablemente pues la máquina de estados del jugador fue la primera en implementarse. Debido a nuestra falta de experiencia en Unreal y nuestro aprendizaje según avanzamos en el desarrollo, cuando llegó el momento de implementar la de los enemigos supimos hacerlo de una manera distinta y más limpia a nuestro parecer. La máquina de estados del jugador utiliza el enum PlayerStateMachine. En la clase del jugador se guarda una variable con el estado actual del jugador. Hay dos funciones vitales para la máquina de estados: el EventTick y ChangeState. EventTick, el evento que se llama cada frame del juego, a su vez llama a StatesTick, un evento que gestiona el tick dependiendo de en que estado esté el jugador. A su vez, ChangeState se encarga del cambio de un estado a otro: llamando a StateExit, cambiando el valor de la variable de estado actual y posteriormente llama a StateEnter. Este sistema permite alterar el comportamiento del jugador y las acciones posibles dependiendo de su estado, además de facilitar más adelante el cambio entre animaciones. Vemos que es mediantes este sistema que se implementa la voltereta, usando un estado que solo dura activo hasta que termina la animación.
5.2. Diseño e implementación 47 Figura 5.13: Usando un switch se implementa la funcionalidad de cada estado Figura 5.14: Un pequeño vistazo a algunos de los estados Figura 5.15: Funcionalidad del estado de voltereta 5.2.2.3. Generación de ruido Uno de las mecánicas del sigilo del juego involucra el sonido que el jugador genera al realizar ciertas acciones. Para esto creamos una pequeña librería
48 Capítulo 5. Contribución de generación de ruido, que se encargase de a la vez reproducir el sonido correspondiente y reportar el evento de ruido que podría capturar la IA. Figura 5.16: Un ejemplo de la función de generación de ruido para los disparos Luego, a esta función se le llamaría desde AnimNotifies de las animaciones de movimiento, la función de disparo de la pistola y otras acciones que generan ruido. 5.2.2.4. Sistema de Inventario y uso de objetos La implementación de este sistema tiene varias clases y componentes funcionando. Definición de Items. Primero, se necesita una manera de definir los objetos que se van a recoger y usar. Cada objeto se vería primero en el escenario, con lo que tendría que tener asignado un actor de objeto recogible (PickUpItem). Luego, una vez en el inventario, tendría una funcionalidad (necesitaría una clase componente: ItemFunctionalityComponent). Y por último, si se trata de un objeto equipable, tendría una representación visual en el mundo (EquipableItem). Item Structure es una estructura que junta múltiples variables para definir al completo un objeto concreto. Esta estructura se utiliza para crear el Figura 5.17: Estructura de información de los objetos ItemsDataTable. Una tabla donde podemos definir los distintos objetos que habrá en el juego.
5.2. Diseño e implementación 49 Figura 5.18: Tabla de objetos. Cada fila representando un objeto tiene un ID, que se usará para identificar los objetos en el inventario PickUp Item. Esta clase guarda el ItemID del objeto que corresponde y la cantidad que se recibe de este objeto cuando se recoge. Implementa la interfaz PickUp, que servirá para que el componente de inventario añada la cantidad del objeto contenido cuando se pasa por encima. Item Functionality Component. El componente de funcionalidad asignado a cada objeto. Esta clase se añadirá como componente al jugador cuando se seleccione un objeto. Contiene funciones para cada acción que se puede realizar con un objeto (4 Actions) y funciones para equipar/desequipar y acivar y desacivar la funcionalidad. A través de la funcíón equipar lo objetos spawnearán su Equipable Item unido al jugador. Equipable Item. La representación del objeto en el mundo del juego una vez equipado. Pueden tener funcionalidad extra como en el caso de la pistola, que genera efectos de partículas y tiene un evento de disparo que reproduce el sonido y lanza el raycast para la colisión de las balas. Inventory Manager Component. Componente agregado al Sala-
50 Capítulo 5. Contribución manderCharBP que se encarga de mantener guardados, añadir y eliminar los objetos del jugador. Utiliza la estructura InventorySlot (que guarda ID de objeto y cantidad) para su array de objetos en el inventario. Se ocupa también de gestionar el equipado y desequipado de objetos, añadiendo el componente de funcionalidad y llamando al equip del objeto. 5.2.2.5. Cámara En el juego hay 3 tipos de cámara, aunque uno de ellos fue deshabilitado para el prototipo porque producía imágenes confusas en ciertas ocasiones. Top Down. La cámara estándar, sigue al jugador y se puede mover en el plano. Está implementada con una cámara hija de la malla del jugador. Primera Persona. Cuando se cambia a esta cámara, se deshabilita el movimiento del jugador. Se trata de una cámara colgada del socket de la cabeza del esqueleto del jugador, de manera que la cámara seguirá las animación de Salamander apropiadamente. Cámara de esquina. Esta cámara funciona con el sistema de cobertura. La cámara se coloca en una perspectiva más cercana cuando el jugador se acerca a la esquina de una cobertura. Esta cámara se eliminó del prototipo ya que en múltiples lugares la cámara resultaba obstruida por otros elementos del entorno. Más detalles de su implementación en el sistema de cobertura. 5.2.2.6. Cobertura El sistema de cobertura funciona con una clase: CoverTriggerZone. Esta clase proporciona una caja de colisión para que en el nivel se coloque sobre las zonas que van a servir de cobertura. En la clase del jugador, un raycast busca colisión con esta coverTriggerZone, si la encuentra realiza los cambios de animación y control para entrar en cobertura. Además, otro par de raycast separados hacia ambos lados del jugador comprueban que no hay colisión con un objeto en cierta distancia. Si no hay, se cambia la perspectiva de la cámara a la esquina (esto está deshabilitado en el prototipo por fallos de obstrucción de cámara). 5.2.2.7. Menús e interfaz Todos los menús e interfaz se implementaron usando los widgets de Unreal. La interfaz del juego proporciona una visualización de la salud del jugador y el objeto equipado. Además oculta un elemento interno, el inventario,
5.2. Diseño e implementación 51 que se visualiza y se le da la atención del input cuando el jugador pulsa el botón correspondiente. Una vez está el inventario abierto el propio widget es el que responde al input. Aquí el jugador puede elegir el objeto que quiere equipar. El menú de pausa y el menú principal funcionan ambos de manera similar. Cada botón es un widget propio con distintos delegados para cuando se marca o desmarca la opción y para cuando se selecciona. Desde el menú se pueden implementar esos delegados para realizar la acción que se desee. En el caso del menú principal puede ser cargar el nivel, abrir la pantalla de controles o salir del juego. 5.2.3. IA de enemigos y Goap NPC en el juego Partimos de la base que proporciona GOAP NPC. Esto es una clase que hereda de AI Controller, GOAP Controller, y la clase GOAPAction. 5.2.3.1. Añadidos al controlador base Creamos clases que heredan del GOAPController para expandir su funcionalidad. SHCGOAPContoller (SHC era el nombre en clave del juego antes de tener nombre definitivo) hereda directamente de GOAPController. A parte de añadir varias funciones para ayudar al debug de los NPCs (Debug Plan, Debug Goal y Debug State: muestran por consola respectivamente el nombre de las acciones del plan actual, la lista de objetivos y el estado del mundo) también implementa una lista priorizada de objetivos. De base, el GOAPController solo puede tener un objetivo en cada momento. Con esta lista priorizada permitimos que en determinados momentos se añadan a la lista objetivos que no necesariamente tienen que ejecutarse al momento. Por ejemplo un NPC puede tener un objetivo de baja prioridad constante: Patrullar. Si el NPC no tiene otro objetivo de mayor prioridad eligirá patrullar, pero si en algún momento se le añade el objetivo atacar al jugador (que tendría mayor prioridad), pasará a perseguir este objetivo. Esto también permite que el NPC cambia de objetivo por sí solo si el objetivo actual deja de tener sentido o no puede completarlo. BasePatrollerController El controlador del que heredarán todos los controladores de enemigos actualmente. La separación de implementación a un nuevo controlador se hizo con la idea de que hubiesen otros enemigos que no siguiesen patrullas. Este controlador implementa el bucle de ejecución de GOAP con los añadidos de la lista priorizada. En cada iteración coge el objetivo de mayor prioridad, si no consigue realizar un plan lo elimina de la lista y coge el siguiente hasta que
52 Capítulo 5. Contribución consigue un plan válido. Además, este controlador guarda algunas variables que serán útiles para todos los NPCs que tienen relación con las acciones. Una de las limitaciones que tienen las acciones es que sólo se crea una instancia de cada una. Es decir, que cualquier variable que se use en las acciones debería de ser externa a la acción, de manera que su valor sea independiente por cada NPC. Este problema surgió cuando se quiso crear un Go To genérico, es decir una acción que mueva al NPC a las coordenadas indicadas. Estas coordenadas deben de pasarse a través de la información del propio NPC, y es por esto que en BasePatrollerController hay una variable vector GoToPoint. Otra limitación que encontramos surgió de querer usar unas acciones que duren un cierto tiempo o que usen una medición de tiempo para algo. Por la naturaleza de las acciones, estas no pueden medir el tiempo de manera independiente para cada NPC. Para solventar este problema creamos unos eventos de timer, que se ejecutarían desde las acciones para empezar a contar hasta un tiempo determinado y se podría comprobar si el timer ha llegado a su fin. La variable TimerActive indica si hay un timer activo actualmente. TimerComplete indica que el timer ha terminado de contar el tiempo indicado. Surgió un problema con esta implementación. Si se cambia de acción antes de que termine el timer seguiría estando activo y contando. Por esto se comprueba en el bucle de ejecución de GOAP cuál es la acción actual y la de la anterior iteración. Si difieren, el timer se restablece (ClearTimer). Por último queda la información de patrulla. Esto tiene que ver con un sistema auxiliar y almacena la información de patrulla que se usará en una acción que todos los NPCs que heredan de este controlador poseen. 5.2.3.2. Sistema de patrulla Las patrullas de los enemigos se definen con una estructura PatrolRoute. Esta estructura está formada por un array con los puntos de patrulla (que es una clase concreta y se puede colocar en el nivel libremente para dirigir a los enemigos) el tipo de patrulla (un enum que define los tipos cíclico, ida y vuelta y aleatorio) y el tiempo de espera (tiempo que se pasará el enemigo quieto en cada punto de patrulla antes de dirigirse al siguiente). 5.2.3.3. SkullWatch Point Similar a los puntos de patrulla, son actores pensados para colocar en los puntos del escenario donde los enemigos CFC (esqueletos) podrán colocar su cabeza en modo vigilancia.
5.2. Diseño e implementación 53 5.2.3.4. Sistemas de percepción de enemigos Inicialmente para la percepción de los enemigos se estaba utilizando únicamente AIPerception, un sistema otorgado por Unreal Engine que gestiona los sentidos de los NPCs. Pero AIPerception tiene una limitación relacionada con la visión. AIPerception es un componente que no tiene posición en el mundo. Esto hace imposible conseguir que el cono de visión de los enemigos siga el movimiento de la cabeza durante las animaciones. Existen maneras de solucionarlo, creando un actor peón que tenga este componente y colgando el peón de la cabeza del personaje. El problema que surge con esto es que se vuelve imposible debuguear los sentidos del NPC. Al estar el componente en un peón que no tiene IA, el debugger de IA de Unreal no detecta este componente. Según se trabajaba con esta solución empezamos a notar que el cono de visión de los enemigos no funcionaba como debía, pero se nos hacía imposible encontrar el fallo sin poder debuguear. Finalmente decidimos crear un sistema de visión propio que se pudiese debuguear fácilmente. El funcionamiento es bien simple. Se trata de una malla de cono invisible configurada como trigger. Creamos un nuevo canal de colisión de objetos para los conos de visión. De esta manera podíamos ignorar absolutamente todas las colisiones entre este y el resto de objetos del mundo, excepto aquellos que designasemos expresamente para que colisionen con el cono de visión. Una vez detectamos que el objeto que queremos percibir está dentro del cono de visión, lanzamos un raycast al objeto. El punto que se usará como referencia del final del raycast se añadió al blueprint del jugador, que tiene un nodo de escena en el cuello. El raycast comprueba que no hay ningún obstáculo entre el NPC y su objetivo antes de enviar la señal de que lo ha percibido exitosamente. 5.2.3.5. Máquinas de estados de enemigos La máquina de estados se implementó de una manera distinta a la del jugador. En este caso tenemos por un lado el componente que gestiona la máquina de estados y por otro las clases estado para cada tipo de estado distinto. Cada estado tiene un state tick un state enter y un state exit. La máquina de estados guarda una lista de estados. Posee un estado actual que ejecuta su state tick en cada iteracion del componente. Por último cuenta con un change state que realiza el state exit del anterior estado y el state enter del nuevo siempre y cuando el estado nuevo esté dentro de la lista de estados posibles. Los estados implementados son los siguientes: Normal State. Estado de los enemigos cuando no son conscientes de la presencia del jugador. El estado actualiza la velocidad de movimiento y gestiona el lanzamiento de líneas de diálogo. Investigating State. Estado al que los enemigos saltan cuando se
54 Capítulo 5. Contribución disponen a investigar un estímulo sospechoso. Actualiza la velocidad de movimiento y sirve para actualizar el estado de la animación. Combat State. Estado de los enemigos cuando detectan al jugador y entran en combate. Actualiza la velocidad de movimiento y el estado de animación. Communicating State. Estado en el que los enemigos empiezan la comunicación por radio. Gestiona el tiempo que tarda el NPC en dar la alarma. Para poder gestionar valores como el tiempo entre líneas de diálogo, cuáles son las líneas de diálogo que lanzan, y la velocidad de movimiento en cada estado se creó una tabla información de enemigos en el que se pueden modificar todos estos valores para cada tipo de enemigo. 5.2.3.6. Tipos de enemigos Para el prototipo se desarrollaron 2 enemigos, cada uno implementa un GOAPController distinto. Ambos enemigos heredan de la misma clase, BaseEnemy. Esta clase define e implementa funciones, eventos y variables que se usarán para ambos tipos de enemigo. Base enemy cuenta con los componentes HPManager que gestiona la salud del NPC, StateMachineComponent para controlar los estados y EnemyChatManager, un componente que gestiona la reproducción de líneas de diálogo. También declara funciones cuya implementación puede variar en cada enemigo. Entre estas se cuentan FireWeapon que se encargará de hacer disparar el arma y checkLineOfSight que mediante un raycast comprobará si el enemigo tiene línea de tiro con su objetivo. HellCommunications. Utiliza el controller HellCommsController, con las siguientes variables de mundo. Player Detected y PlayerInRange determinan si el jugador ha sido detectado y está dentro del rango de acción del NPC respectivamente. Investigate determina la intención de investigar una actividad sospechosa. PlayerKilled indica si el jugador ha sido eliminado. GoToPointReached se usa para implementar el GoTo, indicando si la posición del GoTo actual ha sido alcanzada. EnemyAlerted no se usa actualmente. AlertedHQ muestra si el NPC ha avisado por radio de la presencia del jugador. LineOfSight será true cuando el enemigo tenga línea de tiro con el jugador. SearChLineOfSight indica la necesidad de buscar una nueva línea de tiro. Finalmente pathfinding significa que el NPC usará pathfinding en su movimiento (para este enemigo siempre será true). La mayoría de variables de mundo se modifican mediante lo que perciben los sentidos del NPC, así que echémosle un vistazo a su imple-
5.2. Diseño e implementación 55 Figura 5.19: Las variables de mundo, con un mundo deseado de patrullar a true mentación. Los sentidos del NPC se separan en dos sistemas, el proporcionado por Unreal AIPerception y el cono de visión implementado por nosotros. AIPerception ofrece un delegado, PerceptionTargetUpdated, que nos da la información del estímulo y el actor que lo generó. En este caso recibimos el estímulo sonoro para llamar a nuestra función que hará los cambios de mundo y objetivos. Noise Heared realiza dos acciones. Primero actualiza el punto de GoTo a la fuente del sonido. Después añade el objetivo de investigación. Hacemos uso de los objetivos priorizados para añadir este objetivo. Nuestro cono de visión funciona de manera similar, lanzando un PerceptionUpdated cuando se detecta o deja de detectar al objetivo. PlayerEntersVisionCone y PlayerExitsVisionCone actualizan un booleano de playerOnSight. En el tick se encarga de incrementar o decrementar el valor de detección en base a este valor . Usamos el valor
62 Capítulo 5. Contribución ◦SearchLineofSight: False •Efectos ◦LineOfSight: True SearchForLineOfSight. En esta acción los NPCs comprueban constantemente la línea de tiro mientras se mueven entre posiciones de flanqueo. •Prerrequisitos ◦SearchLineOfSight: True •Efectos ◦SearchLineOfSight: False ShootPlayer. Una vez con línea de tiro, el NPC dispara su arma. •Prerrequisitos ◦PlayerInRange: True ◦PlayerDetected: True ◦LineOfSight: True •Efectos ◦PlayerKilled: True 5.2.4. Arte Durante el desarrollo contamos con la ayuda de dos artistas que proporcionaron assets para el juego, un músico que no sólo le dio banda sonora al título si no que se encargó del proyecto de sonido en FMOD, un actor de doblaje que le dio vida a los enemigos del juego y un ilustrador que nos proporcionó el arte de título del juego. El arte de la pantalla de título y portada del juego fue ilustrada por Adrián Morgade, tomando inspiración del estilo de concept art de Yoji Shinkawa. 5.2.4.1. Modelos A partir de los conceptos a lápiz de Brais Morgade, Daniel Sánchez (artista 3D) se dispuso a modelar los personajes del juego y algunos props del escenario. Siguiendo la estética del juego, estos modelos tratan de mantenerse en mínimos de poligonado. En concreto Daniel Sánchez modeló a Little Salamander, avatar del juego, el guardia de HellCommunications y un camión. El enemigo que falta, el CFC, fue modelado por Brais Morgade. Diego López se encargó de la mayoría del resto de props del escenario como las estanterías, la morgue, camillas, sillas, mesas, ordenadores y todo tipo de props
5.2. Diseño e implementación 63 de oficina y laboratorio. Otros props como las armas tanto de Salamander como de los enemigos los modeló Brais Morgade, además de la estatua de Hachimiko. 5.2.4.2. Texturizado La creación de casi todas las texturas del juego seguían el mismo proceso. Usualmente comenzaban a partir de imágenes de calidad variable, que luego se disminuía a los estándares de PS1 (256x256 máximo) con una elección de filtro que mantenga el pixel-art de la baja resolución. El texturizado de todos los assets del juego fue realizado por Brais Morgade. 5.2.4.3. Materiales Diego López nos proporcionó con un material que usaríamos sobre la mayoría de assets. El material Cartoon, junto con unos shaders de postprocesado consiguen darle un look de dibujo o cómic al juego. Este material consigue crear unos trazos en las líneas exteriores de los modelos reminiscente del cellshading. 5.2.4.4. FX Brais Morgade realizó unos pocos efectos de partículas para el láser de la pistola y las salpicaduras de sangre de los enemigos. Estos efectos se crearon usando del Niagara System, un sistema de partículas que proporciona Unreal. 5.2.4.5. Iluminación Brais Morgade se encargó de la iluminación del nivel. La iluminación del escenario sufrió muchos cambios a lo largo del desarrollo, la iluminación final utiliza tanto fuentes de luz estáticas como focos estacionarios (luces mucho menos costosas que las dinámicas, pero que permiten generar sombras dinámicas de objetos dinámicos). Aunque en PlayStation no hubiesen luces dinámicas, este extra en la iluminación mejoraba considerablemente la estética, así que decidimos mantenerlas. Los focos ayudan a dar la sensación de que el escenario está siendo iluminado por regletas en el techo, mientras las luces estáticas iluminan todo el escenario con el valor de temperatura alto que le da un poco de ambiente al nivel. 5.2.4.6. Animación La gran mayoría de animaciones del juego fueron descargadas de Mixamo, con unas pocas excepciones. Algunas de estas animaciones necesitaban retoques, principalmente las animaciones que tienen que ver con el apuntado de las armas ya que al colocarle el arma esta apuntaba en una dirección
64 Capítulo 5. Contribución incorrecta. Estas animaciones se retocaron algunas desde el propio editor de animaciones en Unreal, otras desde Blender. Para las de movimiento del jugador se utilizaron varias animaciones de velocidades distintas juntándolas en un blendspace. También se hizo uso de montajes para animaciones más puntuales y blends entre la parte de arriba y parte de abajo del cuerpo del personaje usando cada parte una animación distinta. Esta última técnica es útil para no tener que hacer incontables variaciones de animaciones como por ejemplo: animación de hit quieto, animación de hit andando, animación de hit corriendo. La solución consiste en reproducir la animación de hit solo en la parte superior del cuerpo mientras la parte de abajo reproduce la animación que corresponda con la locomoción. 5.2.5. Música y sonido Miguel Beneyto-Guillamas compuso una banda sonora compuesta por dos canciones: la canción del menú principal y la del nivel. Esta última tiene elementos de banda sonora adaptativa que luego se podrían aprovechar en el juego. 5.2.5.1. FMOD A parte de componer estas dos canciones, Miguel creó un proyecto de FMOD con todos los sonidos que se pueden escuchar en el juego, todos espacializados. Los sonidos del juego pasaron por una bajada de frecuencia de sample para darle el toque retro. Para implementar en le juego los eventos de FMOD se necesitaría instalar el plugin de FMOD para Unreal. Una vez generados los eventos de FMOD, Brais se encargó de implementarlos dentro del juego. 5.2.5.2. Implementación de música adaptativa La música del nivel cuenta con varios valores que modifican la pista de distintas maneras. La principal es la alerta, dependiendo de estado de alerta de la base la canción saltará a una pista de mayor o menor intensidad de manera suave. Hay dos capas extras que se añaden a la canción cuando se activan. Una es Tecnológico-Arcaico (pensado para cuando se presentan los enemigos no-muertos) que le da un tono misterioso y la otra es la de jefe que añade tensión a la mezcla. Dos pequeñas pistas se añaden a la canción cuando se activa su respectivo parámetro. Enemigo eliminado salta cuando se abate a un enemigo mientras que Resurrección se reproduce en el momento en el que vemos resucitar a un no-muerto. Por último hay dos pistas alternativas que se reproducen cuando el jugador muere o cuando termina el nivel.
5.2. Diseño e implementación 65 5.2.5.3. Doblaje El doblaje de los enemigos lo realizó Borja Bayón, que juntó su conocimiento de ruso, polaco y otros idiomas para actuar unas líneas de diálogo donde los guardias hablan en una mezcla de idiomas.
Capítulo 6 Pruebas En este capítulo hablaremos del experimento realizado con usuarios y sus resultados. Además intentaremos extraer algunas conclusiones a partir de las repuestas dadas. 6.1. Esquema del experimento A la hora de realizar pruebas con usuarios hemos creado un cuestionario dividido en secciones claramente diferenciadas con el cual valoramos todo lo trabajado en el proyecto. Primero preguntamos por la experiencia del usuario desarrollando videojuegos, motores de videojuegos y en IA para videojuegos. Con esto queremos saber cuáles son sus conocimientos para poner en contexto sus respuestas en las secciones posteriores. Después se le dará un enlace al usuario para que descargue el juego. Una vez hecho deberá jugar una partida y pasarse el nivel. Tras jugar una partida hay una sección de preguntas relacionadas con el resto del juego. Queremos saber con estas preguntas si le ha parecido interesante el prototipo del juego y, por tanto, podría tener algo de futuro si se acabase de desarrollar como juego completo. Por último realizaremos una serie de preguntas sobre GOAP NPC y GoalOriented Action Planning. Para ello primero tienen los usuarios una explicación de cómo funciona para que puedan responder de forma más informada las preguntas que hay a continuación. En esta última parte del experimento nos centramos en la herramienta y la IA generada por la herramienta. 67
68 Capítulo 6. Pruebas Todas las preguntas realizadas están en Apéndice D. 6.2. Resultados de las pruebas La primera sección de preguntas estaba enfocada en averiguar los conocimientos previos de los usuarios En estas primeras preguntas (Figura 6.1) llama la atención que menos de la mitad de los usuarios han usado Unreal y sólo uno de ellos tiene más de 2 años de experiencia. También destaca que uno de los usuarios nunca ha utilizado ningún motor de videojuegos.Después de las respuestas anteriores las siguientes (Figura 6.2) eran de esperar. Ninguno de los usuarios tiene experiencia profesional, y la mayoría nunca ha desarrollado nada relacionado con Inteligencia Artificial. Hay un gran desconocimiento general entre los usuarios en relación con el área de la Inteligencia Artificial como se puede ver en Figura 6.3. Respecto a GOAP y GOAP NPC hay un total desconocimiento a excepción de un usuario que conocía Goal.Oriented Action Planning previamente, así lo muestra Figura 6.4. Tras esto empezamos con preguntas sobre el juego (Figura 6.5). Por lo general no se considera que haya una gran originalidad en los enemigos pero sí hay bastante interés en ver como quedarían en una versión final del juego. Respecto a la estética, hay división de opiniones sobre lo interesante que es tener esa estética en el juego. A la gran mayoría de los usuarios Slamander’s Nightmare les recuerda a juegos de sigilo de Playstation original. Esto se ve en Figura 6.6. En las últimas preguntas sobre el juego (Figura 6.7) hay una gran división de opiniones. A pesar de esta división de opiniones, a más de la mitad de los usuarios les gustaría jugar al juego completo. Aunque también es destacable que ninguno de los usuarios ha entendido qué hace el último enemigo. Las respuestas respuestas más acertadas apuntan a que hay unas cámaras que indican al enemigo dónde estás en caso de que te vean. En las preguntas respecto a Goal-Oriented Action Planning y GOAP NPC hay un gran desconocimiento acerca de cómo funciona GOAP como algoritmo. La gran mayoría de los usuarios considera que se podía haber realizado Salamander’s Nightmare haciendo uso de otras técnicas de IA en vez de GOAP. Esto se ve en Figura 6.8. Como se puede comprobar en Figura 6.9 la gran mayoría de usuarios se plantearía usar GOAP NPC en proyectos futuros y recomendarlo a otros desarrolladores. Los resultados de las pruebas han sido muy variados en la mayoría de preguntas. Esto se debe principalmente a que tan solo hemos contado con 5 usuarios para realizar las pruebas.
6.3. Discusión sobre el experimento 69 6.3. Discusión sobre el experimento Lo primero de todo que hay que recalcar es que hemos contado con 5 usuarios, una cifra bastante baja como para sacar grandes conclusiones pero sí para hacernos una idea. Además, los usuarios que han realizado las pruebas no tienen mucha experiencia desarrollan videojuegos, ni en el área de Inteligencia Artificial ni usando Unreal Engine. Teniendo en consideración lo anterior, hemos visto que no se ha considerado muy original el comportamiento de los NPCs por lo que habría que trabajar más en que se vea en qué se diferencian estos personajes de los que suele haber habitualmente en otros juegos. Además, nadie ha entendido qué hace el último de los enemigos. Los que más cerca se han quedado consideran que hay unas cámaras en la sala que si te ven avisan al enemigo que está patrullando. Aunque lo que han dicho no es muy distinto a lo que sucede en realidad nadie ha visto como es el propio enemigo el que deja su cabeza en una posición estratégica para poder ver si viene alguien, mientras es su cuerpo el que está patrullando. Seguramente habría que hacer que se viera mejor cómo deja la cabeza y así a los usuarios les quedaría claro qué está sucediendo. Por otro lado, la estética ha tenido más éxito. La mayoría de usuarios considera interesante la idea estética propuesta. Uniendo las mecánicas del juego con su estética se consigue que haya una respuesta casi unánime en que Salamander’s Nightmare les recuerda a juegos de sigilo de la Playstation original. En lo que respecta a GOAP NPC había un desconocimiento general previo sobre la herramienta al igual que sobre Goal-Oriented Action Planning. Tras probar el juego y leer cómo funciona se ha generado bastante interés en usar la herramienta y en recomendarla a otros desarrolladores. Sin embargo, se considera que se podría haber realizado el juego con otras técnicas de IA. 6.4. Discusión sobre GOAP NPC Por lo que se ha visto hay un gran desconocimiento acerca de planificación automática en general y GOAP NPC en particular. Esto provoca que haya un menos número de desarrolladores utilizando esta técnica de Inteligencia Artificial por encima de otras técnicas más clásicas como árboles de comportamiento o maquinas de estados. No podremos saber el potencial real
70 Capítulo 6. Pruebas de esta técnica hasta que no se investigue y utilice más, aunque ya se está investigando fuera del sector de los videojuegos con resultados interesantes. Respecto a GOAP NPC esperamos que su éxito en Unreal Marketplace, con más de 112 mil descargas, ayude a popularizar Goal-Oriented Action Planning y la planificación automática. Ya ha muchos usuarios utilizando la herramienta y esperamos que sean más. Creemos firmemente que GOAP NPC puede convertirse en un referente para Unreal Engine gracias a su potencia y a que es gratis, dándole así un posicionamiento privilegiado en Unreal Marketplace. 6.5. Gráficos de las pruebas Como hemos usado cuestionarios de Google hemos obtenido gráficas de forma automática. Estas gráficas son las siguientes:
6.5. Gráficos de las pruebas 71 Figura 6.1: Respuestas a las preguntas 1 y 2 de la primera sección
78 Capítulo 6. Pruebas Figura 6.9: Respuestas a las preguntas 3 y 4 de la segunda sección
Capítulo 7 Conclusiones En este capítulo exponemos las conclusiones del trabajo y esbozamos posibles líneas de trabajo futuro para facilitar la continuación del proyecto a terceros. 7.1. Conclusiones Al inicio de este proyecto nos planteamos una serie de objetivos y aquí revisamos si los hemos alcanzado. Revisar y actualizar GOAP NPC. Hemos conseguido actualizar GOAP NPC para las nuevas versiones de Unreal Engine además de haber resuelto el principal problema que tenía (incompatibilidad de nomenclaturas). Una vez hecho eso le añadimos un sistema de depuración. Desarrollar un prototipo de juego donde se use GOAP NPC. Este objetivo también ha sido cumplido. Hemos desarrollado Salamander’s Nightmare, un prototipo de videojuego en el cual hemos usado GOAP NPC para crear los blueprints de la IA de los enemigos. Estos enemigos no utilizan otra técnica de IA que no sea Goal-Oriented Action Planning. Realizar pruebas del juego y reunir feedback de desarrolladores y jugadores. En este caso no podemos considerar que hemos cumplido totalmente el objetivo. Las pruebas que hemos realizado han contado con sólo 5 usuarios por lo que es una cifra inferior a la que nos gustaría para poder considerar significativos los datos. Además estos usuarios, a los que agradecemos profundamente haber realizado las pruebas, contaban con una experiencia en el sector prácticamente nula en todos los casos. Debido a esto no hemos podido obtener un feed79
80 Capítulo 7. Conclusiones back muy valioso en lo que a GOAP NPC respecta pero sí que han sido mucho más útiles los comentarios sobre Salamander’s Nightmare. 7.2. Trabajo futuro A pesar de haber cumplido el objetivo nos habría gustado hacer avanzar aún más la herramienta y por eso recogemos aquí posibles mejoras. 7.2.1. GOAP NPC A lo largo del desarrollo del videojuego, encontramos varios problemas con la herramienta que nos forzaron a encontrar soluciones alternativas. Algunos de ellos los contamos en el capítulo de contribución, pero para reiterar y ofrecer posibles soluciones las listamos aquí. Falta de lista priorizada de objetivos Es muy frecuente necesitar tener varios objetivos establecidos con distinta prioridad a la hora de hacer NPCs un poco complejos. En GOAP NPC a un controlador sólo se le puede asignar un objetivo en cada momento. Nosotros implementamos una lista priorizada de objetivos en una extensión del controlador base GOAPController, pero se podría añadir esta característica al código original de GOAPController. Control del tiempo. Durante el desarrollo nos topamos con la necesidad de implementar acciones que iniciasen y comprobasen algún tipo de timer. Dada la naturaleza de las acciones, esto no se puede hacer dentro de ellas, así que lo que más sentido nos tiene es que se añada un timer al controlador que se pueda llamar desde las acciones. GoTo genérico. Este es un tema complicado. Crear un GoTo genérico implicaría tener que poder crear las acciones con parámetros iniciales y que los prerrequisitos de algunas acciones fuesen variables. Si cierta acción requiere que el NPC esté en X lugar, necesitará que se haga un GoTo[X]. Un GoTo genérico reduciría ampliamente la cantidad de acciones que requieren de mover al personaje. Variables de mundo de más tipos. Las variables del mundo, que forman también los prerrequisitos y efectos de las acciones, son todas booleanas. Una buena ampliación de la herramienta permitiría que se pudiesen elegir varios tipos como floats, ints o enums. Los prerrequisitos se tendrían que escribir como condiciones del tipo numeroDeAliados <X o tipoDeArma == MELEEWEAPON y podrían mejorar la calidad del código y ser más precisos con la percepción del estado del mundo.
7.3. Comentarios finales 81 Debug. Un problema recurrente que nos topamos trabajando la IA es la carencia de medios para debuguear. En muchas ocasiones nos enfrentamos a bugs y planes no ejecutándose de los que desconocíamos el motivo dada la naturaleza cerrada de lo que está pasando con las comprobaciones y elecciones de acciones al formar planes. Durante el desarrollo creamos unas funciones que sacan la mínima información del planeador, pero este es un campo en el que se puede trabajar y mejorar considerablemente. Código abierto. Está planificado que GOAP NPC pase a ser de código abierto como ha pedido mucha gente de la comunidad. Esto requerirá cierta supervisión de vez en cuando para organizar y subir a Unreal Marketplace las nuevas versiones. 7.2.2. Salamander´s Nightmare Para este prototipo no conseguimos desarrollar todo lo que habíamos propuesto en el GDD. Uno de nuestros objetivos de cara al futuro es seguir desarrollando tipos de enemigos, objetos y niveles. Con los resultados de las pruebas quedó una cosa clara. Los jugadores no entendieron del todo el concepto de los enemigos esqueleto, diciendo en el caso que más se acercaba a la realidad que se trataba de una cámara y un enemigo funcionando por separado. La mayor prioridad a partir de ahora debería de ser hacer mucho más claro lo que es este enemigo, como funciona y potenciar el concepto, añadiendo más interacciones y movimientos únicos que sorprendan y al mismo tiempo sean intuitivos. Por la parte de la estética en general se consiguió lo que nos proponíamos, con la mayoría de los encuestados confirmando la similitud con los juegos de la época PS1. Aún así, como vimos en el análisis de las características de la estética PS1 en el Capítulo 3:Objetivos, algunos de los efectos más únicos de PS1 no pudieron ser implementados, con lo que nos proponemos conseguir generar estos efectos aunque sea mediante vías distintas. 7.3. Comentarios finales Al principio de esta memoria mencionamos que hacer un videojuego como trabajo final de la carrera de desarrollo de videojuegos nos parecía el final más lógico y tras este año de desarrollo podemos decir que ha sido una experiencia en la que hemos aprendido mucho. No es la primera vez que ponemos en práctica nuestros conocimientos en un trabajo de este tipo, pero la escala y la atención que hemos puesto en la
82 Capítulo 7. Conclusiones IA y la estética resultó en posiblemente el proyecto que más nos ha hecho avanzar como desarrolladores. Hemos puesto en práctica desde lo aprendido sobre animación, modelado o sonido hasta trabajar algunas de las facetas más importantes en la industria como el trabajo en equipo (junto a ayudantes externos al proyecto como Daniel Sánchez, Diego López y Miguel Beneyto-Guillamas) y la importancia de saber presentar las ideas a los demás. Además hemos aprendido a usar un motor en el que ninguno de los dos teníamos experiencia previa y conocimos mucho sobre la Inteligencia Artificial en videojuegos y su desarrollo que nunca habíamos visto a lo largo de la carrera. Estamos orgullosos del resultado de este TFG y queremos seguir desarrollándolo y mejorándolo pues tenemos muchas ideas y sobre todo, ganas.
Apéndice A Contribuciones individuales A.1. Brais Santiago Morgade Valcárcel Me encargué del diseño y desarrollo del videojuego, programación, IA y algo de arte. Empezando por la fase de preproducción del videojuego, ideé el primer concepto e idea general del videojuego, más adelante dibujando unos primeros bocetos de los personajes del juego. Cuando tuvimos más claro el diseño del juego, redacté el GDD. Cuando se unieron los artistas Diego López y Daniel Sánchez tuve varias reuniones con ellos para discutir las ideas del juego y la estética y posteriormente escribí un documento de referencias y objetivos para dirigir el estilo artístico del diseño de personajes. Una vez comenzamos la producción, lo primero de lo que me encargué fue de la programación mediante blueprints de las mecánicas del jugador. Entre estas se cuentan el control de movimiento, el control de la cámara tanto en la perspectiva top down como en primera persona, la máquina de estados que permitirá al jugador cambiar entre posturas y otras mecánicas, el sistema de salud, recolección de objetos y sistema de inventario, sistema de coberturas, sistema de apuntado y la funcionalidad de la pistola silenciada. Con la actualización de GOAP NPC pude finalmente empezar a trabajar en la IA y los enemigos. Para ampliar la funcionalidad de GOAP NPC debido a las necesidades de los NPCs del juego, desarrollé un SHCController que hereda de GOAPController, al que sigue un PatrollerController que sirve de base para los controladores de los enemigos. Junto a PatrollerController implementé unos sistemas auxiliares para la IA. Estos son el sistema de patrulla, la máquina de estados de los enemigos y cada EnemyState individual, el sistema de diálogo de los enemigos y un sistema de cono de visión propio. Desarrollé los actores de HellComms y CFC, los dos enemigos vistos en el 83
84 Apéndice A. Contribuciones individuales prototipo. CFC tiene la particularidad de separarse en dos agentes distintos, con lo que creé los actores CFCHead y CFCBody. Para darle comportamiento a estos actores implementé HellCommsController, CFCController y CFCBodyController y realicé el scripteado de la asignación de objetivos y actualización de estado del mundo para cada uno. CFCHead no utiliza un controlador como tal, pero implementé la gestión de los sentidos y las órdenes que envía a su CFCBody. Por último, programé los numerosos GOAPActions que luego usan los controladores para ejecutar sus planes y cumplir los objetivos. Los menús e interfaz también ocuparon una parte importante del desarrollo del juego. En este aspecto me ocupé del menú principal, menú de pausa, HUD durante el nivel, menú de inventario y diálogos de enemigos en pantalla. En la construcción del nivel, diseñé del nivel y monté el greyboxing inicial para luego completarlo con los assets finales y la colocación de luces y gestión de iluminación. En el terreno de animación, la gran mayoría de animaciones se descargaron de Mixamo. Yo mismo elegí y recopilé las animaciones necesarias con las que luego generé el Animation Blueprint de cada personaje. Algunas animaciones no cuadraban bien para lo que se iban a usar, con lo que me dediqué a editar y retocarlas usando el propio editor de Unreal y Blender. Con todos los assets de animación, implementé algunos Animation Blendspace para la locomoción de los personajes. A mayores, una de las animaciones que vemos en el juego es original y la hice en Blender (alertingHQ). El juego cuenta con numerosos modelos 3D, entre los cuales el enemigo CFC, las distintas armas y la pica del CFC fueron modelados y texturizados por mí. Hablando de texturas, no confundir con los materiales que generó Diego López, generé todas las texturas del juego a excepción de una, con el UVMapping acorde a cada modelo en el que se usaron. En el juego existen un par de efectos de partículas que generé, el láser de apuntado de la pistola y el efecto de salpicadura de sangre. Uno de los elementos con más importancia en el aspecto retro del juego es el RetroShader, un blueprint de terceros que integré en el proyecto y configuré para darle al juego el aspecto final. Por último, también trabaje algo del sonido. Miguel Beneyto-Guillamas
A.2. Daniel Gil Aguilar 85 fue el responsable de la grandísima mayoría de sonido y música en el juego, y el proyecto de FMODStudio fue su creación. Por mi parte instalé el plugin de FMOD en el proyecto de Unreal e implementé los distintos eventos generados por Miguel en el juego. A parte, varias veces abrí el proyecto de FMOD para editar algún que otro evento y añadir efectos de sonido nuevos, que previamente habría editado usando Audacity. A.2. Daniel Gil Aguilar Primero se me asignó ponerme en contacto con los autores originales de GOAP NPC para tener su beneplácito para el uso de la herramienta que ellos crearon. Tras su visto bueno, tuve que ponerme al día con la situación actual de GOAP NPC, ver los problemas que la gente ha reportado en los últimos meses y familiarizarme con él código. El principal problema que detecté fue que la versión 1.3 de GOAP NPC dejó de ser compatible con proyectos realizados en versiones anteriores de la herramienta. Esto se debía a una refactorización del código que provocó que Unreal Engine detectase las distintas versiones de GOAP NPC como si fueran herramientas distintas. También investigué sobre cómo funciona Goal-Oriented Action Planning. Además realicé un análisis de la principal competencia de GOAP NPC y su posicionamiento. Otro trabajo que se me encargó fue realizar pruebas para montar un repositorio en GitHub, ya que era previsible que el proyecto del juego en Unreal fuese de un gran tamaño. Tras realizar pruebas con GitHub y su extensión para grandes archivos vimos que no iba a ser posible usar GitHub como software de control de versiones y tendríamos que buscar una opción alternativa. Finalmente utilizamos Perforce como repositorio ya que pude comprobar que podíamos almacenar ahí proyectos más pesados. Una vez detectado el problema de GOAP NPC, había que buscar la mejor solución. Finalmente se decidió continuar con la nomenclatura de clases que había tras la refactorización de código pero compilé builds de todas las versiones disponibles con ambas nomenclaturas. De esa forma si alguien quería actualizar a GOAP NPC 1.3 sin perder lo que hizo con GOAP NPC 1.2 podría descargarse un archivo .zip con la build de GOAP NPC 1.3 con nomenclatura antigua. Además compilé builds de GOAP NPC en las últimas versiones de Unreal Engine y se subieron a Unreal Marketplace para asegurar la compatibilidad de la herramienta con las últimas versiones del motor. También decidimos hacer uso de alguna librería de Unreal Marketplace que nos ayudase crear un sistema de sigilo en el juego. Me encargué de buscar y analizar diversas opciones para que después decidiéramos en conjunto cuál
86 Apéndice A. Contribuciones individuales usar. Una vez decidido qué librería íbamos a utilizar, monté una demo con los comportamientos básicos y así tener una referencia para el juego. Después realicé una demo con la última versión de GOAP NPC en la que había NPCs con distintos comportamientos en un laberinto. Para ello cogí una demo que había hecha previamente de GOAP NPC con personajes en un laberinto con una versión antigua. Gracias a esto pude reutilizar la escena con el laberinto y los personajes, y así sólo tuve que rehacer los blueprints de acciones y controladores. Creé acciones y controladores para patrullar, perseguir, vigilar una estancia y atacar a un jugador. Estas acciones podían mezclarse en los controladores y crear personajes que, por ejemplo, patrullasen hasta que detectaran al jugador y empezaran a perseguirlo. De esta forma le di a Brais una serie de blueprints con acciones y controladores de comportamientos básicos para los NPCs, a partir de ahí podría usarlos como base de acciones y controladores más complejos. Tras esto me centré en realizar mejoras a GOAP NPC. Nos vimos en una situación en la que tuvimos que sacrificar mejoras en GOAP NPC para poder avanzar en Salamander’s Nightmare. Esto se debe a que algunas mejoras que estuve desarrollando implicaban que cuando se actualizase la versión de GOAP NPC utilizada en el juego habría que rehacer o, al menos, reajustar todos los blueprints ya creados con todos los potenciales problemas que ello conlleva. Por ello tuve que descartar una clase que estaba desarrollando en GOAP NPC que permitía utilizar variables de más tipos aparte de bool en acciones y estados del mundo. Tuve que buscar mejoras que no implicasen tener que rehacer blueprints en el juego. Finalmente crear un sistema de debug para la herramienta. Esta era una mejora muy pedida en la comunidad creada alrededor de la herramienta. Esta mejora permite poder saber el plan generado por el controlador que quieras en el editor de Unreal Engine. Todo lo referente al sistema de debug está explicado con detalle en 5. Para finalizar con el desarrollo del juego creé el plan de pruebas. Para ello redacté el cuestionario que utilizamos para realizar las pruebas con usuarios y lo compartimos por distintos grupos de Whatsapp y Telegram para conseguir la mayor cantidad de usuarios posibles realizando las pruebas. También creé una versión en inglés del cuestionario para pasárselo a los desarrolladores que forman parte de la comunidad de GOAP NPC pero desafortunadamente ninguno quiso realizar las pruebas. Respecto a la memoria me encargué de crear la estructura que seguiríamos y de qué hablaríamos en cada apartado y sección. Tras esto, y después de realizar los cambios en la estructura propuestos por el director del TFG, pasé a Overleaf la estructura del la memoria y configuré el proyecto. He re-
A.2. Daniel Gil Aguilar 87 dactado los capítulos de Introducción, Estado de la cuestión, Metodología y herramientas y Pruebas. Además de escribir sobre los cambios realizados en GOAP NPC en el capítulo de Contribución.
94 Appendix C. Conclusions C.2. Future work Although we met our goal, we would have liked to advance the tool even further, so here are some possible improvements. C.2.1. GOAP NPC Throughout the development of the video game, we encountered several problems with the tool that forced us to find alternative solutions. Some of them we recounted in the contribution chapter, but to reiterate and offer possible solutions we list them here. Lack of prioritized list of targets It is very common to need to have several targets set with different priority when making somewhat complex NPCs. In GOAP NPC a controller can only be assigned one target at a time. We implemented a prioritized list of targets in an extension of the base GOAPController, but this feature could be added to the original GOAPController code. Time control During development we ran into the need to implement actions that would initiate and check some kind of timer. Given the nature of the actions, this cannot be done within them, so what makes the most sense to us is to add a timer to the controller that can be called from the actions. Generic GoTo This is a tricky issue. Creating a generic GoTo would imply having to be able to create the actions with initial parameters and that the prerequisites of some actions would be variable. If a certain action requires the NPC to be in X place, it will need a GoTo[X] to be made. A generic GoTo would greatly reduce the number of actions that require moving the character. World variables of more types The world variables, which also form the prerequisites and effects of actions, are all boolean. A nice extension of the tool would allow multiple types such as floats, ints or enums to be chosen. The prerequisites would have to be written as conditions of type numberOfAllies < X or typeWeapon == MELEEWEWEAPON and could improve the quality of the code and be more accurate with the perception of the state of the world. Debug A recurring problem we encounter when working with AI is the lack of debugging facilities. On many occasions we were faced with bugs and plans not executing for which we did not know the reason given the closed nature of what is going on with the checks and action choices when forming plans. During development we created some
C.3. Final comments 95 functions that pull minimal information from the glider, but this is an area that can be worked on and improved considerably. Open Source GOAP NPC is planned to be made open source as many people in the community have requested. This will require some supervision from time to time to organize and upload new versions to the Unreal Marketplace. C.2.2. Salamander’s Nightmare For this prototype we did not manage to develop everything we had proposed in the GDD. One of our goals for the future is to continue developing enemy types, objects and levels. One thing was clear from the test results. Players did not fully understand the concept of skeleton enemies, saying in the case that was closest to reality that it was a camera and an enemy working separately. The main priority from now on should be to make it much clearer what this enemy is, how it works and enhance the concept, adding more interactions and unique moves that surprise and at the same time are intuitive. On the aesthetics side in general we got what we were aiming for, with the majority of respondents stating the similarity to the PS1 era. Still, as we saw in the analysis of the characteristics of the PS1 aesthetics in the objectives chapter, some of the more unique effects of PS1 could not be implemented, so we aim to succeed in generating these effects albeit through different avenues. C.3. Final comments At the beginning of this report we mentioned that making a video game as the final work of the video game development degree seemed to us the most logical end and after this year of development we can say that it has been an experience in which we have learned a lot. It is not the first time we put our knowledge into practice in a work of this type, but the scale and attention we have put into the AI and aesthetics resulted in possibly the project that has made us advance the most as developers. We have put into practice from what we have learned about animation, modeling or sound to work some of the most important facets in the industry such as teamwork (along with external helpers to the project as Daniel Sanchez, Diego Lopez and Miguel Beneyto-Guillamas) and the importance of knowing how to present ideas to others. We have also learned to use an
96 Appendix C. Conclusions engine in which neither of us had previous experience and we learned a lot about Artificial Intelligence in videogames and its development that we had never seen throughout the career. We are proud of the result of this TFG and we want to continue developing and improving it because we have a lot of ideas and above all, desire.
Apéndice D Entrevistas En este apéndice están las preguntas realizadas a los usuarios que han realizado el experimento. Sección 1: Experiencia previa. ¿Qué motores de videojuegos has utilizado? ¿Cuánta experiencia tienes usando Unreal Engine? ¿Tienes experiencia desarrollando videojuegos? ¿Tienes experiencia programando IA para videojuegos? ¿Qué técnicas de IA para videojuegos conoces? ¿Habías oído hablar de Goal-Oriented Action Planning (GOAP) anteriormente? ¿Conocías la extensión de Unreal Engine llamada GOAP NPC? Sección 2: Salamander’s Nightmare. En esta sección hay una serie de afirmaciones y debes de indicar cuán de acuerdo estás con las mismas. La última sí que es una pregunta de respuesta larga. El comportamiento de la IA que tienen algunos enemigos es original. Me gustaría conocer los enemigos y las IA que se presentarán en la versión final. La estética retro del videojuego es interesante. Me recuerda a juegos de sigilo de la Playstation original (PS1). Si fuese publicado como juego completo me gustaría jugarlo. 97
98 Apéndice D. Entrevistas ¿Has entendido lo que hace el segundo tipo de enemigo que aparece en el juego? Explícalo con tus palabras. Sección 3: GOAP NPC. En esta sección vuelve a haber una serie de afirmaciones y debes de indicar cuán de acuerdo estás con las mismas. Salamander’s Nightmare se podría haber hecho con otras técnicas de IA. Sabías cómo funciona GOAP antes de leer la explicación. Después de esto, me plantearía usar GOAP NPC en algún proyecto futuro. Recomendaría GOAP NPC a otros desarrolladores.
Bibliografía Bjarnolf, P.,Gustavsson, P. M.,Brax, C. yFredin, M. Threat analysis using goal-oriented action planning. Skövde, Sweden: University of Skövde, 2008. Ghallab, M.,Nau, D. yTraverso, P. Automated Planning: theory and practice. Elsevier, 2004. Guerrero, E. I. B. I – introducción a la ia 2. agentes inteligentes. 2010. Lagervik, C. yGustavsson, P. M. A system theoretical approach to situation awareness and architecture. En International Command and Control Research and Technical symposium, páginas 16–s. 2006. Long, E. Enhanced npc behaviour using goal oriented action planning. Master’s Thesis, School of Computing and Advanced Technologies, University of Abertay Dundee, Dundee, UK , 2007. Miranda, M.,Sánchez-Ruiz, A. A. yPeinado, F. A neuroevolution approach to imitating human-like play in ms. pac-man video game. En CoSECivi, páginas 113–124. 2016. Orkin, J. Ai game programming wisdom 2. Charles River Media Inc, 2004. Orkin, J. Agent architecture considerations for real-time planning in games. En Proceedings of the AAAI Conference on Artificial Intelligence and Interactive Digital Entertainment, vol. 1, páginas 105–110. 2005. Orkin, J. Three states and a plan: the ai of fear. En Game developers conference, vol. 2006, página 4. CMP Game Group SanJose, California, 2006. Romero-Hombrebueno Santos, D.,Sánchez Blanco, M. ySierra Ramos, J. M. Planificación automática para el comportamiento de personajes de videojuegos como extensión de unreal engine. 2020. Torres González, C. et al. Simulación en unity 3d mediante modelos goap de personas de movilidad reducida en aeropuertos. 2021. 99