Du bist nicht angemeldet.

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

1

21.01.2013, 21:58

Spielarchitektur

Huhu!
Ähm, ja. Wie entwickelt ihr eure Spielarchitektur? Hat sie jedes mal das gleiche System, was so ja genau nicht sondern nur im Groben sein kann, wenn man in den Genres umherspringt, oder einfach wild drauf los und dann später das Chaos beendet? So nach dem Motto "erst mal alles in die main und dann pack' ich das in Klassen" oder natürlich auch "ganz" ohne Spiel-Klassen die nichts mit Monstern oder so zu tun haben, ich meine halt manche Manager und die Gameklasse.
Ich bleibe ums verrecken einfach kalt bei dem Aufbau aus dem guten alten Kapitel, das 12. Kapitel, aus dem guten alten Buch von Heiko oder ähnlichen Ansätzen.
Also ja. Das ist jetzt nun ein wenig wirr.
Ich möchte wissen, um es relativ prägnant zu haben, wie ihr überhaupt beginnt und wie sich das Ganze weiterentwickelt. Dazu jetzt natürlich nicht unbedingt in die "Details" gehen, was ein Spiel 'braucht', dessen bin ich mir bewusst. Einfach nur wie das Ganze so von statten läuft. Ich breche mir einfach jedes Mal dabei dermaßen einen ab, sodass ich schließlich auch abbrechen 'muss'.
Ich kann mir einfach nicht vorstellen, dass das so die einzige Masche ist oder nur leichte Änderungen davon möglich sind. Selbst eine für mich zu (er)finden, dafür bin ich zu kalt geworden... Kostet ja auch nicht die Welt mal herum zu fragen. :3
Danke und so^^

MfG
Check

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

2

22.01.2013, 11:31

Ich bau drauflos und betreibe kräftiges Refactoring, wenn sich der Bedarf dafür herausstellt.

Bei den Splitterwelten habe ich ein "Modulsystem", wo nach Priorität geordnet ein Rudel Module jedes Frame einmal arbeiten und einmal zeichnen können, wobei das höchste sichtbare Modul den Eingabefokus hat. Über das Modulsystem kann man dann andere Module triggern. Klappt ganz gut, hat aber seine Detailschwächen, wenn man z.B. im Inventar ein Buch anklickt und das Buchleser-Modul hochkommt und man dann die InGame-Konsole obendrauf packt. Eins der Module, eigentlich immer das unterste, betreibt und rendert dann die Spielwelt und reicht Eingaben rein. Eine Rückschnittstelle triggert aus der Spielwelt heraus Verhalten im Spielmodul, sowas wie "Spieler hat einen NSC angelabert, starte bitte Dialog Bla".

Bei Splatter war mir das zu kompliziert, da habe ich nur zwei feste Module, nämlich Spiel und GUI. Das Spiel kann neue Dialoge erzeugen und an die GUI übergeben, die jeweiligen Dialige können im Spielmodul den aktuellen Spielmodus beeinflussen und neue starten. Der Spielmodus macht dann so Sachen wie HUD, Siegbedingungen und Sonderlogik. Der Story-Spielmodus z.B. macht Spielstände bei Tastendruck oder Skript-Trigger und wechselt Welten nach Skript-Trigger. Der Multiplayer-Deathmatch-Modus spawnt dagegen Spieler neu, wenn sie gestorben sind, zählt Kills und Tode mit und zeigt das Abschluss-Menü, wenn die vorher gesetzten Siegbedingungen erfüllt sind. Mit dem System bin ich bisher sehr zufrieden. Es könnte aber langfristig betrachtet ein Problem werden, dass jede Art von Spieler-Interaktion entweder Spielmodus, GUI oder Theater-System ist... wenn ich mal den Waffen-Ausbau-Dialog neu machen will und sich herausstellt, dass meine GUI die Optik nicht erreichen kann, bin ich gearscht.

