Multiplayer...

Algorithmen, Sprachunabhängige Diskussionen zu Konzepten, Programmiersprachen-Design
Benutzeravatar
Jside
Beiträge: 377
Registriert: Di Nov 11, 2008 12:56 am

Multiplayer...

Beitrag von Jside » Di Mär 17, 2009 1:29 pm

Ich bastle gerade an dem Konzept einer Game Engine, etwas hab ich auch schon gecodet, aber ich zerbreche mir den Kopf, wie ich den Multiplayerteil umsetzten soll, dieser soll folgendes können:

1. Die Welt und Modelle vom Server laden(in realtime, immer das was in der Richtung liegt, und nochnicht schtbar ist), sodass der Admin diese beliebig vergrößern kann, ohne das alle Clienten Addons installieren müssen.
2. Multiplayer unterstützten, sodass auch hunderte von Leuten gleichzeitig im Sichtbaren Bereich seien können.

Dabei entstehen folgende Probleme:
1. Ich habe mir das so vorgestellt, das der Server immer bestimmte Stellen der Welt Datei versendet, samt einer Liste von "required models", und der Client diese Downloadet, dabei entstehen folgende Probleme: Sehr hoher Memory Bedarf am Server, ich kann mir ja keine Cray XT5 hinstellen... Und die Traffic würde bei schwächeren Leitungen den Multiplayer part stören... Wie machen das andere Multiplayerspiele??

2. Ich habe mir das so vorgestellt, das alle 0,5 - 1sec ein struct array mit allen Sub-Informationen der Spieler zum Clienten versendet wird, wobei der Server immer die im Umkreis von X Metern zum Clienten sendet, wobei nur Einmal alle Informationen(Name 3D Model etc.) versendet werden, und ab dann nurnoch Positionsdaten/Animations Frame Status, der dann halt mit Clienten synchronisiert wird, der Client kennt natürlich alle Animations Frame States, und kann diese allein abspielen, sodass alles recht flüssig sein sollte, dabei aber das Problem der Komplexheit, denn es sollen sehr viele Variablen versendet werden, wobei ab einer bestimmten Anzahl von Spielern nichts mehr flüssig geht.

Also gesagt: Wie stell ich es geschicktesten an, das selbst Leute mit einem 56k Modem ohne Probleme obrige Punkte benutzen können ?

Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Re: Multiplayer...

Beitrag von Dirty Oerti » Di Mär 17, 2009 3:59 pm

Hm, was mir dazu einfällt:

Auf den Server liegen Dateien für die Welt und die einzelnen Modelle samt ihrer Animationen.
Jetzt beschließen X Clients, sich mit dem Server zu verbinden und zusammen ein Spiel zu spielen.

Der Server schickt daraufhin jedem der Clients die kompletten Welt- und Modelldaten zu.
Wenn alle Clients ihre Daten erhalten haben, kann das Spiel gestartet werden.

Damit nun alle Clients auf dem gleichen Stand bleiben, werden regelmäßig vom Server Informationen über Position, Energie (o.ä.), Animationsstand, etc der (evtl, je nach Art des Spiels) umliegenden Modelle geholt.

Wenn du also pro Spieler nur diese Daten versenden musst hält sich das doch recht in Grenzen, oder?
Vorallem, wenn du es räumlich eingrenzt und nur die Daten runterlädst, die der jeweilige Client gerade braucht. (Das sollte aber der Clientrechner berechnen müssen!).
Bsp:

Jeder Spieler hat eine Spielfigur.
Diese hat folgende Daten:
Position (3 x 4 Byte = 12 Byte)
Animation und die jeweilige Framenummer (4 Byte, oder sogar nur 2)
Leben (1 Byte)
Schild (1 Byte)
Waffentyp1 (1 Byte)
Waffentyp2 (1 Byte)
Munition1 (1 Byte)
Munition2 (1 Byte)

Macht zusammen 22 Byte pro Spieler.

Ist die Spielfigur von einem Clienten nun in der nähe von 50 anderen Spielern, dann müssen (aktualisierungszeit von sagen wir mal 10 hertz):

