RTS-Spiel AI Thread

14

Ich habe ein Projekt, um ein Echtzeit-Strategiespiel von Grund auf neu zu erstellen. Ich bin noch in der frühen Planungsphase, aber ich habe ein wenig programmiert, um die Mechanik zu sehen.

Ich kann programmieren. Ich habe auch eine gute Vorstellung davon, wie ich die Spielklassen und die regelbasierte (State-Machine) KI für den Computerspieler strukturieren werde.

Ich möchte Doktrinen entwickeln, die einer bestimmten Einheit ein bestimmtes Verhalten verleihen (aber auf vielen Einheiten gleichzeitig angewendet werden können), wie z. B. Pfadfinder, Missionsroute folgen, Position halten (jeden nahenden Feind angreifen oder sich zurückziehen, wenn er überfordert ist). , etc...

Die Doktrinen gelten nur für die Einheiten, haben also eine Einheitsperspektive und sind nicht auf die gesamte Kartensituation bezogen.

Die Computer-KI analysiert die gesamte sichtbare Karte und entscheidet anhand eines anderen Regelsatzes, welcher Einheit welche Soktrin zugewiesen werden soll.

Ich mache dies in C # mit OpenGL.

Im Moment habe ich nicht viel, nur ein paar Dinge in Tests, bevor ich mit meiner Hauptkonzeption beginne. Ich habe eine Spieleschleife, in der die gesamte Spielverarbeitung (bei der ich die Aktualisierung, den Kampf, das Rendern usw. nacheinander aufrufen werde) stattfinden wird. Sie wird sehr oft aufgerufen, wenn das Application.Idle-Ereignis eintritt.

Jetzt habe ich mich gefragt. Da es im Gameloop eine Menge Dinge zu verarbeiten gibt, sollten die Computer-KI und die Einheiten ihre Aktionen in dieser Schleife auswählen, oder wird es zu langsam sein?

Wenn alle Dinge gleichzeitig ausgeführt werden sollen, sollte ich einen separaten Thread für die Computer-KI erstellen? Oder sogar einen eigenen Thread für jede Einheit?

Ich habe nicht viel Erfahrung mit Multithreading. Was wäre der beste Ansatz dafür?

Nate
quelle
Unabhängig - als Ogre3D statt OpenGL?
Eigentlich habe ich noch nie davon gehört. Ich benutze OpenGL, weil ich das in meinen Klassen gelernt habe. Kann Ogre3D auch 2D? Ich nehme an, es kann, aber wir wissen nie ...
Ja, es kann, es hat sogar ein eigenes GUI-Toolkit (Cegui). Zum Beispiel wird TorchLight damit gebaut. Es kann Ihnen Zeit sparen, weil es sich gut um OpenGL dreht. ogre3d.org/tikiwiki/MOGRE
"Oder sogar einen eigenen Thread für jede Einheit" Hölle nein. Der Overhead eines Threads ist viel zu groß. Zum einen gibt es den reservierten Speicher für den Stapel des Threads (standardmäßig 1 MB). Und Thread-Schalter sind auch teuer.

Antworten:

3

Was bedeutet "von Grund auf neu"? Können Sie mit DirectX stattdessen so etwas wie XNA verwenden?

Sie sollten zwischen 30 und 60 Bilder pro Sekunde rendern, um flüssige Bewegungen zu erzielen. Es ist wirklich nicht nötig mehr fps zu haben.

Wenn das Rendern von + Logik weniger als die 16 ms dauert, die 60 fps ergeben, sollte kein AI-Thread erforderlich sein.

Wenn Sie zwischen dem Rendern der Frames nicht genügend Zeit haben, müssen Sie sich wirklich genau überlegen, was bei jedem Frame aktualisiert werden muss und was nicht.

Ich würde schätzen, dass der Teil "Doktrinen" so einfach und effizient wie möglich sein sollte, damit er für jeden Frame aktualisiert werden kann, zumindest für sichtbare Einheiten und andere Einheiten in der Nähe. Die Einheiten, die die sichtbaren Einheiten nicht direkt beeinflussen, können seltener (und entsprechend mit einem größeren Delta T) aktualisiert werden.

Die Haupt-KI muss mehr Arbeit leisten, da sie alle Einheiten auf der Karte verarbeiten und eine Strategie ausarbeiten muss. Daher sollte sie den größten Teil der Rechenzeit in Anspruch nehmen. Es ist der erste Kandidat für einen separaten Thread.

Beachten Sie, dass Sie möglicherweise eine weitere Ebene zwischen den beiden hinzufügen möchten, etwa eine KI auf Truppenniveau. Grundsätzlich sollte die KI jeder Einheit sicherstellen, dass die Einheit "intelligent" auf die unmittelbare Situation reagiert, daher muss sie schnell und reaktionsschnell sein. Die KI des Trupps ist für die "intelligenten" Aktionen mehrerer Einheiten verantwortlich, die über mehrere Sekunden verteilt sind, wie das Finden einer Brücke, wenn der Trupp einen Fluss überqueren muss. Und die Haupt-KI sollte die Aktionen vieler Trupps über einen langen Zeitraum lenken.

