mmofacts.com

Echtzeit-Multiplayer-Programmierung ... Wie Was Wo?

gepostet vor 15 Jahre, 9 Monate von Blabbo

Moin,

irgendwann muss ich unbedingt mal ein Echtzeit-Multiplayer-Projekt umsetzen.
Nicht sofort, aber ich will mich schonmal schlau machen/einlesen.

Als Client würde ich Flash benutzen, da ich das recht gut beherrsche.

Nur von der Serverseite hab ich nahezu null Ahnung.
Soviel ich gehört hab, wird oft Java benutzt.

Die Macher von Whirled.com und Kdice.com benutzen wohl das GWT (http://code.google.com/webtoolkit).

Was haltet ihr davon? Kann man damit was wirklich echtzeitiges machen wie ein Rennspiel oder Geschichten mit richtig vielen Spielern wie DarkOrbit?
Arbeitet das auch mit Flash zusammen oder nur mit AJAX?

Wie aufwändig ist es, so einen MultiplayerServer selber zu schreiben im Vergleich dazu, sowas wie GWT zu verwenden?

Kennt jemand ein gutes (deutsches) Buch zum Thema Multiplayer Server Programmierung?

gepostet vor 15 Jahre, 9 Monate von Sarge

Als erstes solltest du mal versuchen zu verstehen was GWT ist bzw macht.

GWT ist nichts anderes als ein Compiler der aus java code javascript code für die Clientseite macht. Da du 3 Zeilen zuvor geschrieben hast du willst für die Clientseite Flash verwenden, sollte dir spätestens jetzt auffallen, das GWT dir da wohl nichts helfen wird ;)

GWT nutzt zur Kommunikation den RPC-Mechanismus von Java. Sehr komfortabel und es wäre prinzipiell sicher möglich den aus Flash heraus anzusprechen. Vllt gibts da sogar ne fertige Library zu? Ansonsten weiß ich, das Flash selbst einige eigene Serverlösungen anbietet mit nem rpc-ähnlichen Mechanismus. Du willst aber ein echtzeit Projekt schreiben. Dafür hat man in der Regel höhere Anforderungen. Dazu verwendet man ein eigenes Protokoll auf basis von TCP/UDP. Da Echtzeit  -also so schnell wie möglich- gefordert, meist UDP natürlich mit den entsprechenden Nachteilen verbunden.

Bevor du anfängst wild irgendwelche Frameworks für deine Serverseite zu suchen, ohne zu verstehen was da eigentlich gemacht wird, solltest du dir einfach kurz die Grundlagen der Socket/Netzwerkprogrammierung anschauen und nen kurzen beispiel Telnet/Chat Server schreiben und diesen wiederrum mit Flash ansprechen und schon weißt du wie das Prinzip funktioniert. Solltest du mit 1-2 Tagen aufwand hingestellt haben. Und dann kannst du dir nocheinmal überlegen was du eigentlich alles brauchen wirst.

Google dürfte dir entsprechende Howto's in jeder Sprache anbieten die du verwenden willst.

gepostet vor 15 Jahre, 9 Monate von Drezil

wenns dir z.b. auch darum geht dass du das ganze spielbar haben willst (nidriege pings, auch bei vielen spielern etc.), dann kannst du dir auch mal anschauen, wie die "Profis" das machen.

Der Quake3-Server code liegt ja z.b. als ioQuake3 offen. Da kannst du dir ja (in C++) ansehen, wie die das handeln. Das man bei solchen sachen auf UDP setzen sollte ist ohnehin schon klar. Q3 arbeitet, soweit ich das mitbekommen hat mit timeframes (z.b. 20x pro sec) in denen der server die daten rausschickt und der client kann sich dann auch drauf einrichten und z.b. den ping rausrechnen  (inkl. toleranz), bemerken, wenn pakete fehlen etc.

Genau hab ich mich damit auch nicht auseinander gesetzt - das war nur das, was ich von "aussen" mitbekommen hab.

http://ioquake3.org/get-it/ - steht unter der gpl v2 und kann auch als basis eigener spiele verwendet werden. (Nur für dich wär das nichts, da es statische level-grenzen gibt und ab 32 spielern wirds schon arg hakelig..) - ist eben nur als anschauungsmaterial für die netzwerkkommunikation gedacht :D

gepostet vor 15 Jahre, 9 Monate von Dunedan

Original von Drezil

Da kannst du dir ja (in C++) ansehen, wie die das handeln.

In C, nicht C++. ;-)

http://ioquake3.org/get-it/ - steht unter der gpl v2 und kann auch als basis eigener spiele verwendet werden.

Kann man machen, würde ich aber nicht empfehlen. Dafür ist der Code einfach zu alt und zu dreckig. Da einzelne Bestandteile rauszunehmen ist nahezu unmöglich, da alles irgendwie voneinander abhängt. Das verhindert gerade im Bezug auf die Netzwerkkommunikation beispielsweise die Entwicklung alternativer Clients bzw. Server, da die Verschlüsselung ein bisschen tricky und schlecht dokumentiert ist. Das heißt, selbst zu reimplementieren ist kaum möglich und den vorhandenen Source zu nehmen auch nicht, weil da die Abhängigkeiten zum Rest von Quake3 nicht rauszukriegen sind.

gepostet vor 15 Jahre, 9 Monate von MarcusSchwarz

Wenn du die Client-Seite mit Flash bauen willst solltest du dir überlegen, auch die Serverseite mit Flash aufzubauen. Dazu dürfte sich der Interactive-Server anbieten:

http://www.adobe.com/de/products/flashmediaserver/