Bei meinem Voxel-Minecraft-Irgendwas-Projekt habe ich getrennte Module für Server und Client, wobei der Client auf Wunsch auch die Resou.rcen des Servers mitnutzen kann und dann einen Großteil der vom Server befohlenen Änderungen rausfiltern muss, weil sie ja schon auf den Resou.rcen ausgeführt wurden. Intern gibt es da wie bei Splatter ein Spielmodul und ein GUI-Modul, aber das Spielmodul hat jeweils einen aktuellen Zustand, der die Spiellogik macht, zustandabhängige Netzwerkpakete verarbeitet und Zustandswechsel auslöst. Irgendwo da ist auch die Logik-Optik-Trennung veranlagt, die dieses Mal sehr wichtig war, damit ich auch einen Dedicated Server hinkriege. Es gibt dieses Mal tatsächlich eine Logik-Spielwelt, die nur Abläufe, innere Zustände und Kollision und sowas macht, und separat davon eine Render-Spielwelt, die nur die Darstellung macht. Ein Listener Interface ermöglicht der Render-Spielwelt, auf neue und gelöschte Logik-Objekte zu reagieren.

Und das alles ist nur historisch so gewachsen. Ich mache mir vorher immer umfangreich Gedanken und Skizzen, wie ich das alles strukturieren möchte, aber ich ende eigentlich immer in so einer Art Design-Lähmung, bei der ich merke, dass ich das Gesamt-System mit allen zukünftigen Eventualitäten nicht mehr überblicke. Immer wieder, wenn ich was habe, fällt mir noch ein Sonderfall ein, und das verhindert effektiv, dass ich überhaupt anfange. Also mache ich irgendwann einen Schnitt und programmiere drauflos. Und wenn ich dann die ersten Abläufe habe und dem ersten Sonderfall begegne, sehe ich viel klarer, woran es hängt und was ich am System ändern müsste. Daher stammt auch meine übliche Empfehlung: bau los und baue nur das Mindeste, was Du gerade brauchst, solange Du offen für Refactoring bist.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

3

22.01.2013, 18:41

Ansonsten hilft es auch weiter wenn du dir immer mal wieder neue Frameworks und Engines anguckst. Du musst damit nicht die Riesenprojekte starten, sondern einfach nur rumspielen. Dabei siehst du immer mal wieder neue Wege wie Probleme angegangen werden. Ich habe mir zum Beispiel letztens Construct2 angeguckt und dabei stark Gefallen an eventbasierten Lösungen gefunden. Jetzt teste ich das ganze mal selbst aus.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

4

22.01.2013, 21:48

Ich bau drauflos und betreibe kräftiges Refactoring, wenn sich der Bedarf dafür herausstellt.

Jup, genau so! :D

Mein Hauptproblem ist natürlich, dass ich jetzt noch nicht weiß, wie genau das fertige Spiel aussehen wird. Andererseits finde ich es gerade lohnend, wenn man ein Spiel anfängt und so lange Stärken ausbaut, bis etwas tolles dabei entsteht. Welchen Sinn hat es, ein Spiel von vorne bis hinten zu planen, wenn ich noch nicht weiß, wie sich die Mechanik hinterher anfühlt und welche Stärken oder Schwächen sie hat?
Wenn man also schon das Spiel nicht von vorne bis hinten planen kann, dann auch nicht den Code.

Aber selbst wenn man genau weiß, was man coden wird, kommt man um Refactoring kaum herum. Wenn ich irgendein Problem angehe, habe ich meistens im Kopf eine Vorstellung davon, wie es funktionieren wird, welche Klassen es gibt, wie diese zusammen spielen und so weiter. Die grundsätzliche Idee ist auch ansich immer ok, Fehler kommen im Detail. Da schreibt man 5 Zeilen Code und merkt, dass eine davon Dinge benötigt, an die du einfach nicht rankommst. Per Design. Also musst du das Design ändern. Das ein Design auf hoher Ebene zu funktionieren scheint, ist schnell klar, aber für manche Dinge müsste man eben so detailliert planen, dass man es im Grunde auf dem Papier schon programmiert hat. Dann programmiere ich doch lieber direkt, und kann zwischendrin testen.

Wichtig bei allen Umbaumaßnahmen: Immer auf sauberen und strukturierten Code achten. Keine fiesen Hacks einbauen (außer zu Testzwecken). Ich achte immer darauf, dass mein Code eine logische Idee hat und möglichst robust ist. Das klingt ziemlich vage, und ist es wohl irgendwie auch. Vermutlich kommt das erst mit der Erfahrung. Aber vielleicht lässt es sich damit zusammenfassen: Sorge dafür das auch der größte Idiot deinen Code nicht falsch benutzen kann, bzw. es wenigstens auf jeden Fall merkt. Weil eben jener ist man selber.

