Ladezeit vor dem Spiel vs. Ladezeit im Spiel

9

Ich entwickle ein Spiel, in dem ein zufälliges Labyrinth enthalten ist.
Es gibt einige KI-Kreaturen, die im Labyrinth lauern. Und ich möchte, dass sie einen Weg gehen, der der Form der Labyrinthe entspricht.

Jetzt gibt es zwei Möglichkeiten für mich, dies umzusetzen. Der erste Weg (den ich verwendet habe) besteht darin, mehrere gewünschte Lauernpfade zu berechnen, sobald das Labyrinth erstellt ist.
Die zweite Möglichkeit besteht darin, einen Pfad zu berechnen, der einmal berechnet werden musste, wenn eine Kreatur anfängt, ihn zu lauern.

Mein Hauptanliegen sind Ladezeiten. Wenn ich beim Erstellen des Labyrinths viele Pfade berechne, ist die Vorladezeit etwas lang, daher habe ich darüber nachgedacht, sie bei Bedarf zu berechnen.
Im Moment ist das Spiel nicht "schwer", so dass das Berechnen von Pfaden in der Mitte des Spiels nicht auffällt, aber ich fürchte, es wird, sobald es komplizierter wird.

Vorschläge, Kommentare und Meinungen sind hilfreich.

Bearbeiten:

Sei es pjetzt die Anzahl der vorberechneten Pfade, eine Kreatur hat die Wahrscheinlichkeit 1/p, einen neuen Pfad (was eine Pfadberechnung bedeutet) anstelle eines vorhandenen Pfades zu nehmen.
Eine Kreatur beginnt ihre Patrouille erst, wenn der Pfad vollständig berechnet ist. Sie müssen sich also keine Sorgen machen, dass sie dabei getötet wird.

Bewahrer
quelle
8
Zu diesem Zeitpunkt wäre es eine Voroptimierung. Ich würde es so lassen, wie es ist, bis es ein Problem gibt.
John McDonald
3
Und um ein bisschen mit @JohnMcDonald zu läuten, wenn Sie diese Pfade während des Spiels berechnen können und es nicht auffällt, wie viel können sie zum Ladezeitpunkt beitragen?
James

Antworten:

6

BerickCook hat die Idee richtig ausgedrückt. Lassen Sie die Berechnungen dort, wo sie sind, wenn sie jetzt richtig funktionieren.

Wenn Sie die Berechnung vorher durchführen können und sicher sind, dass Sie sie während des Spiels nicht benötigen, tun Sie dies vorher. Andernfalls tun Sie es nach dem Laden. Wenn die Berechnung während des Spiels nicht bemerkt wird, können Sie sie dort ausführen. Wenn sich irgendwann die Komplexität entwickelt und die Berechnungen zu schwer werden, beginnen Sie mit der Optimierung.

Aber eines: Wenn Ihre Berechnungen so implementiert sind, dass sie während des Spiels ausgeführt werden, können Sie sie jederzeit zwingen, während des Ladens ausgeführt zu werden.

Es gibt zahlreiche Lösungen:

  • Berechnen / Laden Sie die Pfade während der Levelerstellung / des Ladens
  • Verwenden Sie einen zweiten Thread, um die Pfade zu berechnen
  • Optimieren Sie Ihre Algorithmen
  • Verwenden Sie ein unterbrechbares System, wenn Sie keinen Zugriff auf Threading haben.

Ich habe die letzte Option in einem Massenmarktspiel gesehen und verwendet. Stellen Sie einfach sicher, dass Sie alle Daten ordnungsgemäß speichern, damit die Berechnung fortgesetzt werden kann, und überprüfen Sie regelmäßig die verbleibende Zeit / den verbleibenden Betrieb während der Berechnung.

Abhängig von Ihrem Fall kann das unterbrechbare System vorläufige und Teillösungen liefern, die verwendet werden können, bevor die Berechnung beendet ist.


Bearbeiten : @Keeper beantworten

Der "unterbrechbare Algorithmus" war nur aufgrund der Einschränkungen nützlich, die wir hatten. Grundsätzlich haben wir den Mangel an Multithreading gelindert.