Virtual Kicker League z.B. basiert auf dieser Technologie, die jeweiligen Spiele finden in "Echtzeit" statt. Das Projekt wurde auch wissenschaftlich begleitet und z.B. mit einem Artikel bei Springer bedacht:

http://www.springerlink.com/content/d48463115l3051rx/?p=bb7f72fb7db048fdbf0557bf71d10ce4&pi=0

(Rich Internet Architectures for Browser-Based Multiplayer Real-Time Games Design and Implementation Issues of virtual-kicker.com)

gepostet vor 15 Jahre, 9 Monate von Blabbo

Danke erstmal,

da ich bisher weder C(++) noch Java-Kenntnisse habe,
welche Sprache ist besser geeignet (bzw. hat welche Vor- und Nachteile bei der Serverprogrammierung)?

Auch in Bezug auf Verwendbarkeit auf nem eigenen Server.
Ich wollte möglichst wenig Energie auf die konfiguration meines Servers verwenden.

Womöglich nehme ich auch wirklich ne Komplettlösung.

Wobei meines Wissens der Flash Media Server für wirkliche Echtzeit zu langsam ist.

Es gäbe da noch den SmartFox Server (http://www.smartfoxserver.com/products/),
der hat einen Raw modus für sowas ("Raw data protocols for better data compression in real time games").
Meint ihr, dass das dann gleichwertig schnell zu so einer Quake-UDP-Methode? (hab ehrlich gesagt noch keinen Schimmer, was der Unterschied zwischen UDP und TCP ist ;))

Sowas ist natürlich nicht kostenlos und mir ists prinzipiell lieber, wenn ich sachen benutze, von denen ich weiss, wie sie funktionieren.

Ist nur die Frage, ob ich mich nicht übernehme beim Versuch, sowas selber zu proggen, kann ich halt schlecht abschätzen.

gepostet vor 15 Jahre, 9 Monate von TheUndeadable

> UDP und TCP

Vereinfacht:

Bei TCP übernimmt das Protokoll die Garantie, dass die Pakete ankommen und zwar auch noch in der richtigen Reihenfolge. Dies geschieht mit Hilfe von Feedback-Meldungen.

Bei UDP kommen die Pakete einfach. Oder sie kommen nicht. Dafür sparst du dir die Feedbackmeldungen. Wenn du auf manche Pakete verzichten kannst und die Reihenfolge nicht so wichtig ist, kannst du UDP nutzen.

Das Problem ist:

Meines Wissens nach ist es nicht möglich aus Browsern UDP-'Verbindungen' aufzubauen. Weder mit JS, noch mit Flash/Silverlight/Java.

Ein weiteres Problem sind viele Firewalls, die auf Grund der Zustandslosigkeit UDP-Pakete nicht richtig zustellen können. Hier kommt UPNP zum Beispiel zum Einsatz.

gepostet vor 15 Jahre, 9 Monate von Kallisti

Zudem ist es Unsinn zu behaupten im Spielebereich waere UDP die Antwort auf alle Fragen. Auch hier kann einem TCP mehr Vor- als Nachteile bieten. Man sollte halt nur daran denken gewisse Protokolloptimierungen vorzunehmen, wie beispielsweise Nagle-Algo deaktivieren oder nur noch jedes dritte Paket mit nem ACK zu bestaetigen anstatt jedes einzelne. Das reduziert das Buffering sowie die noetigen Roundtrips und somit die effektive Latenz um einiges.

Beispielsweise nutzt Blizzard fuer Diablo 2, Warcraft 3 und WoW reines TCP. Und gerade D2 und Wc3 sind schon extrem fast paced mit 6-10 Useraktionen pro Sekunde im "skilled" Bereich.

FPS games sind ein anderes Kaliber, da mag UDP seine Existenzberechtigung haben, aber in Strategie- und Rollenspielen sind imho garantierte packet delivery und flow control weit wichtiger als bedingungslos kleine Pakete/Datagramme.

Wenn man ontop von UDP noch Sequenznummern, Retransmitting etc. implementiert - wieso dann nicht direkt TCP nutzen? Imho macht UDP nur Sinn, wenn es egal ist, ob mal ein Paket verloren geht, wie z.B. bei multimedia content, also voice/video chat/streaming und dergleichen. Genau dafuer wurde es designed.

In Spielen kann man halt streiten ob es etwas macht, wenn der User nicht jede Fremdaktion immer korrekt und beim ersten Auftreten sieht, aber die Aktionen des Spielers selbst, muessen auf jeden Fall beim Server ankommen und wenn das Protokol gut designed ist, dann sollte auch jede Fremdaktion nur einmal uebertragen werden (sprich Bewegungen nicht als Sequenz von Koordinaten, sondern als Vektor uebertragen, vielleicht mit regelmaessigen syncs).

Das AoE paper sieht aber ganz interessant aus, schau ich mir mal in Ruhe an.

Falls du zum Lernen/Testen einen kleinen TCP Listening Server brauchst, mal wieder mein Rat zu Perl. Dort implementierst du das in wenigen Zeilen und es finden sich im Internet dutzende von Beispielen.

gepostet vor 15 Jahre, 9 Monate von Sarge

Niemand hat doch hier gesagt das UDP zwingend notwendig ist.

Was zwingend notwendig ist, ist aber dass man sich überlegen muss,  ob man herunter auf die Netzwerkschicht gehen will/muss oder ob man bei RPC/RMI oder ähnliche "middleware" geschichten schon stehenbleiben kann. Dazu muss man aber ein Grundlegendes Verständis aufbringen, was einem was bringt. Ob man TCP oder UDP nimmt ist doch nurnoch eine Detail Frage. Bei beiden musst du dir selbst ein Protokoll über tcp/udp schreiben. Bei UDP musst du halt evtl noch einzelne Sicherungsmechanismen selbst implementieren (Reihenfolge getreu, Quittungen) die dir TCP schon abnehmen würde.

