Wie die FĂ€higkeiten in Kriegsrobotern funktionieren





Hallo! Mein Name ist Vladimir Popov und ich bin ein Client-Entwickler fĂŒr das War Robots-Projekt.



War Robots gibt es schon seit mehreren Jahren: In dieser Zeit sind Dutzende neuer Mechs im Spiel aufgetaucht. Und natĂŒrlich wĂ€re keiner von ihnen ohne seine eigenen FĂ€higkeiten einzigartig.



Ich werde Ihnen in diesem Artikel erklÀren, wie das System der FÀhigkeiten in unserem Spiel funktioniert und wie es sich entwickelt hat, einfach und ohne technische Details.



Lassen Sie uns zunÀchst in die Geschichte eintauchen und die alte Implementierung betrachten - jetzt wird sie im Projekt nicht mehr verwendet.



Die alten FÀhigkeiten waren sehr trivial: Sie hatten eine Komponente, die am Roboter aufgehÀngt war. Es war ein monolithisches Konstrukt, in dem der Programmierer vollstÀndig beschrieb, wie die FÀhigkeit funktioniert: ihr Fluss, wie und mit was sie interagiert. Die gesamte Logik wird in einer Komponente beschrieben, die der Spieledesigner einfach an den Roboter hÀngen und die Parameter anpassen kann. Es gab keine Möglichkeit, die FlussfÀhigkeiten zu Àndern - Spieleentwickler konnten nur Parameter und Timings Àndern.



Die alte FÀhigkeit konnte nur in zwei ZustÀnden existieren: aktiv und inaktiv. Jedem Staat kann eine eigene Aktion zugewiesen werden.







Betrachten Sie das Beispiel der Jammer-FĂ€higkeit. Sie war zum Beispiel einmal der Roboter Stalker. Sie arbeitete wie folgt:



  1. Wenn die FĂ€higkeit aktiv ist, wird die Animation abgespielt und der Roboter wechselt in den Jammer-Status. In diesem Zustand kann der Roboter nicht angegriffen werden.
  2. Wenn die FĂ€higkeit inaktiv ist, passiert nichts.
  3. Wenn Sie versuchen, die FĂ€higkeit zu aktivieren, wird ĂŒberprĂŒft, ob seit der letzten Aktivierung mehr als n Sekunden vergangen sind.
  4. Die Deaktivierung erfolgt automatisch nach m Sekunden.


Diese FunktionalitĂ€t hat uns lange Zeit gereicht. Im Laufe der Zeit hat sich jedoch alles geĂ€ndert: Sowohl Spieleentwickler als auch Programmierer sind mit diesem Ansatz nicht mehr zufrieden. FĂŒr Programmierer war es schwierig, solche FĂ€higkeiten aufrechtzuerhalten, da der Code monströs wurde - mit einer sehr langen Vererbungskette, in der jede Situation beschrieben werden musste. Spieledesignern mangelte es an SystemflexibilitĂ€t. Das heißt, um eine Änderung einer FĂ€higkeit zu erreichen, mussten sie bei den Programmierern eine Überarbeitung anordnen, selbst wenn in der benachbarten FĂ€higkeit genau dieselbe FunktionalitĂ€t vorhanden war.



Dann wurde uns klar, dass wir etwas Àndern mussten. Und sie entwickelten ein neues System. Darin wurde jede FÀhigkeit als eine Reihe von mehreren verwandten Objekten dargestellt. Die Funktion wurde in ZustÀnde, FÀhigkeiten und Komponenten von ZustÀnden unterteilt.



Wie es funktioniert?



Jede FĂ€higkeit hat einen Meister . Dies ist ihr zentrales Objekt. Es verbindet den Rest der FĂ€higkeitsobjekte mit der Außenwelt und umgekehrt. Und er trifft auch alle wichtigen Entscheidungen.



Es kann eine beliebige Anzahl von ZustÀnden geben . Im Wesentlichen unterscheidet sich der Status hier nicht wesentlich von dem Status "aktiv" / "inaktiv" in der alten Version. Aber jetzt kann es eine beliebige Anzahl von ihnen geben, und ihr Zweck ist abstrakter geworden. Es kann immer nur ein Status aktiv sein.



Die Hauptinnovation gegenĂŒber dem alten System waren die Komponenten . Die Komponente beschreibt eine Aktion. Jeder Zustand kann eine beliebige Anzahl von Komponenten haben.







Wie funktionieren neue FĂ€higkeiten?



Eine FĂ€higkeit kann sich jeweils nur in einem der ZustĂ€nde befinden. Der Master ist damit beschĂ€ftigt, sie zu schalten. Die Komponenten, die mit dem Status verknĂŒpft sind, reagieren auf die Aktivierung / Deaktivierung des Status und können abhĂ€ngig davon entweder eine Aktion ausfĂŒhren oder die AusfĂŒhrung beenden.



