Ist es für einen Server möglich, nur einen kachelbasierten Bereich an einen Client zu senden?

8

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.


quelle
Ich schlage vor, Sie werfen einen Blick auf freemmorpgmaker.com. Dieser Motor hat mir sehr geholfen, als ich gerade angefangen habe. Das Skript ist relativ einfach und es macht viel Spaß, damit zu arbeiten. Der Code brachte mir alles bei, was ich wissen musste, um meine eigene 2D-Engine / mein eigenes 2D-Spiel zu erstellen. Was Sie nicht von ihnen lernen sollten, ist, wie Sie Ihren Server / Client sichern.
Nick

Antworten:

6

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.

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?

Genau das sollten Sie tun. Senden Sie nur die Daten, die Sie senden müssen.

  1. Wenn ein Client beitritt, senden Sie ihm einen Teil der Kachelkarte (oder alles, wenn es sich um kleine Bereiche handelt).
  2. Wenn der Spieler versucht, ein Plättchen zu ändern, senden Sie diese Daten an den Server.
  3. Wenn sich der Status einer Kachel ändert, senden Sie ein Paket mit diesen Informationen an alle relevanten Clients.

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

Nick Caplinger
quelle
1
wow, vielen Dank! Dies ist ein großer Vertrauensschub, von dem mir gesagt wurde, dass ich auf dem richtigen Weg bin, wenn ich so wenig weiß. Es sagt mir, dass ich die Dinge richtig verstehe und so gut ich kann konstruiere. Ich bin zuversichtlich, dass ich, wenn ich weiter lerne, angemessen genug tun werde. Es ist so befriedigend, positive Ratschläge zu hören, und nein "Sie machen es falsch!" lol :)
Es hat lange gedauert, bis ich die Nerven für Multiplayer- und 3D-Spiele gesammelt habe. :)
Nick Caplinger
Positive Ratschläge sind auch das, wovon diese Community lebt. Ich ermutige alle, auf jede erdenkliche Weise einen Beitrag zu leisten!
Nick Caplinger
3

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.

Philipp
quelle
-1

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