Wie kann ein Spiel mit allen Charakteren gleichzeitig umgehen?

31

Diese Frage ist nur, um zu erfahren, wie ein Spiel mit so vielen Charakteren gleichzeitig umgehen kann. Ich bin neu im Spiel, deshalb bitte ich Sie im Voraus um Verzeihung.

Beispiel

Ich erstelle ein Tower Defense-Spiel, in dem es 15 Tower Slots gibt, in denen Türme gebaut werden und jeder Tower Geschosse mit einer bestimmten Geschwindigkeit auswirft. Nehmen wir an, dass jede Sekunde 2 Projektile von jedem der Türme erzeugt werden und es Feinde gibt, die auf dem Schlachtfeld marschieren, sagen wir 70 (jede mit 10 Arten von Attributen wie HP, Mana usw.), die sich ändern, wenn sie sich auf dem Schlachtfeld bewegen Schlachtfeld).

Zusammenfassung

Turmzahl = 15
Geschosse pro Turm pro Sekunde = 2
Gesamtzahl der Geschosse pro Sekunde = 30
Einheiten in der Schlachtfeldzahl = 70

Bewältigt das Spiel diese 30 Projektile und 70 Einheiten, indem es sie auf 100 verschiedenen Threads (was für einen PC zu viel ist) oder 1 Thread, der sie alle bewegt, ihren Wert verringert usw. (was etwas langsam sein wird) handhabt , Ich glaube)?

Ich habe keine Ahnung davon. Kann mich jemand anleiten, wie das funktionieren wird?

Developer Nation
quelle
Kommentare sind nicht für längere Diskussionen gedacht. Diese Unterhaltung wurde in den Chat verschoben .
MichaelHouse
Fügen Sie die anderen Antworten hinzu ... ein Beispiel für einige gewaltige Spiele. Skyrim hat den größten Teil seiner Spielelogik auf einem einzigen Thread aktualisiert. Dies gelingt so gut, dass entfernte NPCs (meilenweit entfernte NPCs) gemäß ihrem Zeitplan angenähert werden. Die meisten MMOs aktualisieren die Spielelogik auf einem einzelnen Thread, ABER jeder Teil einer Map befindet sich auf einem anderen Thread oder Server-Rack.
MoonshineTheleocat

Antworten:

77

Wie geht das Spiel nun mit diesen 30 Projektilen und 70 Einheiten um, indem es sie auf 100 verschiedenen Threads handhabt?

Nein, mach das nie. Erstellen Sie niemals einen neuen Thread pro Ressource. Dies skaliert weder im Netzwerk noch bei der Aktualisierung von Entitäten. (Erinnert sich jemand an die Zeiten, als Sie einen Thread zum Lesen pro Socket in Java hatten?)

1 Thread, der alle von ihnen bewegt, reduziert ihren Wert usw.?

Ja, für den Anfang ist dies der richtige Weg. Die "großen Motoren" teilen einige Aufgaben zwischen den Threads auf, aber dies ist nicht erforderlich, um ein einfaches Spiel wie ein Tower-Defense-Spiel zu starten. Wahrscheinlich gibt es für jeden Tick noch mehr Arbeit, die Sie auch in diesem einen Thread erledigen werden. Oh ja, und das Rendering natürlich.

(das wird irgendwie langsam sein, denke ich)

Nun ... Was ist Ihre Definition von langsam ? Für 100 Entities sollte es nicht länger als eine halbe Millisekunde dauern, wahrscheinlich sogar weniger, abhängig von Ihrer Codequalität und der Sprache, mit der Sie arbeiten. Und selbst wenn es zwei volle Millisekunden dauert, ist es immer noch gut genug, um die 60 tps zu erreichen (Ticks pro Sekunde, in diesem Fall handelt es sich nicht um Frames).

tkausl
quelle
34
Eher wie eine halbe Mikrosekunde, es sei denn, Sie tun etwas Seltsames. Vor allem aber wird die Aufteilung der Arbeit auf mehrere Threads alles noch schlimmer machen , nicht besser. Ganz zu schweigen davon, dass Multithreading extrem schwierig ist.
Luaan
13
+1 Die meisten modernen Spiele-Engines rendern Tausende oder sogar Zehntausende von Polygonen in Echtzeit. Dies ist weitaus intensiver als die Verfolgung der Bewegung von nur 100 Objekten im Speicher.
Phyrfox
1
"Ein einfaches Spiel wie ein Tower Defense-Spiel." Hmm ... haben Sie schon einmal Defense Grid: The Awakening oder seine Fortsetzung gespielt?
Mason Wheeler
4
"Erstellen Sie niemals einen neuen Thread pro Ressource, dies ist im Netzwerk nicht skalierbar ..." Hmm , genau das tun einige sehr skalierbare Architekturen!
NPSF3000,
2
@BarafuAlbino: Das ist eine seltsame Sache zu sagen. Es gibt viele triftige Gründe, mehr Threads als Kerne zur Verfügung zu stellen. Es ist ein Kompromiss zwischen Komplexität, Leistung usw., wie bei jeder anderen Designentscheidung.
Dietrich Epp
39