Imho macht UDP nur Sinn, wenn es egal ist, ob mal ein Paket verloren geht, wie z.B. bei multimedia content, also voice/video chat/streaming und dergleichen. Genau dafuer wurde es designed.

UDP ist für alles gut bei dem der Overhead eines verbindungsorientierten+zuverlässigen Dienst zu groß ist oder ein zuverlässiger Dienst nicht nötig ist. Letzteres ist z.B. Voice streaming. Wen störts da wenn ein Packet nicht durchkommt? Niemanden. Nehmen wir aber das UDP Protokoll, das hier wohl jeder am meisten nutzt: DNS. Hier ist es wichtig, dass jedes Datenpaket ankommt. Aber es ist schlichtweg zuviel Overhead nen kompletten 3-way Handshake durchzuführen, um dann ein einzelnes Packet zu übermitteln. Viel einfacher ist es die Sendung (auf applikationsebene) zu wiederholen, wenn doch mal eine Anfrage verloren geht.

Du hast Flusskontrolle von TCP erwähnt. Sicherlich wünschenswert dies zu haben. Aber TCP kommt ja nicht nur mit Flusskontrolle sondern gleich auch mit Staukontrolle einher. Willst du z.B. das Feature wirklich? Das wäre z.B. imho ein guter Grund auf TCP zu verzichten. Ich als Echtzeitanwendung will eben nicht fair zu meinen konkurrierenden Datenströmen sein. Als Echtzeitanwendung will ich egoistisch versuchen auch bei Überlast möglichst ungehindert durchzukommen. Klar ist das für das gesamt-netz schlechter, aber wenn nen tcp service wie ein Download dadurch überpropertional gebremst wird und dafür mein Spiel flüssig läuft... ?

//Noch ein Grund pro UDP: Bei TCP hast du keinen einfluss auf den Retransmission Timer. Das regelt TCP selbst und passt dies entsprechend dynamisch an. Du kannst aber eventuell aus Game-mechanischen Gründen eine wesentlich bessere Abschätzung geben wann ein Packet wiederholt werden muss und somit ist ein selbstgeschriebener Retransmission Timer eventuell günstiger. Eventuell brauchst du auch keine Paketreihenfolge? etc etc.. gibt viele Gründe für und wieder.

Ich würde aber vermutlich auch wenn dann TCP nehmen. Weil ich keine Lust hätte das ganze Zeugs selbst zu implementieren ;)

Das AoE Paper ist btw sehr interessant und es ist schön zu sehen, dass es in der Realwelt genau so gemacht wird, wie ich es mir schon  gedacht habe :)

gepostet vor 15 Jahre, 9 Monate von Kallisti

Original von Sarge

Niemand hat doch hier gesagt das UDP zwingend notwendig ist.

Hmmm, doch hat jemand (Drezil) gesagt, darauf bezog ich mich ja:

Das man bei solchen sachen auf UDP setzen sollte ist ohnehin schon klar

Bzgl. 3-way Handshake bei simplen requests und kurzen Abrufen ohne Folgepakete hast Du natuerlich Recht (DNS), aber das hatte ich im Falle eines Spieles eben sowieso ausgeschlossen. Hier moechte man ja defintiv eine verbindungsorientierte Kommunikation haben, ausser man spielt Fernschach mit einem Zug am Tag... Aber bei Realtime Multiplayer kommt man da nicht drum herum.

Congestion control hat man natuerlich auch, ja. Aber auch da kann man selbst Einfluss (allein die Auswahl potentieller Berechnungsalgorithmen ist gigantisch) nehmen, ist ja nicht als sei alles vorgegeben. Du kannst auch gnadenlos Pakete rauspumpen, egal ob Dir die Leitung vollaeuft und keine ACKS mehr zurueckkommen oder nicht... und die window size kannst du auch entsprechend anpassen. Grad bei hoher Latenz und dicken Leitungen macht so was ja Sinn (z.B. Hi-Speed TCP). Da ist man durch TCP nicht limitiert, sofern man nicht die Defaults nutzt (die in den meisten Faellen eh ausreichen).

Und TCP retransmit errechnet sich ja aus der geschaetzten RTT, von daher liegt das schon recht nah am Optimum. Dazu kommen mit fast retransmit noch Optimierungen/prediction durch den Kontext anderer Pakete. Ich bezweifle, dass selbstgestrickte Loesungen das sonderlich besser hinbekommen, dafuer ist schon zu viel Know-how in TCP geflossen (wenngleich es immer noch ein paar Schwachstellen hat).

Also ich bin in den meisten Faellen sehr klar pro TCP, auch wenn UDP sicher eine coole Sache ist, wenn es um Multimedia Content geht oder eben um verbindungslose Anfragen. ;)

Grad das AoE Paper ueberflogen, hab grad nicht mehr die Zeit ins Detail zu gehen, aber so wie ich das mit dem Turnkonzept und der lokal berechneten Simulation verstehe, ist das groesste Risiko dabei doch, dass man Clienthacking Informationen in die Hand gibt, die der normale User noch nicht hat. Sie schreiben Sicherheit sei grad ein Vorteil der Simulationsloesung, aber was wenn ein Hack einfach die Simulation normal ausfuehrt und in einem zusaetzlichen Layer zwei turns (also 200-400ms!) frueher Informationen einblendet, die man eigentlich erst zwei turns spaeter erfahren wuerde? Es macht doch einen Riesenunterschied, ob ich einen Wechsel im Focus fire des Gegners eine halbe Sekunde vorher mitbekomme oder nicht... und ich finde das ein ziemlich grosses Manko, bzw. ein Killerargument... oder hab ich da etwas falsch verstaden?

