Was ist die am besten geeignete Lösung für die Wegfindung für eine sehr große prozedural generierte Umgebung?

7

Ich habe ziemlich viel gelesen, um die folgende Wahl zu treffen: Welche Wegfindungslösung sollte man in einem Spiel implementieren, in dem die Welt prozedural generiert wurde, von wirklich großen Dimensionen?

So sehe ich die Hauptlösungen und ihre Vor- und Nachteile:

1) Gitterbasierte Pfadfindung - Dies ist die einzige Option, für die keine Vorverarbeitung erforderlich wäre, was gut passt. Mit der Erweiterung der Welt wächst der verwendete Speicher jedoch exponentiell auf ein wahnsinniges Niveau. Dies kann in Form von Verarbeitungspfaden durch Lösungen wie den Block A * - oder Subgoal A * -Algorithmen erfolgen. Die Speichernutzung ist jedoch das schwer zu umgehende Problem.

2) navmesh - dies wäre aufgrund seiner Präzision, schnellen Pfadberechnung und geringen Speichernutzung sehr schön. Es kann jedoch eine obszöne Vorverarbeitungszeit dauern.

3) Sichtbarkeitsdiagramm - Diese Option benötigt auch eine hohe Vorverarbeitungszeit, obwohl sie durch die Verwendung schneller Vorverarbeitungsalgorithmen verringert werden kann. Dann ist die Pfadberechnung im Allgemeinen auch schnell. Die Speichernutzung kann jedoch je nach Konfiguration der prozeduralen Welt noch verrückter als gitterbasiert werden.

Was wäre also der beste Ansatz (andere, die nicht in dieser Liste aufgeführt sind, sind ebenfalls willkommen) für eine solche Situation? Gibt es Techniken oder Tricks, mit denen prozedurale unendliche Welten gehandhabt werden können?

Vorschläge, Ideen und Referenzen sind willkommen.

BEARBEITEN:

Um mehr Details zu geben, sollte man die Anwendung, von der ich spreche, als eine sehr sehr große Büroebene betrachten, in der Räume prodecuraly generiert werden. Der Algorithmus funktioniert wie folgt. Zunächst werden Räume platziert. Als nächstes Wände. Dann die Türen und später die Möbel / Hindernisse, die in jedem Raum gehen. Die Umgebung kann also sehr groß werden und viele Objekte enthalten, da neue Räume entstehen, sobald sich die Spieler der Grenze des bereits erzeugten Bereichs nähern. Dies bedeutet, dass es keine großen offenen Flächen ohne Hindernisse geben wird.

Andy Astro
quelle
5
Könnten Sie Ihre Bedürfnisse weiter beschreiben? Diese können je nach Spiel und Art der prozeduralen Generierung geeignet sein.
Anko
Sind die Grenzen Ihrer begehbaren Funktionen gitterorientiert oder handelt es sich um eine offene Welt usw.?
Steven
Es gibt auch eine Quadtree-basierte Pfadfindung, die irgendwo zwischen Grid- und Navmesh-Ansätzen liegt. Es sollte sowohl für Outdoor-Welten als auch für Dungeon-Welten funktionieren (Sie geben nicht an, welche Sie möchten oder beides). Um auf die Idee zu kommen: youtube.com/watch?v=sn6P7xCTvvc
Igor S.
Vielen Dank für Ihre Nachrichten, Anko und @Steven. Stellen Sie sich das bitte als ein prozedural erzeugtes gigantisches Büro vor, mit vielen Räumen und Objekten in der Mitte des Weges. Es ist also nicht so, dass ich große Freiflächen ohne Hindernisse habe. Außerdem ist es bisher nicht gitterbasiert (ich könnte es nur aus Gründen der Wegfindung machen, und das ist Teil meines Zweifels).
Andy Astro
1
Sie werden nicht alle Ihre Navigationsdiagramme im Speicher behalten. Das wäre völlig unlogisch, wenn zu einem bestimmten Zeitpunkt tatsächlich nur ein bestimmter Bereich im Speicher vorhanden wäre. Wenn Sie durch die ganze Welt navigieren müssen, möchten Sie ein mehrstufiges Adjazenzdiagramm speichern. Welche Bereiche mit welchen Bereichen verbunden sind, stellen Sie diese Bereiche in die Warteschlange. Dann navigieren Sie für den aktuellen Bereich, in dem sich Ihr Charakter befindet, durch diesen zu den Kanten, die mit dem nächsten Bereich verbunden sind. Dann das nächste und so weiter, bis das Ziel erreicht ist.
MondscheinTheleocat