Irgendwann hatten wir ein Spiel, in dem die KI große Mengen an Zügen basierend auf mehreren Wörterbüchern berechnen musste. Während dieser Berechnung wurden alle Animationen gestoppt, da die Wörterbücher mit mehr Daten erweitert wurden und der Datensatz mit den Daten geändert wurde und weniger effizient war, wenn das Spiel für den Mehrspielermodus angepasst wurde (wobei die KI selbst für die Züge des Spielers interagieren musste). Wir hatten nur einen Thread für die Spieleschleife verfügbar (das Gebot ist, dass der Multi-Plattform-Code auf allen unterstützten Plattformen ausgeführt werden muss). Zu diesem Zeitpunkt wurde beschlossen, den Berechnungsalgorithmus zu unterbrechen, damit wir ihn unterbrechen können. Daher konnten wir nicht einfach das vorhandene rekursive System verwenden, da Variablen nicht gespeichert werden konnten. Die Funktionen wurden durch Objekte ersetzt, die einfach alle erforderlichen Variablen und Zeiger auf übergeordnete und untergeordnete Objekte enthielten. Ich nicht

  • Speichern Sie den Status der aktuellen Berechnungen
  • entweder am Ende einer Schleife oder während einer Schleife unterbrechen (wenn ein untergeordnetes Objekt unterbricht)
  • Beenden Sie, wenn die Zeit abgelaufen ist
  • Fortsetzen, wenn entweder eine Neustart einer Schleife am rechten Index gestoppt oder das untergeordnete Objekt aufgerufen wird, das sich derzeit oben auf dem untergeordneten Stapel befindet.
  • Reinigen Sie alles, wenn die Berechnung unterbrochen wird
  • Geben Sie das beste Teilergebnis.

Nur die teuersten Operationen wurden in separate Objekte aufgeteilt und es dauerte einige Zeit, um die richtigen Stellen zu finden, an denen wir die Berechnungen stoppen konnten, aber am Ende funktioniert es sehr gut.

Wir haben an Leistung verloren, aber die wahrgenommene Leistung war für den Benutzer viel besser, da Animationen auf allen Plattformen reibungslos liefen. Alle Plattformen konnten dann die größeren Wörterbücher verwenden, ohne unter abgehackten Animationen oder Einfrierungen zu leiden. Dies ermöglichte es uns auch, mehrere Instanzen parallel auszuführen, wenn wir sie später benötigten.

Natürlich braucht das Spiel dies jetzt auf dem iPhone und iPad nicht mehr. Die Verwendung eines zweiten Threads wäre ideal. Aber ich vermute, der Code ist noch da.

Kojote
quelle
Danke, das klingt sehr interessant. Können Sie bitte das Konzept des "unterbrechbaren Systems" näher erläutern (warum und wie)? (googeln war nicht so hilfreich ..). Ich werde der Frage einige Details hinzufügen.
Keeper
@Keeper Ich hoffe ich habe deine Frage zum unterbrechbaren Teil beantwortet. Es ist ein Problem, aber es ist auf den meisten modernen Systemen nicht relevant.
Coyote
Obwohl ich diese Methode vorerst nicht anwenden werde, haben Sie mir die Augen für etwas Neues geöffnet. Ihre Antwort verdient es, akzeptiert zu werden.
Keeper
8

Da die Berechnung der Pfade während des Spiels nicht bemerkt werden kann, ist dies vorerst der ideale Ansatz. Wenn es zu dem Punkt kommt, an dem das Gameplay durch die Berechnungen unterbrochen wird, schalten Sie es auf die Berechnung der Pfade um, bevor das Level geladen wird.

Längere anfängliche Ladezeiten sind verzeihlich, zufällige FPS-Schwankungen während des Spiels jedoch im Allgemeinen nicht.

BerickCook
quelle
2

Eine Möglichkeit, wenn Sie es brauchen, besteht darin, die Berechnungen in einen zweiten Thread zu verschieben, da heutzutage fast jeder PC mehr als einen CPU-Kern hat.

Der grundlegende Prozess wäre:

  • Wenn eine Kreatur einen Pfad anfordert, füge die Anforderung einer thread-sicheren Anforderungswarteschlange hinzu und signalisiere dem Thread.
  • Die Kreatur steht im Leerlauf, während sie darauf wartet, dass der Thread den Eintrag aus dieser Warteschlange entfernt, verarbeitet und in eine vollständige Liste einfügt.
  • Jeder Frame überprüft die abgeschlossene Liste aus dem Haupt-Thread und weist den Kreaturen abgeschlossene Pfade zu.

Sie müssen auch auf einige zusätzliche Randfälle achten (z. B. was passiert, wenn die Kreatur stirbt, bevor die Anfrage bearbeitet wird).

Adam
quelle
2
Wenn Sie kein Threading einführen möchten, können Sie Ihren Pfad auch inkrementell berechnen (z. B. einige Schritte pro Frame berechnen).
Bummzack