Alle Objekte sind jetzt anpassbar. Der Spieledesigner kann ZustĂ€nde und Komponenten auf beliebige Weise miteinander mischen und erhĂ€lt so eine neue FĂ€higkeit aus den vorinstallierten Blöcken. Programmierer mĂŒssen nur noch eine neue Komponente oder einen neuen Status erstellen, was das Schreiben von Code erheblich erleichtert. Jetzt arbeiten sie mit kleinen Einheiten, beschreiben einige einfache Elemente und bauen die FĂ€higkeiten nicht selbst zusammen - Spieleentwickler haben damit begonnen.



Flow wurde so:



  1. Der Master aktiviert den ersten Zustand;
  2. ;
  3. ;
  4. ;
  5. ;
  6. ;
  7. .


Anschließend wird dieser Vorgang immer wieder wiederholt. Zur Vereinfachung der Verwendung ist ein Status nicht nur ein Container fĂŒr Komponenten, sondern bestimmt auch, wann in einen anderen Status gewechselt werden muss, und fordert den Master auf, zu wechseln.



Im Laufe der Zeit reichte uns dies nicht aus, und das Schema der FĂ€higkeit wurde in die folgende Form umgewandelt:







Meister, Zustand und Komponenten blieben an ihren PlĂ€tzen, aber neue Elemente wurden hinzugefĂŒgt.



Das erste, was Ihnen auffĂ€llt, ist, dass wir jedem Zustand und jeder Komponente Bedingungen hinzugefĂŒgt haben. FĂŒr Staaten definieren sie zusĂ€tzliche Anforderungen fĂŒr das Verlassen des Staates. FĂŒr Komponenten bestimmen sie, ob die Komponente ihre Aktion ausfĂŒhren kann.



Ein GebĂŒhrencontainer (GebĂŒhren) enthĂ€lt GebĂŒhren, lĂ€dt sie auf, stoppt das Aufladen bei Bedarf und stellt den Staaten GebĂŒhren zur Verwendung zur VerfĂŒgung.



Der Timer wird verwendet, wenn mehrere ZustĂ€nde eine gemeinsame AusfĂŒhrungszeit haben mĂŒssen, ihre eigene AusfĂŒhrungszeit jedoch nicht definiert ist.



Es ist wichtig zu beachten, dass alle FĂ€higkeitsobjekte optional sind. Technisch gesehen reichen nur der Master und ein Zustand fĂŒr die ArbeitsfĂ€higkeit aus.



Es gibt nicht so viele FĂ€higkeiten, die ohne die Einbeziehung von Programmierern vollstĂ€ndig zusammengestellt werden, aber die Entwicklung ist im Allgemeinen spĂŒrbar billiger geworden, weil Programmierer jetzt sehr kleine Dinge schreiben: Zum Beispiel einen neuen Zustand oder zwei Komponenten, der Rest wird wiederverwendet.



Lassen Sie uns zusammenfassen, welche Bestandteile der FĂ€higkeiten wir haben und was sie sind:



  • Der Master fungiert als Zustandsmaschine. Es liefert ZustĂ€nde und Komponenten mit Informationen ĂŒber die Welt und die Welt - Informationen ĂŒber eine FĂ€higkeit. Der Master dient als Verbindung zwischen den ZustĂ€nden, Komponenten und Serviceteilen einer FĂ€higkeit: GebĂŒhren und externe Timer.
  • Der Status hört die Befehle zum Aktivieren und Deaktivieren vom Master ab und aktiviert und deaktiviert dementsprechend die Komponenten und fordert den Master auf, in einen anderen Status zu wechseln. Der Staat entscheidet, wann er zum nĂ€chsten wechseln muss. Dazu verwendet er seine interne Bedingung: ob der Spieler auf die FĂ€higkeitsschaltflĂ€che geklickt hat, ob eine bestimmte Zeit seit der Aktivierung des Status vergangen ist usw. - und externe Bedingungen, die mit dem Status verknĂŒpft sind.
  • : . : , , .
  • , , . . , . , . — , .
  • Ein GebĂŒhrenbehĂ€lter enthĂ€lt GebĂŒhren, lĂ€dt sie auf, lĂ€dt sie bei Bedarf nicht mehr auf und gewĂ€hrt Staaten GebĂŒhren. Es wird in MehrfachladungsfĂ€higkeiten verwendet, wenn Sie dem Spieler die Möglichkeit geben mĂŒssen, es mehrmals, jedoch nicht mehr als n Mal hintereinander zu verwenden.
  • Der Timer wird verwendet, wenn mehrere ZustĂ€nde eine gemeinsame Dauer haben, aber nicht bekannt ist, wie lange jeder von ihnen gĂŒltig ist. Jeder Zustand kann einen Timer fĂŒr n Sekunden starten. Alle interessierten Staaten abonnieren das Ereignis gegen Ende des Timers und tun etwas, wenn es endet.