Vielleicht mal ein Beispiel. Früher hatte ich eine Klasse, die alle Gegner gemanagt hat. Pro Typ einen Manager. Irgendwann kam ich dahinter, dass Gegner eigentlich gleich Gegner sind, und ich mit etwas generischen Code mit einem einzigen Manager auskomme.
Später kam ich dann auf die Idee, das man auch den Spieler und sonstige Objekte in gewisser Weise genauso wie die Gegner behandeln kann. Also gab es eine Charakter-Oberklasse, und abgeleitete Klasse für Spieler und diverse Gegnertypen.
Dann habe ich gemerkt, dass statische Typen eigentlich doof sind. Was ist, wenn ich mal in die Haut eines Gegners schlüpfen möchte um ihn zu steuern? Aslo war ein Gegner keine Abgeleitete Klasse mehr, sondern ein Charakter, der einen AI-Kontroller hat. Diese kann ich durch einen Player-Kontroller ersetzen und schon kann ich den Gegner als Spieler steuern.
Mittlerweile ist daraus ein Entity-System geworden, bei dem alles was in der Welt rumsteht ein Entity ist und verschiedene Componenten hat. Diese sorgen zum Beispiel für Kollisionsabfrage, oder geben einem Gebäude die Fähigkeiten, Güter zu produzieren. Durch ein Eventsystem können Componenten auf Dinge wie "Entity wird gerender" oder "Entity ändert seine Position" reagieren.

Aber: Man kann alles auch übertreiben, leider. Festgestellt habe ich das bei meinem 3D-Engine Teil. Die Grundidee war, eine 3D-Modell Klasse zu haben, mit der man Objekte laden und rendern kann. Nach Implementation diverser Features habe ich jetzt an die 30 Klassen, die alle irgendwie zusammenarbeiten. Das Problem dabei ist nur, dass man irgendwann alles auf derartig viele Objekte verteilt hat, dass das Zusammenspiel eben jener mehr Arbeit macht, als die eigentliche Logik. Flexibilität an Stellen wo man sie braucht, ist eine Last und kein Feature. Wenn du ein Problem hast, dass du entweder durch 5 Klassen in 10 Dateien (cpp/hpp) lösen kannst, oder aber durch einen 30 Zeilen Algorithmus, der zwar hässlich ist, aber geht, dann ist letzteres die bessere Lösung. Erst wenn du noch 3 mal ein ähnliches Problem hast, für dass du sie selben Klassen benutzen könntest, lohnen sich diese.

Ganz interessant ist dabei auch: http://scientificninja.com/blog/write-games-not-engines
Lieber dumm fragen, als dumm bleiben!

Toa

Alter Hase

Beiträge: 944

Beruf: Research associate

  • Private Nachricht senden

5

22.01.2013, 22:05

MVC [1] eignet sich oftmals hervorragend. Grüße T0a

[1] http://en.wikipedia.org/wiki/Model%E2%80…80%93controller
"Das ist ein Minkovski Raum, manche Menschen nennen ihn auch Weltraum" Prof. Dr. Jürgen Wambach, Theoretische Physik, TU Darmstadt | Meine Homepage

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

6

23.01.2013, 07:54

Ich bau drauflos und betreibe kräftiges Refactoring, wenn sich der Bedarf dafür herausstellt.

Jup, genau so! :D

Kann ich auch so unterzeichnen. Damit bin ich bisher am besten gefahren. Egal, wie gut du deine Architektur planst, du wirst immer Dinge finden, die genau das erfordern :).

Ein gutes Hilfsmittel ist, ob sich deine API leicht verwenden lässt. Wenn du während der Verwendung merkst, dass sich deine Klassen umständlich verwenden lassen, dann hast du keine gute Architektur.

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

7

23.01.2013, 15:58

MVC [1] eignet sich oftmals hervorragend. Grüße T0a


Das ist mir ein bisschen zu billig, einfach nur ein Stichwort in die Diskussion zu werfen. Zumal MVC für die meisten Spiele meiner Meinung nach Overkill ist. Man kommt deutlich einfacher zu Ergebnissen, wenn man alle zusammenwirft, oder zumindest Model und Controller. Und bei den meisten Hobby-Spielen wird man den Nachteilen dieser starren Verbindung nie begegnen und spart eine Menge Arbeitszeit. Für Allein-Freizeitentwickler, wie die meisten Mitleser hier sind, halte ich das für einen wichtigen Vorteil.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

Werbeanzeige