Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
Das hatte ich in Beitrag 6 ja schon getan, was konkret ist dir da unklar?
TGGC kannst du das gleiche Verhalten einmal ohne das Command Pattern beschreiben, wie würdest du es machen?
Ja klar, das Verhalten muss existieren sonst kann man es logischerweise nicht executen. Nur beim Command Pattern muss das gesamte Verhalten inkl. dessen Context den execute Methoden der Commands bekannt sein, damit diese das dann korrekt aufrufen können. Daher der Trick dem execute einen actor zu uebergeben, das geht vlt. noch gut in einem FPS wo man wirklich nur einen einzigen Actor beeinflussen muss. Aber stell dir mal ein RTS vor, was da eine allgemeine execute Methode als Parameter bräuchte.Der Code für das Verhalten kann auch in einer Datei geschrieben werden, oder in mehreren Klassen. Die Frage ist, was ist wartbar und erweiterbar.
Der Code muss auf jeden Fall irgendwo existieren, in welcher Form auch immer.
Ja, in der Theorie kann man das. Ist aber auch nicht besser als wenn man ein Replay irgendwie anders macht. Allein diese Vererbungshierachie abzuspeichern ist genauso pain in the ass. In der Praxis funktioniert es nicht so problemlos wie du dir das vorstellst, denn diese Daten sind total fragil. Eine minimale Aenderung von Code oder Spieledaten und man kann das nicht mehr benutzen. Starcraft hat das so gemacht, vermutlich weil sie das auch fürs Netzwerkprotokoll brauchten. Im ersten Teil haben sie ewig gebraucht das überhaupt reinzupatchen und nach 10 Jahren Entwicklung hats immer noch nicht richtig funktionert, bei Coop oder pausieren gabs immer noch Fehler. Beim zweiten haben sie dann ein extrem kompliziertes System gebaut, mit dem sich das Spiel in genau die richtige Version inkl. Daten zurückpatchen kann, um ein Replay korrekt abzuspielen. Sowas wie in der Quakeengine ist wesentlich robuster für Replays.Das schöne am Command Pattern ist, das man damit auf einfachste Art und Weise ein Spiel nachstellen und testen kann. Man sieht sofort welche Eingaben gemacht worden sind und kann ganze Spielpartien erneut ablaufen lassen. Damit kann man gemeldete Bugs ausfindig machen oder einfach eine Aufnahmefunktionalität schaffen so das sich Spieler ihr Spiel im nachhinein nochmal anschauen können. Gleichzeitig können einzelne Commands vom Server validiert werden.
Um die 80% bestimmt. C++, Java, Pascal, Basic so ungefaehr in Reihenfolge der Häufigkeit.
Wie viele diese Projekte waren dabei Games? Und in welchen Sprachen wurden diese umgesetzt?
Ja. Auch erfolgreich. Nur eben nicht für das hier genannte Problem.Die nächste Frage ist, hast du das Pattern schon mal ausprobiert?
Dieser Beitrag wurde bereits 10 mal editiert, zuletzt von »Chromanoid« (09.08.2017, 21:10)
Oh wie naiv. Als wenn sich nur was in den Commands ändert und man dann einfach das execute eines alten Commands ausführen müsste...Die Vermeidung von Fragilität für Replays finde ich jetzt gerade beim Command-Pattern eigentlich recht einfach umsetzbar. Man kann die Kommandos ja schon am Klassennamen versionieren. Bei Refactorings muss die Funktionalität dann erhalten bleiben. Das kann man dann recht gut testen.
Events ist sehr weit gefasst! Man kann jeden Methodenaufruf als "Event" begreifen...Ich weiß nicht, ob das hier diskutiert werden darf, aber wie läuft das denn z.B. in Anno - also jetzt abgesehen von Eingabegeräteverarbeitung? Wird da aus allem Events gemacht? Das Event-Pattern erscheint mir persönlich für Spiele noch etwas geeigneter, wenn man Replays und Netzwerkfähigkeit haben will. Aber das kann man ja trotzdem mit Commands vereinen.
Warum gleich so persönlich werden? Ich behaupte gar nicht, dass man nicht immer darauf achten muss, was da so drumherum passiert. Aber wenn man wirklich alles mit Commands abhandelt und den globalen Zustand vorher und nachher kennt, dann kann man das relativ gut abtesten - zur Not auch mit Mutation-Testing, dann kann man die Test Coverage wirklich ziemlich ernst nehmen. Oft hat man doch gar keine andere Wahl, wenn man eine effiziente Undo-Redo-Funktion einbauen will. Ich habe noch nie in einer größeren Gruppe über längere Zeit ein "One-Shot-Projekt", wie das bei Spielen meist der Fall ist, entwickelt. Da stelle ich mir das aufrecht erhalten der Rückwärtskompatibilität allgemein schwierig bzw. einfach vernachlässigbar vor. Bei Anwendungen hat man ja oft einfach keine andere Wahl, weil irgendwelche Geschäftsprozesse "wie immer" weiterlaufen sollen. Webservice-Versionierung ist ja eine ziemlich harte Nuss für viele Unternehmen. Da finde ich das Kapseln von Verhalten in eigene Klassen schon ziemlich sinnvoll.Oh wie naiv. Als wenn sich nur was in den Commands ändert und man dann einfach das execute eines alten Commands ausführen müsste...Die Vermeidung von Fragilität für Replays finde ich jetzt gerade beim Command-Pattern eigentlich recht einfach umsetzbar. Man kann die Kommandos ja schon am Klassennamen versionieren. Bei Refactorings muss die Funktionalität dann erhalten bleiben. Das kann man dann recht gut testen.
Das ist schon klar. In einigen Programmiersprachen sind Methodenaufrufe konzeptuell ja sogar relativ nah dran. Ich dachte Du würdest verstehen, warum ich das frage. Mich würde das einfach grundsätzlich interessieren, welche Patterns ihr so einsetzt, um zum Einen Verhalten zu kapseln und zum Anderen reproduzierbare Zustandsänderungen z.B. für Multiplayer umzusetzen.Events ist sehr weit gefasst! Man kann jeden Methodenaufruf als "Event" begreifen...Ich weiß nicht, ob das hier diskutiert werden darf, aber wie läuft das denn z.B. in Anno - also jetzt abgesehen von Eingabegeräteverarbeitung? Wird da aus allem Events gemacht? Das Event-Pattern erscheint mir persönlich für Spiele noch etwas geeigneter, wenn man Replays und Netzwerkfähigkeit haben will. Aber das kann man ja trotzdem mit Commands vereinen.
Das sehe ich auch so. Allerdings repräsentieren Klassen auch wunderbar eindeutige Bezeichner, die bei den richtigen Sprachen wie eine Event-ID fungieren können. Viele Events will man ja auch dokumentieren, das kann man dann wunderbar an der individuellen Event-Klasse machen. Was Reflection angeht scheiden sich ja die Geister, aber ich finde instanceof und Co. sehr sinnvolle Sprachmittel. Jedenfalls im Kontext dieser Sprachen kann ich das sehr ausgiebige Erstellen von Klassen für Events und Co. gut verstehen und finde das auch sinnvoll. Wenn man davon ausgeht, dass bei Klassen auf Einzigartigkeit im Softwareprojekt geachtet wird, dann sind Klassen ein wunderbares Mittel, um sehr entkoppelt effiziente Event-Systeme zu entwickeln. In allen anderen Fällen ist man immer darauf angewiesen, irgendwie IDs zentral festzulegen.Mein eigentlicher Punkt ist nur, das man nicht jeden Event in eine eigene Klasseninstanz stecken muss, die dann auch noch von einen bestimmten Basisklasse ableiten muss. Falls hier jemand in einem sinnvollen Projekt mal alle seine Tastatureingaben direkt so verpackt hat, würde ich da gerne mal von den Erfahrungen mit dieser Methode hören.
Dieser Beitrag wurde bereits 8 mal editiert, zuletzt von »Chromanoid« (13.08.2017, 17:51)
Ach komm, man muss nicht alles auf sich beziehen. Dir ist sicher bekannt das man auch Algorithmen als naiv bezeichnet und nicht nur Personen.Warum gleich so persönlich werden? Ich behaupte gar nicht, dass man nicht immer darauf achten muss, was da so drumherum passiert. Aber wenn man wirklich alles mit Commands abhandelt und den globalen Zustand vorher und nachher kennt, dann kann man das relativ gut abtesten
Werbeanzeige