paint-brush
10 Jahre Kriegsroboter und ein Blick aus technischer Perspektivevon@pauxi
3,667 Lesungen
3,667 Lesungen

10 Jahre Kriegsroboter und ein Blick aus technischer Perspektive

von Paul Xi31m2024/04/30
Read on Terminal Reader

Zu lang; Lesen

In diesem Beitrag werfen wir einen Blick auf die technische Seite von War Robots der letzten 10 Jahre: die coolen Sachen, die Probleme, die Experimente, die Neuauflage des Spiels und mehr!
featured image - 10 Jahre Kriegsroboter und ein Blick aus technischer Perspektive
Paul Xi HackerNoon profile picture
0-item
1-item


The War Robots feiert diesen April sein 10-jähriges Jubiläum! Und bis heute entwickeln und unterstützen wir es weiter, indem wir nicht nur neue Funktionen für unsere Spieler veröffentlichen, sondern es auch technisch verbessern.


In diesem Artikel berichten wir über unsere langjährige Erfahrung bei der technischen Entwicklung dieses großen Projekts. Doch zunächst hier ein kurzer Überblick über den aktuellen Stand des Projekts:


  • Hunderttausende DAU (Daily Active Users)
  • Hunderte Millionen Installationen
  • Zehntausende gleichzeitige 12-Personen-Spiele
  • Verfügbar auf vier großen Plattformen (iOS, Android, Steam, Amazon)
  • Zehntausende unterstützte Geräte, darunter Android und PC
  • Hunderte von Servern
  • Ungefähr 20 Client-Entwickler, 9 Server-Entwickler, ein projektübergreifendes Entwicklungsteam von 8 Personen und 3 DevOps
  • Etwa 1,5 Millionen Zeilen clientseitiger Code
  • Ich verwende Unity ab Version 4 im Jahr 2014 und verwende aktuell die Version 2022 LTS im Jahr 2024.


Um die Funktionalität dieser Art von Projekt aufrechtzuerhalten und eine weitere qualitativ hochwertige Entwicklung sicherzustellen, reicht es nicht aus, nur an unmittelbaren Produktaufgaben zu arbeiten; es ist auch wichtig, den technischen Zustand des Produkts zu verbessern, die Entwicklung zu vereinfachen und Prozesse zu automatisieren – einschließlich derjenigen, die mit der Erstellung neuer Inhalte zusammenhängen. Darüber hinaus müssen wir uns ständig an den sich verändernden Markt der verfügbaren Benutzergeräte anpassen.


Der Text basiert auf Interviews mit Pavel Zinov, Leiter der Entwicklungsabteilung bei Pixonic (MY.GAMES), und Dmitry Chetverikov, leitender Entwickler von War Robots.


Der Anfang

Gehen wir zurück ins Jahr 2014: Das War Robots-Projekt wurde ursprünglich von einem kleinen Team entwickelt und alle technischen Lösungen passten in das Paradigma der schnellen Entwicklung und Bereitstellung neuer Funktionen für den Markt. Zu diesem Zeitpunkt verfügte das Unternehmen nicht über die nötigen Ressourcen, um dedizierte Server zu hosten, und so kam War Robots mit einem Netzwerk-Multiplayer auf den Markt, der auf P2P-Logik basierte.


Photon Cloud wurde zum Übertragen von Daten zwischen Clients verwendet: Jeder Spielerbefehl, sei es Bewegung, Schießen oder ein anderer Befehl, wurde mithilfe separater RPCs an den Photon Cloud-Server gesendet. Da es keinen dedizierten Server gab, hatte das Spiel einen Master-Client, der für die Zuverlässigkeit des Spielstatus für alle Spieler verantwortlich war. Gleichzeitig verarbeiteten die übrigen Spieler den Status des gesamten Spiels vollständig auf ihren lokalen Clients.


Beispielsweise gab es keine Bewegungsüberprüfung – der lokale Client bewegte seinen Roboter nach eigenem Ermessen, dieser Status wurde an den Master-Client gesendet, und der Master-Client glaubte diesem Status bedingungslos und leitete ihn einfach an andere Clients im Spiel weiter. Jeder Client führte unabhängig ein Protokoll des Kampfes und schickte es am Ende des Spiels an den Server. Anschließend verarbeitete der Server die Protokolle aller Spieler, vergab eine Belohnung und schickte die Ergebnisse des Spiels an alle Spieler.


Wir verwendeten einen speziellen Profilserver, um Informationen über Spielerprofile zu speichern. Dieser bestand aus mehreren Servern mit einer Cassandra-Datenbank. Jeder Server war ein einfacher App-Server auf Tomcat, und die Clients interagierten über HTTP mit ihm.


Nachteile unseres ersten Ansatzes

Der im Gameplay verwendete Ansatz hatte eine Reihe von Nachteilen. Das Team war sich dieser natürlich bewusst, aber aufgrund der Geschwindigkeit der Entwicklung und der Markteinführung des Endprodukts mussten einige Kompromisse eingegangen werden.


Zu diesen Nachteilen gehörte vor allem die Qualität der Verbindung des Master-Clients. Wenn der Client ein schlechtes Netzwerk hatte, kam es bei allen Spielern in einem Spiel zu Verzögerungen. Und wenn der Master-Client nicht auf einem sehr leistungsstarken Smartphone lief, kam es aufgrund der hohen Belastung auch beim Spiel zu Verzögerungen bei der Datenübertragung. In diesem Fall hatten also neben dem Master-Client auch andere Spieler zu leiden.


Der zweite Nachteil war, dass diese Architektur anfällig für Probleme mit Betrügern war. Da der Endzustand vom Master-Client übertragen wurde, konnte dieser Client viele Spielparameter nach eigenem Ermessen ändern, beispielsweise die Anzahl der eroberten Zonen im Spiel zählen.


Drittens gibt es ein Problem mit der Matchmaking-Funktionalität von Photon Cloud: Der älteste Spieler im Photon Cloud Matchmaking-Raum wird zum Master-Client, und wenn ihm während des Matchmakings etwas passiert (z. B. eine Unterbrechung), wird die Gruppenerstellung negativ beeinflusst. Dazugehörige interessante Tatsache: Um zu verhindern, dass das Matchmaking in Photon Cloud nach dem Senden einer Gruppe zu einem Match geschlossen wird, haben wir eine Zeit lang sogar einen einfachen PC in unserem Büro aufgestellt, der das Matchmaking immer unterstützte, was bedeutet, dass das Matchmaking mit Photon Cloud nicht fehlschlagen konnte.


Irgendwann erreichte die Zahl der Probleme und Supportanfragen eine kritische Masse und wir begannen ernsthaft darüber nachzudenken, die technische Architektur des Spiels weiterzuentwickeln – diese neue Architektur wurde Infrastruktur 2.0 genannt.


Der Übergang zur Infrastruktur 2.0

Die Hauptidee hinter dieser Architektur war die Schaffung dedizierter Spieleserver. Zu dieser Zeit fehlten dem Team des Kunden Programmierer mit umfassender Erfahrung in der Serverentwicklung. Das Unternehmen arbeitete jedoch gleichzeitig an einem serverbasierten Analyseprojekt mit hoher Auslastung, das wir AppMetr nannten. Das Team hatte ein Produkt entwickelt, das Milliarden von Nachrichten pro Tag verarbeitete, und es verfügte über umfassendes Fachwissen in der Entwicklung, Konfiguration und korrekten Architektur von Serverlösungen. Und so beteiligten sich einige Mitglieder dieses Teams an der Arbeit an Infrastruktur 2.0.