Antworten:

3

Angesichts der Tatsache, dass die Räume prozedural gebaut, Portale erstellt und dann gefüllt werden, habe ich einige Ideen.

A * funktioniert sehr gut in Navigationsnetzen und auch hierarchisch. Ich würde in Betracht ziehen, ein Wegfindungssystem aufzubauen, das auf zwei Ebenen funktioniert - erstens Raum für Raumebene und zweitens in jedem Raum von Portal zu Portal. Ich denke, Sie können dies während der Generierung zu einem erschwinglichen Preis tun. Sie müssen erst dann von Raum zu Raum gehen, wenn Sie ihn betreten. Daher ist er für Speicher- / CPU-Kosten sehr erschwinglich.

High Level A * kann durch Erstellen eines Diagramms für jedes Portal und jeden Raum erstellt werden - ein Raum ist der Knoten und der 'Pfad' oder Rand ist das Portal zu einem anderen Raum. Die Kosten für die Durchquerung haben einige Optionen - sie können beispielsweise vom Mittelpunkt des Raums zum Mittelpunkt des anderen Raums reichen. Oder Sie möchten bestimmte Kanten von Portal zu Portal mit realen Entfernungen erstellen, was meiner Meinung nach nützlicher ist. Auf diese Weise können Sie die Pfadfindung auf hoher Ebene von Raum A nach Raum B durchführen. Türen können geöffnet und geschlossen werden, wodurch bestimmte Pfade aktiviert oder deaktiviert werden. Dies ist für bestimmte Spieltypen hilfreich. Da es raum- / portalbasiert ist, sollte es ziemlich einfach und erschwinglich zu berechnen sein - nur Entfernungsberechnungen und Grafikbuchhaltung.

Der schwierigere Teil ist das niedrige Level A *, da es sich um ein polygonales Navigationsnetz handeln sollte. Wenn jeder Raum quadratisch ist, können Sie mit einem Polygon beginnen. Wenn Sie Hindernisse platzieren, subtrahieren Sie den belegten Bereich vom Polygon und machen Sie Löcher darin. Wenn alles fertig ist, möchten Sie es wieder in Dreiecke zerlegen und das Diagramm aufbauen. Ich denke nicht, dass das so langsam ist, wie du denkst. Der schwierige Teil besteht darin, das Schneiden von Polygonlöchern durchzuführen, was eine gute Menge an Buchhaltung für solche Dinge erfordert, aber es ist gut dokumentiert in Strukturen mit halben Kanten und etablierten Grafikbüchern für die Informatik. Sie können diese Generation auch träge in einem Hintergrunddiagramm ausführen, da Sie die A * -Ergebnisse dieses Levels erst dann benötigen, wenn sich jemand im Raum befindet. Das High-Level kümmert sich für Sie um die grundlegende Pfadplanung.