Die erste Regel für Multithreading lautet: Verwenden Sie sie nur, wenn Sie für die Leistung oder Reaktionsfähigkeit mehrere CPU-Kerne parallelisieren müssen . Die Anforderung "x und y sollten aus Benutzersicht gleichzeitig auftreten" ist noch kein ausreichender Grund für die Verwendung von Multithreading.

Warum?

Multithreading ist schwierig. Sie haben keine Kontrolle darüber, wann jeder Thread ausgeführt wird, was dazu führen kann, dass Probleme jeglicher Art nicht reproduzierbar sind ("Race Conditions"). Es gibt Methoden, um dies zu vermeiden (Synchronisationssperren, kritische Abschnitte), aber diese haben ihre eigenen Probleme ("Deadlocks").

Gewöhnlich verarbeiten Spiele, die mit einer so geringen Anzahl von Objekten wie nur ein paar Hundert (ja, das ist in der Spieleentwicklung nicht so viel) zu tun haben , diese normalerweise seriell, wobei jeder Logik-Tick eine gemeinsame forSchleife verwendet.

Selbst die relativ schwächeren Smartphone-CPUs können Milliarden von Anweisungen pro Sekunde ausführen . Das heißt, auch wenn die Aktualisierungslogik Ihrer Objekte komplex ist und etwa 1000 Anweisungen pro Objekt und Tick benötigt und Sie großzügige 100 Ticks pro Sekunde anstreben, haben Sie genügend CPU-Kapazität für Zehntausende von Objekten. Ja, dies ist eine stark vereinfachte Back-of-the-Envelope-Berechnung, aber sie gibt Ihnen eine Idee.

Es ist auch allgemein bekannt, dass die Spielelogik sehr selten der Engpass eines Spiels ist. Der leistungskritische Teil ist fast immer die Grafik. Ja, auch für 2D-Spiele.

Philipp
quelle
1
"Die erste Regel für Multithreading lautet: Verwenden Sie es nur, wenn Sie für die Leistung oder Reaktionsfähigkeit mehrere CPU-Kerne parallelisieren müssen." Könnte für die Spieleentwicklung zutreffen (aber das bezweifle ich sogar). Wenn Sie mit Echtzeitsystemen arbeiten, ist der Hauptgrund für das Hinzufügen von Threads die Einhaltung von Fristen und die logische Vereinfachung.
Sam
6
@Sam Die Einhaltung von Fristen in Echtzeitsystemen ist ein Fall, in dem Sie Multithreading für die Reaktionsfähigkeit benötigen. Aber selbst dort ist die logische Einfachheit, die Sie scheinbar durch Threading erreichen, oft tückisch, weil sie verborgene Komplexität in Form von Deadlocks, Rassenbedingungen und Ressourcenverknappung erzeugt.
Philipp
Leider habe ich oft gesehen, wie die Spiellogik das ganze Spiel durchgesickert ist, wenn es Probleme mit der Pfadfindung gibt.
Loren Pechtel
1
@LorenPechtel Ich habe das auch gesehen. In der Regel war dies jedoch lösbar, indem keine unnötigen Pfadberechnungen (wie das Neuberechnen jedes einzelnen Pfads bei jedem einzelnen Tick) durchgeführt, häufig angeforderte Pfade zwischengespeichert, mehrstufige Pfadsuche verwendet und geeignetere Pfadfindungsalgorithmen verwendet wurden. Dies ist etwas, wo ein erfahrener Programmierer normalerweise viel Optimierungspotential findet.
Philipp
1
@LorenPechtel In einem Tower Defense-Spiel könnten Sie beispielsweise die Tatsache nutzen, dass es normalerweise nur eine Handvoll Zielpunkte gibt. Sie können also den Dijkstra-Algorithmus für jedes Ziel ausführen , um eine Richtungskarte zu berechnen, die alle Einheiten anleitet. Selbst in einer dynamischen Umgebung, in der Sie diese Karten für jeden Frame neu berechnen müssen, sollte dies immer noch erschwinglich sein.
CodesInChaos
26