Im Jahr 2015 wurde innerhalb relativ kurzer Zeit ein .NET-Server erstellt, der in das Photon Server SDK-Framework eingebettet war und auf Windows Server lief. Wir beschlossen, Photon Cloud aufzugeben, nur das Photon Server SDK-Netzwerkframework im Clientprojekt beizubehalten und einen Masterserver zum Verbinden von Clients und entsprechenden Servern für das Matchmaking zu erstellen. Ein Teil der Logik wurde vom Client auf einen dedizierten Spieleserver verschoben. Insbesondere wurde eine grundlegende Schadensvalidierung eingeführt und die Berechnung der Spielergebnisse auf den Server verlagert.



Die Entstehung von Microservices

Nach der erfolgreichen Erstellung von Infrastruktur 2.0 wurde uns klar, dass wir die Verantwortung der Dienste weiter entkoppeln mussten: Das Ergebnis war die Erstellung einer Microservice-Architektur. Der erste Microservice, der auf dieser Architektur erstellt wurde, war Clans.


Daraus entstand ein separater Kommunikationsdienst, der für die Datenübertragung zwischen den Mikrodiensten zuständig war. Dem Client wurde beigebracht, eine Verbindung mit dem „Hangar“ herzustellen, der für die Metamechanik auf dem Spielserver zuständig ist, und API-Anfragen (ein einziger Einstiegspunkt für die Interaktion mit Diensten) mit UDP über Photon Cloud zu stellen. Nach und nach wuchs die Anzahl der Dienste, und infolgedessen überarbeiteten wir den Matchmaking-Mikrodienst. Damit wurde die Nachrichtenfunktion Inbox erstellt.


Als wir Clans erstellten, war klar, dass die Spieler im Spiel miteinander kommunizieren wollten – sie brauchten eine Art Chat. Dieser wurde ursprünglich auf Basis von Photon Chat erstellt, aber der gesamte Chatverlauf wurde gelöscht, sobald der letzte Client die Verbindung trennte. Daher konvertierten wir diese Lösung in einen separaten Microservice auf Basis der Cassandra-Datenbank.


Infrastruktur 4.0 und Serverstandorte

Durch die neue Microservices-Architektur konnten wir eine große Zahl voneinander unabhängiger Dienste komfortabel verwalten, das gesamte System also horizontal skalieren und Ausfallzeiten vermeiden.


In unserem Spiel erfolgten Updates, ohne dass Server angehalten werden mussten. Das Serverprofil war mit mehreren Clientversionen kompatibel, und was Spieleserver betrifft, haben wir immer einen Pool von Servern für die alten und neuen Versionen des Clients. Dieser Pool verschob sich nach der Veröffentlichung einer neuen Version in den App Stores allmählich, und Spieleserver verschwanden mit der Zeit aus der alten Version. Der allgemeine Umriss der aktuellen Infrastruktur wurde Infrastruktur 4.0 genannt und sah folgendermaßen aus:



Neben der Änderung der Architektur standen wir auch vor dem Dilemma, wo unsere Server untergebracht werden sollten, da sie Spieler aus aller Welt abdecken sollten. Ursprünglich befanden sich viele Microservices aus verschiedenen Gründen in Amazon AWS, insbesondere wegen der Flexibilität, die dieses System in Bezug auf die Skalierung bietet, da dies in Zeiten mit hohem Gaming-Verkehr (wie etwa wenn es in Geschäften angeboten wurde und um UA zu steigern) sehr wichtig war. Außerdem war es damals schwierig, in Asien einen guten Hosting-Anbieter zu finden, der eine gute Netzwerkqualität und Verbindung mit der Außenwelt bieten konnte.


Der einzige Nachteil von Amazon AWS waren die hohen Kosten. Daher wurden viele unserer Server im Laufe der Zeit auf unsere eigene Hardware verlagert – Server, die wir in Rechenzentren auf der ganzen Welt mieten. Dennoch blieb Amazon AWS ein wichtiger Teil der Architektur, da es die Entwicklung von Code ermöglichte, der sich ständig änderte (insbesondere der Code für die Dienste Ligen, Clans, Chats und Nachrichten) und der nicht ausreichend durch Stabilitätstests abgedeckt war. Aber sobald wir erkannten, dass der Microservice stabil war, haben wir ihn in unsere eigenen Einrichtungen verlagert. Derzeit laufen alle unsere Microservices auf unseren Hardwareservern.


Gerätequalitätskontrolle und weitere Kennzahlen

Im Jahr 2016 wurden wichtige Änderungen am Rendering des Spiels vorgenommen: Das Konzept der Ubershader mit einem einzigen Texturatlas für alle Mechs im Kampf erschien, was die Anzahl der Draw Calls erheblich reduzierte und die Spieleleistung verbesserte.


Es wurde klar, dass unser Spiel auf Zehntausenden verschiedener Geräte gespielt wurde, und wir wollten jedem Spieler die bestmöglichen Spielbedingungen bieten. Daher haben wir den Quality Manager erstellt, im Grunde eine Datei, die das Gerät eines Spielers analysiert und bestimmte Spiel- oder Rendering-Funktionen aktiviert (oder deaktiviert). Darüber hinaus ermöglichte uns diese Funktion, diese Funktionen bis auf das spezifische Gerätemodell zu verwalten, sodass wir die Probleme unserer Spieler schnell beheben konnten.


Es ist auch möglich, die Einstellungen des Quality Managers vom Server herunterzuladen und die Qualität auf dem Gerät dynamisch je nach aktueller Leistung auszuwählen. Die Logik ist ganz einfach: Der gesamte Hauptteil des Quality Managers ist in Blöcke unterteilt, von denen jeder für einen bestimmten Leistungsaspekt verantwortlich ist. (Zum Beispiel die Qualität der Schatten oder des Anti-Aliasing.) Wenn die Leistung eines Benutzers nachlässt, versucht das System, die Werte innerhalb des Blocks zu ändern und eine Option auszuwählen, die zu einer Leistungssteigerung führt. Wir werden etwas später auf die Entwicklung des Quality Managers zurückkommen, aber zu diesem Zeitpunkt war seine Implementierung recht schnell und bot das erforderliche Maß an Kontrolle.


Auch die Arbeit am Quality Manager war notwendig, da die Grafikentwicklung weiterging. Das Spiel verfügt jetzt über kaskadierende dynamische Schatten, die vollständig von unseren Grafikprogrammierern implementiert wurden.


Nach und nach tauchten im Code des Projekts ziemlich viele Entitäten auf, also beschlossen wir, dass es gut wäre, ihre Lebensdauer zu verwalten und den Zugriff auf verschiedene Funktionen abzugrenzen. Dies war besonders wichtig für die Trennung des Hangar- und Kampfcodes, da viele Ressourcen nicht gelöscht wurden, wenn sich der Spielkontext änderte. Wir begannen, verschiedene IoC-Abhängigkeitsverwaltungscontainer zu untersuchen. Insbesondere haben wir uns die StrangeIoC-Lösung angesehen. Zu diesem Zeitpunkt erschien uns die Lösung ziemlich umständlich, also implementierten wir unsere eigene einfache DI in das Projekt. Wir führten auch Hangar- und Kampfkontexte ein.