Ich vermute mal AoE hatte einfach keine Hacking Szene, die auch nur ansatzweise Skill und Popularitaet wie in d2 oder wc3 erreicht hat, wo komplette Komprimierungs- und Verschluesselungsalgorithmen reverse engineered wurden, sonst waere das Konzept ziemlich auf die Schnauze geflogen...

gepostet vor 15 Jahre, 9 Monate von cherry

Hi Leute,

coole Diskussion. Die Links von "shadows" fand ich sehr aufschlussreich. Ein paar Anmerkungen habe ich. Die Diskussion geht schon sehr ins Detail und interessante technische Aspekte werden erwähnt. Aber was fehlt ist das "Big Picture" finde ich. Echtzeit Multiplayer ist ja ein weit zu spannender Begriff.. also nicht extrem weit aber relativ weit :-) Von wenigen u-Sekunden bis zu ein paar Sekunden um genau zu sein.

Man kann darum Quake3 und Age of Empires schwer vergleichen. Beide sind Real-Time insofern, als dass die Antwort zur richtigen Zeit kommen muss. Aber während man Age of Empires (oder Sieder 3) wahrscheinlich mit 1s Latenz noch relativ passabel spielen kann ist das bei Quake3 praktisch nicht möglich. Daraus ergeben sich auch sehr unterschiedliche Kommunikationsprinzipien. Die Diskussion TCP vs UPD ist darum zwar interessant aber wohl verfrüht.
Blabbo, Du solltest darum vielleicht ein wenig genauer beschreiben was Du vor hast. Willst Du ein Action-Spiel machen in dem wenige Millisekunden einen Unterschied machen oder soll es in Deinem Spiel ok sein wenn die Aktion eines Spielers erst eine Sekunde später bei den Mitspielern ankommt?
Mit Flash stelle ich mir so einen klassischen FPS mit Multiplayer schwierig zu implementieren vor (obwochl ich sehr wenig Erfahrung damit habe). Einfach wegen des Overheads und weil ich mir nicht vorstellen kann, dass Du direkt an den Netzwerkstack drankommst (berichtigt mich wenn ich da falsch liege). Sowas wie Starcraft z.B. ist da denke ich schon eher möglich.
Und auf Deine Frage ob Du Dir zu viel vornimmst wenn Du sowas selber implementieren willst würde ich sagen ja. Aber Du kannst ja einmal einen einfachen Prototypen versuchen der eine grundlegende Funktionalität des Spiels implementiert und darauf aufbauen. Dann hast Du schonmal was in der Hand und was "geschafft", kannst vielleicht sogar testen was passiert wenn 10 Leute gleichzeitig spielen usw.
cherry

gepostet vor 15 Jahre, 9 Monate von Kallisti

Nur kurz zum Gesichtspunkt Anspruch / sich uebernehmen: Also wenn man jetzt nicht die krasseste High-Performance Loesung, mit zig Abstraktionsebenen braucht, sondern nur ein recht simples Netzwerkprotokoll, ist das nicht wirklich komplex und auch nicht viel vorgenommen.

Ich hab halt mal in perl nen clientless bot (also ohne den echten client, rein paketbasiert) fuer diablo 2 geschrieben (allerdings nicht fertiggestellt, weil das Interesse nachliess, aber von bnet login bis gamejoin und im game rumlaufen kann er) und der Grossteil der Komplexitaet entsteht dort z.B. nur ueber die Kommunikation zu zig verschiedenen Servern (Login, MCP, adserver, gameserver - wodurch man multithreading/multitasking benoetigt), die Paket Sequenzen fuer verschiedene Aktionen, Anti-Cheating (hashing lokaler files mit div. Algorithmen, cd-key de-/encryption) und Security-Massnahmen (eine eigene SHA-1 Variation, Warden...). Das Protokoll ist dort binaer mit simplen opcodes (www.bnetdocs.org) und eben Stueck fuer Stueck reverse engineered worden, aber wirklich schwierig ist das alles nicht. - Eben vor allem weil einem TCP so gut wie alles abnimmt.

Da sind die Fragen welche Daten man uebertraegt und was man wie lokal berechnet viel schwieriger, interessanter und spannender. Eben allem voran mit dem Gesichtspunkt hacking im Kopf. Am Beispiel Blizzard kann man das auch sehr gut erkennen - und trotz aller Erfahrungen stecken selbst in WoW noch eine Menge Toleranzen im Netzcode. Aber Blizzard hat eben auch Warden.

Schliesse mich aber an, dass ein paar Details mehr sehr interessant waeren. Und ich finde du solltest es auf jeden Fall versuchen. Nicht vor den vielen unbekannten Dingen zurueckschrecken, das ist alles weit einfacher als man zunaechst meint.

gepostet vor 15 Jahre, 9 Monate von Blabbo

Also jetzt hab ich schonmal ganz grob ein etwas genaueres Bild von TCP und UDP.

Welche Sprache zur serverseitigen Programmierung (für mich) am geeignetsten ist, wäre noch interessant.

Im Prinzip schwirren mir einige Ideen im Kopf rum.
Zum testen würd ich natürlich erstmal nen Chat ausprobieren.

Dann vielleicht ein simples RTS-Spiel. Wie gesagt braucht man dafür nicht die überperformance.

