Haben Sie Die Chroniken des Bernsteins von Roger Zelazny gelesen?
Stellen Sie sich vor, Sie spielen im 3rd Person MMO-Spiel. Du laichst in der Welt und fängst an herumzulaufen. Nach einiger Zeit, wenn Sie denken, dass Sie die Karte gelernt haben, stellen Sie fest, dass Sie sich an einem Ort befinden, den Sie noch nie zuvor gesehen haben. Sie kehren zu dem letzten Ort zurück, von dem Sie sicher waren, dass Sie ihn kennen und der immer noch dort ist. Aber der Rest der Welt hat sich verändert und Sie haben nicht einmal bemerkt, wie es passiert ist.
Ich habe über prozedurale Welterzeugung gelesen. Ich habe über Perlin-Rauschen und Oktaven, Simplex-Rauschen, Diamantquadrat-Algorithmus, Simulation von tektonischen Platten und Wassererosion gelesen. Ich glaube, ich habe ein vages Verständnis der allgemeinen Herangehensweise an die prozedurale Welterzeugung.
Und mit diesem Wissen habe ich keine Ahnung, wie man so etwas machen kann wie oben geschrieben. Jede Idee, die mir in den Sinn kommt, stößt auf einige theoretische Probleme. Hier sind einige Ideen, die mir einfallen:
1) "Reversible" Weltgeneration mit einer Startnummer als Eingabe und einer vollständig beschreibenden Blocknummer
Ich bezweifle, dass es überhaupt möglich ist, aber ich stelle mir eine Funktion vor, die einen Keim erhält und eine Zahlenmatrix erzeugt, auf der Brocken aufgebaut sind. Und für jede eindeutige Nummer gibt es einen eindeutigen Block. Und eine zweite Funktion, die diese eindeutige Chunk-Nummer erhält und einen Startwert erzeugt, der diese Nummer enthält. Ich habe versucht, ein Schema im Bild unten zu machen:
2) Brocken komplett zufällig machen und einen Übergang zwischen ihnen machen.
Wie Aracthor vorschlug. Der Vorteil dieses Ansatzes ist, dass es möglich ist und keine Magie erforderlich ist Vorteil Wirkung benötigt :)
Der Nachteil dieses Ansatzes ist meiner Meinung nach, dass es wahrscheinlich nicht möglich ist, eine vielfältige Welt zu haben. Wenn Sie sagen, dass sowohl der Archipel als auch ein Kontinent, der nur durch eine Zahl dargestellt wird, und die angrenzenden Abschnitte gleich sind, wäre die Größe eines Abschnitts nicht gleich dem Kontinent. Und ich bezweifle, dass es möglich ist, gut aussehende Übergänge zwischen Stücken zu machen. Vermisse ich etwas?
Mit anderen Worten, Sie entwickeln ein MMO mit prozedural generierter Welt. Aber anstatt eine Welt zu haben, hast du viele . Welchen Ansatz würdest du wählen, um Welten zu generieren, und wie würdest du den Übergang des Spielers von einer Welt zur anderen implementieren, ohne dass der Spieler den Übergang bemerkt.
Jedenfalls glaube ich, dass Sie die allgemeine Idee haben. Wie hättest du das gemacht?
quelle
Antworten:
Verwenden Sie ein Stück Rauschen höherer Ordnung. Wenn Sie zuvor 2D-Rauschen für eine Höhenkarte verwendet haben, verwenden Sie stattdessen 3D-Rauschen mit fester letzter Koordinate. Jetzt können Sie die Position in der letzten Dimension langsam ändern, um das Gelände zu ändern. Da Perlin-Rauschen in allen Dimensionen kontinuierlich ist, erhalten Sie weiche Übergänge, solange Sie die Position ändern, an der Sie die Rauschfunktion abtasten.
Wenn Sie zum Beispiel nur das vom Abstand zum Spieler entfernte Gelände als Versatz ändern möchten. Sie können auch den Versatz für jede Koordinate auf der Karte speichern und ihn nur erhöhen, aber niemals verringern. Auf diese Weise wird die Karte nur neuer, aber niemals älter.
Diese Idee funktioniert auch, wenn Sie bereits 3D-Rauschen verwenden. Dann probieren Sie einfach 4D aus. Schauen Sie sich auch das Simplex-Rauschen an. Es ist die verbesserte Version von Perlin Noise und funktioniert besser für mehr Dimensionen.
quelle
Ihre Idee, die Welt in mehrere Teile aufzuteilen, ist nicht schlecht. Es ist einfach unvollständig.
Das einzige Problem sind Verbindungsstellen zwischen Stücken. Wenn Sie beispielsweise Perlin-Rauschen verwenden, um Entlastung zu erzeugen, und für jeden Block einen anderen Startwert festlegen, und dies riskieren, geschieht Folgendes:
Eine Lösung wäre, nicht nur aus dem Perlin-Rausch-Samen, sondern auch aus anderen Brocken um ihn herum eine Brockenentlastung zu erzeugen.
Perlin-Algorithmus verwendet zufällige Kartenwerte, um sich selbst zu "glätten". Wenn sie eine gemeinsame Karte verwenden, würde es zusammen geglättet.
Das einzige Problem ist, wenn Sie einen Chunk-Samen ändern, um ihn zu ändern, wenn der Spieler zurücktritt, müssen Sie auch Chunks neu laden, da sich auch deren Ränder ändern sollten.
Dies würde die Größe der Chunks nicht ändern, aber den minimalen Abstand vom Player zum Laden / Entladen vergrößern, da ein Chunk geladen werden muss, wenn der Player dies sieht, und bei dieser Methode auch benachbarte Chunks .
AKTUALISIEREN:
Wenn jeder Teil Ihrer Welt von einem anderen Typ ist, wächst das Problem. Hier geht es nicht nur um Erleichterung. Eine kostspielige Lösung wäre:
Nehmen wir an, grüne Brocken sind Waldwelten, blaue Archipele und gelbe flache Wüsten.
Die Lösung besteht darin, "Übergangszonen" zu schaffen, in denen sich Ihr Relief und Ihre Bodennatur (sowie geerdete Objekte oder alles andere, was Sie wollen) nach und nach von einem Typ zum anderen wandeln.
Und wie Sie auf diesem Bild sehen können, wären kleine Quadrate in den Ecken der Blöcke der Hölle zu codieren: Sie müssen eine Verbindung zwischen 4 Blöcken herstellen, möglicherweise unterschiedlicher Natur.
Ich denke, für diese Komplexitätsstufe können klassische Generationen der 2D-Welt wie Perlin2D einfach nicht verwendet werden. Ich verweise Sie auf @ Danijar Antwort dafür.
quelle
Während die Idee von danijar ziemlich solide ist, könnten Sie am Ende eine Menge Daten speichern, wenn Sie möchten, dass der lokale Bereich und die Entfernung gleich sind. Und fordern immer mehr Scheiben von immer komplexerem Lärm. Sie können all dies auf eine standardmäßige 2D-Art und Weise erhalten.
Ich entwickelte einen Algorithmus zur prozeduralen Erzeugung von zufälligem fraktalem Rauschen, der teilweise auf dem Algorithmus des Diamantquadrats basierte , den ich als unendlich und deterministisch festlegte. Diamantquadrat kann also eine unendliche Landschaft erzeugen, ebenso wie mein eigener ziemlich blockartiger Algorithmus.
Die Idee ist im Grunde die gleiche. Anstatt jedoch höherdimensionales Rauschen abzutasten, können Sie Werte auf verschiedenen iterativen Ebenen iterieren.
Sie speichern also immer noch die Werte, die Sie zuvor angefordert haben, und speichern sie im Cache (dieses Schema kann unabhängig verwendet werden, um einen bereits superschnellen Algorithmus zu beschleunigen). Und wenn ein neuer Bereich angefordert wird, wird er mit einem neuen y-Wert erstellt. und jeder Bereich, der in dieser Anforderung nicht angefordert wurde, wird entfernt.
Also anstatt durch andere Räume in zusätzlichen Dimensionen zu blättern. Wir speichern ein zusätzliches Stück monotoner Daten, um sie in verschiedenen (zunehmend größeren Mengen auf verschiedenen Ebenen) zu mischen.
Wenn der Benutzer in eine Richtung fährt, werden die Werte entsprechend verschoben (und auf jeder Ebene) und neue Werte an den neuen Kanten generiert. Wenn der top iterative Startwert geändert wird, verschiebt sich die gesamte Welt drastisch. Wenn die abschließende Iteration ein anderes Ergebnis liefert, ist der Änderungsbetrag sehr gering, etwa + -1 Block. Aber der Hügel wird immer noch da sein und das Tal usw., aber die Ecken und Winkel werden sich verändert haben. Es sei denn, Sie gehen weit genug, und dann wird der Hügel verschwunden sein.
Wenn wir also 100x100 Chunk-Werte pro Iteration gespeichert haben. Dann könnte sich beim 100x100 vom Player nichts ändern. Bei 200x200 können sich die Dinge jedoch um einen Block ändern. Bei 400x400 könnten sich die Dinge um 2 Blöcke ändern. Bei einer Entfernung von 800x800 können sich die Dinge um 4 Blöcke ändern. Also werden sich die Dinge ändern und sie werden sich immer mehr ändern, je weiter Sie gehen. Wenn du zurückgehst, werden sie anders sein, wenn du zu weit gehst, werden sie komplett verändert und gehen komplett verloren, da alle Samen aufgegeben würden.
Eine andere Dimension hinzuzufügen, um diesen stabilisierenden Effekt zu erzielen, würde sicherlich funktionieren und das y in der Ferne verschieben, aber Sie würden eine Menge Daten für sehr viele Blöcke speichern, wenn Sie dies nicht müssten. In deterministischen Algorithmen für fraktales Rauschen können Sie denselben Effekt erzielen, indem Sie einen sich ändernden Wert (mit einem anderen Betrag) hinzufügen, wenn sich die Position über einen bestimmten Punkt hinaus bewegt.
https://jsfiddle.net/rkdzau7o/
quelle