Darüber hinaus haben wir mit der Qualitätskontrolle des Projekts begonnen; FirebaseCrashlytics wurde in das Spiel integriert, um Abstürze, ANRs und Ausnahmen in der Produktionsumgebung zu identifizieren.


Mithilfe unserer internen Analyselösung namens AppMetr haben wir die erforderlichen Dashboards für die regelmäßige Überwachung des Kundenstatus und den Vergleich der während der Releases vorgenommenen Änderungen erstellt. Um die Qualität des Projekts zu verbessern und das Vertrauen in die am Code vorgenommenen Änderungen zu erhöhen, haben wir außerdem mit der Erforschung von Autotests begonnen.


Die zunehmende Anzahl von Assets und einzigartigen Bugs im Inhalt brachte uns dazu, über die Organisation und Vereinheitlichung von Assets nachzudenken. Dies galt insbesondere für Mechs, da ihr Aufbau für jeden von ihnen einzigartig war. Dafür erstellten wir Tools in Unity und mit diesen erstellten wir Mech-Dummies mit den wichtigsten erforderlichen Komponenten. Dies bedeutete, dass die Spieledesignabteilung sie dann problemlos bearbeiten konnte – und so begannen wir erstmals, unsere Arbeit mit Mechs zu vereinheitlichen.


Weitere Plattformen

Das Projekt wuchs weiter und das Team begann darüber nachzudenken, es auf anderen Plattformen zu veröffentlichen. Außerdem war es für einige mobile Plattformen zu dieser Zeit wichtig, dass das Spiel so viele native Funktionen der Plattform wie möglich unterstützte, da dies die Präsentation des Spiels ermöglichte. Also begannen wir mit der Arbeit an einer experimentellen Version von War Robots für Apple TV und einer Begleit-App für die Apple Watch.


Außerdem haben wir das Spiel 2016 auf einer für uns neuen Plattform herausgebracht – dem Amazon AppStore. In Bezug auf die technischen Eigenschaften ist diese Plattform einzigartig, da sie eine einheitliche Gerätereihe wie Apple hat, die Leistung dieser Reihe jedoch auf dem Niveau von Low-End-Androids liegt. Vor diesem Hintergrund wurde beim Start auf dieser Plattform viel Arbeit in die Optimierung der Speichernutzung und Leistung gesteckt, beispielsweise haben wir mit Atlanten und Texturkomprimierung gearbeitet. Das Amazon-Zahlungssystem, ein Analogon des Game Center für Anmeldung und Erfolge, wurde in den Client integriert, sodass der Arbeitsablauf mit der Spieleranmeldung überarbeitet und die ersten Erfolge eingeführt wurden.


Es ist auch erwähnenswert, dass das Kundenteam gleichzeitig erstmals eine Reihe von Tools für den Unity Editor entwickelte, mit denen es möglich wurde, In-Game-Videos in der Engine aufzunehmen. Dies erleichterte unserer Marketingabteilung die Arbeit mit Assets, die Steuerung des Kampfes und die Nutzung der Kamera, um die Videos zu erstellen, die unser Publikum so sehr liebte.


Kampf gegen Betrüger

Da Unity und insbesondere die Physik-Engine auf dem Server fehlten, wurden die meisten Spiele weiterhin auf den Geräten der Spieler emuliert. Aus diesem Grund gab es weiterhin Probleme mit Cheatern. In regelmäßigen Abständen erhielt unser Support-Team Feedback von unseren Benutzern mit Videos von Cheatern: Sie beschleunigten zu einem günstigen Zeitpunkt, flogen über die Karte, töteten andere Spieler um eine Ecke herum, wurden unsterblich und so weiter.


Im Idealfall würden wir die gesamte Spielmechanik auf den Server übertragen. Abgesehen davon, dass das Spiel ständig weiterentwickelt wird und bereits eine ganze Menge Legacy-Code angesammelt hat, könnte ein Ansatz mit einem autoritativen Server jedoch auch andere Nachteile mit sich bringen. Beispielsweise eine erhöhte Belastung der Infrastruktur und die Notwendigkeit einer besseren Internetverbindung. Angesichts der Tatsache, dass die meisten unserer Benutzer in 3G/4G-Netzwerken spielten, war dieser Ansatz zwar naheliegend, aber keine effektive Lösung des Problems. Als alternativen Ansatz zur Bekämpfung von Cheatern innerhalb des Teams hatten wir eine neue Idee – die Schaffung eines „Quorums“.


Quorum ist ein Mechanismus, der es Ihnen ermöglicht, mehrere Simulationen verschiedener Spieler zu vergleichen, wenn Sie den verursachten Schaden bestätigen. Das Erleiden von Schaden ist eines der Hauptmerkmale des Spiels, von dem praktisch der Rest seines Zustands abhängt. Wenn Sie beispielsweise Ihre Gegner zerstören, können diese keine Beacons erobern.


Die Idee dieser Entscheidung war folgende: Jeder Spieler simulierte weiterhin die gesamte Welt (einschließlich des Erschießens anderer Spieler) und sendete die Ergebnisse an den Server. Der Server analysierte die Ergebnisse aller Spieler und entschied, ob und in welchem Ausmaß der Spieler letztendlich Schaden erlitten hatte. An unseren Spielen nehmen 12 Personen teil. Damit der Server also davon ausgeht, dass Schaden entstanden ist, reicht es aus, wenn dies in den lokalen Simulationen von 7 Spielern registriert wird. Diese Ergebnisse würden dann zur weiteren Validierung an den Server gesendet. Schematisch kann dieser Algorithmus wie folgt dargestellt werden:



Mit diesem Schema konnten wir die Anzahl der Cheater, die sich im Kampf unsterblich machten, deutlich reduzieren. Die folgende Grafik zeigt die Anzahl der Beschwerden gegen diese Benutzer sowie die Phasen der Aktivierung von Schadensberechnungsfunktionen auf dem Server und der Aktivierung des Schadensquorums:



Dieser Schadensmechanismus löste lange Zeit das Cheat-Problem, denn trotz der fehlenden Physik auf dem Server (und der damit verbundenen Unfähigkeit, Dinge wie die Oberflächentopographie oder die tatsächliche Position der Roboter im Raum zu berücksichtigen) ermöglichten die Ergebnisse der Simulation für alle Clients und deren Konsens ein eindeutiges Verständnis darüber, wer wem unter welchen Bedingungen Schaden zugefügt hatte.


Weiterentwicklung des Projekts

Im Laufe der Zeit haben wir dem Spiel zusätzlich zu dynamischen Schatten Post-Effekte hinzugefügt, indem wir den Unity Post Processing Stack und Batch-Rendering verwendet haben. Beispiele für verbesserte Grafiken durch die Anwendung von Post-Processing-Effekten sind im folgenden Bild zu sehen:



Um besser zu verstehen, was in Debug-Builds passiert, haben wir ein Protokollierungssystem erstellt und einen lokalen Dienst in der internen Infrastruktur bereitgestellt, der Protokolle von internen Testern sammeln und die Suche nach Fehlerursachen erleichtern kann. Dieses Tool wird von der Qualitätssicherung weiterhin für Playtests verwendet und die Ergebnisse seiner Arbeit werden an Tickets in Jira angehängt.


