Génération de niveaux dans 2 inexplorés
Nous sommes très fiers du générateur de niveau de jeu Unexplored 2, c'est un programme qui répond à toutes les exigences modernes. Dans un article, je parlerai de la façon dont les niveaux de jeu sont créés.
Nous n'avons pas eu à réinventer la roue. Dans Unexplored 1, nous avons déjà créé des techniques qui ont grandement influencé le succès du premier jeu. Unexplored 2 vient de poursuivre ce qui a été commencé. Le fondement de notre technologie se compose de deux parties: nous utilisons la génération à plusieurs étapes, qui simule presque un processus très similaire au travail d'un concepteur de niveau vivant. De plus, nous utilisons une technique appelée «
génération de donjons cycliques », qui est bien meilleure pour générer des niveaux d'apparence naturelle que la plupart des applications de création de contenu génératif standard. Dans cet article, je parlerai du premier aspect. L'adaptation de la génération de donjons cycliques à Unexplored 2 fera l'objet d'un prochain billet.
Imitation de la conception au niveau «humain»
Le générateur de niveau décompose le processus de génération de niveau en un ensemble d'étapes contrôlées. Cela va de la planification de haut niveau à une carte détaillée de bas niveau. En fait, il crée d'abord une esquisse du niveau, puis commence à ajouter des détails jusqu'à ce que le niveau soit terminé et rempli.
À chaque étape individuelle de ce processus, nous utilisons des grammaires génératives pour transformer le niveau généré dans les étapes précédentes. En particulier, nous utilisons des grammaires de tuiles et des grammaires de graphes, qui sont des variétés de grammaires de chaînes plus générales qui recherchent et remplacent simplement des parties de chaînes par d'autres chaînes, tout comme les expressions régulières. Si vous n'êtes pas familier avec les concepts de grammaires génératives et d'expressions régulières, je vous recommande de rechercher des exemples sur Internet (ou simplement de continuer à lire - vous n'aurez pas besoin de connaissances approfondies pour comprendre la signification de ce message).
La première étape du niveau est relativement simple. Nous utilisons un bitmap basse résolution pour localiser les bases du niveau. Dans l'exemple ci-dessous, le niveau est initialement très simple: il se compose uniquement de l'entrée (e) à gauche, de l'entrée à droite et reliant le chemin direct. La plupart des autres tuiles sont soit indéfinies (u) ou bloquées (B) car elles sont sur les bords du niveau.
Figure 1: Un simple croquis du niveauÀ l'étape suivante, des détails sont ajoutés: un groupe de pièces apparaît, reliées par des portes, conçues pour passer dans une certaine direction:
Figure 2: Structure ajoutéeLes cartes de tuiles sont idéales pour créer une géométrie de niveau, mais il est plus pratique de travailler avec des graphiques pour générer des structures et une logique de jeu. C'est ce que le générateur fait ensuite:
Figure 3: Graphique de baseDans le graphique, certains nœuds contiennent des sous-nœuds, dans notre cas la plupart des portes sont marquées comme dangereuses (H), et certaines sont marquées comme ouvertes (O).
Sur la base d'une analyse assez simple et de règles génératives, de nouveaux éléments sont ajoutés au graphique. Par exemple, le point final (G) est situé à un endroit suffisamment éloigné des entrées. De plus, de petits dangers sont ajoutés au graphique pour rendre le niveau plus menaçant.
Figure 4: Nouveaux éléments ajoutés au graphique.
En attendant, une carte de tuiles basse résolution est convertie à l'aide de plusieurs fonctions de bruit en une carte de tuiles haute résolution pour lui donner un aspect plus naturel:
Figure 5: Carte de tuiles haute résolution
Ensuite, les informations du graphique sont utilisées pour décorer la carte des tuiles et ajouter de nouveaux éléments:
Figure 6: Carte de tuile décorée.La carte telle qu'elle est générée est uniquement destinée à être présentée dans le gameplay. Les tuiles blanches indiquent des espaces ouverts, et presque toutes les autres tuiles indiquent des éléments de jeu très spécifiques, par exemple, un passage secret à travers les buissons (cercles verts), des «portes dans les fourrés» (carrés verts et bandes lilas) ou des frayères pour attacher des arbres (cercles rouges avec lettre s). La partie principale du niveau n'est pas encore définie, et à ce stade, le générateur suppose que ces zones doivent être remplies de manière à bloquer le mouvement du joueur.
Il effectue cette tâche sur plusieurs couches: la couche inférieure indique le niveau de hauteur et le type de surface, la seconde ajoute de l'eau à certains endroits, et la troisième couche ajoute de la végétation et d'autres décorations.
Figure 7: Types de surfaces terrestres (herbe, boue et pierres)Figure 8: eauFigure 9: Végétation et autres décorationsCes couches sont ensuite ajoutées au fichier de données de niveau final, auquel des détails supplémentaires sont ajoutés. Le jeu utilise ces données pour placer des ressources et construire le niveau tel que vous le voyez. Il existe de nombreuses astuces à ce stade. Par exemple, vous remarquerez peut-être que les tuiles de terrain de la figure ci-dessus ont des formes étranges. Ces formulaires sont utilisés pour créer des «tuiles» au sol de telle manière que le joueur ne remarque pas que les données source étaient une carte de tuiles. J'en parlerai dans la deuxième partie de l'article.
Figure 10: Niveau prêtAjout de gameplay
Cette méthode de génération de niveau présente de nombreux avantages. L'étape de conversion d'un niveau en graphique est particulièrement importante afin de simplifier le «raisonnement» sur le gameplay au générateur. Dans l'exemple ci-dessus, nous n'avons rien fait d'autre que de vérifier que les cibles de niveau sont créées à une certaine distance des entrées. Mais pour d'autres niveaux à ces étapes, plus de tâches sont exécutées.
Prenez par exemple une carte de grotte dans un style de donjon plus classique (par rapport au niveau de la forêt de l'exemple ci-dessus). Le graphique de base de ce niveau n'a qu'une seule entrée et quelques nouveaux types de portes. Une paire d'entre eux est fermée (L): certaines portes emprisonnent le joueur d'un côté (T), et vert foncé j'appelle la "valve": ce type de porte permet au joueur d'aller dans une seule direction.
Figure 11: dénombrement de base de la grotteLa structure de ce niveau permet au générateur de créer une mission beaucoup plus complexe. Par exemple, la seule façon d'arriver à ce niveau est à travers une «valve», forçant le joueur à chercher une autre issue. La clé pour ouvrir la sortie (en bas à gauche) est située derrière le danger en haut à gauche, et la cible est située derrière les portes qui piègent le joueur. Un exemple d'un tel objectif serait un passage qui s'effondre derrière un joueur. En général, cela crée une grotte intéressante à explorer seule, mais Unexplored 2 a également la possibilité d'ajouter des créatures et des événements qui se fondent au moment de l'exécution.
Figure 12: Serrures et clés ajoutées à la grotteEn utilisant le processus décrit ci-dessus, le graphique est utilisé pour générer et remplir une carte de tuiles entièrement détaillée. L'application de divers paramètres reflétant la nature des grottes de ce niveau conduit à des résultats très variés avec des structures souterraines détruites (carrés bleus marqués de la lettre c) et de larges abysses à pointes (cercles lilas):
Figure 13: Niveau de la grotte en détailPour résumer
J'espère que vous avez une idée générale de la façon dont nous abordons la génération de niveaux dans Unexplored 2. Il s'agit d'un processus complexe en plusieurs étapes, sur lequel j'ai l'intention d'écrire plus dans un proche avenir. Au moins, je vous ai déjà promis d'écrire sur l'application de la génération de donjons cycliques. Mais vous pouvez en dire beaucoup plus, des techniques de narration génératives, des lignes de rendu et des méthodes d'ombrage au long processus de conception que nous avons utilisé pour créer le système de chance, ainsi que d'autres aspects.
Partie 2. Des tuiles aux courbes, ou du plaisir avec le nombre de Voronoi
Un générateur de contenu inexploré 2 génère des cartes de tuiles. Un résultat typique ressemble à ceci:
Ces cartes de tuiles sont empilées les unes sur les autres et utilisent différentes tuiles pour indiquer les types de surface de la terre (dans cet exemple l'herbe ou la saleté), ainsi que diverses décorations. Dans ce cas, il existe plusieurs buissons (grands cercles verts), pierres (cercles noirs), plantes (petits cercles verts), fleurs (cercles blancs) et textures décoratives (carrés gris). Il existe également des tuiles spéciales qui indiquent les données de jeu, par exemple, les points d'apparition marqués de la lettre «s». De plus, les tuiles peuvent être marquées avec des informations supplémentaires, par exemple, le niveau de hauteur ou des sous-types spéciaux.
Les cartes de tuiles sont une structure de données pratique pour les générateurs. Mais en même temps, c'est assez simple, et la grille est souvent perceptible dans le jeu. Cependant, après avoir chargé les données dans le jeu et placé les ressources, le résultat ressemble à ceci:
Je pense que nous avons assez bien caché les carreaux, et c'est ainsi que nous l'avons obtenu.
Voronoi Magic
L'astuce est que les tuiles individuelles correspondent aux cellules du diagramme de Voronoi. Ce diagramme peut être utilisé pour générer des formes d'aspect beaucoup plus naturel. Le diagramme de Voronoi est créé en semant l'avion avec des points aléatoires et en le divisant en cellules de telle sorte que chaque point de l'avion appartient à la cellule correspondant au point de départ le plus proche. Dans la génération de contenu procédural, les diagrammes de Voronoi peuvent être utilisés de plusieurs manières intéressantes.
Un diagramme de Voronoï typique est créé à partir d'une distribution aléatoire, mais assez uniforme des points générateurs, qui ressemble à ceci:
Dans Unexplored 2, nous utilisons un autre type de distribution des points générateurs. Tout d'abord, nous générons un point pour chaque tuile. Nous pouvons donc être sûrs que chaque tuile sur la carte de tuiles correspondra à une cellule du diagramme de Voronoi.
Si nous plaçons les points de génération au milieu de chaque cellule, nous obtenons une grille droite qui ressemble exactement à une carte de tuiles (pour cela et d'autres images ci-dessous, j'ai fait une version d'échecs dans laquelle la moitié des tuiles sont rendues jaunes afin que vous puissiez faire un peu mieux voir les modèles):
Le moyen le plus simple consiste à améliorer le graphique en randomisant simplement la position de chaque point de génération. Lors du déplacement de points, il convient de vérifier que le point ne dépasse pas la tuile d'origine.
Le résultat ressemble à ceci:
Déjà mieux, mais très bruyant, et n'obtiennent donc pas de belles lignes sinueuses. L'image peut être améliorée en effectuant la «relaxation» des diagrammes de Voronoi (c'est une technique standard pour eux, que je ne discuterai pas ici). Mais il restera toujours toujours un peu bruyant, et il est difficile de prédire efficacement les chiffres sur une échelle qui dépasse l'échelle des carreaux individuels.
Pour résoudre ce problème, nous devons non seulement nous déplacer de manière aléatoire, mais aussi l'aborder plus intelligemment. Différents types de mouvements peuvent avoir un effet très différent. Par exemple, lors de l'utilisation du bruit Perlin, des cartes de tuiles sinueuses intéressantes sont obtenues. Ou vous pouvez transformer la grille entière en tuiles hexagonales en déplaçant simplement toutes les deux lignes des points générateurs vers la gauche:
Nous avons fait une véritable percée lorsque nous avons commencé à déplacer les points de génération dans certains modèles pour créer des coins arrondis. La première étape de ce processus est déjà en cours à l'intérieur du générateur de niveau. Les angles entre les différents types de surface de la terre sont reconnus, et les tuiles d'angle sont marquées de différentes figures, indiquant la façon dont elles sont déformées pour générer un environnement plus beau:
Dans ce cas, la différence de niveaux d'élévation fait également apparaître des angles sur la carte des tuiles. C'est pourquoi vous voyez des coins arrondis supplémentaires dans l'herbe en haut à droite et en bas à gauche, où les pentes ont été générées.
Le jeu utilise ces informations pour décaler les points de génération du graphique Voronoi. Chaque coin arrondi décale l'emplacement du point d'origine (voir l'image ci-dessous). De plus, il déplace également les points de génération de ses quatre voisins orthogonaux. Ce processus est cumulatif; les points de génération peuvent se déplacer plusieurs fois s'ils sont proches de plusieurs angles. Cependant, après avoir traité tous les décalages, les points de génération sont un peu aléatoires (environ 10% de la largeur de la tuile dans chaque direction), et le décalage final est limité à un maximum de 40% de la largeur de la tuile.
Le résultat est déjà de très bonne qualité:
Mais nous n'avons pas encore fini ...
Décorez sagement
La forme générale est devenue meilleure, mais les bords sont toujours très droits et semblent un peu dentelés. Nous cacherons cela en plaçant des éléments courbes sur les bords où les couleurs diffèrent. Cependant, l'astuce réelle est qu'une courbe est souvent placée sur deux bords et que leurs angles les uns par rapport aux autres sont utilisés pour déterminer la direction de la courbe.
Le résultat ressemble à ceci:
Ensuite, nous avons utilisé des ressources 3D pour ajouter des coupures de texture:
Enfin, nous ajoutons un autre atout pour remplir le niveau. L'emplacement de ces actifs est déterminé par les données de niveau précédemment générées et suit généralement des principes simples. Nous utilisons de petits actifs entourant les plus grands pour créer des transitions naturelles et belles. En particulier, il convient de noter que des pierres sont ajoutées au pied des falaises, créant une variabilité et adoucissant visuellement les pentes verticales nécessaires au gameplay:
Variabilité locale
Les angles ne sont pas le seul type de déplacement que nous utilisons. En particulier, nous voulons que les bords soient plus droits à côté des structures artificielles (par exemple, les murs détruits illustrés ci-dessous):
Dans notre système, cet effet est facile à réaliser. Nous ajoutons simplement une autre règle de déplacement, qui interdit le déplacement de carreaux avec des structures artificielles. Le générateur utilise de petits carrés pour marquer ces tuiles, et le jeu garantit que tous les décalages sont simplement ignorés:
Si vous regardez le sol, vous pouvez clairement voir que certaines zones sont droites, tandis que d'autres se plient plus naturellement:
N'est-ce pas beau?
Il existe d'autres règles qui peuvent être facilement ajoutées à l'aide de cette technique. Par exemple, nous forçons parfois les carreaux à créer un motif hexagonal afin que les chemins étroits restent suffisamment larges pour se déplacer autour d'eux. Je suis sûr que nous trouverons d'autres utilisations pour d'autres modèles.
C'est l'une des nombreuses raisons pour lesquelles j'aime les diagrammes de Voronoi. Une autre fois, j'écrirai comment nous les utilisons pour générer et décorer 2 cartes du monde inexplorées.