Was Diablo-mäßiges wäre auch interessant.

Genauso wie ein Rennspiel, ich denke, wenn das mit den Kollisionen hinhauen soll, braucht man da schon wirklich ne niedrige Latenz. Aber wie gesagt würde ich vorher erstmal mit langsameren Geschichten Erfahrung sammeln wollen.

Wie ist denn das, wenn man mehrere "Spielwelten" haben will. Sollte man das alles von einem Prozess steuern lassen oder dann mehrere Serverprogramme laufen lassen?

Und wenn jemand ne Buchempfehlung parat hat?

gepostet vor 15 Jahre, 9 Monate von TheUndeadable

> Welche Sprache zur serverseitigen Programmierung (für mich) am geeignetsten ist, wäre noch interessant.

Da bietet sich in meinen Augen alle modernen skriptbasierten oder vollkompilierten Sprachen an.

Konkret: Perl/Ruby/Python/C# [Mono]/Java/Groovy

Da musst du schon selbst entscheiden, welche Sprache dir mehr liegt. Du kannst in allen Sprachen das gleiche mit mehr oder weniger Code erreichen. Ein TCP-Listener in C# ist zum Beispiel eine einfache Zeile, in Perl und Python meines Wissens nach auch.

Allerdings wird hier nun jeder seine Lieblingssprache nennen ;-) Das wirst du vollkommen selbst entscheiden müssen.

> Wie ist denn das, wenn man mehrere "Spielwelten" haben will. Sollte man das alles von einem Prozess steuern lassen oder dann mehrere Serverprogramme laufen lassen?

Ich persönlich würde für jede Spielwelt einen eigenen Prozess (bzw in .Net die sogenannten AppDomains, die virtuellen Prozesse in einem Prozesse [nicht Threads]) nutzen.

So kannst du schnell Spielwelten auf andere Server portieren. Laufen sie in einem Adressraum, so hast du eine schnelle, 'vertragsbasierte' Kommunikation über Shared Memory, laufen sie auf zwei unterschiedlichen Rechnern, so hast du es über Pipes/TCP. Damit kannst du schnell die verschiedenen Welten miteinander verbinden, sei es auch nur für ein gemeinsames Login.

Auch reißt eine Spielwelt nicht alle anderen Spielwelten mit, auch wenn sich das Problem einfach über Exceptionhandling auch innerhalb eines Prozesses lösen lässt.

gepostet vor 15 Jahre, 9 Monate von Todi42

Original von Blabbo

da ich bisher weder C(++) noch Java-Kenntnisse habe,
welche Sprache ist besser geeignet (bzw. hat welche Vor- und Nachteile bei der Serverprogrammierung)?

Ich selber bin C++-Fan, würde aber bei so einem Projekt nicht C++ nehmen, sondern Java:

- Es gib viel mehr Leute, die Java können, als vernünftig C++ Entwickler (und C++ ist blöd schwerr zu lehrnen)

- Für so ein Projekt könnte Java reichen, wenn es das nicht tut, kann man Teile später noch in C/C++ umsetzen

- Ich nehme mal an, dass mit einem Flash Client immer über TCP kommuniziert wird, dann könnte I/O das bottle neck sein und da wird eine asynchrone IO lib für Java nicht langsamer sein, als eine für C++

+ Dicker Pluspunkt für C++ könnte sein, wenn Du vor hast, die Spielwelt in weiten Teilen Transistent in Speicher zu halten. Da wäre der geschätzte, benötigte Speicherverbrauch um 50% niedriger.

edit: es gingen einige Formatierungen verloren (diese Forumsoftware ist grausam!)

gepostet vor 15 Jahre, 9 Monate von Kallisti

Mit dem Rennspiel und den Kollisionen ist imho nicht sooo kritisch. Du uebermittelst ja nur die Bewegungsvektoren und die Clients errechnen dann lokal die Kollisionsabfrage fuer die Darstellung. Natuerlich musst du Online auch entsprechend checken wg. Cheating. Aber es wird immer gewisse Toleranzgrenzen geben, die Latenzprobleme abfangen.

Das mit den Spielwelten ist relativ einfach denke ich. Die erste Frage ist wieso versch. Welten? Wenn nur darum geht Last zu verteilen, dann willst Du es ja ueber mehrere versch. Server aufteilen. Von daher eruebrigt sich die Frage mit dem Prozess dann. Wenn es darum geht logisch zu trennen, dann wuerde ich persoenlich es auch in versch. Prozessen machen, sofern die Spielwelt auch wirklich komplett getrennt ist. Also wenn die eine Welt niemals in irgendeiner Weise mit der anderen interagiert, dann sollte es komplett getrennt sein.

Interessanter wird es, wenn du instanzierte Welten haben moechtes, wie beispielsweise ein "Spiel" in Diablo 2 oder Dungeon, Arena oder Battleground in WoW. Da will man ja schon mehrere auf einem Server verwalten. Innerhalb einer Instanz (oder auch Spielwelt, je nach Konzept) kommst Du um threading/non-blocking sockets und multiplexing nicht herum, weil du ja auf der Serverseite memory sharen musst. Da die eine Instanz nicht die andere blocken sollte, sollte es zumindest auch multithreaded sein. Ob man das Ganze im Endeffekt dann mit Threads oder mit Forking loest, haengt denke ich von der Sprache der Wahl ab.

Fuer das Erlernen kann ich wie gesagt Perl uneingeschraenkt empfehlen, weil es dank CPAN sehr viele Libraries gibt, so dass man erstmal ohne viel Hintergrundwissen starten kann und direkt sehr maechtige Loesungen an der Hand hat. Wobei es in Sachen Threading etwas unflexibel und eingeschraenkt ist, weshalb man in Perl eben eher forked.