Wir haben dem Projekt auch einen selbstgeschriebenen Paketmanager hinzugefügt. Ursprünglich wollten wir die Arbeit mit verschiedenen Paketen und externen Plugins verbessern (von denen das Projekt bereits eine ausreichende Anzahl angesammelt hatte). Die Funktionalität von Unity reichte damals jedoch nicht aus, sodass unser internes Plattformteam eine eigene Lösung mit Paketversionierung, Speicherung mithilfe von NPM und der Möglichkeit entwickelte, Pakete einfach durch Hinzufügen eines Links zu GitHub mit dem Projekt zu verbinden. Da wir dennoch eine native Engine-Lösung verwenden wollten, haben wir uns mit Kollegen von Unity beraten, und einige unserer Ideen wurden in die endgültige Lösung von Unity aufgenommen, als sie 2018 ihren Paketmanager veröffentlichten.


Wir haben die Anzahl der Plattformen, auf denen unser Spiel verfügbar war, weiter ausgebaut. Schließlich erschien Facebook Gameroom, eine Plattform, die Tastatur und Maus unterstützt. Dies ist eine Lösung von Facebook (Meta), mit der Benutzer Anwendungen auf einem PC ausführen können; im Wesentlichen ist es ein Analogon zum Steam-Store. Natürlich ist das Facebook-Publikum recht vielfältig, und Facebook Gameroom wurde auf einer großen Anzahl von Geräten gestartet, hauptsächlich solchen, die nicht für Spiele gedacht sind. Daher haben wir beschlossen, die mobile Grafik im Spiel beizubehalten, um die PCs des Hauptpublikums nicht zu belasten. Aus technischer Sicht waren die einzigen wesentlichen Änderungen, die das Spiel erforderte, die Integration des SDK, des Zahlungssystems und die Unterstützung für Tastatur und Maus mithilfe des nativen Unity-Eingabesystems.


Technisch unterschied es sich kaum von der Version des Spiels für Steam, aber die Qualität der Geräte war deutlich geringer, da die Plattform als Ort für Gelegenheitsspieler mit relativ einfachen Geräten positioniert war, auf denen nichts weiter als ein Browser laufen konnte. Mit diesem Gedanken hoffte Facebook, einen relativ großen Markt zu erobern. Die Ressourcen dieser Geräte waren begrenzt, und insbesondere die Plattform hatte ständige Speicher- und Leistungsprobleme.


Später wurde die Plattform geschlossen und wir haben unsere Spieler auf Steam übertragen, wo das möglich war. Dafür haben wir ein spezielles System mit Codes zum Übertragen von Konten zwischen Plattformen entwickelt.


Kriegsroboter in VR ausprobieren

Ein weiteres bemerkenswertes Ereignis im Jahr 2017 war die Veröffentlichung des iPhone X, des ersten Smartphones mit einer Notch. Zu diesem Zeitpunkt unterstützte Unity keine Geräte mit Notch, daher mussten wir eine benutzerdefinierte Lösung basierend auf den Parametern UnityEngine.Screen.safeArea erstellen, die die Benutzeroberfläche zwingt, unterschiedliche Sicherheitszonen auf dem Telefonbildschirm zu skalieren und zu vermeiden.


Darüber hinaus haben wir 2017 beschlossen, etwas anderes auszuprobieren – wir haben eine VR-Version unseres Spiels auf Steam veröffentlicht. Die Entwicklung dauerte etwa sechs Monate und umfasste Tests mit allen damals verfügbaren Helmen: Oculus, HTC Vive und Windows Mixed Reality. Diese Arbeit wurde mithilfe der Oculus API und der Steam API durchgeführt. Darüber hinaus wurde eine Demoversion für PS VR-Headsets sowie Unterstützung für MacOS erstellt.


Aus technischer Sicht war es notwendig, eine stabile FPS aufrechtzuerhalten: 60 FPS für PS VR und 90 FPS für HTC Vive. Um dies zu erreichen, wurde neben Standard-Frustum und Occlusion auch selbst geschriebenes Zone Culling sowie Reprojektionen (wenn einige Frames basierend auf vorherigen generiert werden) verwendet.


Um das Problem der Reisekrankheit zu lösen, wurde eine interessante kreative und technische Lösung gewählt: Unser Spieler wurde zum Roboterpiloten und setzte sich ins Cockpit. Die Kabine war ein statisches Element, sodass das Gehirn sie als eine Art Konstante in der Welt wahrnahm, und daher funktionierte die Bewegung im Raum sehr gut.


Das Spiel hatte außerdem ein Szenario, das die Entwicklung mehrerer separater Auslöser, Skripte und eigener Zeitleisten erforderte, da Cinemachine in dieser Version von Unity noch nicht verfügbar war.


Für jede Waffe wurde die Logik zum Zielen, Sperren, Verfolgen und automatischen Zielen von Grund auf neu geschrieben.


Die Version wurde auf Steam veröffentlicht und von unseren Spielern gut angenommen. Nach der Kickstarter-Kampagne haben wir uns jedoch entschieden, die Entwicklung des Projekts nicht fortzusetzen, da die Entwicklung eines vollwertigen PvP-Shooters für VR mit technischen Risiken verbunden war und der Markt für ein solches Projekt nicht bereit war.


Umgang mit unserem ersten schwerwiegenden Fehler

Während wir daran arbeiteten, die technische Komponente des Spiels zu verbessern und neue Mechaniken und Plattformen zu entwickeln bzw. bestehende weiterzuentwickeln, stießen wir auf den ersten schwerwiegenden Fehler im Spiel, der sich beim Start einer neuen Werbeaktion negativ auf die Einnahmen auswirkte. Das Problem bestand darin, dass die Schaltfläche „Preis“ fälschlicherweise als „Preis“ lokalisiert wurde. Die meisten Spieler waren dadurch verwirrt, kauften mit echtem Geld und verlangten dann eine Rückerstattung.


Das technische Problem bestand darin, dass damals alle unsere Lokalisierungen in den Spieleclient integriert waren. Als dieses Problem auftrat, wurde uns klar, dass wir die Arbeit an einer Lösung, mit der wir Lokalisierungen aktualisieren konnten, nicht länger aufschieben konnten. So entstand eine Lösung auf Basis von CDN und begleitenden Tools, wie z. B. Projekten in TeamCity, die das Hochladen von Lokalisierungsdateien auf das CDN automatisierten.


Dadurch konnten wir Lokalisierungen von den von uns verwendeten Diensten (POEditor) herunterladen und Rohdaten auf das CDN hochladen.

Danach begann das Serverprofil, Links für jede Version des Clients entsprechend den Lokalisierungsdaten zu setzen. Beim Starten der Anwendung begann der Profilserver, diesen Link an den Client zu senden, und diese Daten wurden heruntergeladen und zwischengespeichert.


Optimierte Arbeit mit Daten

Springen wir ins Jahr 2018. Mit dem Wachstum des Projekts wuchs auch die Datenmenge, die vom Server an den Client übertragen wurde. Beim Verbinden mit dem Server mussten ziemlich viele Daten über den Kontostand, aktuelle Einstellungen usw. heruntergeladen werden.


Die aktuellen Daten wurden im XML-Format präsentiert und mit dem standardmäßigen Unity-Serialisierer serialisiert.

Neben der Übertragung einer ziemlich großen Datenmenge beim Starten des Clients sowie bei der Kommunikation mit dem Profilserver und dem Spieleserver verbrauchten die Spielergeräte viel Speicher für die Speicherung des aktuellen Kontostands und dessen Serialisierung/Deserialisierung.


Es wurde deutlich, dass zur Verbesserung der Leistung und Startzeit der Anwendung F&E-Arbeiten zur Suche nach alternativen Protokollen erforderlich sein würden.


