Zu Beginn habe ich viel Hintergrundwissen im Netzwerk (Hardware, Router, z. B.), aber nur sehr wenig Wissen über die Grundlagen der Netzwerkprogrammierung hinaus. Dies mag wie eine dumme Frage erscheinen, aber ich möchte wissen, worauf ich mich einlasse, während ich die Implementierung von Multiplayer in meinem Spiel ergründen kann.
Ich erstelle eine kachelbasierte Welt, die durch ein einfaches 2D-Array generiert wird. Sagen wir der Einfachheit halber etwas wie Welt [100] [100].
Derzeit rendert die Rendermethode nur die Kacheln basierend auf der Auflösung des Fensters plus einer Kachel (für ein reibungsloses Rendern während der Bewegung). Unabhängig von der Größe der Welt (10 x 10, 1 Million x 1 Million) ist die Leistung des Renderings einwandfrei.
Das Gameplay braucht nichts weiter als zu wissen, was in den aktuell sichtbaren (auf Bildschirm +1 gerenderten) und höchstens EINIGEN Informationen von Kacheln in einem Bereich um den Spieler herum angezeigt wird.
Alles, was vom Server mehr gesendet wird, ist also nicht die vollständige Kachelinformation. Ex. Gegenstände, die auf dem Boden liegen, Bodentyp, Bäume usw. wären in dem Bereich außerhalb der Sicht des Spielers nicht wichtig, sondern nur das, was der Kunde / Spieler in diesen Kacheln wissen muss. (Bsp. Ultima Online 'eingehende Namen', bei denen Spieler einen Charakter [Spieler oder Monster] kennen konnten, befanden sich in ihrer gerenderten Ansicht direkt hinter den Kacheln.)
Ich weiß nicht viel über Networking. Wenn ich das lerne, könnte dies meine Frage beantworten. Ich bin jedoch gespannt, ob dies eine praktikable Lösung ist oder ob die Idee einfach lächerlich ist.
Die gesendeten Informationen würden sich auf einen 10x15-Bereich von Kacheln beziehen, und jede Kachel enthält Informationen darüber, was sich auf der Kachel befindet. Effizienter wäre alles ein Objekt, in dem die Kachel alle Objekte auf der Kachel enthält. Ex. Plättchen [4] [4] enthält Schwert # 23452, Rock2, Baum5, Spieler3, Monster4.
Leere Kacheln senden nur den Geländetyp [Gras, Sand, Wasser], wenn sie nicht bereits während der Initialisierung / des Ladens geladen wurden. Einige Kacheln hätten eine Handvoll Gegenstände [Tree2, Sword # 924, Gold, Corpse, Rock3].
Daher kann ich mir nicht vorstellen, dass eine Kachel sehr viele Informationen vom Server an den Client senden muss, da der Client hauptsächlich nur die zu ladende Textur und die Position kennen muss, um sie auf dem Bildschirm zu platzieren. Position ist nur zwei Ganzzahlen und Textur ist eine Ganzzahl für eine Liste von Dateien, die der Client zum Rendern anweist.
Im verrücktesten Fall müsste der Server 150 Kacheln mit Informationen zu nur einer Handvoll von Objekten auf LOAD senden und von da an nur noch Kacheln (falls vorhanden) und neue Kacheln (10 bis 15 jedes Mal, wenn sich ein Spieler in eine Richtung bewegt) aktualisieren ) und die Bewegungsrichtung der Zeichen auf dem Bildschirm (damit der Client eine reibungslose Bewegung zwischen den Kacheln simulieren kann).
Ich gehe davon aus, dass ich zu Recht denke, dass dies eine unglaublich geringe Menge an Informationen ist, die über das Internet oder zwischen Kollegen gesendet werden. Daher sollte es auch bei verzögerten Verbindungen kaum Probleme mit der Leistung geben. Oder bin ich so unwissend über Networking, dass mein Verstand überwältigt sein wird, wenn ich endlich dazu komme, mein Buch über Multiplayer-Networking zu öffnen?
Wenn nur sehr wenige Informationen zwischen Client / Server gesendet werden, ist es sinnvoller, bei der Initialisierung einfach die gesamte Welt zu laden? Oder 'Karte', wenn die Welt zu groß ist. Und dann nach dem Laden nur Kacheln senden, die aktualisiert werden?
Ich überlege immer noch, wie ich speziell mit Daten umgehen soll. Das Buch, das ich als Referenz verwende, möchte, dass ich eine verknüpfte Liste habe, in der ich Objekte hinzufüge und entferne, sodass alles ein Kinderspiel ist. "Gibt es einen Charakter? Gibt es einen Baum?"
Ich dachte an einen anderen Ansatz, wie einen Container, der Objekte enthält, und eine Serverlogik, die nur das sendet, was erforderlich ist, um dem Client mitzuteilen, was gerendert werden soll. Möglicherweise mit Objekten, die Netzwerkinformationen in sich enthalten, die gesendet werden, wenn sie vom Server angefordert werden.
Antworten:
Du bist auf dem richtigen Weg.
Betrachten Sie Minecraft. Minecraft lädt nur die Bereiche (auch Chunks genannt), die die Spieler unmittelbar umgeben. Auf diese Weise kann der Server ausgeführt werden, ohne dass der Arbeitsspeicher knapp wird, und warum Clients nicht vom Netzwerkverkehr blockiert werden.
Genau das sollten Sie tun. Senden Sie nur die Daten, die Sie senden müssen.
Wenn Sie nur ein 2D-Array mit Kachel-IDS senden, kann die Datengröße sehr gering sein, insbesondere wenn Sie weniger als 256 verschiedene Kacheltypen haben. In diesem Fall können Sie ein einzelnes Byte (oder ein Zeichen ohne Vorzeichen) verwenden. Wenn Sie also 100x100 Plättchen an den Player senden und jedes Plättchen nur aus einem einzelnen Byte besteht ... Sie haben die Idee. Es sind nicht viele Daten.
Die Minecraft-Community hat hervorragende Arbeit geleistet, um ihr Protokoll zu dokumentieren: http://mc.kev009.com/Protocol
http://www.minecraftwiki.net/wiki/Classic_server_protocol
quelle
Im Allgemeinen ist es eine gute Idee, nur die Informationen an den Kunden zu senden, die dem Spieler angezeigt werden sollen. Das Befolgen dieses Prinzips reduziert den Netzwerkverkehr und verhindert Betrug.
Beachten Sie jedoch, dass Sie, wenn der Spieler seinen Charakter bewegt, den Zug auf der Clientseite beginnen möchten, bevor Sie die Bestätigung vom Server erhalten, damit das Spiel weniger verzögert und reaktionsschneller erscheint. Das bedeutet wahrscheinlich, dass Sie auch den Bildschirm zu einem Bereich scrollen möchten, der noch nicht geladen ist. Dies zwingt Sie, diesen Teil der Karte leer zu lassen und ihn durch die tatsächliche Welt zu ersetzen, wenn sie geladen wurde. Das wäre ein ziemlicher Immersionsbrecher. Aus diesem Grund sollten Sie den Bereich in einem bestimmten Radius um den Bildschirm des Spielers vorladen.
Die Größe des vorinstallierten Bereichs hängt davon ab, wie schnell sich Ihre Spieler bewegen können und wie lange ihre durchschnittliche Latenz dauern wird.
quelle
Die Datenmenge, die Sie vom Server an den Client senden, kann UNGLAUBLICH unbedeutend sein. Wenn dies alles ist, was Sie senden müssen, würde ich vehement empfehlen, so viel wie möglich auf Load zu laden, damit noch weniger Daten benötigt werden. Die Menge, die beim Laden gesendet wird, ist klein genug, um die Ladezeit zu rechtfertigen. Die Speichernutzung ist nahezu nicht vorhanden, es sei denn, Ihre Welt ist lächerlich überdimensioniert, und Sie müssen fast keine Daten aktualisieren.
Ich kann mir vorstellen, dass Sie auch einige nette Tricks ausführen können, um die Verzögerungsvorhersage zu optimieren, die die durchschnittliche Verzögerung eines Benutzers kompensiert und vorhersehbare Bewegungen mit Charakteren ermöglicht.
Auch die Priorisierung der unbedeutenden Daten, wobei die Bewegung der Charaktere und die Aktionen / Reaktionen der Charaktere die höchste Priorität haben, kann dazu beitragen, dass selbst verzögerte Spieler nur eine geringe Verzögerung verspüren.
quelle