2 Spieler Netzwerkmodus, wie geht mans an?
-
Hallo zusammen!
Es geht um ein DirectX 9 zwei Spieler Spiel, bei dem jeder Spieler fünf bis zehn Fahrzeuge per Maus steuern kann. Die Verbindung soll direkt von PC zu PC (erstmal nur im LAN) stattfinden und wird momentan per Winsock realisiert - d.h., dass eine Verbindung aufgebaut wird und Daten hin- und hergeschickt werden können.
Auszutauschende Daten zwischen den Rechnern sollen folgende sein:
- Fahrzeugpositionen
- welches Fahrzeug lebt/ist tot
- Geschosspositionen eventuell
- ...Dinge dieser Art ebenEs stellen sich nun mehrere Fragen:
1. Wie oft pro Sekunde müssen/sollten Daten ausgetauscht werden?
2. Sollte man Threads benutzen? Wenn ja, wie viele und mit welchen Aufgaben?
3. Was ist von nonblocking Sockets zu halten? Wäre die Anwendung in diesem Fall sinnvoll?
4. Wie sollte man das Ganze am besten angehen? Ganz generell...Vielen Dank schon einmal im Voraus!
-
iop schrieb:
1. Wie oft pro Sekunde müssen/sollten Daten ausgetauscht werden?
So oft, wie du denkst dass du es brauchst. Ausprobieren... Vielleicht wäre es sinnvoll, nur dann etwas zu senden wenn auch eine Änderung stattfindet.
iop schrieb:
2. Sollte man Threads benutzen? Wenn ja, wie viele und mit welchen Aufgaben?
Dir überlassen. Du könntest einen extra Thread zum Empfangen nehmen, und den Hauptthread für den Rest (Game-Schleife incl. Senden...).
iop schrieb:
3. Was ist von nonblocking Sockets zu halten? Wäre die Anwendung in diesem Fall sinnvoll?
Nie ausprobiert, da kann ich nix dazu sagen sorry. Sollte dann aber alles in einem Thread funktionieren. Ausprobieren...
iop schrieb:
4. Wie sollte man das Ganze am besten angehen? Ganz generell...
Nachdenken, nachdenken, nachdenken, planen, nachdenken, nachdenken, planen, planen, nachdenken...
Bau dir vielleicht mal ne kleine Anwendung (Minispiel zB.) um ein Gefühl für den Umgang mit dem Netzwerk zu bekommen.
MfG
-
iop schrieb:
Wie oft pro Sekunde müssen/sollten Daten ausgetauscht werden?
Das hängt natürlich von verschiedenen Faktoren wie deinen Anforderungen, verfügbare Bandbreite und Art des Spiels ab. Gewöhnliche Multiplayer-Shooter werden etwa 40 - 50 mal pro Sekunde mit dem Server synchronisiert.
-
Viel interessanter ist doch die Frage:
Wie interpoliert man zwischen den übertragenden Nachrichten und wie geht man mit unterschiedlich langen Ping Zeiten um?Ich meine:
Bei Shootern macht es ja offensichtlich wenig Sinn TCP zu nehmen, denn wenn eine Nachricht nicht ankommt währe die Information nach dem Neusenden total veraltet.Was ist also wenn man die Position den Spielers abschickt und sich diese überholen. Dann würde die Sielfigur im Vorwärtslaufen kurz nach hinten und dann wieder nach vorne gehen => Es würde also ruckeln.
Dazu hätte ich die Idee, das man die Nachrichten durchnummeriert.Jetzt kann es aber immer noch sein, das man die Nachrichten z.B alle 50 ms abschickt. Diese aber mit UDP unterschiedlich lange brauchen. Sie kommen z.B nach
50 , 120, 150 ms an. Auch hier würde ein ruckeln entstehen obwohl sie in richtiger Reihenfolge ankommen. Die Nummerierung hilft also nicht.
Meine Idee: Man muß man noch die Zeit mitschicken zu der sie abgesendet wurden um unterschiedlich lange Laufzeiten zu bemerken oder auszugleichen.1. Aber wie gleicht man sie aus, wenn man die Information hat?
(Z.B wenn man dir die Position und den Bewegungsvektor des Balls bei dem Spiel Pong überträgt)Wie interpoliert man zwischen den einzelnen Nachrichten generell?
z.B. einer bewegt einen Gegenstand X mit der Maus. Man sendet alle so und so viele Sekunden die Position von X und die Bewegungsrichtung und Geschwindigkeit der Maus.2. Wie interpoliert man zwischen den Werten?
(Der Spieler muß ja keine linare Bewegung dazwischen mit der Maus einhalten.)3. Wie schafft man es das die Uhren wirklich genau synchron laufen?
(Damit das Spiel auf beiden Computern nicht aus dem Takt gerät?
Selbst wenn man die Bewegungen Zeitabhängig macht, addieren sich winzige Abweichungen irgendwann auf, wenn man Stunden lang dieses Spiel spielt)Dies sind Probleme die bei mir aufgetreten sind nachdem ich versucht habe ein so einfaches Spiel wie Pong netzwerkfähig zu proggen.
Und Antworten darauf weiß ich leider immer noch nicht.
Wenn Jemand prinzipielle Antworten hat zu diesen 3 Problemen: Bitte posten!
-
Man könnte beispielsweise bei Bewegungen nur die Richtung und die Geschwindigkeit weitergeben. Kommt ein Paket nun nicht an, läuft er trotzdem weiter in diese Richtung. Anhand der weiteren Pakete wird dann entscheiden, wie es weiter geht (:
Ob das ganze so funktionieren würde weiß ich nicht, aber es würde zumindest ein paar Probleme der Synchronisation aus dem Weg räumen.
-
Andreas XXL schrieb:
Viel interessanter ist doch die Frage:
Wie interpoliert man zwischen den übertragenden Nachrichten und wie geht man mit unterschiedlich langen Ping Zeiten um?Ich meine:
Bei Shootern macht es ja offensichtlich wenig Sinn TCP zu nehmen, denn wenn eine Nachricht nicht ankommt währe die Information nach dem Neusenden total veraltet.im gegenteil udp wäre noch fataler. es ist nicht sichergestellt, dass datenpakete in der richtigen reihenfolge ankommen und ob sie überhaupt ankommen. da wo man mit datenverlust einigermaßen leben kann, wie audio streams (siehe mumble voice software) macht udp sinn um latenzzeiten niedrif zu halten, wo es wichtig ist, dass daten seriell in der richtigen reihenfolge ankommen (wie zum beispiel wenn ein spieler sich bewegt) ist tcp die bessere wahl, man muss aber mit höheren round trip zeiten rechnen. als zwischending kann man sich auch noch selbst um konsistenz und validität der daten mit udp kümmern, was etwas mehraufwand beim programmieren bedeuted.
Andreas XXL schrieb:
Was ist also wenn man die Position den Spielers abschickt und sich diese überholen. Dann würde die Sielfigur im Vorwärtslaufen kurz nach hinten und dann wieder nach vorne gehen => Es würde also ruckeln.
Dazu hätte ich die Idee, das man die Nachrichten durchnummeriert.eben das kann mit tcp eigentlich überhaupt nicht passieren
Andreas XXL schrieb:
Jetzt kann es aber immer noch sein, das man die Nachrichten z.B alle 50 ms abschickt. Diese aber mit UDP unterschiedlich lange brauchen. Sie kommen z.B nach
50 , 120, 150 ms an. Auch hier würde ein ruckeln entstehen obwohl sie in richtiger Reihenfolge ankommen. Die Nummerierung hilft also nicht.
Meine Idee: Man muß man noch die Zeit mitschicken zu der sie abgesendet wurden um unterschiedlich lange Laufzeiten zu bemerken oder auszugleichen.wie gesagt, mit tcp ist diese nummerierung hinfällig, und ist auch mit udp nicht ganz koscher, da immer noch pakete verloren gehen können.
Andreas XXL schrieb:
1. Aber wie gleicht man sie aus, wenn man die Information hat?
(Z.B wenn man dir die Position und den Bewegungsvektor des Balls bei dem Spiel Pong überträgt)Wie interpoliert man zwischen den einzelnen Nachrichten generell?
z.B. einer bewegt einen Gegenstand X mit der Maus. Man sendet alle so und so viele Sekunden die Position von X und die Bewegungsrichtung und Geschwindigkeit der Maus.arbeite mit abstrakten 'ticks' zur synchronisierung, das macht das leben einfacher als mit zeiteinheiten wie ms
Andreas XXL schrieb:
2. Wie interpoliert man zwischen den Werten?
(Der Spieler muß ja keine linare Bewegung dazwischen mit der Maus einhalten.)in der regel, wenn man eben mit solchen ticks arbeitet, überspringt man solche invaliden (outdated) datenpakete im client. bei sehr großer latenz führt dies dann zu dem bekannten 'lag', also figuren springen über größere distanzen usw
Andreas XXL schrieb:
3. Wie schafft man es das die Uhren wirklich genau synchron laufen?
(Damit das Spiel auf beiden Computern nicht aus dem Takt gerät?
Selbst wenn man die Bewegungen Zeitabhängig macht, addieren sich winzige Abweichungen irgendwann auf, wenn man Stunden lang dieses Spiel spielt)nochmal, ticks, eine einfache fortlaufende zahl, die vom server vergeben wird, in einem gewissen intervall erhöht wird, irgendwann wieder bei 0 anfängt und vom client entprechend interpretiert wird

-
Vielen Dank erstmal für die ersten Antworten - hoffe, es kommen noch einige Anregungen

Dir überlassen. Du könntest einen extra Thread zum Empfangen nehmen, und den Hauptthread für den Rest (Game-Schleife incl. Senden...).
Hört sich gut an, habe ich auch schon drüber nachgedacht. Weiß eventuell jemand noch etwas zu nonblocking Sockets zu sagen?
Gewöhnliche Multiplayer-Shooter werden etwa 40 - 50 mal pro Sekunde mit dem Server synchronisiert.
Hm, wo kann man solche Zahlen nachlesen? Hier und da tauchen in Foren Zahlen auf, aber Quellen habe ich bisher nicht gesehen. Hast Du eine Begründung für diese Angabe?
..ist nicht böse gemeint, ich möchte mir einfach nur ein möglichst klares Bild verschaffen..@sothis_
Deine Argumentation für TCP leuchtet ein. Vor allem, wenn man davon ausgehen kann, dass bei der Übertragung von Daten für die kleine Zahl von 10 - 20 [quote]Fahrzeugen und den dazugehörigen Geschossen auszugehen ist. UDP wird hier wahrscheinlich keinen Vorteil, sondern eher Mehraufwand bedeuten.nochmal, ticks, eine einfache fortlaufende zahl, die vom server vergeben wird, in einem gewissen intervall erhöht wird, irgendwann wieder bei 0 anfängt und vom client entprechend interpretiert wird

Könntest Du zu den "Ticks" eventuell mehr sagen? Ich verstehe nicht ganz, worauf das hinausläuft.
Danke nochmals bis hierhin!
-
iop schrieb:
Hm, wo kann man solche Zahlen nachlesen? Hier und da tauchen in Foren Zahlen auf, aber Quellen habe ich bisher nicht gesehen. Hast Du eine Begründung für diese Angabe?
..ist nicht böse gemeint, ich möchte mir einfach nur ein möglichst klares Bild verschaffen..Nimm das Multiplayer-Spiel deiner Wahl und schaue mit welcher Tickrate die verschiedenen Server laufen.
-
Äh.

Wollte nur anmerken: sowas macht man ab besten indem man sich die RakNet oder was ähnliches runterlädt wo das alles schon implementiert ist. Warum immer das Rad neu erfinden?
-
krabbels schrieb:
Nimm das Multiplayer-Spiel deiner Wahl und schaue mit welcher Tickrate die verschiedenen Server laufen.
Ah, ok, das ist doch schonmal was

..hat das denn mit den "Ticks" zu tun, die sothis_ angesprochen hat? Doch nicht, oder? Was muss nun mit den Datenpaketen mitgeschickt werden?hustbaer schrieb:
Äh.

Wollte nur anmerken: sowas macht man ab besten indem man sich die RakNet oder was ähnliches runterlädt wo das alles schon implementiert ist. Warum immer das Rad neu erfinden?Das stimmt schon, so könnte man es machen. Wir wollen es aus bestimmten Gründen erst einmal anders versuchen.
-
hustbaer schrieb:
Äh.

Wollte nur anmerken: sowas macht man ab besten indem man sich die RakNet oder was ähnliches runterlädt wo das alles schon implementiert ist. Warum immer das Rad neu erfinden?um zu lernen und weil es manchen spaß macht. punkt.
-
iop schrieb:
..hat das denn mit den "Ticks" zu tun, die sothis_ angesprochen hat? Doch nicht, oder?
Doch, exakt das meinte sothis_. Pro Tick versendet der Server die zur Synchronisierung benötigten Daten an die Clients. "Tick" ist dabei eine abstrakte Zeiteinheit, und zwar 1 Tick = (1000 / Tickrate)ms. Anstatt "alle so und so viele Sekunden" sagst du einfach "pro Tick".
-
krabbels schrieb:
Doch, exakt das meinte sothis_. Pro Tick versendet der Server die zur Synchronisierung benötigten Daten an die Clients. "Tick" ist dabei eine abstrakte Zeiteinheit, und zwar 1 Tick = (1000 / Tickrate)ms. Anstatt "alle so und so viele Sekunden" sagst du einfach "pro Tick".
Ah, ok, jetzt hab ichs

Dann gehts bald ans ausprobieren - Danke euch bis hierhin!
-
sothis_ schrieb:
hustbaer schrieb:
Äh.

Wollte nur anmerken: sowas macht man ab besten indem man sich die RakNet oder was ähnliches runterlädt wo das alles schon implementiert ist. Warum immer das Rad neu erfinden?um zu lernen und weil es manchen spaß macht. punkt.
Huch bitte nicht so freundlich, sonst fürchte ich mich.