Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Einen wunderschönen guten Tag mal wieder
Nachdem ich nun mein Speicherplatzproblem (theoretisch) gelöst habe, kommts nun zum nächsten Punkt. Da das Strategy Game mein erstes größeres Projekt ist, dachte ich mir, bevor ich jetzt die Weltstruktur ungünstig aufbaue, frag ich doch mal die Spezialisten . Ich hatte schon einen Ansatz, aber der war wohl definitiv zu früh angefangen.
Also. Es ist ja schwachsinnig, auf einem Server Modelle und ähnliches zu laden. Dort reichen ja die Daten an sich, ich brauche keine Modelle oder Texturen. Nun frage ich mich, wie ich am besten die Klassen aufbaue. Ich muss ja irgendwie die Verbindung zwischen Weltobjekt und Modell herstellen. Ich könnte natürlich einfach die Felder in den Datenstrukturen anlegen und auf der Serverseite nil setzen (werden dann ja eh nicht gebraucht) und auf der Clientseite eben laden. Das würde auch für 100% kompatible Datenstrukturen sorgen, wenn ein Client gleichzeitig Host ist.
Ist das denn soweit eine gute idee? Oder sollte ich das besser anders machen?
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Wir haben das so gelöst (Towerdefense, das mittlerweile technisch schon ein 2/3 komplettes RTS ist...):
Jede Einheit (Turm, Creep, später auch Projektil (Im Moment nur Instantwaffen)) ist ein Entity. In dem Entity ist festgelegt, wie viele Lebenspunkte es hat, wohin es gerade maschiert, welche Waffen es hat usw.. Der Server hält nur solche Entities. Wenn z.B. ein Creep spawnt oder ein Turm gebaut wird, schickt der Server dieses Entity zu allen Clients. Das Entity hat außerdem ein Feld "Model". Aus dieser Information weiß der Client, wie er es darstellen soll. Lad Md2-Model bla für das Entity, lad Md2-Model blubb für Waffe1, blargs für Waffe2 des Entities usw.. Der Client erstellt also ein VisualEntity, was das Server-Entity beinhaltet.
Dann noch jedesmal, wenn sich auf dem Server ein Entity bewegt von Feld A nach B eine Info an den Client "Entity xyz bewegt sich von A nach B und braucht dafür 250ms", so dass der den Weg nett animieren kann. Oder auch wenn eins stirbt "Hey Client, da ist das flauschige Fellmonster 123 gestorben, animier mal seinen Tod und entfern dann das Entity aus deiner Liste.". Schickt ein Spieler ein Entity von A nach B wird über's Netzwerk ein entsprechender Request losgeschickt, der Server bewegt das Entity und schickt entsprechende Statusnachrichten los.
-> Die komplette Spiellogik befindet sich auf dem Server. Der Client kriegt nur Events und verschickt Requests und dient "nur" zur grafischen Darstellung. Wie diese wiederrum aussieht, davon hat der Server keinen blassen schimmer.
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Ganu so ist es auch richtig. Auch, dass die Bewegungen vom Server validiert werden. Im Worstcase schreibt der Böse Cheater nämlich sonst ein Tool welches es ermöglicht, durch Wände zu gehen. Mit dieser Strategie ist das ausgeschlossen, weil der Server nämlich sagen würde: Is nich!
Du solltest das Entity, Controller, Boundary Modell aus den SoftwareEntwicklungstutorial (1 oder 2) anwenden.
Das heißt, jede Einheit besteht aus diesen 3 Teilen.
Entity: Hält die Infos, z.B. Lebenspunkte, Richtung etc.
Boundary: sorgt dafür, dass eine Ausgabe zustande kommt, welche die Entity repräsentiert.
Controller: Berechnet alles was mit der Entity zu tun hat. Liefert Daten der Entity an die Spiellogik-Kontroller, nimmt daten entgegen, verwurstet die und leitet sie an die Entity weiter.
Vorteil dieses Ansatzes. Man kann am Anfang eine simple z.B. Konsolenbasierte GUI schreiben.Später muss man dann nur noch die Boundaryklassen durch OpenGL fähige ersetzen. Das erleichtert z.B. das Entwickeln im Team, da die Spiellogikprogrammierer keine OpenGL Grafik zum testen brauchen, sondern mit einer schnell zusammengeschriebenen Ausgabe erstmal entwickeln können und trotzdem was sehen.
Sowas habe ich beim PBM3 vor.
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Hmhm...
Das ist natürlich etwas aufwendiger als das, was ich bisher hatte.
Ich dachte mir das so: Ich habe eine Klasse für jede Objektart. Dann habe ich eine Schnittstellenklasse, um die kommunikation zwischen Oberfläche / Kern zu gewährleisten (sog. Playercontroller). Der könnte auch wunderbar übers Netzwerk arbeiten z.B... Wenn eine Aktion auf dem Clienten ausgeführt wird, wird eine entsprechende Anfrage an den Server geschickt. Der prüft, ob das, was der Client da vorhat möglich ist und sendet eine entsprechende Antwort ("Ja ok", "Ding im Weg", "Kannst dich nicht selber wegnuken", "Fahr zur hölle, die Einheit gibts nicht!") Wenn die Aktion sanktioniert wurde, führt er sie entsprechend in seinem Speicher aus und sendet ebenfalls eine benachrichtung an alle anderen Clienten, dass diese Aktion durchgeführt wurde, sodass sie das in ihrem Abbild ebenfalls tun können. [Anm.: Daher sollte das Netzwerk möglichst nicht Blocking sein, die Rückmeldungen würden auf dem Clienten, der die Aktion initiiert hat genauso asynchron verarbeitet wie bei den Clienten, denen nur von der Aktion "erzählt" wird. Das hätte den Vorteil, dass man schon andere Dinge in Auftrag geben kann, während die andere Aktionen noch ausstehen] Da müsste natürlich jeder Client auch wieder ein Abbild vom kompletten Spielfeld im Speicher haben (wobei das, wie mir gerade auffällt, für versierte HackerCracker vermutlich einfach wäre, daraus dann die Infos für alle anderen Spieler zu bekommen). Alternativ könnte man natürlich von anfang an den Clienten nur mit den ihm auch wirklich bekannten Informationen versorgen. Ist denke ich besser so.
Das Argument von Flash, für die Darstellung doch komplett unabhängige Klassen zu verwenden ist natürlich schlagkräftig... Eventuell könnte man da einfach eine zweite Klasse für jeden Objekttyp anlegen (oh-oh), der dann im Konstruktor die Instanz vom Objekt erhält und sich dann in den Scene-Graph (hu bin ich optimistisch ) einhängt oder so...
Sagt mir, was ihr dazu denkt
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Was genau meinst du mit zweiter Klasse? Was ist die erste?
Beschreib mal deinen Ansatz genauer.
Nebenbei... wir mir gerade einfällt, kann man die Trennung wie ich sie oben beschrieben habe auch nutzen, um verschieden gute Hardware zu unterstützen. Auch eine parallele DirectX Ausgabe ist so machbar.
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Also. Mein Zwei-Klassen-Konzept wäre:
1. Klasse: Das Objekt an sich. Die Daten dazu, alle Informationen, Ausstattung, Zustand usw.
2. Klasse: "Zeichner" des Objektes. Er bekommt eine Referenz auf das Objekt der 1. Klasse und zeichnet anhand dessen das Objekt.
Von der 2. Klasse gäbe es dementsprechend nur auf dem Clienten instanzen, da der Server logischerweise keine Darstellungsinfos braucht.
Gruß Lord Horazont
OT: DirectX? Bloß nicht.
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Die Logik liegt auf der Serverseite, beim Empfänger der Playercontroller. Dort liegen zumindest alle Aktionen, die der Spieler direkt ausführen kann. Bewegungen usw. liegen in den Datenklassen. Solche Dinge (fliegende Projektile, Animationen, Planetenbewegungen usw...) könnten dann synchron auf dem Clienten durchgeführt werden, ohne, dass der Server dauernd bestätigen muss. Denn das sind ja nur die "Fortsetzungen" der bereits sanktionierten Befehle. Selbst wenn der Client hier was rumhackt, beim nächsten Befehl, der etwas damit zu tun hat, fliegt das auf und der Client aus dem spiel.
Die Aktionen über den Playercontroller sind wahrscheinlich Methoden, die nur wieder Dinge in der Kernlogik in den Hauptklassen ausführen. Aber mit Fehlerbehandlung usw., wobei die Fehler dann zurück an den Spieler gegeben werden.
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Mitglieder in diesem Forum: 0 Mitglieder und 20 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.