Die anderen Antworten haben sich mit dem Threading und der Leistung moderner Computer befasst. Um die größere Frage zu beantworten, vermeiden Sie hier "n squared" Situationen.

Wenn Sie zum Beispiel 1000 Geschosse und 1000 Feinde haben, besteht die naive Lösung darin, sie alle gegeneinander zu prüfen.

Dies bedeutet, dass Sie am Ende p * e = 1.000 * 1.000 = 1.000.000 verschiedene Schecks haben! Das ist O (n ^ 2).

Auf der anderen Seite können Sie vieles vermeiden, wenn Sie Ihre Daten besser organisieren.

Wenn Sie beispielsweise auf jedem Feld des Gitters angeben, welche Feinde sich auf diesem Feld befinden, können Sie Ihre 1000 Projektile durchlaufen und das Feld auf dem Gitter überprüfen. Jetzt müssen Sie nur noch jedes Projektil gegen das Quadrat prüfen, dies ist O (n). Anstelle von einer Million Schecks pro Frame benötigen Sie nur tausend.

Die größte Einzeloptimierung, die Sie jemals vornehmen können, besteht darin, Ihre Daten zu organisieren und sie aufgrund dieser Organisation effizient zu verarbeiten.

Tim B
quelle
1
Alternativ zum Speichern des gesamten Rasters im Speicher, um nur einige Elemente zu verfolgen, können Sie auch B-Bäume verwenden, einen für jede Achse, um schnell mögliche Kandidaten für Kollisionen usw. zu suchen. Einige Engines erledigen dies sogar automatisch für Sie "; Sie geben Trefferregionen an und fordern eine Liste der Kollisionen an. Die Bibliothek gibt sie an Sie weiter. Dies ist einer von vielen Gründen, warum Entwickler eine Engine verwenden sollten, anstatt von Grund auf neu zu schreiben (natürlich wenn möglich).
Phyrfox
@phyrfox Natürlich gibt es eine Reihe von Möglichkeiten, dies zu tun - abhängig von Ihrem Anwendungsfall, der besser ist, wird es erhebliche Unterschiede geben.
Tim B
17

Erstellen Sie keine Threads pro Ressource / Objekt, sondern pro Abschnitt Ihrer Programmlogik. Beispielsweise:

  1. Thread zum Aktualisieren von Einheiten und Projektilen - Logikthread
  2. Thread zum Rendern des Bildschirms - GUI-Thread
  3. Thread für Netzwerk (zB Multiplayer) - IO-Thread

Dies hat den Vorteil, dass Ihre GUI (z. B. Schaltflächen) nicht unbedingt hängen bleibt, wenn Ihre Logik langsam ist. Der Benutzer kann das Spiel trotzdem anhalten und speichern. Es ist auch gut, um Ihr Spiel für den Mehrspielermodus vorzubereiten, da Sie jetzt die Grafik von der Logik trennen.

Tomáš Zato - Setzen Sie Monica wieder ein
quelle
1
Für Anfänger würde ich nicht empfehlen, separate Grafik- und Logik-Threads zu verwenden, da das Rendern des Spielstatus Lesezugriff auf den Spielstatus erfordert, damit Sie den Spielstatus nicht ändern können, während Sie ihn zeichnen.
CodesInChaos
1
Nicht zu oft zu zeichnen (z. B. mehr als 50 Mal pro Sekunde) ist ein bisschen wichtig, und bei dieser Frage ging es um die Leistung. Das Aufteilungsprogramm ist die einfachste Möglichkeit, um einen echten Leistungsvorteil zu erzielen. Es ist wahr, dass dies einige Kenntnisse über Threads erfordert, aber der Erwerb dieses Wissens lohnt sich.
Tomáš Zato - Reinstate Monica
Das Aufteilen eines Programms in mehrere Threads ist für einen Programmierer am schwierigsten. Die meisten wirklich ärgerlichen Fehler entstehen durch Multithreading und es ist eine Menge Ärger und die meiste Zeit einfach nicht wert - Erste Regel: Überprüfen Sie, ob Sie ein Leistungsproblem haben, und optimieren Sie DANN . Und optimieren Sie genau dort, wo der Engpass ist. Möglicherweise ein einzelner externer Thread für einen bestimmten komplexen Algorithmus. Aber selbst dann müssen Sie sich überlegen, wie Ihre Spiellogik voranschreitet, wenn dieser Algorithmus 3 Sekunden benötigt, um fertig zu werden ...
Falco
@Falco Sie überwachen die langfristigen Vorteile dieses Modells - sowohl für das Projekt als auch für die Programmiererfahrung. Ihre Behauptung, dass es am schwierigsten ist zu denken, kann nicht wirklich angesprochen werden, das ist nur eine Meinung. Für mich ist GUI-Design viel furchterregender. Alle weiterentwickelten Sprachen (C ++, Java) haben ziemlich klare Multithreading-Modelle. Und wenn Sie sich nicht sicher sind, können Sie ein Schauspielermodell verwenden, das nicht an Multithreading-Fehlern für Anfänger leidet. Sie wissen, dass es einen Grund gibt, warum die meisten Anwendungen so gestaltet sind, wie ich es vorgeschlagen habe, aber Sie können sich gerne darüber streiten.
Tomáš Zato - Reinstate Monica
4