50 * 22 * 10 Byte /sec geholt werden.
=> 11000 Byte/sec = 10,74 KByte/sec worüber selbst meine langsame Verbindung lachen würde :)
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

Benutzeravatar
Jside
Beiträge: 377
Registriert: Di Nov 11, 2008 12:56 am

Re: Multiplayer...

Beitrag von Jside » Di Mär 17, 2009 4:45 pm

Dirty Oerti hat geschrieben:Hm, was mir dazu einfällt:

Auf den Server liegen Dateien für die Welt und die einzelnen Modelle samt ihrer Animationen.
Jetzt beschließen X Clients, sich mit dem Server zu verbinden und zusammen ein Spiel zu spielen.

Der Server schickt daraufhin jedem der Clients die kompletten Welt- und Modelldaten zu.
Wenn alle Clients ihre Daten erhalten haben, kann das Spiel gestartet werden.

Damit nun alle Clients auf dem gleichen Stand bleiben, werden regelmäßig vom Server Informationen über Position, Energie (o.ä.), Animationsstand, etc der (evtl, je nach Art des Spiels) umliegenden Modelle geholt.

Wenn du also pro Spieler nur diese Daten versenden musst hält sich das doch recht in Grenzen, oder?
Vorallem, wenn du es räumlich eingrenzt und nur die Daten runterlädst, die der jeweilige Client gerade braucht. (Das sollte aber der Clientrechner berechnen müssen!).
Bsp:

Jeder Spieler hat eine Spielfigur.
Diese hat folgende Daten:
Position (3 x 4 Byte = 12 Byte)
Animation und die jeweilige Framenummer (4 Byte, oder sogar nur 2)
Leben (1 Byte)
Schild (1 Byte)
Waffentyp1 (1 Byte)
Waffentyp2 (1 Byte)
Munition1 (1 Byte)
Munition2 (1 Byte)

Macht zusammen 22 Byte pro Spieler.

Ist die Spielfigur von einem Clienten nun in der nähe von 50 anderen Spielern, dann müssen (aktualisierungszeit von sagen wir mal 10 hertz):

50 * 22 * 10 Byte /sec geholt werden.
=> 11000 Byte/sec = 10,74 KByte/sec worüber selbst meine langsame Verbindung lachen würde :)
Die Idee, hat mich sogar noch einen Schritt weiter gebracht: Man kann auswählen, wie schnell die Internatanbindung ist, diese wird dann aufgeteilt, sodass sizeof(Playerdaten) + sizeof(NummerderSpieler * sizeof(Playerdaten)) subtrahiert wird, und die restliche Line nur für die Daten bereit steht, wenn sich neue Spieler einloggen, wird die Datenline um sizeof(Playerstruct) also quasi int-- verkleinert... Ich hab jetzt auch eine Idee, für die Welt, diese ist quasi in "Low" Form d.h. enthält nur die Positionsdaten der Statischen modelle, das dürfte mit zusätzlicher .tar.bz2 Kompression nicht allzugroß werden... Die Heigtmap wird in RAW Form auf dem Server abgelegt, so kann dieser bestimmte Stellen herausnehmen, ohne das Bild erst in den RAM laden zu müssen, den richtigen Abschnitt heraussnehmen zu müssen, und diesen zu versenden, sondern einfach via fseek() die richtige Stelle ansprechen.... Gegen cheating werde ich eine MySQL Datenbank(mit C Anbindung versteht sich) nehmen, die bei jedem verlassen/starten eines Clienten die Savedaten mit einer md5sum abgleicht, die vor dem beenden des Clienten versendet wird, zudem wird alle ~20sec überprüft, ob sich irgendwelche Werte verändert wurden, vonderen Änderung nichts aufgezeichnet wurde...Ist zwar noch fießer als DRM, allerdings lässt sich das vom Serveradmin abschalten(bei meinen allerdings dann nicht ;))

Aber eine Sache wäre da noch: Der Server kann ja nicht im milisec Takt:
Pseudocode hat geschrieben: int c = 0;
while(Player[c]) {
int i = 0;
while(Player) {
if(InRadius(Player.Position, Player[c].Position)) SendToClient(Player);
i++;
}
c++;
}