Die Ergebnisse der Studie anhand unserer Testdaten sind in dieser Tabelle dargestellt:


Protokoll

Größe

zuordnen

Zeit

XML

2,2 MB

18,4 MiB

518,4 ms

MessagePack (ohne Vertrag)

1,7 MB

2 MiB

32,35 ms

MessagePack (Str-Schlüssel)

1,2 MB

1,9 MiB

25,8 ms

MessagePack (int-Schlüssel)

0,53 MB

1.9

16,5

Flachpuffer

0,5 MB

216 B

0 ms / 12 ms / 450 KB


Aus diesem Grund haben wir uns für das MessagePack-Format entschieden, da die Migration kostengünstiger war als die Umstellung auf FlatBuffers bei ähnlichen Ausgabeergebnissen, insbesondere bei der Verwendung von MessagePack mit ganzzahligen Schlüsseln.


Für FlatBuffers (und mit Protokollpuffern) ist es notwendig, das Nachrichtenformat in einer separaten Sprache zu beschreiben, C#- und Java-Code zu generieren und den generierten Code in der Anwendung zu verwenden. Da wir diese zusätzlichen Kosten für die Umgestaltung von Client und Server nicht auf uns nehmen wollten, sind wir auf MessagePack umgestiegen.


Der Übergang verlief nahezu nahtlos und in den ersten Versionen unterstützten wir die Möglichkeit, zu XML zurückzukehren, bis wir davon überzeugt waren, dass es mit dem neuen System keine Probleme gab. Die neue Lösung deckte alle unsere Aufgaben ab – sie reduzierte die Client-Ladezeit erheblich und verbesserte auch die Leistung bei Anfragen an Server.


Jede Funktion oder neue technische Lösung in unserem Projekt wird unter einer „Flagge“ veröffentlicht. Diese Flagge wird im Profil des Spielers gespeichert und kommt zusammen mit dem Guthaben beim Start des Spiels an den Client. Wenn eine neue Funktion veröffentlicht wird, insbesondere eine technische, enthalten mehrere Client-Versionen in der Regel beide Funktionen – die alten und die neuen. Die Aktivierung neuer Funktionen erfolgt streng in Übereinstimmung mit dem Status der oben beschriebenen Flagge, sodass wir den technischen Erfolg einer bestimmten Lösung in Echtzeit überwachen und anpassen können.


Nach und nach wurde es Zeit, die Dependency Injection-Funktionalität im Projekt zu aktualisieren. Die aktuelle Version konnte mit einer großen Anzahl von Abhängigkeiten nicht mehr umgehen und führte in einigen Fällen nicht offensichtliche Verbindungen ein, die sehr schwer zu unterbrechen und umzugestalten waren. (Dies galt insbesondere für Innovationen, die auf die eine oder andere Weise mit der Benutzeroberfläche zusammenhingen.)


Bei der Auswahl einer neuen Lösung war die Wahl einfach: das bekannte Zenject, das sich in unseren anderen Projekten bewährt hatte. Dieses Projekt befindet sich seit langem in der Entwicklung, wird aktiv unterstützt, es werden neue Funktionen hinzugefügt und viele Entwickler im Team waren in irgendeiner Weise damit vertraut.


Nach und nach begannen wir, War Robots mit Zenject neu zu schreiben. Alle neuen Module wurden damit entwickelt und die alten nach und nach überarbeitet. Seitdem wir Zenject verwenden, haben wir eine klarere Abfolge von Ladediensten innerhalb der Kontexte, die wir zuvor besprochen haben (Kampf und Hangar). Dadurch konnten die Entwickler leichter in die Entwicklung des Projekts eintauchen und in diesen Kontexten selbstbewusster neue Funktionen entwickeln.


In relativ neuen Versionen von Unity wurde es möglich, über async/await mit asynchronem Code zu arbeiten. Unser Code verwendete bereits asynchronen Code, aber es gab keinen einheitlichen Standard für die Codebasis. Da das Unity-Skripting-Backend nun async/await unterstützte, beschlossen wir, Forschung und Entwicklung durchzuführen und unsere Ansätze für asynchronen Code zu standardisieren.


Eine weitere Motivation bestand darin, die Callback-Hölle aus dem Code zu entfernen – diese entsteht, wenn es eine sequentielle Kette asynchroner Aufrufe gibt und jeder Aufruf auf die Ergebnisse des nächsten wartet.


Zu dieser Zeit gab es mehrere beliebte Lösungen wie RSG oder UniRx. Wir haben sie alle verglichen und in einer einzigen Tabelle zusammengestellt:



RSG.Versprechen

TPL

TPL mit Warten

UniTask

UniTask mit asynchron

Zeit bis zum Abschluss, s

0,15843

0,1305305

0,1165172

0,1330536

0,1208553

Zeit/Selbst des ersten Frames, ms

105,25/82,63

13,51/11,86

21,89/18,40

28,80/24,89

19,27/15,94

Erste Frame-Zuweisungen

40,8 MB

2,1 MB

5,0 MB

8,5 MB

5,4 MB

Zweites Bild Zeit/Selbst, ms

55,39/23,48

0,38/0,04

0,28/0,02

0,32/0,03

0,69/0,01

Zweite Frame-Zuordnungen

3,1 MB

10,2 KB

10,3 KB

10,3 KB

10,4 KB


Letztendlich haben wir uns für die Verwendung von nativem async/await als Standard für die Arbeit mit asynchronem C#-Code entschieden, mit dem die meisten Entwickler vertraut sind. Wir haben uns gegen die Verwendung von UniRx.Async entschieden, da die Vorteile des Plug-ins die Notwendigkeit einer Drittanbieterlösung nicht aufwiegen.


Wir haben uns entschieden, den Weg der minimal erforderlichen Funktionalität zu gehen. Wir haben die Verwendung von RSG.Promise oder Holdern aufgegeben, weil es erstens notwendig war, neue Entwickler in der Arbeit mit diesen, normalerweise unbekannten Tools zu schulen, und zweitens war es notwendig, einen Wrapper für den Drittanbietercode zu erstellen, der asynchrone Tasks in RSG.Promise oder Holdern verwendet. Die Wahl von async/await half auch dabei, den Entwicklungsansatz zwischen den Projekten des Unternehmens zu standardisieren. Dieser Übergang löste unsere Probleme – wir hatten am Ende einen klaren Prozess für die Arbeit mit asynchronem Code und entfernten die schwer zu unterstützende Callback-Hölle aus dem Projekt.


Die Benutzeroberfläche wurde schrittweise verbessert. Da in unserem Team die Funktionalität neuer Features von Client-Programmierern entwickelt wird und die Layout- und Schnittstellenentwicklung von der UI/UX-Abteilung durchgeführt wird, brauchten wir eine Lösung, die es uns ermöglicht, die Arbeit an derselben Funktion zu parallelisieren – sodass der Layout-Designer die Schnittstelle erstellen und testen kann, während der Programmierer die Logik schreibt.


Die Lösung für dieses Problem wurde durch den Übergang zum MVVM-Modell für die Arbeit mit der Schnittstelle gefunden. Dieses Modell ermöglicht es dem Schnittstellendesigner, nicht nur eine Schnittstelle zu entwerfen, ohne einen Programmierer einzubeziehen, sondern auch zu sehen, wie die Schnittstelle auf bestimmte Daten reagiert, wenn noch keine tatsächlichen Daten verbunden wurden. Nach einigen Recherchen zu Standardlösungen sowie dem schnellen Prototyping unserer eigenen Lösung namens Pixonic ReactiveBindings haben wir eine Vergleichstabelle mit den folgenden Ergebnissen zusammengestellt:



