Generación de nivel en inexplorado 2
Estamos muy orgullosos del generador de nivel de juego Unexplored 2, este es un programa que cumple con todos los requisitos modernos. En una publicación hablaré sobre cómo se crean los niveles de juego.
No tuvimos que reinventar la rueda. En Unexplored 1, ya creamos técnicas que influyeron mucho en el éxito del primer juego. Inexplored 2 simplemente continuó lo que comenzó. La base de nuestra tecnología consta de dos partes: utilizamos la generación de etapas múltiples, que casi simula un proceso muy similar al trabajo de un diseñador de nivel de vida. Además, utilizamos una técnica llamada "
generación de mazmorras cíclicas ", que es mucho mejor para generar niveles de aspecto natural que la mayoría de las aplicaciones estándar de creación de contenido generativo. En este post hablaré sobre el primer aspecto. Adaptar la generación de mazmorras cíclicas a Unexplored 2 será el tema de una publicación futura.
Imitación del diseño de nivel "humano"
El generador de niveles desglosa el proceso de generación de niveles en un conjunto completo de etapas controladas. Va desde la planificación de alto nivel a un mapa de nivel detallado de bajo nivel. De hecho, primero crea un boceto del nivel y luego comienza a agregar detalles hasta que el nivel se complete y se complete.
En cada etapa individual de este proceso, utilizamos gramáticas generativas para transformar el nivel generado en las etapas anteriores. En particular, utilizamos gramáticas de mosaico y gramáticas de gráficos, que son variedades de gramáticas de cadenas más generales que simplemente buscan y reemplazan partes de cadenas con otras cadenas, al igual que las expresiones regulares. Si no está familiarizado con los conceptos de gramáticas generativas y expresiones regulares, le recomiendo que busque ejemplos en Internet (o simplemente continúe leyendo, no necesitará un conocimiento profundo para comprender el significado de esta publicación).
La primera etapa del nivel es relativamente simple. Usamos un mapa de bits de baja resolución para localizar los conceptos básicos del nivel. En el siguiente ejemplo, el nivel es inicialmente muy simple: consiste solo en la entrada (e) a la izquierda, la entrada a la derecha y conectando la ruta directa. La mayoría de las otras fichas están indefinidas (u) o bloqueadas (B) porque están en los bordes del nivel.
Figura 1: un bosquejo simple del nivelEn la siguiente etapa, se agregan detalles: aparece un grupo de habitaciones, conectadas por puertas, que están diseñadas para pasar en una determinada dirección:
Figura 2: Estructura agregadaLos mapas de mosaico son excelentes para crear geometría de nivel, pero es más práctico trabajar con gráficos para generar estructuras y lógica de juego. Esto es lo que hace el generador a continuación:
Figura 3: Gráfico baseEn el gráfico, algunos nodos contienen subnodos, en nuestro caso la mayoría de las puertas están marcadas como peligrosas (H), y algunas están marcadas como abiertas (O).
Basado en un análisis bastante simple y reglas generativas, se agregan nuevos elementos al gráfico. Por ejemplo, el punto final (G) se encuentra en una ubicación que está lo suficientemente lejos de las entradas. Además, se agregan pequeños peligros al gráfico para hacer que el nivel sea más amenazante.
Figura 4: Nuevos elementos agregados al gráfico.
Mientras tanto, un mapa de mosaico de baja resolución se convierte utilizando varias funciones de ruido en un mapa de mosaico de alta resolución para darle un aspecto más natural:
Figura 5: Mapa de mosaico de alta resolución
Luego, la información del gráfico se usa para decorar el mapa de mosaico y agregar nuevos elementos:
Figura 6: Tarjeta de azulejos decorados.El mapa tal como está se genera únicamente para su presentación en el juego. Las fichas blancas indican espacios abiertos, y casi todas las demás fichas indican elementos de juego muy específicos, por ejemplo, un pasaje secreto a través de los arbustos (círculos verdes), "puertas en la espesura" (cuadrados verdes y rayas lilas) o lugares de desove para atar árboles (círculos rojos con letra s). La parte principal del nivel aún no está definida, y en esta etapa el generador asume que estas áreas deben llenarse para bloquear el movimiento del jugador.
Realiza esta tarea en varias capas: la capa inferior indica el nivel de altura y el tipo de superficie, la segunda agrega agua en ciertos lugares y la tercera capa agrega vegetación y otras decoraciones.
Figura 7: Tipos de superficie terrestre (hierba, barro y piedras)Figura 8: AguaFigura 9: Vegetación y otras decoraciones.Estas capas se agregan al archivo de datos de nivel final, al que se agregan algunos detalles más. El juego usa estos datos para colocar activos y construir el nivel tal como lo ves. Hay muchos trucos en esta etapa. Por ejemplo, puede notar que las fichas de tierra en la figura anterior tienen formas extrañas. Estos formularios se utilizan para crear "mosaicos" de tierra de tal manera que el jugador no se da cuenta de que los datos de origen eran un mapa de mosaicos. Hablaré sobre esto en la segunda parte del artículo.
Figura 10: Nivel listoAgregar juego
Hay muchos beneficios para este método de generación de nivel. La etapa de convertir un nivel en un gráfico es especialmente importante para simplificar el "razonamiento" sobre el juego al generador. En el ejemplo que se muestra arriba, no hicimos nada con él excepto para verificar que los objetivos de nivel se crean a cierta distancia de las entradas. Pero para otros niveles en estas etapas se realizan más tareas.
Tomemos, por ejemplo, un mapa de cuevas en un estilo de mazmorra más clásico (en comparación con el nivel del bosque del ejemplo anterior). El gráfico base de este nivel tiene solo una entrada y un par de nuevos tipos de puertas. Un par de ellos está cerrado (L): algunas puertas atrapan al jugador desde un lado (T), y verde oscuro llamo la "válvula": este tipo de puerta permite que el jugador vaya en una sola dirección.
Figura 11: Conteo base de la cuevaLa estructura de este nivel permite al generador crear una misión mucho más compleja. Por ejemplo, la única forma de llegar a este nivel es a través de una "válvula", lo que obliga al jugador a buscar otra salida. La llave para abrir la salida (abajo a la izquierda) se encuentra detrás del peligro en la esquina superior izquierda, y el objetivo se encuentra detrás de las puertas que atrapan al jugador. Un ejemplo de tal objetivo sería un pasaje que se derrumba detrás de un jugador. En general, esto crea una cueva que es interesante explorar por sí sola, pero Unexplored 2 también tiene la capacidad de agregar criaturas y eventos que se mezclan en el tiempo de ejecución.
Figura 12: Cerraduras y llaves agregadas a la cuevaUsando el proceso descrito anteriormente, el gráfico se utiliza para generar y completar un mapa de mosaico completamente detallado. La aplicación de varios parámetros que reflejan la naturaleza de la cueva de este nivel conduce a resultados muy variables con estructuras subterráneas destruidas (cuadrados azules marcados con la letra c) y amplios abismos con púas (círculos lilas):
Figura 13: Nivel de la cueva con todo detallePara resumir
Espero que tenga una idea general de cómo abordamos la generación de niveles en Unexplored 2. Este es un proceso complejo de múltiples etapas, sobre el cual planeo escribir más en el futuro cercano. Al menos ya te prometí escribir sobre la aplicación de la generación de mazmorras cíclicas. Pero puede decir mucho más, desde técnicas de narración generativa, líneas de representación y métodos de sombreado hasta el largo proceso de diseño que utilizamos para crear el sistema de suerte, así como otros aspectos.
Parte 2. De los azulejos a las curvas, o diviértete con los conteos de Voronoi
El generador de contenido inexplorado 2 genera mapas en mosaico. Un resultado típico se ve así:
Estas tarjetas de fichas se apilan unas encima de otras y utilizan diferentes fichas para indicar los tipos de superficie de la tierra (en este ejemplo, hierba o tierra), así como varias decoraciones. En este caso, hay varios arbustos (círculos verdes grandes), piedras (círculos negros), plantas (círculos verdes pequeños), flores (círculos blancos) y texturas decorativas (cuadrados grises). También hay fichas especiales que indican datos de juego, por ejemplo, puntos de generación marcados con la letra "s". Además, los mosaicos se pueden marcar con información adicional, por ejemplo, nivel de altura o subtipos especiales.
Los mapas de mosaico son una estructura de datos conveniente para los generadores. Pero al mismo tiempo, es bastante sencillo, y la grilla a menudo se nota en el juego. Sin embargo, después de cargar los datos en el juego y colocar los activos, el resultado se ve así:
Creo que escondimos las fichas bastante bien, y así es como lo conseguimos.
Magia Voronoi
El truco es que las fichas individuales corresponden a las celdas en el diagrama de Voronoi. Este diagrama se puede usar para generar formas mucho más naturales. El diagrama de Voronoi se crea sembrando el plano con puntos aleatorios y dividiéndolo en celdas de tal manera que cada punto del plano pertenezca a la celda correspondiente al punto de partida más cercano. En la generación de contenido procesal, los diagramas de Voronoi se pueden usar de varias maneras interesantes.
Un diagrama típico de Voronoi se crea a partir de una distribución aleatoria, pero bastante uniforme, de los puntos de generación, que se parece a esto:
En Unexplored 2 usamos un tipo diferente de distribución de puntos generadores. Primero, generamos un punto para cada mosaico. Por lo tanto, podemos estar seguros de que cada mosaico en el mapa de mosaicos corresponderá a una celda en el diagrama de Voronoi.
Si colocamos los puntos de generación en el medio de cada celda, obtenemos una cuadrícula recta que se ve exactamente como un mapa de mosaicos (para esta y otras imágenes a continuación, hice una versión de ajedrez en la que la mitad de los mosaicos se vuelven amarillos para que pueda mejorar un poco ver patrones):
La forma más fácil es mejorar el gráfico simplemente aleatorizando la posición de cada punto generador. Al mover puntos, vale la pena verificar que el punto no vaya más allá del mosaico original.
El resultado se parece a esto:
Ya mejor, pero muy ruidoso, y por lo tanto no se obtienen hermosas líneas sinuosas. La imagen se puede mejorar realizando "relajación" de los diagramas de Voronoi (esta es una técnica estándar para ellos, que no discutiré aquí). Pero siempre seguirá siendo un poco ruidoso, y es difícil predecir efectivamente las cifras en una escala que excede la escala de los mosaicos individuales.
Para resolver este problema, no solo necesitamos movernos al azar, sino abordarlo de manera más inteligente. Diferentes tipos de movimiento pueden tener un efecto muy diferente. Por ejemplo, cuando se usa el ruido Perlin, se obtienen interesantes cartas de fichas curvilíneas. O puede convertir toda la cuadrícula en mosaicos hexagonales simplemente moviendo cada segunda línea de los puntos de generación a la izquierda:
Hicimos un gran avance cuando comenzamos a mover los puntos de generación en ciertos patrones para crear esquinas redondeadas. La primera etapa de este proceso ya se está realizando dentro del generador de nivel. Se reconocen los ángulos entre los diferentes tipos de superficie de la tierra, y los mosaicos de las esquinas están marcados con diferentes figuras, lo que indica la forma en que se deforman para generar un entorno más hermoso:
En este caso, la diferencia en los niveles de elevación también hace que aparezcan ángulos en el mapa de mosaico. Es por eso que ve esquinas redondeadas adicionales en la hierba en la parte superior derecha e inferior izquierda, donde se generaron las pendientes.
El juego usa esta información para cambiar los puntos de generación del gráfico Voronoi. Cada esquina redondeada cambia la ubicación del punto de origen (ver imagen a continuación). Además, también cambia los puntos de generación de sus cuatro vecinos ortogonales. Este proceso es acumulativo; los puntos generadores pueden moverse varias veces si están cerca de varios ángulos. Sin embargo, después de procesar todos los desplazamientos, los puntos de generación son un poco aleatorios (aproximadamente el 10% del ancho del mosaico en cada dirección), y el desplazamiento final se limita a un máximo del 40% del ancho del mosaico.
El resultado ya está obteniendo una calidad bastante alta:
Pero aún no hemos terminado ...
Decorar sabiamente
La forma general ha mejorado, pero los bordes siguen siendo muy rectos y se ven algo irregulares. Ocultaremos esto colocando activos curvos en los bordes donde los colores difieren. Sin embargo, el truco real es que una curva a menudo se coloca en dos bordes, y sus ángulos relativos entre sí se utilizan para determinar la dirección de la curva.
El resultado se ve así:
A continuación, utilizamos recursos 3D para agregar recortes de textura:
Finalmente, agregamos otro activo para llenar el nivel. La ubicación de estos activos está determinada por los datos de nivel generados previamente y, en general, sigue principios simples. Utilizamos pequeños activos que rodean a los más grandes para crear transiciones naturales y hermosas. En particular, vale la pena señalar que se agregan piedras al pie de los acantilados, creando variabilidad y suavizando visualmente las pendientes verticales que son necesarias para el juego:
Variabilidad local
Los ángulos no son el único tipo de desplazamiento que utilizamos. En particular, queremos que los bordes sean más rectos junto a las estructuras artificiales (por ejemplo, las paredes destruidas que se muestran a continuación):
En nuestro sistema, este efecto es fácil de lograr. Simplemente agregamos otra regla de desplazamiento, que prohíbe el desplazamiento de azulejos con estructuras hechas por el hombre. El generador utiliza pequeños cuadrados para marcar esas fichas, y el juego garantiza que todos los desplazamientos simplemente se ignoren:
Si miras al suelo, puedes ver claramente que ciertas áreas están enderezadas, mientras que otras se doblan más naturalmente:
¿No es hermoso?
Existen otras reglas que se pueden agregar fácilmente con esta técnica. Por ejemplo, a veces forzamos a los mosaicos a crear un patrón hexagonal para que los caminos estrechos permanezcan lo suficientemente anchos como para moverse a su alrededor. Estoy seguro de que encontraremos otros usos para otros patrones.
Esta es una de las muchas razones por las que amo los diagramas de Voronoi. En otra ocasión, escribiré sobre cómo los usamos para generar y decorar mapas mundiales de Unexplored 2.