Wie kann der Server am besten herausfinden, welche Daten der Client benötigt(=im Sichtfeld sind) und das bei warscheinlich richtig großen Mengen?

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: Multiplayer...

Beitrag von Kerli » Di Mär 17, 2009 4:49 pm

Dirty Oerti hat geschrieben:=> 11000 Byte/sec = 10,74 KByte/sec worüber selbst meine langsame Verbindung lachen würde :)
Man darf jedoch nicht vergessen das es auch einen gewissen Overhead durch das Protokoll gibt und natürlich auch eine Latency. Da kann gar nicht einmal so wenig zusammenkommen.
Dirty Oerti hat geschrieben:Der Server schickt daraufhin jedem der Clients die kompletten Welt- und Modelldaten zu.
Ich würde versuchen so wenig wie möglich Daten zu übertragen. Dh. Modelle nach möglichkeit wiederverwenden und auch auf dem Client speichern, also nicht jedes mal neu laden.
Ein weiterer interessanter Ansatz wäre noch das Peer-to-Peer Prinzip ins Spiel zu bringen und damit die Modell-/Weltdaten auch unter den Clients zu verteilen und so den Server zu entlasten.
Jside hat geschrieben:2. Multiplayer unterstützten, sodass auch hunderte von Leuten gleichzeitig im Sichtbaren Bereich seien können.
Wenn du da in Echtzeit Modelle nachladen möchtest brauchst du ws eine Serverfarm mit einer Glasfaseranbindung :)

Es gibt genug Daten zum Übertragen selbst wenn keine Modelle dabei sind. Denk nur einmal an die Positionen und Zustände aller sichtbaren Spieler...
Jside hat geschrieben:Gegen cheating[...]
Nur so ein Tipp: Versuch es zuerst einmal ohne Schutzmaßnahmen ordentlich zum Laufen zu bringen ;)
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

Benutzeravatar
Jside
Beiträge: 377
Registriert: Di Nov 11, 2008 12:56 am

Re: Multiplayer...

Beitrag von Jside » Di Mär 17, 2009 5:14 pm

Kerli hat geschrieben:Wenn du da in Echtzeit Modelle nachladen möchtest brauchst du ws eine Serverfarm mit einer Glasfaseranbindung :)
Oh, das wäre garnicht mal so abwägig... :mrgreen:
Kerli hat geschrieben:Es gibt genug Daten zum Übertragen selbst wenn keine Modelle dabei sind. Denk nur einmal an die Positionen und Zustände aller sichtbaren Spieler...
Dazu habe ich gerade eine Idee bekommen, wenn der Spieler sich nicht bewegt, müssen auch keine Daten übertragen werden d.h. Der Server schaut nach, ob sich der Player bewegt hat, wenn nein wird dieser bei der Übertragung übersprungen, zudem machen ich feste "Schritte", d.h. wenn der Spieler sich nach Links bewegt, dann tut er das in einer bestimmten "größe", so muss pro Schritt nur einmal übertragen werden, was dem Upstream mancher Leute auch zugutekommt, die Clienten der anderen Spieler bekommen dann die Nachricht, das sich jemand um X/Y/Z bewegt hat, und können dessen Schrittbewegung ohne die Animation abzugleichen selber anzeigen, nur halt bei "Interaktiven" Sachen werden dann auch die AnimationsStates übertragen, d.h. wenn der Spieler nur Läuft, werden nur X/Y/Z übertragen, und nur, wenn der Spieler ein neues Inventar bekommt, wird dieses hochgeladen/Vom Server zu den anderen Spielern geschickt, so dürfte das ganz rudimentär funktionieren, jeder Client hat alle Daten der Spieler gespeichert, und nur bei Änderungen werden zusätzliche bytes übertragen...
Kerli hat geschrieben:Nur so ein Tipp: Versuch es zuerst einmal ohne Schutzmaßnahmen ordentlich zum Laufen zu bringen ;)
Also das hintergrund Zeug, ist nicht das Problem, sondern das hintergrundzeug optisch mit 3D Grafik aufzuwärten ;)

Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Re: Multiplayer...

Beitrag von Dirty Oerti » Di Mär 17, 2009 5:23 pm