CPU-Zeit

Mem.-Zuteilung

Speichernutzung

Peppermint-Datenbindung

367 ms

73 KB

17,5 MB

DisplayFab

223 ms

147 KB

8,5 MB

Einheitsschweißen

267 ms

Datei:90 KB

15,5 MB

Pixonic Reaktive Bindungen

152 ms

23 KB

Gesamtgröße: 3 MB


Sobald sich das neue System bewährt hatte, vor allem hinsichtlich der Vereinfachung der Erstellung neuer Schnittstellen, begannen wir, es für alle neuen Projekte sowie für alle im Projekt auftretenden Neuerungen einzusetzen.


Remaster des Spiels für neue Generationen mobiler Geräte

Bis 2019 wurden mehrere Geräte von Apple und Samsung veröffentlicht, die in Sachen Grafik recht leistungsstark waren, sodass unser Unternehmen auf die Idee kam, War Robots deutlich zu verbessern. Wir wollten die Leistung all dieser neuen Geräte nutzen und das visuelle Erscheinungsbild des Spiels aktualisieren.


Neben dem aktualisierten Image hatten wir auch mehrere Anforderungen an unser aktualisiertes Produkt: Wir wollten einen 60-FPS-Spielemodus sowie unterschiedliche Ressourcenqualitäten für verschiedene Geräte unterstützen.


Auch der aktuelle Qualitätsmanager musste überarbeitet werden, da die Anzahl der Qualitäten innerhalb der Blöcke zunahm und diese im laufenden Betrieb umgeschaltet wurden, was die Produktivität verringerte und eine große Anzahl von Permutationen erzeugte, von denen jede einzelne getestet werden musste, was dem QA-Team bei jeder Veröffentlichung zusätzliche Kosten verursachte.


Als Erstes haben wir bei der Überarbeitung des Clients mit der Neugestaltung der Aufnahme begonnen. Die ursprüngliche Implementierung hing von der Frame-Rendering-Geschwindigkeit ab, da die Spieleinheit und ihre visuelle Darstellung im Client ein und dasselbe Objekt waren. Wir haben uns entschieden, diese Einheiten zu trennen, sodass die Spieleinheit der Aufnahme nicht mehr von ihrer visuellen Darstellung abhängig war. Dies führte zu einem faireren Spiel zwischen Geräten mit unterschiedlichen Frameraten.


Im Spiel wird eine große Anzahl von Schüssen abgefeuert, aber die Algorithmen zur Verarbeitung dieser Daten sind recht einfach – Bewegung, Entscheidung, ob der Gegner getroffen wurde usw. Das Konzept des Entity Component Systems passte perfekt zur Organisation der Logik der Projektilbewegung im Spiel, also haben wir uns entschieden, dabei zu bleiben.


Darüber hinaus verwendeten wir in all unseren neuen Projekten bereits ECS, um mit Logik zu arbeiten, und es war an der Zeit, dieses Paradigma zur Vereinheitlichung auf unser Hauptprojekt anzuwenden. Als Ergebnis der geleisteten Arbeit haben wir eine wichtige Anforderung erfüllt – die Möglichkeit, Bilder mit 60 FPS auszuführen. Allerdings wurde nicht der gesamte Kampfcode auf ECS übertragen, sodass das Potenzial dieses Ansatzes nicht vollständig ausgeschöpft werden konnte. Letztendlich haben wir die Leistung nicht so stark verbessert, wie wir es uns gewünscht hätten, aber wir haben sie auch nicht verschlechtert, was bei einem so starken Paradigmen- und Architekturwechsel immer noch ein wichtiger Indikator ist.


Gleichzeitig begannen wir mit der Arbeit an unserer PC-Version, um zu sehen, welches Grafikniveau wir mit unserem neuen Grafik-Stack erreichen konnten. Dabei begannen wir, Unity SRP zu nutzen, das damals noch in der Vorschauversion war und sich ständig änderte. Das Bild, das bei der Steam-Version herauskam, war ziemlich beeindruckend:



Darüber hinaus konnten einige der im obigen Bild gezeigten grafischen Funktionen auf leistungsstarke Mobilgeräte übertragen werden. Dies galt insbesondere für Apple-Geräte, die seit jeher über gute Leistungsmerkmale, hervorragende Treiber und eine enge Kombination aus Hardware und Software verfügen. Dadurch können sie ein Bild von sehr hoher Qualität erzeugen, ohne dass wir auf temporäre Lösungen zurückgreifen müssen.


Uns wurde schnell klar, dass sich das Bild allein durch die Änderung des Grafikstapels nicht ändern ließ. Außerdem wurde klar, dass wir neben leistungsstarken Geräten auch Inhalte für schwächere Geräte benötigen würden. Also begannen wir mit der Planung, Inhalte für verschiedene Qualitätsstufen zu entwickeln.


Dies bedeutete, dass Mechs, Waffen, Karten, Effekte und ihre Texturen qualitativ getrennt werden mussten, was bedeutet, dass unterschiedliche Entitäten für unterschiedliche Qualitäten gelten. Das heißt, die physischen Modelle, Texturen und Sätze von Mech-Texturen, die in HD-Qualität funktionieren, unterscheiden sich von Mechs, die in anderen Qualitäten funktionieren.


Darüber hinaus verwendet das Spiel viele Ressourcen für Karten, und diese müssen ebenfalls neu erstellt werden, um den neuen Qualitäten zu entsprechen. Es stellte sich auch heraus, dass der aktuelle Qualitätsmanager unseren Anforderungen nicht entsprach, da er die Qualität der Assets nicht kontrollierte.


Also mussten wir zunächst entscheiden, welche Qualitäten in unserem Spiel verfügbar sein würden. Unter Berücksichtigung der Erfahrungen unseres aktuellen Qualitätsmanagers stellten wir fest, dass wir in der neuen Version mehrere feste Qualitäten wollten, die der Benutzer in den Einstellungen unabhängig voneinander umschalten kann, je nach der maximal verfügbaren Qualität für ein bestimmtes Gerät.


Das neue Qualitätssystem ermittelt das Gerät, das ein Benutzer besitzt, und ermöglicht es uns, basierend auf dem Gerätemodell (im Fall von iOS) und dem GPU-Modell (im Fall von Android) die maximal verfügbare Qualität für einen bestimmten Player festzulegen. In diesem Fall ist diese Qualität sowie alle vorherigen Qualitäten verfügbar.


Außerdem gibt es für jede Qualität eine Einstellung, um die maximale FPS zwischen 30 und 60 umzustellen. Ursprünglich hatten wir etwa fünf Qualitäten geplant (ULD, LD, MD, HD, UHD). Während des Entwicklungsprozesses wurde jedoch klar, dass die Entwicklung dieser Anzahl an Qualitäten sehr lange dauern würde und es uns nicht ermöglichen würde, die Belastung der Qualitätssicherung zu reduzieren. Vor diesem Hintergrund haben wir uns letztendlich für die folgenden Qualitäten im Spiel entschieden: HD, LD und ULD. (Als Referenz ist die aktuelle Verteilung des Publikums, das mit diesen Qualitäten spielt, wie folgt: HD – 7 %, LD – 72 %, ULD – 21 %.)