Falls das fuer Dich eine Moeglichkeit ist, schau dir mal Net::Server an. Das ist eine Lib fuer TCP Server, die ziemlich maechtig ist und dir viel Arbeit abnimmt. Du kannst halt mit 3-4 Zeilen Code einen vollwertigen Listening Server, inkl. Forking/Multiplexing/etc. starten. Fuer ein wenig mehr low level dann IO::Socket und IO::Select. Man kann auch in Perl noch eine Ebene weiter herunter, aber das macht hier denke ich erstmal keinen Sinn.

Alternativ sind die POE Varianten auch sehr sexy. POE::Component::Server::TCP und POE::Component::Client::TCP.

Beispiele finden sich tausende, vor allem in den Online Varianten der O'Reilly Buecher.

gepostet vor 15 Jahre, 9 Monate von BjoernLilleike

Wir haben zwarnicht so viele kritische Echtzeitkomponenten,so dass ich zur Performance nichts sagen kann.

Unser Backend zum Flash-Client ist in Java und zwar der OpenSource-Server Red5. Dieser bietet direkte Kommunikation über das flasheigene RTMP-Protokoll. Insgesamt ist das natürlich deutlich mehr High-Level und wir haben uns um die eigentliche Kommunikationsschicht noch nie gekümmert.
Da hätten wir auch gar keine Zeit übrig gehabt bisher - frei nach der alten Alpia-Schokoladenwerbung: Wir stecken jede Mark ins Spiel und keine Mark in die Technik..

Der SmartFoxServer war auch noch in der Wahl, wobei dermehr auf einzelne Partien als auf Massive-Multiplayer ausgelegt zu sein scheint. Letztlich war auch die Lizensierung ein Argument.

gepostet vor 15 Jahre, 9 Monate von COrthbandt

Ich werf auch mal meine Meinung zu verschiedenen Punkten in den Raum...

Programmiersprache für die Serverseite:

Von C++ rate ich ab, wenn Du nicht genau weisst, was Du da tust. Java ist brauchbar, allerdings ist Parallelisierung (=Performance) problematisch. Ruby und PHP scheiden auch aus Performancegründen aus.

Alternativ bietet sich bei einem Flash-Client auch SmartFox an.

Netzwerkprotokolle:

TCP, ohne Wenn und Aber. Die bei UDP auftretenden Probleme wie NAT, guaranteed delivery und out-of-order packets zu lösen ist unglaublich viel Arbeit. Und dann landet man praktisch immer bei einer TCP-Emulation. Da die Netzwerktechnik TCP aber schon kennt und speziell behandelt hat man bei so einer Emulation nur Nachteile.

Der primäre Nachteil bei TCP ist, dass auf dem Server höherer Protokollaufwand anfällt. Und die Menge an ephemeral ports ist auch begrenzt und damit auch die Anzahl gleichzeitig aktiver Spieler. Allerdings sollte das kein allzugrosses Problem sein, da wir hier von 20000-40000 reden.

Wenn Dein Server-Code 20000 gleichzeitig aktive Spieler in einem Realtime-Spiel verkraftet weisst Du auch, wie Du das Problem löst :)

Normale RPCs für die Realtime-Kommunikation würde ich nicht einsetzen, der Dekodierungsaufwand auf dem Server steht in keinem Verhältnis zu den übrigen Aufgaben. Ein kompaktes Binärprotokoll spart darüberhinaus auch massiv Bandbreite.

Also wenn ich jetzt nicht fit in C++ wäre, würde ich für den Client Flash und für den Server Java nehmen. Und dann ein natives Socket-Protokoll auf TCP-Basis.

HTH...

gepostet vor 15 Jahre, 9 Monate von dreaddy

Ich würde auch zu Java raten.

Setze grad ein Projekt mit einem C++ Server um, zwar eine Anwendung und kein Spiel, aber Resumee nach ca 1 Jahr Entwicklungszeit:
Allein schon TCP(oder halt UDP) und Multithreading ist in C++ ein Krampf, ich habe da auch in Java schon etwas mehr mit gemacht und muss sagen: da war das Beides viel angenehmer und die Threads machen sich keinen Spaß daraus, seltsame Verhalten an den Tag zu legen. Und ich habe einiges an Erfahrung mit C++, als Anfänger wirst du daran noch wesentlich mehr verzweifeln, zumal C++ keine Sprache ist, die man mal eben in einer Woche lernt und dann anwenden kann ohne in gefühlte tausend Fallgruben zu stolpern.
Also wenn du es im Gegensatz zu uns vermeiden kannst, C++ zu verwenden, wirst du viel Zeit und graue Haare sparen ;).

UDP macht halt für unkritische Daten Sinn, die entweder korrekt ankommen oder wenn sie nicht ankommen veraltet sind und keiner mehr braucht. Wird beispielsweise alle X Millisekunden die Position, Richtung etc von Spieler xy geschickt, wäre das so ein Kandidat.
Diese Daten werden, wenn sie nicht ankommen, verworfen, warum sollte man Zeit verschwenden um sie mühsam erneut zu senden und zu bestätigen.
Würde ich wenn dann aber mit TCP kombinieren, denn Daten die einfach ankommen MÜSSEN, gibt es immer und dann fängt man wie schon gesagt wurde an, UDP zu einem TCP umzuprogrammieren, was nicht Sinn der Sache ist.

gepostet vor 15 Jahre, 9 Monate von knalli