Jside hat geschrieben:Dazu habe ich gerade eine Idee bekommen, wenn der Spieler sich nicht bewegt, müssen auch keine Daten übertragen werden d.h. Der Server schaut nach, ob sich der Player bewegt hat, wenn nein wird dieser bei der Übertragung übersprungen, zudem machen ich feste "Schritte", d.h. wenn der Spieler sich nach Links bewegt, dann tut er das in einer bestimmten "größe", so muss pro Schritt nur einmal übertragen werden, was dem Upstream mancher Leute auch zugutekommt, die Clienten der anderen Spieler bekommen dann die Nachricht, das sich jemand um X/Y/Z bewegt hat, und können dessen Schrittbewegung ohne die Animation abzugleichen selber anzeigen, nur halt bei "Interaktiven" Sachen werden dann auch die AnimationsStates übertragen, d.h. wenn der Spieler nur Läuft, werden nur X/Y/Z übertragen, und nur, wenn der Spieler ein neues Inventar bekommt, wird dieses hochgeladen/Vom Server zu den anderen Spielern geschickt, so dürfte das ganz rudimentär funktionieren, jeder Client hat alle Daten der Spieler gespeichert, und nur bei Änderungen werden zusätzliche bytes übertragen...
Ich hoffe mal ich hab dich richtig verstanden.
Was ich da für ein Problem sehe:

Ob sich ein Spieler bewegt oder nicht sagt doch nichts über seine Aktivität aus?
Wenn er z.B. auf den Feind wartend in der Ecke sitzt braucht der Client natürlich auch Daten, eben z.B. wann der Feind da vorbeikommt, um es anzuzeigen, damit der Spieler dann z.B. Schießen kann.
Natürlich muss der Client an den Server keine Positionsdaten schicken, wenn die sich eh nicht verändert haben.

Außerdem solltest du immer die Position übermitteln!
Nicht "das sich jemand um X/Y/Z bewegt hat" sondern dass dieser jemand nun an Position X/y/Z steht. Weil stell dir vor eine so eine Information geht verloren, dieser Fehler würde sich dann weiter durchziehen und die Bewegung würde nicht mehr richtig übermittelt.

Was du wirklich allgemein vermeiden solltest ist das Verteilen von Daten (Level, Modelle, Texturen) während dem Spiel. Das ist wirklich nicht zu empfehlen, das kann das Spiel dann ausbremsen, wenn nur eine Person eine langsamere Verbindung hat.
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3123
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Multiplayer...

Beitrag von cloidnerux » Di Mär 17, 2009 7:32 pm

1. Die Welt und Modelle vom Server laden(in realtime, immer das was in der Richtung liegt, und nochnicht schtbar ist), sodass der Admin diese beliebig vergrößern kann, ohne das alle Clienten Addons installieren müssen.
Das ist schlecht, denn ja nach dem welche verbindung du hast(>500kb/s) braucht es sehr lange um
a.) alles zu senden und
b.) es belastet den Server.
Wenn 10 leute relativ gleichzeitig zu dem Server Connecten, ensteht eine sehr großes Traffic volumen und der Client muss lange warten bis er alles hat.
Besser ist es nur die Inforamtionen über das Spiel zu senden und alles Local zu laden, dadurch sparst du dir Zeit, Resourcen und lästige Spielverzögerungen.
Wenn jemand daten nciht aht muss er sie sich dann übers netztwerk beziehen. Wer schon einmal ein Online-Spiel gespielt hat, weiß wie lange das Dauern kann...
Auch sollte sowas wie Physik-Engine und so auch local laufen, weil ein server für sowas keine Resourcen hat. Er sollte lediglich das spiel verwalten-> Wenn sihc ein Speiler bewegt soll er das allen mitteilen.
Redundanz macht wiederholen unnötig.
quod erat expectandum

Benutzeravatar
+Fuss+
Beiträge: 385
Registriert: Fr Nov 14, 2008 8:16 pm

Re: Multiplayer...

Beitrag von +Fuss+ » Di Mär 17, 2009 8:07 pm

Ich würde an deiner stelle vielleicht in einem anderen Multiplayer-Game nach schauen. Was mir da so direkt einfallen würde, wäre http://www.teeworlds.com . Da kann man sich auch den Sourcecode einzeln herunterladen. der Code für einen Server ist auch dabei.

