Avez-vous lu The Chronicles of Amber de Roger Zelazny?
Imaginez-vous jouer dans un jeu MMO à la 3ème personne. Vous apparaissez dans le monde et commencez à vous promener. Après un certain temps, quand vous pensez que vous avez appris la carte, vous vous rendez compte que vous êtes dans un endroit que vous n'avez jamais vu auparavant. Vous revenez au dernier endroit que vous étiez sûr de connaître et il est toujours là. Mais le reste du monde a changé et vous n'avez même pas remarqué comment cela s'est produit.
J'ai lu sur la génération du monde procédural. J'ai lu sur le bruit Perlin et les octaves, le bruit Simplex, l'algorithme Diamond-square, la simulation des plaques tectoniques et l'érosion hydrique. Je crois avoir une vague compréhension de l'approche générale dans la génération du monde procédural.
Et avec cette connaissance, je n'ai aucune idée de comment pouvez-vous faire quelque chose comme écrit ci-dessus. Chaque idée qui me vient à l'esprit rencontre des problèmes théoriques. Voici quelques idées auxquelles je peux penser:
1) Génération mondiale "réversible" avec un numéro de départ comme entrée et un certain nombre de description complète
Je doute que ce soit même possible, mais j'imagine une fonction, qui recevra une graine et produira une matrice de nombres, sur laquelle des blocs sont construits. Et pour chaque numéro unique, il y a un morceau unique. Et une deuxième fonction, qui obtient ce numéro de bloc unique et produit une graine, qui contient ce numéro. J'ai essayé de faire un schéma dans l'image ci-dessous:
2) Faire des morceaux complètement aléatoires et faire une transition entre eux.
Comme l'a suggéré Aracthor . Les avantages de cette approche sont qu'elle est possible et ne nécessite pas de fonction magique :)
Les inconvénients de cette approche à mon avis, c'est qu'il n'est probablement pas possible d'avoir un monde diversifié. Si vous avez disons à la fois l'archipel et un continent représenté par un seul numéro et ses morceaux adjacents, la taille d'un morceau ne serait-elle pas égale au continent. Et je doute qu'il soit possible de faire une belle transition entre des morceaux. Suis-je en train de manquer quelque chose?
Donc, en d'autres termes, vous développez un MMO avec un monde généré de manière procédurale. Mais au lieu d'avoir un monde, vous en avez plusieurs . Quelle approche adopteriez-vous pour générer des mondes et comment mettriez-vous en œuvre la transition du joueur d'un monde à l'autre sans que le joueur ne remarque la transition.
Quoi qu'il en soit, je crois que vous avez l'idée générale. Comment l'auriez-vous fait?
la source
Réponses:
Utilisez une tranche de bruit d'ordre supérieur. Si vous avez déjà utilisé du bruit 2D pour une carte de hauteur, utilisez plutôt du bruit 3D avec la dernière coordonnée fixe. Vous pouvez maintenant changer lentement la position dans la dernière dimension pour modifier le terrain. Étant donné que le bruit Perlin est continu dans toutes les dimensions, vous obtiendrez des transitions fluides tant que vous modifiez en douceur la position où vous échantillonnez la fonction de bruit.
Si vous souhaitez uniquement modifier le terrain loin de la distance par rapport au joueur comme décalage par exemple. Vous pouvez également stocker le décalage pour chaque coordonnée sur la carte et seulement l'augmenter mais jamais le diminuer. De cette façon, la carte ne devient plus récente mais jamais plus ancienne.
Cette idée fonctionne également si vous utilisez déjà du bruit 3D, il vous suffit alors d'échantillonner à partir de 4D. Jetez également un œil au bruit Simplex. C'est la version améliorée du bruit Perlin et fonctionne mieux pour plus de dimensions.
la source
Votre idée de diviser le monde en plusieurs morceaux n'est pas mauvaise. C'est juste incomplet.
Le seul problème est les jonctions entre les morceaux. Par exemple, si vous utilisez du bruit perlin pour générer du relief et une graine différente pour chaque morceau, et risquez que cela se produise:
Une solution serait de générer un soulagement des morceaux non seulement à partir de sa source de bruit Perlin, mais aussi à partir d'autres morceaux autour de lui.
L'algorithme Perlin utilise des valeurs de carte aléatoire autour d'eux pour se "lisser". S'ils utilisent une carte commune, ils seraient lissés ensemble.
Le seul problème est que si vous changez une graine de morceau pour la rendre différente lorsque le joueur recule, vous devrez également recharger des morceaux, car leurs bordures devraient également changer.
Cela ne changerait pas la taille des morceaux, mais cela augmenterait la distance minimale entre le lecteur et le chargement / déchargement, car un morceau doit être chargé lorsque le joueur le voit, et, avec cette méthode, comme les morceaux adjacents doivent l'être aussi .
MISE À JOUR:
Si chaque morceau de votre monde est d'un type différent, le problème augmente. Il ne s'agit pas seulement de soulagement. Une solution coûteuse serait la suivante:
Supposons que des morceaux verts soient des mondes forestiers, des archipels bleus et des déserts plats jaunes.
La solution ici est de créer des zones de «transition», où votre relief et votre nature au sol (ainsi que les objets mis à la terre ou tout ce que vous voulez) passeraient progressivement d'un type à un autre.
Et comme vous pouvez le voir sur cette image, l'enfer à coder serait de petits carrés dans les coins de morceaux: ils doivent faire un lien entre 4 morceaux, de natures potentiellement différentes.
Donc, pour ce niveau de complexité, je pense que les générations classiques du monde 2D comme Perlin2D ne peuvent tout simplement pas être utilisées. Je vous renvoie à la réponse @danijar pour cela.
la source
Bien que l'idée de danijar soit assez solide, vous pourriez finir par stocker beaucoup de données, si vous vouliez avoir la même zone locale et le décalage de distance. Et demander de plus en plus de tranches de bruit de plus en plus complexes. Vous pouvez obtenir tous ces éléments d'une manière 2d plus standard.
J'ai développé un algorithme pour générer de manière procédurale du bruit fractal aléatoire, en partie basé sur l'algorithme carré de diamant que j'ai fixé pour être à la fois infini et déterministe. Donc, le carré de diamant peut créer un paysage infini, ainsi que mon propre algorithme assez bloc.
L'idée est fondamentalement la même. Mais, plutôt que d'échantillonner un bruit de dimension supérieure, vous pouvez itérer des valeurs à différents niveaux itératifs.
Ainsi, vous conservez toujours les valeurs que vous avez demandées auparavant et vous les mettez en cache (ce schéma pourrait indépendamment être utilisé pour accélérer un algorithme déjà super rapide). Et lorsqu'une nouvelle zone est demandée, elle est créée avec une nouvelle valeur y. et toute zone non demandée dans cette demande est supprimée.
Donc, plutôt que de parcourir différents espaces dans des dimensions supplémentaires. Nous stockons un bit supplémentaire de données monotones à mélanger dans différents (à des quantités progressivement plus grandes à différents niveaux).
Si l'utilisateur se déplace dans une direction, les valeurs sont déplacées en conséquence (et à chaque niveau) et de nouvelles valeurs sont générées aux nouveaux bords. Si la graine itérative supérieure est modifiée, le monde entier sera radicalement changé. Si l'itération finale obtient un résultat différent, alors le montant de la modification sera très mineur + -1 bloc environ. Mais, la colline sera toujours là et la vallée, etc., mais les coins et recoins auront changé. À moins que vous n'alliez assez loin, la colline disparaîtra.
Donc, si nous avons stocké 100 x 100 morceaux de valeurs à chaque itération. Ensuite, rien ne pouvait changer à 100x100 du joueur. Mais, à 200x200, les choses pourraient changer d'un bloc. À 400x400, les choses pourraient changer de 2 blocs. À 800x800 de distance, les choses pourront changer de 4 blocs. Les choses vont donc changer et elles changeront de plus en plus à mesure que vous avancerez. Si vous revenez en arrière, elles seront différentes, si vous allez trop loin, elles seront complètement modifiées et complètement perdues car toutes les graines seront abandonnées.
L'ajout d'une dimension différente pour fournir cet effet de stabilisation fonctionnerait certainement, en décalant le y à distance, mais vous stockeriez beaucoup de données pour un grand nombre de blocs lorsque vous ne devriez pas avoir à le faire. Dans les algorithmes déterministes de bruit fractal, vous pouvez obtenir ce même effet en ajoutant une valeur changeante (à un montant différent) lorsque la position se déplace au-delà d'un certain point.
https://jsfiddle.net/rkdzau7o/
la source