Sobald uns klar wurde, dass wir mehr Qualitäten implementieren mussten, begannen wir damit, herauszufinden, wie wir die Assets nach diesen Qualitäten sortieren könnten. Um diese Arbeit zu vereinfachen, einigten wir uns auf den folgenden Algorithmus: Die Künstler würden Assets in maximaler Qualität (HD) erstellen und dann mithilfe von Skripten und anderen Automatisierungstools Teile dieser Assets vereinfachen und als Assets für andere Qualitäten verwenden.


Im Zuge der Arbeit an diesem Automatisierungssystem haben wir folgende Lösungen entwickelt:

  • Asset Importer – ermöglicht es uns, die notwendigen Einstellungen für Texturen vorzunehmen
  • Mech Creator – ein Tool, das die Erstellung mehrerer Mech-Versionen basierend auf Unity Prefab-Varianten sowie Qualitäts- und Textureinstellungen ermöglicht, die in den entsprechenden Projektordnern verteilt werden.
  • Texture Array Packer – ein Tool, mit dem Sie Texturen in Textur-Arrays packen können
  • Quality Map Creator – ein Tool zum Erstellen mehrerer Kartenqualitäten aus einer Quellkarte in UHD-Qualität


Es wurde viel Arbeit in die Umgestaltung bestehender Mech- und Kartenressourcen gesteckt. Die ursprünglichen Mechs wurden nicht mit unterschiedlichen Qualitäten im Hinterkopf entworfen und daher in einzelnen Prefabs gespeichert. Nach der Umgestaltung wurden grundlegende Teile daraus extrahiert, die hauptsächlich ihre Logik enthielten, und mithilfe von Prefab-Varianten wurden Varianten mit Texturen für eine bestimmte Qualität erstellt. Außerdem haben wir Tools hinzugefügt, die einen Mech automatisch in verschiedene Qualitäten unterteilen können, wobei die Hierarchie der Texturspeicherordner je nach Qualität berücksichtigt wird.


Um bestimmte Assets an bestimmte Geräte zu liefern, war es notwendig, den gesamten Inhalt des Spiels in Bundles und Packs aufzuteilen. Das Hauptpaket enthält die Assets, die zum Ausführen des Spiels erforderlich sind, Assets, die in allen Funktionen verwendet werden, sowie Qualitätspakete für jede Plattform: Android_LD, Android_HD, Android_ULD, iOS_LD, iOS_HD, iOS_ULD usw.


Die Aufteilung der Assets in Pakete wurde dank des von unserem Plattformteam entwickelten Tools ResourceSystem möglich. Mit diesem System konnten wir Assets in separaten Paketen sammeln und sie dann in den Client einbetten oder sie separat zum Hochladen auf externe Ressourcen wie ein CDN verwenden.


Zur Bereitstellung von Inhalten haben wir ein neues System verwendet, das ebenfalls vom Plattformteam entwickelt wurde: das sogenannte DeliverySystem. Mit diesem System können Sie ein vom ResourceSystem erstelltes Manifest empfangen und Ressourcen von der angegebenen Quelle herunterladen. Diese Quelle kann entweder ein monolithischer Build, einzelne APK-Dateien oder ein Remote-CDN sein.


Ursprünglich wollten wir zum Speichern von Ressourcenpaketen die Funktionen von Google Play (Play Asset Delivery) und AppStore (On-Demand Resources) nutzen, auf der Android-Plattform gab es jedoch viele Probleme im Zusammenhang mit automatischen Client-Updates sowie Einschränkungen hinsichtlich der Anzahl der gespeicherten Ressourcen.


Darüber hinaus haben unsere internen Tests gezeigt, dass ein Content-Delivery-System mit einem CDN am besten funktioniert und am stabilsten ist. Daher haben wir die Speicherung von Ressourcen in Stores aufgegeben und begonnen, sie in unserer Cloud zu speichern.


Veröffentlichung des Remasters

Als die Hauptarbeiten am Remaster abgeschlossen waren, war es Zeit für die Veröffentlichung. Wir erkannten jedoch schnell, dass die ursprünglich geplante Größe von 3 GB ein schlechtes Download-Erlebnis darstellte, obwohl einige beliebte Spiele auf dem Markt von den Benutzern den Download von 5-10 GB Daten erforderten. Unsere Theorie war, dass sich die Benutzer an diese neue Realität gewöhnt hätten, wenn wir unser remastertes Spiel auf den Markt bringen würden, aber leider.


Mit anderen Worten, die Spieler waren diese Art von großen Dateien für Handyspiele nicht gewohnt. Wir mussten schnell eine Lösung für dieses Problem finden. Wir entschieden uns, einige Iterationen später eine Version ohne HD-Qualität zu veröffentlichen, stellten sie unseren Benutzern aber trotzdem später zur Verfügung.


Links – vor dem Remaster, rechts – danach


Parallel zur Entwicklung des Remasters haben wir aktiv an der Automatisierung der Projekttests gearbeitet. Das QA-Team hat großartige Arbeit geleistet und dafür gesorgt, dass der Status des Projekts automatisch verfolgt werden kann. Im Moment haben wir Server mit virtuellen Maschinen, auf denen das Spiel läuft. Mithilfe eines selbstgeschriebenen Testframeworks können wir mit Skripten jede beliebige Taste im Projekt drücken – und dieselben Skripte werden verwendet, um verschiedene Szenarien beim Testen direkt auf Geräten auszuführen.


Wir entwickeln dieses System ständig weiter: Hunderte von ständig laufenden Tests wurden bereits geschrieben, um Stabilität, Leistung und korrekte Logikausführung zu überprüfen. Die Ergebnisse werden in einem speziellen Dashboard angezeigt, wo unsere QA-Spezialisten zusammen mit den Entwicklern die problematischsten Bereiche im Detail untersuchen können (einschließlich echter Screenshots vom Testlauf).


Vor der Inbetriebnahme des aktuellen Systems nahmen Regressionstests viel Zeit in Anspruch (etwa eine Woche bei der alten Version des Projekts), die zudem in Bezug auf Umfang und Inhaltsmenge viel kleiner war als die aktuelle. Dank automatischer Tests wird die aktuelle Version des Spiels jedoch nur zwei Nächte lang getestet; dies kann noch weiter verbessert werden, aber derzeit sind wir durch die Anzahl der an das System angeschlossenen Geräte eingeschränkt.


Gegen Ende des Remasters kontaktierte uns das Apple-Team und gab uns die Möglichkeit, an einer neuen Produktpräsentation teilzunehmen, um die Fähigkeiten des neuen Apple A14 Bionic-Chips (der mit neuen iPads im Herbst 2020 veröffentlicht wird) mit unserer neuen Grafik zu demonstrieren. Während der Arbeit an diesem Miniprojekt wurde eine voll funktionsfähige HD-Version erstellt, die auf Apple-Chips mit 120 FPS läuft. Darüber hinaus wurden mehrere grafische Verbesserungen hinzugefügt, um die Leistung des neuen Chips zu demonstrieren.


Nach einem harten Wettbewerb wurde unser Spiel in die Herbstpräsentation des Apple-Events aufgenommen! Das gesamte Team versammelte sich, um dieses Event anzuschauen und zu feiern, und es war wirklich cool!



Photon aufgeben und zur WorldState-Architektur migrieren.