Ist als Beispiel bestimmt nicht schlecht.


MfG Fuss

Benutzeravatar
Jside
Beiträge: 377
Registriert: Di Nov 11, 2008 12:56 am

Re: Multiplayer...

Beitrag von Jside » Mi Mär 18, 2009 6:15 pm

+Fuss+ hat geschrieben:Ich würde an deiner stelle vielleicht in einem anderen Multiplayer-Game nach schauen. Was mir da so direkt einfallen würde, wäre http://www.teeworlds.com . Da kann man sich auch den Sourcecode einzeln herunterladen. der Code für einen Server ist auch dabei.

Ist als Beispiel bestimmt nicht schlecht.


MfG Fuss
Das war sehr hilfreich, ich hab jetzt glaubisch den richtigen Ansatz...
cloidnerux hat geschrieben:Auch sollte sowas wie Physik-Engine und so auch local laufen, weil ein server für sowas keine Resourcen hat. Er sollte lediglich das spiel verwalten-> Wenn sihc ein Speiler bewegt soll er das allen mitteilen.
Auch eine Serverfarm? ;) Also Physik hab ich folgendermaßen vorgestellt: Server 1 hängt mit eth0 am Inet, und mit eth1 an einem Switch, Server zwei hängt ebenfalls an diesem Switch, und berechnet alles (Physik, Wettersystem, Zeitzonen(wegen nachtmodus etc.(falls die Engine das auch optisch darstellen kann, ich bin nicht der beste in sachen GUI/3D, bin halt ein Konsolenkind ;) )) Und kann dieses über 100MB/s (bzw. 1000MB/s wenn ich einen Gigabitswitch zufassen bekomme) Zu Server 1 senden, der die Netztwerksachen verwaltet.
Dirty Oerti hat geschrieben: Was du wirklich allgemein vermeiden solltest ist das Verteilen von Daten (Level, Modelle, Texturen) während dem Spiel. Das ist wirklich nicht zu empfehlen, das kann das Spiel dann ausbremsen, wenn nur eine Person eine langsamere Verbindung hat.
Ich könnte es ja auch z.b. so machen, das bei Spielstart erstmal eine kleine Singeplayer mit NPCs zur Verfügung steht, während man diese Spielen kann, wird im hintergrund der Rest gedownloadet...

So, mal eine Technische Frage:
Sollte ich die Anfragen der Cliente quasi Batchmäßig in einem anderen Thread verarbeiten, oder direkt?(Dateien ausgenommen, die werden über FTP versendet)
Verdeutlicht;

Code: Alles auswählen

while(1) {
empfange daten;
Überprüfe daten;
Lese Status aus Tabelle;
Sende Daten zu Player, und anderen Clients;
}
oder Extern, sodass alle Commands/Anfrage einem User zugeordnet werden, und diese in einem anderem POSIX Thread in einer while-Schleife verarbeitet werden? Dürfte egal sein oder? Wenn man die Netztwerkkarte einließt, kommen doch die Anfragen hintereinander herein oder?

P.s. 120 Codezeilen der Serversoftware vor 10min angefangen.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3123
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Multiplayer...

Beitrag von cloidnerux » Mi Mär 18, 2009 6:26 pm

Also, der Server Solte alles intern machen, da du dann bessere Kontrole über die alles hast. Es wäre vielleicht auch zu Überlegen ob du für die Verteilung der Daten eine Arte Peer-To-Peer Netztwerk einrichtes, heißt das wenn ein Client schon Daten EMpfangen aht er diese An andere Sendet um den Server zu Entlasten.
Und es sollte so gemacht werden, das jede map eine Deskriptor Datei hat, wo drinn steht welche Datein sie Benötigt und ein Client überprüft ober diese Besitzt und wenn nciht er sie sihc einfach nachlädt., um so unnötigen Netzwerktraffic zu Sparen.
Aber bevor das solltest du dir die Engine programmieren, denn du must ja auhc den Austausch der Engine Informationen Kümmern, da darauf ja egt. das Spiel basiert.
Redundanz macht wiederholen unnötig.
quod erat expectandum

Antworten