Sogar Space Invaders verwaltete Dutzende interagierender Objekte. Während das Dekodieren eines HD-H264-Videoframes Hunderte von Millionen arithmetischer Operationen umfasst. Sie haben viel Rechenleistung zur Verfügung.

Das heißt, Sie können es immer noch langsam machen, wenn Sie es verschwenden. Das Problem ist weniger die Anzahl der Objekte als vielmehr die Anzahl der durchgeführten Kollisionstests. Die einfache Methode, jedes Objekt mit dem anderen zu vergleichen, quadriert die Anzahl der erforderlichen Berechnungen. Das Testen von 1001 Objekten auf Kollisionen auf diese Weise würde eine Million Vergleiche erfordern. Oft wird dies dadurch behoben, dass zB keine Projektile auf Kollision miteinander geprüft werden.

pjc50
quelle
2
Ich bin mir nicht sicher, ob Space Invaders der beste Vergleich ist. Der Grund, warum es langsam anfängt und schneller wird, wenn Sie Gegner töten, ist nicht, dass es so konzipiert wurde, sondern dass die Hardware nicht mit dem Rendern so vieler Gegner auf einmal fertig wird. en.wikipedia.org/wiki/Space_Invaders#Hardware
Mike Kellogg
Was ist, jedes Objekt führt eine Liste aller Objekte, die nah genug sind, um in der nächsten Sekunde mit ihnen kollidieren zu können, und wird einmal pro Sekunde oder bei jedem Richtungswechsel aktualisiert?
Random832
Kommt darauf an, was du modellierst. Space-Partitioning-Lösungen sind ein weiterer gängiger Ansatz: Unterteilen Sie die Welt in Regionen (z. B. BSP, das Sie möglicherweise ohnehin für Rendering-Zwecke ausführen müssen, oder Quadtree). Dann können Sie nur mit Objekten in derselben Region kollidieren.
pjc50
3

Ich werde mit einigen der anderen Antworten hier nicht einverstanden sein. Separate Logikthreads sind nicht nur eine gute Idee, sondern auch von großem Vorteil für die Verarbeitungsgeschwindigkeit - wenn Ihre Logik leicht trennbar ist .

Ihre Frage ist ein gutes Beispiel für eine Logik, die sich wahrscheinlich trennen lässt, wenn Sie eine zusätzliche Logik hinzufügen können. Sie können beispielsweise mehrere Threads zur Treffererkennung ausführen, indem Sie die Threads auf bestimmte Bereiche des Speicherplatzes beschränken oder die betroffenen Objekte mutexen.