Kommen wir nun zum FĂ€higkeitsdiagramm zurĂŒck. Wie hat sie angefangen zu handeln?



  1. Zu Beginn des Spiels wÀhlt der Meister den ersten Zustand und aktiviert ihn.
  2. Staat aktiviert alle seine Komponenten;
  3. ;
  4. ;
  5. , ;
  6. ;
  7. .


Staaten können GebĂŒhren als zusĂ€tzliche Übergangsbedingung verwenden. Wenn ein solcher Übergang auftritt, nimmt die Anzahl der Ladungen ab. Außerdem können ZustĂ€nde einen gemeinsamen Zeitgeber verwenden. In diesem Fall wird die Gesamtzeit ihrer AusfĂŒhrung vom Zeitgeber bestimmt, und jeder Zustand kann jederzeit einzeln andauern.



Wir haben uns nichts völlig Neues fĂŒr die BenutzeroberflĂ€che ausgedacht. So ist es bei uns geregelt.



Der Master hat eine eigene BenutzeroberflÀche. Es definiert einige Elemente, die sich immer in der BenutzeroberflÀche befinden sollten und nicht davon abhÀngen, welcher Status derzeit aktiv ist.



Jeder StaatEs gibt ein paar in der BenutzeroberflĂ€che. Die Status-BenutzeroberflĂ€che wird nur angezeigt, wenn ihr Status aktiv ist. Er erhĂ€lt Daten ĂŒber seinen Zustand und kann diese auf die eine oder andere Weise anzeigen. Beispielsweise haben DauerzustĂ€nde normalerweise einen Balken und einen Text in ihrer BenutzeroberflĂ€che, die die verbleibende Zeit darstellen.



Wenn der Status darauf wartet, dass ein externer Befehl die Funktion fortsetzt, zeigt seine BenutzeroberflĂ€che eine SchaltflĂ€che an. Durch DrĂŒcken dieser Taste wird der Befehl an den Status gesendet.







Betrachten wir nun die Arbeit der FĂ€higkeiten anhand konkreter Beispiele. Beginnen wir mit einem Roboter namens Inquisitor.



Wir haben vier ZustĂ€nde, die sich nacheinander Ă€ndern. Über den Status können Sie deren Anzeige in der BenutzeroberflĂ€che sehen. In zwei davon sehen Sie die Komponenten, die auf sie verweisen. Die beiden anderen ZustĂ€nde haben einfach keine Komponenten.



FĂ€higkeitsarbeitsablauf:



  1. WaitForClick. .
  2. , . WaitForGrounded.
  3. . , . , , Jammer, .
  4. .
  5. : Sound Jammer, Shake, n.
  6. Duration, n , .
  7. Duration, : .
  8. Nach Abschluss kehrt die FĂ€higkeit in den ersten Zustand zurĂŒck.






Ein weiteres Beispiel ist Phantom. Ähnlich wie bei Inquisitor passiert hier viel, aber es gibt noch einige Nuancen:



  1. Wir beginnen mit WaitForClick.
  2. Dann wird die Dauer, in der der Teleport eingestellt ist, die Statistiken des Mechs geÀndert, Sound und Animation abgespielt.
  3. Danach - DurationOrClick, in dem die Pelzstatistiken geÀndert werden, werden Animation und FX abgespielt.
  4. Wenn ein Klick gemacht wurde, gehen wir zu einer anderen Dauer, in der das Fell teleportiert wird, die Statistiken geÀndert werden, die Animation, die Effekte und die Sounds abgespielt werden.
  5. Nach diesem Zustand oder nach dem Ende der DurationOrClick-Zeit gehen wir zu Duration.


Der Hauptunterschied besteht darin, dass hier VerzweigungszustÀnde auftreten. DurationOrClick wechselt zu Status a , wenn die angegebene Zeit abgelaufen ist, oder zu Status b , wenn der Spieler zuvor Zeit hatte, auf die FÀhigkeitsschaltflÀche zu klicken.







Es scheint also, dass sich unser System von einfach zu komplex entwickelt hat, aber dadurch das Leben sowohl von Programmierern als auch von Spieledesignern vereinfacht hat. Die Hilfe des ersteren wird jetzt hauptsĂ€chlich beim HinzufĂŒgen kleiner Komponenten benötigt, wĂ€hrend die letzteren eine grĂ¶ĂŸere Autonomie erhalten haben und nun unabhĂ€ngig neue FĂ€higkeiten aus bestehenden ZustĂ€nden und Komponenten zusammenstellen können. Gleichzeitig erhielten die Spieler einen Gewinn in Form vielfĂ€ltigerer und komplexerer FĂ€higkeiten der Mechs.



All Articles