Ich weiß, dass ich die Erzeugung von Navigationsnetzen auf niedriger Ebene beschönigt habe, aber ich denke, es ist eines der Dinge, die Sie sich vorgenommen und gelöst haben, und dann ist es geschafft. Es gibt eine Reihe von Bibliotheken wie CGAL ( http://www.cgal.org ) und andere, die dieses Zeug können, aber um es wirklich schnell zum Laufen zu bringen, müssen Sie es möglicherweise selbst schreiben, damit Sie nur die Dinge haben, die Sie haben brauchen.

Alternativ können Sie jeden Raum zu einem Raster machen, und die Hindernisse füllen Teile des Rasters aus, und dann alle Standard-Rasterglättungsalgorithmen ausführen, aber ich mag Navmesh-Daten, da sie klein und schnell sind.

Hoffe das macht Sinn.

Steven
quelle
Vielen Dank für die aufschlussreiche Antwort! Ihre Denkweise ähnelt der, die ich bisher gemacht habe. Ich habe genau mit Hierarchien gearbeitet. Ich habe genau ein Diagramm erstellt, in dem Räume die Punkte sind. Als erstes muss der Weg durch Räume berechnet werden. Dann sucht die Wegfindung im Raum nach der Tür dieses Raumes und das wars. Ich habe genau das getan, indem ich dafür gesorgt habe, dass in jedem Raum ein eigenes Raster in einem Array-Objekt gespeichert ist und Hindernisse die Zellen füllen, die sie berühren. Meine Befragung begann genau deshalb, weil mir klar wurde, dass die Daten im Speicher riesig werden würden, sobald die Welt wächst (...)
Andy Astro
(...). Ein Raum mit 30x10 hat 300 Zellen. Aber tausend Zimmer wachsen auf 300.000 und so weiter. Wenn ich also Ihren Vorschlag auf niedriger Ebene richtig verstehe, würde ich für jeden Raum ein Navmesh generieren, damit die CPU nicht zu teuer wird, da viel weniger Hindernisse (also Eckpunkte) zu bewältigen sind. Dies ist sinnvoll und wurde gerade implementiert, jedoch mit Sichtbarkeitsdiagrammen anstelle von Navmesh. Während Navmeshes viel weniger Speicherplatz benötigen als Visgraphen, glauben Sie, dass ihre Vorverarbeitung in diesem ganzen Fall mit der Vorverarbeitung von Visgraphen konkurrieren kann?
Andy Astro
1
Übrigens, lassen Sie mich nur anerkennen, dass Sie mir, während ich bereits in Bezug auf die höhere Ebene wie Sie dachte, eine herausragende Idee gegeben haben, die ebenso mächtig wie einfach ist: Die Tür zu den Knotenpunkten des übergeordneten Graphen anstelle der Räume zu machen . Hervorragend.
Andy Astro
1
Richtig - Sie würden für jeden Raum ein Navmesh generieren. Müssen Sie für das Grid-Problem alle vorab generieren oder können Sie sie nach Bedarf generieren - oder gerade rechtzeitig, wenn sich der Spieler nähert? 300k Gitter erscheinen mir nicht zu groß - oder? Welche Plattform bearbeiten Sie? Ein Soundpuffer oder eine größere Textur blasen diese Grenze auf. Warum sollten Sie sich also darum kümmern? Wenn Gitter funktionieren, verwenden Sie sie. Sie können damit beginnen und das Navmesh bei Bedarf später erneut generieren.
Steven
Hallo @Steven, danke für den Kommentar. Ich hatte endlich die Zeit, das zu testen, und ich werde in der Tat das Navmesh pro Raum ausprobieren müssen. Die Speichernutzung kann nach einiger Zeit, in der die Anwendung ausgeführt wird, weit über 300 KB ansteigen, und mit dem Navmesh könnte ich sie wahrscheinlich drastisch reduzieren. Wie Sie bereits erwähnt haben, sollte die Verarbeitung von Navigationsnetzen pro Raum nicht zu langsam sein, da die Räume in Bezug auf Hindernisse nicht sehr detailliert sind. Außerdem muss ich mich nicht mit Bodenneigungen oder Höhenkarten befassen, da diese konstant sind. Würden Sie in einem solchen Szenario einen Navmesh-Algorithmus vorschlagen?
Andy Astro
4

Ich werde einen Stich machen und einen hierarchischen Pfadfindungsalgorithmus wie HPA * empfehlen . Obwohl ich kein Experte für KI bin, bin ich ziemlich zuversichtlich, da Ihr Generator fast identisch mit dem in einem Spiel klingt, an dem ich arbeite , dh ich habe auch ein bisschen über dieses Problem nachgedacht.

HPA * (Hierarchical Path-Finding A *) ist eine Methode zur Optimierung von regulärem A *, indem zuerst die Karte in Bereiche gruppiert wird, die miteinander verbunden sind, und dann ein Diagramm dieser Cluster auf hoher Ebene erstellt wird. Bei der Pfadfindung wird A * (oder ein beliebiger Pfadfindungsalgorithmus) im übergeordneten Diagramm und dann in jedem der Cluster ausgeführt, die den besten übergeordneten Pfad bilden. Anscheinend wird es häufig in RTS-Spielen verwendet, in denen viele Einheiten in Echtzeit über eindeutige Pfade über eine große Karte navigieren müssen. Dies sollte Ihnen eine Vorstellung davon geben, wie effizient diese Methode ist.

Hier ist ein Bild von ihrem Papier; Das linke sind die Cluster mit Verbindungsknoten, und das rechte ist das übergeordnete Diagramm:

HPA *

Zum Glück für Ihren Generator ist er aufgrund der von Ihnen platzierten Räume sehr gut für diesen Algorithmus geeignet: Dadurch erhalten Sie die Hälfte des Clusters kostenlos. Ihr übergeordnetes Diagramm besteht im Wesentlichen aus allen Türen Ihrer Räume. Was HPA * für Sie bedeutet, ist: Finden Sie die Reihe von Räumen / Türen, durch die ich gehen muss, und wie Sie durch jeden Raum in dieser Reihenfolge navigieren.

Noch ein paar nette Dinge über diesen Algorithmus:

  • A * ist langsam, da es den vollständigen Pfad finden muss, bevor Ergebnisse zurückgegeben werden. Mit HPA * können Sie den übergeordneten Pfad sowie den Pfad für den ersten Raum finden, sodass Sie ihm sofort folgen und die Pfade für den Rest der Räume später verschieben können. Dadurch reagiert der Algorithmus.
  • Sie können die Pfadfindungsergebnisse zwischen Türpaaren für jeden Raum zwischenspeichern, da Pfade, die in diesem Raum verlaufen, aber nicht beginnen oder enden, garantiert einem solchen Pfad folgen.
  • Sie können mehrere Ebenen in dieser Hierarchie haben, obwohl dies nur für wirklich gigantische Karten nützlich ist.

Beachten Sie, dass HPA * nahezu optimal ist. Sie können leicht erkennen, warum, wenn Sie sich einen Raum mit so vielen Hindernissen vorstellen, dass es lange dauert, ihn zu überwinden. Aus dem gleichen Grund sollten Sie darauf achten, ob ein Raum über genügend Hindernisse verfügt, um ihn effektiv zu unterteilen. Behandeln Sie diesen Raum im übergeordneten Diagramm nicht als einzelnen Cluster.

Für einige andere mögliche Algorithmen können Sie diese Frage in cstheory.SE ausprobieren , in der eine Tonne davon aufgelistet ist.

Congusbongus
quelle
Danke vielmals! Das ist eine großartige Antwort. Wie ich in der anderen Antwort zu Steven kommentiert habe, kommt das dem, was ich versucht habe, sehr nahe. Ich habe jeden Raum genau als eine der "großen Zellen" der Hierarchie benutzt. Aber Ihre Antwort hat mir geholfen, diesen hochrangigen Teil effizienter zu betrachten. Vielen Dank. Nun, für den Low-Level-Teil (innerhalb von Räumen) würde diese Lösung mich nicht immer noch mit einer enormen Speicherauslastung belassen, da ohnehin alle Zellen im Speicher gespeichert werden müssen, die Teil des Innenraums der Räume sind (dh auf dem niedrigen Niveau)? Ich denke, das ist ein faires Problem, wenn die Anzahl der Zimmer zunimmt
Andy Astro
Übrigens habe ich mich sehr für Ihr Projekt interessiert. Ich werde mir die anderen Beiträge, die Sie in der Vergangenheit dort veröffentlicht haben, genauer ansehen und nachlesen, was Sie getan und besprochen haben. Vielen Dank für das Teilen.
Andy Astro
@AndyAstro lässt sich durch das Diagramm nicht irreführen, es zeigt nur eine mögliche Implementierung basierend auf einer Rasterdarstellung, aber Sie können dies genauso gut mit navmesh tun, das in größeren Räumen effizienter wäre als ein Raster. Bei der Pfadfindung ist jedoch normalerweise die Rechenzeit das größere Problem, nicht der Speicher. Die Speichernutzung ist proportional zur Kartengröße, aber Sie möchten eine effiziente Pfadfindung, bei der dieser hierarchische Ansatz hilfreich ist.
Congusbongus