Besonders wenn Sie nicht viel Erfahrung haben, fädeln Sie nicht ein, wenn Sie nicht müssen. Dies wird kompliziert, da es keine zusätzliche Belastung darstellt. Sie können Multithreading als separates Projekt oder als Erweiterung dieses Projekts lernen, sobald es in einem funktionierenden Zustand ist. Viel Glück!


quelle
0

Habe einen separaten Thread für AI. Aber nicht für jedes Gerät, da es zu viele Betriebssystemressourcen verbraucht und die Synchronisierung ein Albtraum wäre.

Stellen Sie sicher, dass der AI-Thread eine Möglichkeit zur Ausführung findet. Nehmen Sie es nicht leicht, wenn der Haupt-Thread zu viele Dinge tut, kann es sein, dass er diese Gelegenheit nie findet! Wenn Sie dem KI-Thread einfach eine höhere Priorität zuweisen, reagiert das Spiel nicht mehr, was inakzeptabel ist.

Wählen Sie daher Synchronisationspunkte und / oder Ereignisse in der Hauptschleife sorgfältig aus und lassen Sie den AI-Thread seine Berechnungen abschließen, während der Haupt-Thread anhält. Wenn die Benutzereinheit beispielsweise eine andere KI-Einheit sieht, synchronisieren Sie diese, damit Ihre Einheit eine aktualisierte Einheit sieht.


quelle
0

Ich arbeite auch an einem RTS-Spiel von Grund auf neu. Ich habe es noch nicht getestet, aber meine Idee war, Einheit AI in der Hauptspielschleife für alle Einheiten auszuführen, die derzeit für den Spieler sichtbar sind (in dem Teil des Bildschirms, den der Spieler tatsächlich sieht, oder in der Nähe des Randes dieses Bildschirms ), da es wahrscheinlicher ist, dass der Player den Bildschirm ein wenig bewegt.

Die anderen Einheiten werden in einem separaten Thread überprüft, und ich habe zwei Prioritäten: 1. Einheiten, die sich an Stellen befinden, die für den Benutzer sichtbar sind, wenn er den Bildschirm dorthin bewegt. 2. Einheiten, die sich in versteckten Gebieten befinden (noch nicht erkundet und "Nebel des Krieges").

Für Einheiten mit der Priorität "Sekunden" starte ich die Schleife seltener und kompensiere sie, indem ich sie bei Bedarf rückwirkend verschiebe.


quelle
1
Hört sich sehr kompliziert an.
Ihre Idee klingt gut, bis auf den ersten Teil, in dem es darum geht, Einheiten in den Hauptspiel-Loop hinein und aus ihm heraus zu bewegen. Alle KI-Vorgänge sollten in einer eigenen Schleife ausgeführt werden, in der Sie auswählen können, dass die Schleife xbei Einheiten mit niedriger Priorität bei jeder Wiederholung übersprungen werden soll.
Olhovsky
0

Unabhängig davon, ob Sie ein Multithreading benötigen oder nicht, ist es möglicherweise eine gute Idee, die KI auf das Multithreading vorzubereiten.

Ihr Haupt-Thread würde die Welt aktualisieren, die Physik usw. ankreuzen und dann eine Datenstruktur auffüllen, die die Sicht der KI auf die Welt darstellt: Position der Einheiten, Zustand der Ressourcen usw. Diese Datenstruktur würde eher die Hauptsysteme zwischenspeichern als nur Zeiger auf sie zu halten. Dies wird manchmal als Synchronisationspunkt bezeichnet.

Übergeben Sie diese Datenstruktur an die KI und lassen Sie sie nur auf den Inhalt dieser Struktur schließen. Wenn Sie feststellen, dass die KI weitere Informationen benötigt, fügen Sie sie der Struktur hinzu. Im AI-Sprachgebrauch wird dies oft als Blackboard bezeichnet, kann aber auch als Cache bezeichnet werden. Lassen Sie die KI niemals in den Cache schreiben, die Ausgabe sollte über eine separate Datenstruktur erfolgen.

Mit diesem Setup können Sie das Spiel parallelisieren, da die KI nicht mehr direkt von den anderen Spielsystemen abhängig ist. Diese Systeme müssen nicht threadsicher sein und Sie sollten niemals Sperren erhalten. Sie können den Renderer oder etwas sicher ausführen, während die KI davon surrt.

Als sekundärer Vorteil können Sie den Cache in Zukunft erweitern, indem Sie die Informationen, die Sie von den anderen Systemen erhalten, im Laufe der Zeit abbauen und Unsicherheit simulieren, anstatt genaue Kenntnisse zu haben.

Tenpn
quelle