Anmerkung des Übersetzers: Dieser Artikel ist bereits 17 Jahre alt und nur aus historischer Sicht interessant. Es ist interessant zu erfahren, wie es den Entwicklern im Zeitalter von 28,8.000 Modems und den ersten Pentiums gelungen ist, ein reibungsloses Online-Spiel zu erreichen.Dieser Artikel beschreibt die Architektur und Implementierung sowie einige Lehren aus der Erstellung des Mehrbenutzercodes (Netzwerkcodes) für
Age of Empires 1- und 2- Spiele. Außerdem werden aktuelle und zukünftige Ansätze der Netzwerkarchitektur beschrieben, die Ensemble Studios in ihren Game Engines verwenden.
Multiplayer Age of Empires: Strukturanforderungen
Zu Beginn der Arbeit am Multiplayer-Code
Age of Empires im Jahr 1996 haben wir uns sehr spezifische Ziele gesetzt, die für die Implementierung des erforderlichen Gameplays erforderlich sind.
- Große und epische historische Schlachten mit vielen verschiedenen Militäreinheiten
- Unterstützung für bis zu 8 Spieler im Mehrspielermodus
- Reibungslose Gameplay-Simulation über LAN, direkte Modemverbindung und über das Internet
- Unterstützung der Zielplattform: Pentium 90 mit 16 MB RAM und 28,8-Kbit / s-Modem
- Das Kommunikationssystem sollte mit der vorhandenen Engine (Genie) funktionieren.
- Stabile 15 Bilder pro Sekunde auf Maschinen mit minimaler Konfiguration
Die Genie-Engine war bereits fertig und das Gameplay im Einzelbenutzermodus nahm seine Form an. Die Genie-Engine ist eine zweidimensionale Single-Threaded-Game-Loop-Engine. Sprites werden in einer aus Kacheln zusammengesetzten Welt in 256 Farben gerendert. Zufällig generierte Karten sind mit Tausenden von Objekten gefüllt: von Bäumen, die gefällt werden können, bis zu galoppierenden Gazellen. Die ungefähre Aufteilung (nach der Optimierung) der Zeit für die Ausführung von Engine-Aufgaben: 30% für das Rendern von Grafiken, 30% für die KI und das Finden von Pfaden, 30% für das Ausführen von Simulationen und offiziellen Aufgaben.
Bereits zu einem relativ frühen Zeitpunkt war die Engine relativ stabil, und die Mehrbenutzerkommunikation musste mit vorgefertigtem Code arbeiten, ohne dass die vorhandene (funktionierende) Architektur wesentlich geändert werden musste.
Um die Aufgabe zu verkomplizieren, kann die Zeit, die für die einzelnen Schritte der Simulation benötigt wird, sehr unterschiedlich sein: Die Renderzeit hing davon ab, ob der Benutzer die Einheiten beobachtete, scrollte oder den unerforschten Bereich betrachtete, und lange Pfade oder die strategische Planung der KI beeinflussten die Ausführungszeit des Spielzugs erheblich : Die Schwingungen betrugen bis zu 200 ms.
Kurze Berechnungen zeigten, dass die Übertragung selbst eines kleinen Datensatzes über Einheiten und der Versuch, diese in Echtzeit zu aktualisieren, die Anzahl der Einheiten und Objekte, mit denen der Spieler interagieren kann, stark einschränkt. Wenn Sie einfach die X- und Y-Koordinaten, den Status, die Aktion, die Blickrichtung und den Schaden übertragen, können im Spiel nicht mehr als 250 mobile Einheiten vorhanden sein.
Wir wollten, dass die Spieler in der Lage sind, griechische Städte mit Katapulten, Bogenschützen und Kriegern zu zerstören und gleichzeitig Belagerungen mit Triremen aus dem Meer durchzuführen. Offensichtlich brauchten wir einen anderen Ansatz.
Simultane Simulationen
Anstatt den Status jeder Spieleinheit zu übertragen, wollten wir auf jeder Maschine absolut identische Simulationen durchführen und dabei jeweils den gleichen Befehlssatz übergeben, den die Spieler gleichzeitig gegeben haben. Die Computer der Spieler mussten im Wesentlichen das Gameplay in den besten Traditionen von Kriegsfilmen synchronisieren, damit die Spieler Befehle erteilen und diese dann auf die gleiche Weise und zur gleichen Zeit ausführen konnten, um die Identität der Spiele sicherzustellen.
Anfangs war eine solch knifflige Synchronisation schwierig zu implementieren, brachte jedoch in anderen Bereichen unerwartete Vorteile.
Grundlegende ModellverbesserungAuf der einfachsten konzeptionellen Ebene scheint die Implementierung simultaner Simulationen sehr einfach zu sein. In einigen Spielen, die Simulationen mit einem festen Schritt (Lock-Step) und konstanten Timings verwenden, kann dies sogar durchaus möglich sein.
Da bei diesem Ansatz die Verantwortung für das gleichzeitige Verschieben von Hunderten oder Tausenden von Objekten übernommen werden sollte, muss das System auch bei Verzögerungsschwankungen von 20 bis 1000 Millisekunden funktionsfähig bleiben und Änderungen während der Frame-Verarbeitung verarbeiten können.
Das Senden von Spielerbefehlen, das Bestätigen aller Nachrichten und das anschließende Verarbeiten dieser Nachrichten, bevor mit dem nächsten Zug fortgefahren wird, wäre aus Sicht des Spielprozesses ein Albtraum, mit ständigem Warten und einem langsamen Austausch von Teams. Wir brauchten ein Schema, das das Spiel parallel zum Hintergrund weiter verarbeiten konnte und auf den Abschluss des Datenaustauschprozesses wartete.
Mark [Terrano] verwendete ein System zum Markieren von Befehlen, die in Zukunft durch zwei „Datenaustauschbewegungen“ ausgeführt werden sollten (die Datenaustauschbewegungen in
AoE wurden von den Rendering-Frames selbst getrennt).
Das heißt, die während des Kurses 1000 gegebenen Befehle werden zugewiesen, um während des Kurses 1002 ausgeführt zu werden (siehe Fig. 1). Im Laufe von 1001 werden die im Laufe von 0999 erteilten Befehle ausgeführt. Dadurch konnten wir Nachrichten für die Verarbeitung empfangen, bestätigen und vorbereiten, während das Spiel weiterhin Animationen zeichnete und Simulationen durchführte.
Abbildung 1. Markup von Befehlen, die durch zwei „Datenaustauschbewegungen“ ausgeführt werden sollen.Normalerweise dauerten die Bewegungen 200 ms und die Teams wurden in dieser Runde geschickt. Nach 200 ms stoppte die Bewegung und eine neue Bewegung begann. Zu jedem Zeitpunkt des Spiels wurden die Teams in einem Zug verarbeitet, für den nächsten Zug empfangen und gespeichert und zwei Züge später zur Ausführung geschickt.
"Geschwindigkeitsregelung"
Abbildung 2. Geschwindigkeitsregelung.Da Simulationen immer genau die gleiche Eingabe haben sollten, kann ein Spiel nicht schneller ausgeführt werden, als es die langsamste Maschine schafft, den Datenaustausch zu verarbeiten, einen Zug auszuführen und neue Befehle zu senden. Wir haben das System, das die Strichdauer ändert, um reibungslose Animationen und das Gameplay unter Bedingungen variabler Datenaustauschverzögerung und Verarbeitungsgeschwindigkeit aufrechtzuerhalten, als "Geschwindigkeitsregelung" bezeichnet.
Das Gameplay kann aus zwei Gründen als "bremsen" empfunden werden: Wenn die Bildrate einer Maschine sinkt (oder niedriger als die der anderen ist), verarbeiten andere Maschinen ihre Befehle, rendern alles zum festgelegten Zeitpunkt und müssen daher auf den nächsten Zug warten. In diesem Fall macht sich jede Pause sofort bemerkbar. Zusätzlich wird das Spiel durch eine Verzögerung des Datenaustauschs verlangsamt - die Spieler müssen warten, bis die Maschine genügend Daten erhält, um den Zug abzuschließen.
Jeder Client berechnete die als konstant erreichbar angesehene Bildrate, die durch Mittelung der Verarbeitungszeit mehrerer Bilder berechnet wurde. Da sich dieser Wert während des Spiels abhängig vom Umfang, der Anzahl der Einheiten, der Größe der Karte und anderen Faktoren ändert, wurde er in jeder Nachricht über den Abschluss des Zuges übertragen.
Darüber hinaus hat jeder Client auch die „Ping-Zeit“ von sich selbst zu anderen Clients und umgekehrt gemessen. Er schickte auch den durchschnittlichen Ping an den längsten Client in einer Nachricht über den Abschluss der Verschiebung (insgesamt wurden 2 Bytes verwendet, um die Geschwindigkeit zu steuern).
Bei jeder Bewegung analysierte die vom Host bestimmte Maschine die Abschlussnachrichten, berechnete die erforderliche Bildrate und die Korrektur für die Verzögerung bei der Datenübertragung über das Internet. Dann schickte der Host eine neue Bildrate und die Dauer des Datenaustauschs. Die Abbildungen 3-5 zeigen, wie der Datenaustausch unter verschiedenen Bedingungen aufgeteilt wurde.
Abbildung 3. Typischer Datenaustauschfluss.Abbildung 4. Datenübertragung mit hoher Latenz über das Internet bei normaler Maschinengeschwindigkeit.Abbildung 5. Niedrige Maschinengeschwindigkeit bei normaler Datenübertragungsverzögerung.Der "Datenaustauschfortschritt", der ungefähr der Ping-Zeit für den Roundtrip für die Nachricht entsprach, wurde durch die Anzahl der Simulationsrahmen geteilt, die die langsamste Maschine während dieser Zeit durchschnittlich ausführen konnte.
Die Dauer des Datenaustauschs wurde gewichtet, sodass sie entsprechend den Änderungen der Verzögerungen bei der Datenübertragung über das Internet schnell zunehmen und langsam auf die beste Durchschnittsgeschwindigkeit abnehmen konnte, die kontinuierlich beibehalten werden kann. Normalerweise verlangsamte sich das Spiel und verlangsamte sich nur in den Momenten der schlimmsten Spitzen - die Übertragungsverzögerung der Befehle nahm zu, blieb jedoch reibungslos (und erhöhte sich nur um einige Millisekunden pro Runde), da das Spiel die Verzögerungen allmählich auf die bestmögliche Geschwindigkeit reduzierte. Dies führte zu einer größtmöglichen Glätte des Spiels und gleichzeitig zu einer Anpassung an sich ändernde Bedingungen.
Garantierte Lieferung
UDP wurde in der Netzwerkschicht verwendet, und jeder Client war an der Bestellung von Befehlen, der Erkennung von Verlusten und der erneuten Übertragung beteiligt. Jede Nachricht verwendete ein Bytepaar, das den Kurs angibt, für den die Ausführung der Befehle geplant war, und die Seriennummer der Nachricht. Wenn eine Nachricht nach dem Verschieben empfangen wurde, wurde sie abgelehnt und eingehende Nachrichten wurden zur Ausführung gespeichert. Aufgrund der Art von UDP verwendete Mark beim Empfang von Nachrichten das folgende Prinzip: „Im Zweifelsfall sollten Sie die Nachricht als verloren betrachten. Wenn Nachrichten nicht in der richtigen Reihenfolge empfangen werden, sendet der Empfänger sofort eine Anforderung zur erneuten Übertragung verlorener Nachrichten. Wenn die Empfangsbestätigung später als die vorhergesagte Zeit eingeht, sendet der Absender die Nachricht einfach erneut, ohne auf ein Signal über ihren Verlust zu warten. "
Versteckte Vorteile
Da die vom Spiel berechneten Ergebnisse davon abhingen, dass alle Benutzer identische Simulationen durchführten, war es für einen Client (oder Client-Datenstrom) unglaublich schwierig, zu hacken und zu betrügen. Jede anders durchgeführte Simulation wurde als "nicht synchron" markiert und das Spiel gestoppt. Es war immer noch möglich, lokal für die Offenlegung von Informationen zu betrügen, aber solche Lecks konnten in nachfolgenden Patches und Revisionen relativ leicht behoben werden. Sicherheit ist unser größter Sieg geworden.
Versteckte Probleme
Auf den ersten Blick scheint es einfach zu sein, dieselbe Ausführung von zwei Instanzen desselben Codes zu implementieren, ist es aber nicht. Zu Beginn des Projekts erklärte Microsoft-Produktmanager Tim Znamenachek gegenüber Mark: „Jedes Projekt weist einen dauerhaften Fehler auf, der erst nach Abschluss des Projekts aufgibt. Ich denke in unserem Fall wird es nicht synchron sein. “ Und er hatte recht. Die Schwierigkeiten, Synchronisationsfehler herauszufinden, vervielfachten sich mit jeder kleinen Änderung. Der Hirsch, dessen Position beim Erstellen einer zufälligen Karte etwas anders ist, bewegt sich etwas anders, und Minuten später bewegt sich der Jäger etwas aus dem Weg oder verfehlt einen Speer, weil er ohne Fleisch nach Hause zurückkehrt. Was manchmal nur ein Unterschied in den Prüfsummen der Lebensmittelmenge zu sein schien, hatte daher Gründe, die sehr schwer zu verfolgen waren.
Obwohl wir die Welt, Objekte, die Suche nach Pfaden, das Zielen und alle anderen Systeme mit Prüfsummen überprüft haben, gab es immer etwas, das wir nicht berücksichtigen konnten. Riesige (jeweils 50 MB) Mengen an Nachrichtenverfolgung und Speicherauszügen von Weltobjekten machten das Problem noch komplizierter. Ein Teil der Schwierigkeiten war konzeptionell - Programmierer waren es nicht gewohnt, Code zu schreiben, der dieselbe Anzahl von Zufallszahlengeneratoraufrufen in einer Simulation verwendete (ja, Zufallszahlen wurden ebenfalls generiert und synchronisiert).
Lektionen gelernt
Bei der Entwicklung des Netzwerkteils von
Age of Empires haben wir verschiedene Lektionen erhalten, die auf die Entwicklung jedes Gaming-Mehrbenutzersystems angewendet werden können.
Lernen Sie Ihren Benutzer. Das Studium des Benutzers ist der wichtigste Schritt, um seine Erwartungen hinsichtlich der Geschwindigkeit des Mehrspielers, der wahrgenommenen Bremsen und Verzögerungen bei der Übertragung von Befehlen zu verstehen. Jedes Genre ist individuell und Sie müssen verstehen, was zu Ihrem Spiel- und Managementstil passt.
In den frühen Phasen des Entwicklungsprozesses haben Mark und der leitende Designer Verzögerungen beim Datenaustausch prototypisiert (dieser Prototyp wurde während des Entwicklungsprozesses mehrmals überarbeitet). Da sie ein Einzelspielerspiel spielten, war es sehr einfach, verschiedene Ebenen von Teamtransferverzögerungen zu simulieren und Spielerfeedback zu erhalten („Kontrolle scheint gut / langsam / zuckend / einfach schrecklich“).
Bei Spielen des RTS-Genres sind Verzögerungen bei der Befehlsübertragung von 250 Millisekunden nicht einmal erkennbar. Bei 250 bis 500 ms ist das Gameplay gut spielbar, und die Bremsen werden bei 500 ms und höher spürbar. Es ist auch interessant festzustellen, dass die Spieler an das "Tempo des Spiels" und die mentale Erwartung einer Verzögerung zwischen Mausklicks und Einheitenreaktionen gewöhnt sind. Eine konstante verzögerte Antwort war besser als Sprünge bei Befehlsübertragungsverzögerungen (z. B. von 80 auf 500 ms). In diesem Fall wurden konstante Verzögerungen von 500 ms als spielbar empfunden, und veränderbare Verzögerungen schienen „nervös“ zu sein und das Spiel zu komplizieren.
Dies zwang die Programmierer, ihre Bemühungen auf die Gewährleistung der Laufruhe zu richten. Es ist besser, eine längere Hubdauer zu wählen und sicherzustellen, dass alles glatt und konstant ist, als die Operationen angesichts regelmäßiger Verlangsamungen so schnell wie möglich durchzuführen. Alle Geschwindigkeitsänderungen sollten schrittweise erfolgen und die Wachstumsrate sollte so gering wie möglich sein.
Wir haben auch die Anforderungen des Benutzers an das System gemessen - normalerweise gaben sie Befehle (bewegen, angreifen, Bäume fällen) ungefähr alle anderthalb bis zwei Sekunden, manchmal mit Spitzenwerten von 3-4 Teams pro Sekunde während heftiger Kämpfe. Da die aktiven Aktionen in unserem Spiel ständig zunehmen, entstehen die höchsten Anforderungen für den Datenaustausch in der Mitte und gegen Ende des Spiels.
Wenn Sie sich die Zeit nehmen, um das Benutzerverhalten zu untersuchen, werden Sie andere Funktionen der Spielweise bemerken. Dies hilft beim Einrichten des Netzwerkspiels. In
AoE klickten Benutzer während eines Angriffs schnell mit der Maus (Klick-Klick-Klick-Klick - vorwärts-vorwärts-vorwärts-vorwärts!), Was zu enormen Spitzenwerten bei der Anzahl der ausgegebenen Befehle führte. Darüber hinaus schickten sie große Gruppen von Einheiten, die den Weg ebnen müssen - auch große Spitzen bei den Anforderungen für die Datenübertragung über das Netzwerk. Ein einfacher Filter, der wiederholte Befehle an einem Punkt abschneidet, reduziert die negativen Auswirkungen dieses Verhaltens erheblich.
Im Allgemeinen können Sie Benutzer überwachen, um:
- Informieren Sie sich über die Erwartungen der Benutzer bezüglich Spielverzögerungen
- Prototyp-Multiplayer-Aspekte in den frühen Entwicklungsstadien
- Siehe Verhalten, das sich nachteilig auf die Geschwindigkeit des Mehrbenutzermodus auswirkt.
Messung ist das Wichtigste. Wenn Sie in den frühen Arbeitsphasen Metriken einführen, lernen Sie erstaunliche Dinge über Ihr Datenaustauschsystem. Machen Sie die Metriken für Tester lesbar und verwenden Sie sie, um zu verstehen, was in der Netzwerk-Engine vor sich geht.
Lektion: Ein Teil des Problems beim Datenaustausch in AoE trat auf, als Mark die Metriken zu früh ableitete und die Nachrichtenebenen (Länge und Häufigkeit) nach der Erstellung des endgültigen Codes nicht erneut überprüfte. Unerwartete Dinge wie zufällige Rennen zwischen AIs, schwer zu berechnende Pfade und schlecht strukturierte Befehlspakete können große Leistungsprobleme verursachen, selbst wenn das System ansonsten gut funktioniert.
Lassen Sie das System Tester und Entwickler über einen scheinbaren Überschuss an Randbedingungen informieren. Programmierer und Tester sehen im Entwicklungsprozess, welche Aufgaben das System laden. Dies wird Probleme in den frühen Stadien ihres Auftretens lösen.
Nehmen Sie sich Zeit, um den Testern die Funktionsweise des Datenaustauschsystems zu erklären, ihnen Metriken anzuzeigen und zu erklären. Sie werden überrascht sein, dass sie feststellen, wenn im Netzwerkcode unvermeidlich seltsame Fehler auftreten.
Im Allgemeinen sollten Metriken die folgenden Eigenschaften haben:
- Seien Sie für Tester lesbar und verständlich
- Zeigen Sie Engpässe, Bremsen und Probleme an
- Geringe Auswirkungen auf die Ausführung und ständige Einführung.
Entwicklerschulung. Es ist sehr schwierig, Programmierern, die es gewohnt sind, Einzelbenutzeranwendungen zu erstellen, beizubringen, über die Trennung zwischen Geben, Empfangen und Verarbeiten eines Befehls nachzudenken. Es ist leicht zu vergessen, dass Sie nach etwas fragen können, das nicht passiert ist, oder was einige Sekunden nach der Befehlsausgabe passieren kann. Befehle müssen sowohl beim Senden als auch beim Empfang auf ihre Richtigkeit überprüft werden.
In einem synchronen Modell müssen Programmierer auch berücksichtigen, dass der Code innerhalb der Simulation nicht von lokalen Faktoren abhängen sollte (z. B. Verfügbarkeit von Freizeit, Spezialausrüstung oder anderen Einstellungen). Die Codeausführung auf allen Computern muss übereinstimmen. Beispielsweise kann das Vorhandensein zufälliger Geländetöne in einer Simulation zu einem unterschiedlichen Spielverhalten führen.
Andere Lektionen. Dies sollte der übliche gesunde Menschenverstand sein. Wenn Sie jedoch von einem Netzwerk eines Drittanbieters abhängig sind (in unserem Fall DirectPlay), schreiben Sie eine unabhängige Testanwendung, in der bestätigt wird, dass die Nachrichten, wenn die Eigentümer "garantierte Zustellung" beanspruchen, tatsächlich die "garantierte Paketbestellung" erhalten. in der Tat gibt es und dass das Produkt keine versteckten Engpässe oder seltsames Verhalten bei der Verarbeitung der übertragenen Daten in Ihrem Spiel hat.
Machen Sie sich bereit, Simulationsanwendungen und Stresstestsimulatoren zu erstellen. Am Ende haben wir drei verschiedene Minimal-Testanwendungen erstellt, mit denen einzelne und wichtige Probleme untersucht werden: Verbindungsfluten, Probleme mit gleichzeitigen Verbindungen bei der Auswahl von Gegnern und Verlust garantierter Pakete.
Testen Sie so früh wie möglich mit Modems (und mit etwas Glück mit Modemsimulatoren). Setzen Sie die Modemtests (egal wie schmerzhaft sie auch sein mögen) während des gesamten Entwicklungsprozesses fort.
Schließlich sind die Probleme schwer zu isolieren (was ist der Grund für den starken Geschwindigkeitsabfall - Anbieter, Spiel, Kommunikationssoftware, Modem, konkurrierender Suchdienst für ein Match oder etwas anderes?), Und Benutzer möchten sich nicht mit langsamen DFÜ-Verbindungen herumschlagen und sich an sofortige LAN-Geschwindigkeiten gewöhnen . Es ist wichtig, dass Sie Modemverbindungen mit der gleichen Beständigkeit wie bei LAN-Spielen für mehrere Spieler testen.Verbesserungen für Age of Empires 2
In Age of Empires 2: Das Zeitalter der Könige haben wir Mehrbenutzerfunktionen wie Spielaufzeichnung, Dateiübertragung und ständige Verfolgung von Statistiken auf der The Zone-Website hinzugefügt. Wir haben auch Multiplayer-Systeme wie DirectPlay-Integration und Geschwindigkeitskontrolle verbessert, um die nach der Veröffentlichung von Age of Empires festgestellten Fehler und Geschwindigkeitsprobleme zu beheben ., , «» . -. , , . . , , , .
() The Zone
Age of Empires .
Age of KingsWir haben es erweitert, und so konnten wir die Startparameter steuern und ständige Berichte über Statistiken erstellen. Dies ermöglichte es den Spielern, Spiele, an denen sie interessiert waren, besser zu finden, da sie die Matchmaking-Level-Parameter sehen konnten und nicht darauf warten mussten, dass die Spieleinstellungen zum Bildschirm mit den Spieleinstellungen gelangen. Im Backend haben wir ständige Berichts- und Nachverfolgungsstatistiken implementiert. Wir haben The Zone mit einer gemeinsamen Struktur versehen, die am Ende des Spiels ausgefüllt und auf den Server übertragen wurde. Die Daten aus dieser Struktur wurden verwendet, um Benutzerbewertungen zu erstellen und diese auf der The Zone-Website anzuzeigen.RTS3 Multiplayer: Aufgaben
RTS3 ist der Codename für das Strategiespiel Ensemble der nächsten Generation (ca. Per: Das Spiel wurde unter dem Namen Age of Mythology veröffentlicht) . Die RTS3-Struktur basiert auf der erfolgreichen Formel der Age of Empires-Spieleserie und enthält viele neue Funktionen und Anforderungen für den Mehrbenutzermodus.- Basierend auf den Funktionen von Age of Empires 1 und 2 . Obligatorische Anforderungen wie das Spielen im Internet, große und abwechslungsreiche Karten, Tausende von verwalteten Einheiten.
- 3D: RTS3 ist ein vollständig dreidimensionales Spiel mit interpolierten Animationen und nicht diskreten Positionen und Einheitenrotationen.
- Mehr Spieler - Unterstützung für mehr als acht Spieler.
- TCP / IP-Unterstützung: Unser Hauptziel ist eine 56 / kbps-TCP / IP-Internetverbindung.
- — , NAT.
RTS3 ,
Age of Empires 1 2 — — RTS3 .
AOE/AOK DirectPlay, RTS3 , .
Der Übergang zu einer vollständig dreidimensionalen Welt bedeutet, dass wir Probleme mit der Bildrate und der allgemeinen Glätte der Simulation im Mehrbenutzermodus stärker berücksichtigen müssen. Dies bedeutet jedoch auch, dass die Aktualisierungszeit der Simulationssituation und die Bildrate noch stärker variieren und wir mehr Zeit für das Rendern aufwenden müssen. In der Genie-Engine waren die Rotationen der Einheiten diskret und die Animationen an die Bildrate in BANG gebunden! Beliebige Einheitenrotation und sanfte Animation sind möglich, dh das Spiel reagiert visuell viel empfindlicher auf den Einfluss von Verzögerungen und Sprüngen in der Aktualisierungsfrequenz.Das Zeitalter der Könige abschließenWir wollten diese kritischen Bereiche angehen, in denen durchdachtes Design und die Arbeit mit Tools die Debugging-Zeit erheblich verkürzen würden. Wir haben auch erkannt, wie wichtig der iterative Testprozess für das Design unserer Spiele ist, daher wurde dem frühestmöglichen Abschluss des Online-Spiels eine hohe Priorität eingeräumt.RTS3-Kommunikationsarchitektur
Abbildung 6. Die strikte objektorientierte Netzwerkarchitektur von RTS3.Objektorientierter Ansatz. Die Netzwerkarchitektur von RTS3 ist stark objektorientiert (siehe Abbildung 6). Mit den Supportanforderungen für verschiedene Netzwerkkonfigurationen können Sie den OO-Ansatz nutzen, der von den Besonderheiten der Plattform, des Protokolls und der Topologie abstrahiert ist, die einer Reihe verallgemeinerter Objekte und Systeme zugrunde liegen.. . , (, , -). ( Channels, TimeSync ..) , .
.Die Genie-Engine unterstützte eine Peer-to-Peer-Netzwerktopologie, in der alle Clients in einer Sitzung in einer Sternkonfiguration miteinander verbunden sind. In RTS3 haben wir diese Topologie weiterhin verwendet, da sie bei Implementierung mit einem synchronen Simulationsmodell inhärente Vorteile bietet.Die Peer-to-Peer-Topologie impliziert die Verwendung einer Sternkonfiguration für verbundene Clients in einer Sitzung (Abbildung 7). Das heißt, jeder Client ist mit allen anderen Clients verbunden. Das gleiche Schema wurde im Alter von 1 und 2 angewendet .Abbildung 7. Sternkonfiguration von Peer-Clients in einer Sitzung.Peer-to-Peer-Vorteile:- Verringerte Latenz aufgrund des Client-zu-Client-Messaging-Schemas anstelle des Client-Server-Client.
- Es gibt kein zentrales schwaches Glied - wenn der Client (sogar der Host) die Verbindung zur Sitzung trennt, kann das Spiel fortgesetzt werden.
Peer-to-Peer-Nachteile:- Aktivere Verbindungen im System (Summe von n = 0 bis k-1 (n)), dh mehr potenzielle schwache Glieder und höhere wahrscheinliche Verzögerungen.
- Die Unfähigkeit, einige NAT-Konfigurationen in einem solchen Schema zu unterstützen.
Net.lib. RTS3 , , , , . , , , , , .
Abbildung 8. Vier Schichten von Diensten in unserem Netzwerkmodell.RTS3 basiert auf unserer BANG Engine! Eine neue Generation, die eine modulare Architektur mit Komponentenbibliotheken wie Sound, Rendering und Netzwerk verwendet. Das Netzwerk-Subsystem ist hier als Komponente integriert, aber mit der BANG-Engine verbunden! (sowie mit verschiedenen hauseigenen Werkzeugen). Unser Netzwerkmodell ist in vier Service-Schichten unterteilt, die dem im Spiel verwendeten OSI-Netzwerkmodell fast, aber nicht vollständig ähnlich sind (siehe Abbildung 8).Socken Level 1Die erste Ebene, Socks, bietet eine grundlegende API auf Socket-Ebene in C. Sie wird abstrahiert, um einen generischen Satz von Netzwerkprozeduren auf niedriger Ebene für viele Betriebssysteme zu erstellen. Die Schnittstelle ähnelt der Berkeley-Socket-Schnittstelle. Die Socks-Schicht wird hauptsächlich von höheren Schichten der Netzwerkbibliothek verwendet und ist eigentlich nicht für die Verwendung durch Anwendungscode vorgesehen.Link, Level 2Level 2, Link, bietet Transportschichtdienste. Objekte auf dieser Ebene, wie z. B. Link, Listener, NetworkAddress und Packet, sind nützliche Elemente, um eine Verbindung herzustellen und Nachrichten darüber zu senden (siehe Abbildung 9).- Packet (): — , / ( ) .
- Link (): . , . send receive , , void*.
- Listener (): . .
- Data stream ( ): , , , .
- Netzadresse : Eine protokollunabhängige Netzwerkadressierungseinheit.
- Ping: Eine einfache Ping-Klasse. Meldet eine Netzwerkverzögerung bei der Kommunikation mit der Verbindung.
Abbildung 9. Verbindungsebene.
Multiplayer-Level 3Das Multiplayer-Level ist das höchste Level an Objekten und Prozeduren, die in der net.lib-API vorhanden sind. Dies ist die Ebene, mit der RTS3 interagiert, wenn Objekte einer niedrigeren Ebene wie Links gesammelt und in nützlichere Konzepte / Objekte konvertiert werden - Clients, Sitzungen usw.Die interessantesten Objekte in der BANG-Netzwerkbibliothek! sind diejenigen, die sich im Multiplayer-Level befinden. Hier bietet die API eine Reihe von Objekten, mit denen die Spielebene interagieren kann, bietet jedoch eine vom Spielansatz unabhängige Implementierung.- Client (): . () ( ). , .
- Session (): , , , . . host() join(), , , . / , .
- Channel Ordered Channel: . . TimeSync, .
- Shared Data: . , , .
- Time Sync: .
Game Communications, 4RTS3. , , . , , .
Verbessertes Synchronisationssystem. Keines der
Age of Empires- Entwicklungsteams kann sagen, dass wir keine besseren Synchronisationstools benötigen. Wie bei jedem Projekt stellt sich bei der Analyse des Entwicklungsprozesses im Post-Mortem-Bereich heraus, dass die meiste Zeit in einigen Bereichen verbracht wurde, aber es könnte viel weniger sein, wenn wir sie im Voraus angehen. Zu Beginn der Entwicklung von RTS3 stand das Debuggen der Synchronisation ganz oben auf der Liste dieser Bereiche.
Das RTS3-Synchronisationsverfolgungssystem zielt hauptsächlich darauf ab, Synchronisationsfehler schnell zu erkennen. Weitere Prioritäten waren die Vereinfachung der Verwendung, die Fähigkeit, beliebig große Mengen synchronisierter Daten zu verarbeiten, die durch das System geleitet werden, die Fähigkeit, den Synchronisationscode im Release-Build vollständig zu kompilieren, und schließlich die Fähigkeit, die Testkonfiguration durch Ändern von Variablen vollständig zu ändern, anstatt sie vollständig neu zu kompilieren.
Die Synchronisationsprüfung in RTS3 wird mit zwei Makrosätzen durchgeführt:
#define syncRandCode(userinfo)
gSync->addCodeSync(cRandSync, userinfo, __FILE__, __LINE__)
#define syncRandData(userinfo,
v) gSync->addDataSync(cRandSync, v, userinfo, __FILE__, __LINE__)
Beide Makros erhalten den Zeichenfolgenparameter userinfo, der den Namen oder die Angabe eines bestimmten synchronisierten Elements darstellt. Ein Synchronisationsaufruf könnte beispielsweise folgendermaßen aussehen:
syncRandCode("syncing the random seed", seed);
Synchrone Konsolenbefehle und Konfigurationsvariablen. Wie jeder
Quake- Mod-Entwickler bestätigen kann, sind Konsolenbefehle und Konfigurationsvariablen für den Entwicklungsprozess sehr wichtig. Konsolenbefehle sind einfache Funktionsaufrufe, die mithilfe der Startkonfigurationsdatei, der In-Game-Konsole oder der Benutzeroberfläche ausgeführt werden und beliebige Spielfunktionen aufrufen. Konfigurationsvariablen sind benannte Datentypen, die durch die einfachen Funktionen get, set, define und toggle bereitgestellt werden, die wir für alle Arten von Tests und Einstellungskonfigurationsparametern verwenden.
Paul hat Multiplayer-kompatible Versionen unserer Konsolenbefehlssysteme und variablen Konfigurationen erstellt. Mit ihrer Hilfe können wir eine reguläre Konfigurationsvariable (z. B. enableCheating) bequem in eine Multiplayer-Konfigurationsvariable umwandeln, indem wir der Definition der Konfigurationsvariablen ein Flag hinzufügen. Wenn dieses Flag aktiviert ist, wird die Konfigurationsvariable innerhalb des Mehrspielerspiels übertragen, und synchronisierte Entscheidungen im Spiel (z. B. über die Zulässigkeit der freien Übertragung von Ressourcen) können auf ihrem Wert basieren. Konsolenbefehle des Multiplayers haben ein ähnliches Prinzip: Aufrufe der Konsolenbefehle des Multiplayers werden über das Netzwerk übertragen und auf allen Client-Computern synchron ausgeführt.
Mit diesen beiden Tools können Entwickler das Multiplayer-System verwenden, ohne Code schreiben zu müssen. Sie können schnell neue Test- und Konfigurationstools hinzufügen und diese einfach in eine Netzwerkumgebung integrieren.
Zusammenfassend
Die synchronisierte Simulation und das Peer-to-Peer-Modell wurden in der Age of Empires-Spieleserie erfolgreich eingesetzt. Trotz der entscheidenden Bedeutung, Zeit in die Erstellung von Tools und Technologien zur Lösung der Hauptprobleme dieses Ansatzes (wie Synchronisation und Netzwerkmetriken) zu investieren, wurde die Realisierbarkeit dieser Architektur im Genre der Echtzeitstrategien durch Erfahrung bewiesen. Nachfolgende Verbesserungen an RTS3 führten dazu, dass das Multiplayer-Gameplay selbst unter den schrecklichsten Bedingungen von Netzwerkverbindungen kaum von Einzelspielern zu unterscheiden ist.