Schon vor dem Start der remasterten Version des Spiels im Jahr 2021 war eine neue Aufgabe aufgetaucht. Viele Benutzer hatten sich über Netzwerkprobleme beschwert, deren Ursache unsere damals aktuelle Lösung war, die Photon-Transportschicht, die für die Arbeit mit dem Photon Server SDK verwendet wurde. Ein weiteres Problem war das Vorhandensein einer großen und nicht standardisierten Anzahl von RPCs, die in zufälliger Reihenfolge an den Server gesendet wurden.


Darüber hinaus gab es auch Probleme beim Synchronisieren der Welten und beim Überlaufen der Nachrichtenwarteschlange zu Beginn des Spiels, was zu erheblichen Verzögerungen führen konnte.


Um Abhilfe zu schaffen, haben wir beschlossen, den Netzwerk-Match-Stack in Richtung eines konventionelleren Modells zu verschieben, bei dem die Kommunikation mit dem Server über Pakete und den Empfang des Spielstatus und nicht über RPC-Aufrufe erfolgt.


Die neue Online-Match-Architektur hieß WorldState und sollte Photon aus dem Gameplay entfernen.

Diese neue Architektur beinhaltete nicht nur den Ersatz des Transportprotokolls von Photon durch UDP auf Basis der LightNetLib-Bibliothek, sondern auch eine Rationalisierung des Client-Server-Kommunikationssystems.


Durch die Arbeit an dieser Funktion konnten wir die Kosten auf der Serverseite senken (durch Umstellung von Windows auf Linux und Verzicht auf Photon Server SDK-Lizenzen). Zudem konnten wir ein Protokoll entwickeln, das für die Endgeräte der Benutzer viel weniger Anforderungen stellt, die Anzahl der Probleme mit der Statusdesynchronisierung zwischen Server und Client verringern und die Möglichkeit zur Entwicklung neuer PvE-Inhalte schaffen.


Da es unmöglich wäre, den gesamten Spielcode über Nacht zu ändern, wurde die Arbeit an WorldState in mehrere Phasen unterteilt.


Die erste Phase war eine vollständige Neugestaltung des Kommunikationsprotokolls zwischen Client und Server, und die Bewegung der Mechs wurde auf neue Schienen verlagert. Dadurch konnten wir einen neuen Spielmodus erstellen: PvE. Nach und nach wurden Mechaniken auf den Server übertragen, insbesondere die neuesten (Schaden und kritischer Schaden an Mechs). Die Arbeit an der schrittweisen Übertragung des alten Codes auf die WorldState-Mechanismen wird fortgesetzt, und wir werden dieses Jahr auch mehrere Updates haben.


Im Jahr 2022 starteten wir auf einer für uns neuen Plattform: Facebook Cloud. Das Konzept hinter der Plattform war interessant: Spiele auf Emulatoren in der Cloud ausführen und sie in den Browser auf Smartphones und PCs streamen, ohne dass der Endspieler einen leistungsstarken PC oder ein Smartphone haben muss, um das Spiel auszuführen; es ist lediglich eine stabile Internetverbindung erforderlich.


Auf Entwicklerseite können zwei Build-Typen als Haupttypen verteilt werden, die die Plattform verwenden wird: der Android-Build und der Windows-Build. Wir haben uns aufgrund unserer größeren Erfahrung mit dieser Plattform für den ersten Weg entschieden.


Um unser Spiel auf Facebook Cloud zu starten, mussten wir mehrere Änderungen vornehmen, z. B. die Autorisierung im Spiel neu durchführen und die Cursorsteuerung hinzufügen. Außerdem mussten wir einen Build mit allen integrierten Ressourcen vorbereiten, da die Plattform kein CDN unterstützte, und wir mussten unsere Integrationen konfigurieren, die auf Emulatoren nicht immer korrekt ausgeführt werden konnten.


Auch grafisch wurde viel Arbeit investiert, um die Funktionalität des Grafik-Stacks sicherzustellen, denn Facebook-Emulatoren waren keine echten Android-Geräte und hatten ihre eigenen Besonderheiten hinsichtlich der Treiberimplementierung und Ressourcenverwaltung.


Wir mussten jedoch feststellen, dass die Benutzer dieser Plattform auf viele Probleme stießen – sowohl auf instabile Verbindungen als auch auf einen instabilen Betrieb der Emulatoren – und Facebook beschloss, seine Plattform Anfang 2024 zu schließen.




Was auf der Programmiererseite ständig passiert und was in einem so kurzen Artikel nicht im Detail besprochen werden kann, ist die regelmäßige Arbeit mit den technischen Risiken des Projekts, die regelmäßige Überwachung technischer Kennzahlen, die ständige Arbeit mit dem Speicher und die Optimierung der Ressourcen, die Suche nach Problemen in Drittanbieterlösungen von Partner-SDKs, Werbeintegrationen und vieles mehr.


Darüber hinaus führen wir die Forschung und praktische Arbeit zur Behebung kritischer Abstürze und ANRs fort. Wenn ein Projekt auf einer so großen Anzahl völlig unterschiedlicher Geräte läuft, ist dies unvermeidlich.


Wir möchten auch die Professionalität der Leute hervorheben, die sich mit der Suche nach den Ursachen von Problemen beschäftigen. Diese technischen Probleme sind oft komplexer Natur und es ist notwendig, Daten aus mehreren Analysesystemen übereinander zu legen und einige nicht triviale Experimente durchzuführen, bevor die Ursache gefunden wird. Häufig gibt es für die meisten komplexen Probleme keinen konsistent reproduzierbaren Fall, der getestet werden kann, sodass zur Lösung dieser Probleme oft empirische Daten und unsere Berufserfahrung zum Einsatz kommen.


Einige Worte sollten zu den Werkzeugen und Ressourcen verloren werden, die wir zur Problemsuche in einem Projekt einsetzen.


  • AppMetr – eine interne Analyselösung, mit der Sie anonymisierte Daten von Geräten sammeln können, um Spielerprobleme zu untersuchen. Einige ähnliche Tools, die dem Leser vielleicht besser bekannt sind, sind: Firebase Analytics, Google Analytics, Flurry, GameAnalytics, devtodev, AppsFlyer usw.
  • Google Firebase Crashlytics
  • Google Play Console – Android Vitals
  • Protokolle – ein System von Protokollen in Debug-Builds, mit dem Sie die Suche nach Problemen bei Spieletests im Studio minimieren können
  • Öffentlicher Testbereich – unser Spiel verfügt über öffentliche Testserver, auf denen Sie neue Änderungen testen und verschiedene technische Experimente durchführen können.
  • Unity Profiler
  • XCode-Instrumente


Dies ist nur eine kleine Liste der technischen Verbesserungen, die das Projekt während seiner Existenz erfahren hat. Es ist schwierig, alles aufzulisten, was erreicht wurde, da sich das Projekt ständig weiterentwickelt und technische Manager ständig daran arbeiten, Pläne zur Verbesserung der Produktleistung sowohl für Endbenutzer als auch für diejenigen, die im Studio damit arbeiten, einschließlich der Entwickler selbst und anderer Abteilungen, zu erstellen und umzusetzen.


Wir haben noch viele Verbesserungen für das Produkt im nächsten Jahrzehnt im Blick und hoffen, dass wir diese in unseren nächsten Artikeln bekannt geben können.


Alles Gute zum Geburtstag, War Robots, und Danke an das riesige Team von technischen Spezialisten, die das alles möglich machen!