Sie möchten wahrscheinlich NICHT einen Thread für jede mögliche Kollision, nur weil dies wahrscheinlich den Scheduler blockiert. Das Erstellen und Zerstören von Threads ist ebenfalls mit Kosten verbunden. Besser ist es, eine bestimmte Anzahl von Threads um die Systemkerne zu erstellen (oder eine Metrik wie die alte zu verwenden #cores * 2 + 4), und sie dann wieder zu verwenden, wenn der Prozess abgeschlossen ist.

Allerdings ist nicht jede Logik leicht zu trennen. Manchmal können Ihre Vorgänge alle Spieldaten auf einmal erfassen, was das Threading unbrauchbar macht (tatsächlich schädlich, da Sie Prüfungen hinzufügen müssten, um Threading-Probleme zu vermeiden). Wenn mehrere Stufen der Logik in bestimmten Reihenfolgen stark voneinander abhängig sind, müssen Sie die Ausführung von Threads so steuern, dass sichergestellt ist, dass keine von der Reihenfolge abhängigen Ergebnisse erzielt werden. Dieses Problem wird jedoch nicht behoben, indem keine Threads verwendet werden. Threads verschlimmern es lediglich.

Die meisten Spiele tun dies nicht einfach, weil es komplexer ist, als der durchschnittliche Spieleentwickler bereit / in der Lage ist, etwas zu tun, was normalerweise gar nicht der Engpass ist. Die überwiegende Mehrheit der Spiele ist nicht auf die CPU beschränkt, sondern auf die GPU. Eine Verbesserung der CPU-Geschwindigkeit kann zwar insgesamt hilfreich sein, ist jedoch normalerweise nicht der Schwerpunkt.

Das heißt, Physik-Engines verwenden oft mehrere Threads, und ich kann mehrere Spiele nennen, von denen ich glaube, dass sie von mehreren logischen Threads profitiert hätten (zum Beispiel die Paradox RTS-Spiele wie HOI3 und solche).

Ich stimme anderen Posts zu, dass Sie in diesem speziellen Beispiel wahrscheinlich keine Threads verwenden müssten, auch wenn dies von Vorteil sein könnte. Das Threading sollte für Fälle reserviert werden, in denen Sie eine übermäßige CPU-Auslastung haben, die mit anderen Methoden nicht optimiert werden kann. Es ist ein riesiges Unterfangen und wird die Grundstruktur eines Motors beeinflussen; Es ist nichts, woran man nachträglich festhalten kann.


quelle
2

Ich denke, dass die anderen Antworten einen wichtigen Teil der Frage verfehlen, indem sie sich zu sehr auf den Threading-Teil der Frage konzentrieren.

Ein Computer verarbeitet nicht alle Objekte in einem Spiel auf einmal. Es behandelt sie nacheinander.

Ein Computerspiel schreitet in diskreten Zeitschritten voran. Abhängig vom Spiel und der Geschwindigkeit des PCs betragen diese Schritte normalerweise entweder 30 oder 60 Schritte pro Sekunde oder so viele / wenige Schritte, wie der PC berechnen kann.

In einem solchen Schritt berechnet ein Computer, was jedes der Spielobjekte während dieses Schritts tun wird, und aktualisiert sie nacheinander entsprechend. Dies könnte sogar parallel geschehen, indem Threads verwendet werden, um schneller zu sein, aber wie wir gleich sehen werden, ist Geschwindigkeit überhaupt kein Problem.

Eine durchschnittliche CPU sollte 2 GHz oder schneller sein, dh 10 9 Taktzyklen pro Sekunde. Wenn wir berechnen 60 Zeitschritte pro Sekunde, die Blätter 10 9 /60 Taktzyklen = 16.666.666 Taktzyklen pro Zeitschritt. Mit 70 Einheiten haben wir noch etwa 2.400.000 Taktzyklen pro Einheit übrig. Wenn wir optimieren müssten, könnten wir in der Lage sein, jede Einheit in nur 240 Zyklen zu aktualisieren, abhängig von der Komplexität der Spiellogik. Wie Sie sehen, ist unser Computer etwa 10.000-mal schneller als für diese Aufgabe erforderlich.

Peter
quelle
0

Haftungsausschluss: Mein Lieblingsspiel aller Zeiten ist textbasiert und ich schreibe dies als langjähriger Programmierer eines alten MUD.

Ich denke, eine wichtige Frage, die Sie sich stellen müssen, ist folgende: Brauchen Sie überhaupt Fäden? Ich verstehe, dass ein Grafikspiel wahrscheinlich mehr MTs verwendet, aber ich denke, es hängt auch von der Spielmechanik ab. (Es ist auch zu bedenken, dass GPUs, CPUs und alle anderen Ressourcen, die wir heute haben, weitaus leistungsstärker sind, was Ihre Bedenken in Bezug auf Ressourcen so problematisch macht, wie es Ihnen erscheinen mag. Tatsächlich sind 100 Objekte praktisch null.) Es hängt auch davon ab, wie Sie "alle Zeichen auf einmal" definieren. Meinen Sie genau zur gleichen Zeit? Sie werden das nicht haben, wie Peter zu Recht betont, also ist alles auf einmal im wörtlichen Sinne irrelevant; es erscheint nur so.

Vorausgesetzt, Sie gehen mit Threads: Sie sollten auf keinen Fall 100 Threads in Betracht ziehen (und ich werde nicht einmal darauf eingehen, ob es zu viel für Ihre CPU ist oder nicht; ich beziehe mich nur auf die Komplikationen und die Praktikabilität davon).

Aber denken Sie daran: Multithreading ist nicht einfach (wie Philipp betont) und hat viele Probleme. Andere haben viel mehr Erfahrung (viel mehr) als ich mit MT, aber ich würde sagen, dass auch sie dasselbe vorschlagen würden (obwohl sie fähiger wären als ich - besonders ohne Übung von meiner Seite).

Einige argumentieren, dass sie nicht einverstanden sind, dass Threads nicht vorteilhaft sind, und andere argumentieren, dass jedes Objekt einen Thread haben sollte. Aber (und wieder ist dies alles Text, aber selbst wenn Sie mehr als einen Thread betrachten, müssen und sollten Sie ihn nicht für jedes Objekt berücksichtigen), wie Philipp darauf hinweist, dass Spiele dazu neigen, durch die Listen zu iterieren. Aber es ist nicht nur (wie er andeutet, obwohl mir klar ist, dass er nur auf Ihre Parameter von so wenigen Objekten reagiert) für so wenige Objekte. Im MUD bin ich ein Programmierer, denn wir haben Folgendes (und dies ist nicht alles, was in Echtzeit geschieht, denken Sie also auch daran):

(Die Anzahl der Instanzen variiert natürlich - höher und niedriger)

Mobiles (NPC, dh Nicht-Spieler-Charakter): 2614; Prototypen: 1360 Objekte: 4457; prototypen: 2281 zimmer: 7983; Prototypen: 7983. Jeder Raum hat normalerweise seine eigene Instanz, aber wir haben auch dynamische Räume, dh Räume innerhalb eines Raumes; oder Räume in einem Handy, zB der Magen eines Drachen; oder Räume in Objekten (zB wenn Sie ein magisches Objekt betreten). Beachten Sie, dass diese dynamischen Räume pro Objekt / Raum / Mobiltelefon vorhanden sind, für das sie tatsächlich definiert wurden. Ja, dies ähnelt sehr der Idee von World of Warcraft (ich spiele es nicht, aber ein Freund ließ mich es spielen, als ich eine Weile einen Windows-Computer hatte), mit der Ausnahme, dass wir es hatten, lange bevor es World of Warcraft überhaupt gab.

Skripte: 868 (derzeit) (seltsamerweise zeigt unser Statistik-Befehl nicht an, wie viele Prototypen wir haben, also werde ich das hinzufügen). Alle diese Veranstaltungen finden in Gebieten / Zonen statt, von denen wir 103 haben. Wir haben auch spezielle Verfahren, die zu unterschiedlichen Zeiten ablaufen. Wir haben auch andere Veranstaltungen. Dann haben wir auch Steckdosen angeschlossen. Handys bewegen sich, üben verschiedene Aktivitäten aus (außer Kämpfen), haben Interaktionen mit Spielern und so weiter. (So ​​auch andere Arten von Entitäten).

Wie gehen wir ohne Verzögerung damit um?

  • Sockets: select (), Warteschlangen (Eingabe, Ausgabe, Ereignisse usw.), Puffer (Eingabe, Ausgabe usw.) usw. Diese werden 10-mal pro Sekunde abgefragt.

  • Charaktere, Objekte, Räume, Kämpfe, alles: alles in einer zentralen Schleife mit verschiedenen Impulsen.

Wir haben auch (meine Implementierung basiert auf einer Diskussion zwischen dem Gründer / anderen Programmierer und mir) umfangreiche Nachverfolgungs- und Zeigergültigkeitstests für verknüpfte Listen und wir haben mehr als genug freie Ressourcen, falls wir tatsächlich einen Bedarf dafür haben. All dies (mit der Ausnahme, dass wir die Welt erweitert haben) gab es vor Jahren, als es weniger RAM, CPU-Leistung, Festplattenspeicher usw. gab. Und selbst dann hatten wir keine Probleme. In den beschriebenen Loops (Skripte verursachen dies, ebenso wie das Zurücksetzen / Wiederauffüllen von Bereichen und andere Dinge) werden Monster, Objekte (Gegenstände) und andere Dinge erstellt, befreit und so weiter. Verbindungen werden ebenfalls akzeptiert, abgefragt und alles andere, was Sie erwarten würden.


quelle