Ich habe mit dem Thema noch nicht viel (quasi nix) gemacht, aber was meine Kenntnisse und Erfahrungen angeht, dürfte Java auf jeden Fall angenehmer sein.

Egal, ob Java oder C++: Wenn du es falsch angehst, kannst du dir die Performance in beiden Arten mürbe machen. Wenn man es richtig macht, dürfte sich beide nichts geben, außer eben dem üblichen Overhead (bsp. durch Objekte, falls gegegeben).

Wenn du dir ein eigenes Protokoll definierst, könntest du später sogar einen Teil in einer anderen Sprache definieren.. (Middleware, ich hör dich trapsen).

Definitiv: Erst 'mal aufzeichnen (nicht nur grafisch), was du genau brauchst und die Beziehungen klären. Vielleicht mit Kostenschätzungen,  erwartete Volumen, usw..

gepostet vor 15 Jahre, 9 Monate von Liutasil

In meinem Spiel habe ich Echtzeitkämpfe mittels eines Flash-Clienten und eines Java-Servers gelöst.

Das ganz läuft wirklich ausgezeichnet.

Auf Flash-Seite kann man ganz einfach mit einem XML-Socket arbeiten. Den gibt es sowohl in AS2 als auch in AS3.

Auf Java-Seite nutze ich Apache Mina (http://mina.apache.org/)

Über Protokolle und ähnliches musste ich mir gar nicht groß Gedanken machen, das hat alles automatisch funktioniet.

Die Geschwindigkeit ist im Moment wirklich gut, wie das mit richtig vielen Spielern aussieht kann ich allerding noch nicht sagen.

gepostet vor 15 Jahre, 9 Monate von Blabbo

cool, also Java :)

mit XML sind die Datenpakete halt recht groß, bei schnelleren Spielen dürfte das Probleme geben.

gepostet vor 15 Jahre, 9 Monate von Liutasil

Auf XML habe ich verzichtet.

Ich verschicke nur kommagetrennte Strings, damit sind die Pakete viel kleiner.

gepostet vor 15 Jahre, 9 Monate von Blabbo

achso, ich nahm an, wenn man einen XML-Socket benutzt, heisst das auch, dass man XML-formatierte Daten schickt?

Oder war das nur ne allgemeine Aussage, dass man in Flash nen XML-Socket benutzen kann.

Jedenfalls werd ich mir das beizeiten mal anschaun, Red5 benutzt ja scheinbar auch Mina.

gepostet vor 15 Jahre, 9 Monate von Agathor_Fabularis

Servus,

dann  gebe ich auch mal meinen Senf dazu da Fabularis ja zu 100% auf Echtzeit Kommunikation setzt. So hab ichs gemacht:

Client: Flash / AS3 und XMLSocket (über den kann alles geschickt werden, das XML ist irreführend)
Server: Eigenes Javaserverchen.
Protokoll: Was ist das? ;-) Protokoll wäre übertrieben..aber was Selbstgestricktes in der Art gibt es.
Format: Serialisierte Java-HashMaps, auf Client Ebene werden die dann in AS3 Arrays umgewandelt und übertragen wird das Ganze natürlich komprimiert.

Jo, soweit sogrob. Ich hatte erst die verrückte Idee meinen Server in PHP zu schreiben - mann was war das eine blöde Idee (Performance). ;-) Aber man lernt dazu.

Fazit: Server = Java und Client = AS3

gepostet vor 15 Jahre, 9 Monate von Todi42

Original von dreaddy

Ich würde auch zu Java raten.

Setze grad ein Projekt mit einem C++ Server um, zwar eine Anwendung und kein Spiel, aber Resumee nach ca 1 Jahr Entwicklungszeit:
Allein schon TCP(oder halt UDP) und Multithreading ist in C++ ein Krampf

Da C++ ja im Gegensatz zu Java keine TCP und Multithreading unterstützt, must Du mal die verwendeten Bibliotheken mit erwähnen. Ich verwende für Soetwas boost, bzw. in der Vergangenheit RougeWave und finde, dass zumindest Multithreading von vielen Bibliotheken (sehr) gut umgesetzt wird.

gepostet vor 15 Jahre, 9 Monate von TheUndeadable

Oder gar QT, was ich in der C++-Programmierung recht schneckig finde.

gepostet vor 15 Jahre, 9 Monate von Dunedan

Je nach Einsatzzweck ist Qt aber trotz der Modularisierung seit 4.0 ein bisschen viel Overkill.

gepostet vor 15 Jahre, 9 Monate von blum

Ich würde auch Boost verwenden, das ist Teil des nächsten C++ Standards.

Ausserdem ist C++ sexy und Java nicht!!11einself

gepostet vor 15 Jahre, 9 Monate von MrMaxx

Manch einer steht halt auf dicke Frauen

gepostet vor 15 Jahre, 9 Monate von dreaddy

Original von Todi42

Original von dreaddy

Ich würde auch zu Java raten.

Setze grad ein Projekt mit einem C++ Server um, zwar eine Anwendung und kein Spiel, aber Resumee nach ca 1 Jahr Entwicklungszeit:
Allein schon TCP(oder halt UDP) und Multithreading ist in C++ ein Krampf

Da C++ ja im Gegensatz zu Java keine TCP und Multithreading unterstützt, must Du mal die verwendeten Bibliotheken mit erwähnen. Ich verwende für Soetwas boost, bzw. in der Vergangenheit RougeWave und finde, dass zumindest Multithreading von vielen Bibliotheken (sehr) gut umgesetzt wird.

Wir verwenden auch boost für Multithreading und genau dort gibts Probleme, derzeit grad mit shared pointern die trotz x facher Überprüfung des Quellcodes plötzlich den falschen Inhalt im falschen Thread haben aber grundsätzlich einfach darin, dass die Lokalisierung und Beseitigung von Fehlern und auch die Programmierung selbst länger dauert und die Gefahr Fehler zu produzieren deutlich höher ist.

Java ist nunmal unbestreitbar in der Programmierung ein gutes Stück einfacher und es wird einem viel vom System abgenommen wird, wo man sonst gerne mal einen Fehler hineinzaubert.
Das hat zweifellos auch seine Schattenseiten und führt immer wieder zu sehr emotional angehauchten Diskussionen, aber bis man C++ mit den wichtigsten Tücken und dazu noch die gängisten Boost Bibliotheken gelernt hat, so dass man einen stabil laufenden Server programmiert bekommt vergehen viele viele Jahre.

In Java hingegen kommt man wesentlich schneller zu Ergebnissen und alleine das rechtfertigt schon die Aussage: "lass erstmal die Finger von C++ und erst recht von Boost".
Und auch als Fortgeschrittener fragt man sich zunehmend, ob man sich das wirklich noch antun muss oder C++ langsam mal ausgedient hat, egal wie toll man das in den vergangenen Jahren fand.

gepostet vor 15 Jahre, 9 Monate von Blabbo

Wie wichtig ist denn Multithreading und inwiefern muss man da seine Programmierweise umstellen?

Oder erledigt das dieses Boost dann "von alleine"?

Hab von Java echt noch keine Ahnung.

gepostet vor 15 Jahre, 9 Monate von blum

Multithreading brauchst du zb wenn dein Programm auf einem Port lauscht, aber gleichzeitig Events abarbeiten soll. Das machst du dann in 2 Threads, die parallel laufen und der eine Thread muss nicht auf den anderen warten.

gepostet vor 15 Jahre, 9 Monate von knalli

Original von Blabbo

Wie wichtig ist denn Multithreading und inwiefern muss man da seine Programmierweise umstellen?

Oder erledigt das dieses Boost dann "von alleine"?

Hab von Java echt noch keine Ahnung.

Ja, muss man. Vor allem Synchronisation ist etwas, was dir "bisher" egal sein konnte. Atomare Hilfskonstrukte sind da äußerst hilfreich.

Ich hab' mal grad gegoogelt (java + multithreading), und dir gefilterte Ergebnisse zusammengestellt:

Wikipedia und Co helfen da sicher auch.

gepostet vor 15 Jahre, 9 Monate von TheUndeadable

MSDN Magazine: Concurrency

http://msdn.microsoft.com/en-us/magazine/cc159269.aspx

Eine sehr breite Übersicht.

What Every Dev Must Know About Multithreaded Apps

http://msdn.microsoft.com/en-us/magazine/cc163744.aspx

This article discusses:

  • Multithreading and the shared memory threading model
  • Races and how concurrent access can break invariants
  • Locks as the the standard solution to races
  • When locks are needed
  • How to use locks and understand costs
  • How locks can get in each other's way
gepostet vor 15 Jahre, 9 Monate von Tron

Blabbo,

wenn du dich Clientseitig in Flash wohlfühlst, dann ist das sicher keine schlechte Idee das Erstlingswerk in realtime damit anzugehen. Die ganze Diskussion über Optimierung des Traffics bevor überhaupt die Architektur umrissen ist halte ich für Unsinn, so erreicht ein Projekt in diesem Jahrhundert nicht mal die Alpha. Davon ab werden hier Dinosaurier der Netzwerkspiele angeführt, die in Zeiten aktuell waren, als die User teilweise noch mit 56k Modems am Start waren. Wenn du heute mit so einem Projekt anfängst, kannst du die im Schnitt verfügbare Bandbreite bei Betastart getrost mindestens mit dem doppelten ansetzen.

Eine elegante und recht effiziente Methode mit Flashclients zu synchronisieren sind Rtmp-Verbindungen. Serverseitig implementierst du SharedObjects, die die Clients über die States der gemeinsamen Objekte auf dem Laufenden halten.

Man muss für Rtmp btw. keine tausenden von Euros für einen FMSI auf den Tisch legen, es gibt da kostenlose Open Source Lösungen, die  das Protokoll hinreichend gut implementieren um damit arbeiten zu können.

Nebenbei kann man durch pfiffige Architektur das Datenaufkommen um ein vielfaches besser optimieren als mit Byteknauserei bei der Datenübertragung, Wenn ich nicht grad bei UDP-Paketen um die 60 Bytes rauskomme um gängige Bevorzugung durch Trafficshaper rauszukitzeln, dann kann ich auch gern mit vollen Paketen um die 1300 Bytes kalkulieren (darüber kanns durch verkorkste MTU's grad bei hintereinandergeschalteten Routern und verbummfeiter WifiFirmware komisch werden mit der Fragmentierung).

Was die Wahl der Serverseitigen Programmiersprache angeht, bietet sich Java an. Java ist heutzutage in der Ausführungsgeschwindigkeit häufig vergleichbar mit C++, ist aber etwas produktiver in der Entwicklung. Durch diverse existierende Frameworks und gute IDE's ist auch der Overhead nicht mehr so schröcklich tragisch wie anno dunnemals.

Wenn du ein bisschen genauere Vorstellungen bezüglich der Architektur hast, kann ich die präzisere Tips zur umsetzung geben. Du musst nur ein wenig Geduld mitbringen, ich hab zur Zeit Projekte bis über die Ohren ;)

Saludos,

Stefan

Auf diese Diskussion antworten