Est-il possible pour un serveur d'envoyer rien de plus qu'une zone basée sur des tuiles à un client?

8

Pour commencer, j'ai une bonne expérience en réseau (matériel, routeurs, etc.) mais très peu de connaissances au-delà des bases de la programmation réseau. Cela peut sembler une question stupide, mais je veux savoir dans quoi je m'embarque tout en imaginant l'implémentation du multijoueur dans mon jeu.

Je crée un monde basé sur des tuiles, qui est généré via un simple tableau 2D. Disons quelque chose comme World [100] [100], par souci de simplicité.

Actuellement, la méthode de rendu rend uniquement les tuiles en fonction de la résolution de la fenêtre, plus une tuile (pour un rendu fluide pendant le mouvement).

Le gameplay n'a besoin de rien de plus que de savoir ce qui est dans le visible actuellement (rendu sur l'écran +1) et le plus probablement QUELQUES informations de tuiles dans une zone autour du joueur.

Donc, tout ce que le serveur envoie de plus ne serait pas l'information complète sur les tuiles. Ex. Les objets posés sur le sol, le type de sol, les arbres, etc. ne seraient pas importants dans la zone hors de la vue du joueur, mais seraient seulement ce que le client / joueur doit savoir sur ces tuiles. (Ex. Les «noms entrants» d'Ultima Online où les joueurs pouvaient savoir qu'un personnage [joueur ou monstre] était juste au-delà des tuiles dans leur vue rendue.)

Je ne connais pas grand-chose au réseautage, alors peut-être qu'en apprenant cela pourrait répondre à ma question. Cependant, je suis curieux de savoir si c'est une solution réalisable ou si l'idée est tout simplement risible.

Les informations envoyées concerneraient une zone de tuiles de 10 x 15, et chaque tuile contient des informations sur ce qui se trouve sur la tuile. Plus efficacement, tout serait un objet, où la tuile contient tous les objets sur la tuile. Ex. La tuile [4] [4] contient l'épée # 23452, Rock2, Tree5, Player3, Monster4.

Les tuiles vides n'enverraient rien de plus que le type de terrain [Herbe, Sable, Eau] si elles n'étaient pas déjà chargées pendant l'initialisation / chargement. Certaines tuiles auraient une poignée d'objets [Tree2, Sword # 924, Gold, Corpse, Rock3].

Je ne peux donc pas imaginer qu'une tuile aurait beaucoup d'informations à envoyer au client depuis le serveur, car le client n'a principalement besoin de connaître que la texture à charger et la position pour la placer à l'écran. Position étant seulement deux entiers et Texture étant un entier pour une liste de fichiers à dire au client de restituer.

Au plus fou, le serveur devrait envoyer 150 tuiles avec des informations sur seulement une poignée d'objets OnLOAD, et à partir de là, ne mettre à jour que les changements de tuiles (le cas échéant) et de nouvelles tuiles (10 à 15 chaque fois qu'un joueur se déplace dans une direction). ) et le sens de déplacement des personnages à l'écran (afin que le client puisse simuler un mouvement fluide entre les carreaux).

Je suppose que j'ai raison de penser que c'est une quantité incroyablement faible d'informations envoyées sur Internet ou entre pairs, donc cela devrait avoir peu de problèmes de performances même sur des connexions en retard? Ou suis-je si ignorant des réseaux que mon esprit sera époustouflé lorsque j'aurai enfin le temps d'ouvrir mon livre sur les réseaux multijoueurs?

S'il s'agit d'une très faible quantité d'informations envoyées entre client / serveur, serait-il plus logique de simplement charger le monde entier lors de l'initialisation? Ou «Carte» si le monde est trop grand. Et puis après LOAD, envoyer uniquement les tuiles qui sont mises à jour?

Je réfléchis toujours à la manière dont je dois traiter spécifiquement les données. Le livre que j'utilise comme référence veut que j'aie une liste liée, où j'ajoute et supprime des objets, donc tout est un booléen. "Y a-t-il un personnage? Y a-t-il un arbre?"

Je pensais à une approche différente, comme un conteneur qui contient des objets et une logique de serveur qui envoie uniquement ce qui est nécessaire pour dire au client ce qu'il doit rendre. Peut-être avec des objets qui contiennent en eux-mêmes des informations de mise en réseau, qui sont envoyées à la demande du serveur.


la source
Je vous suggère de jeter un œil à freemmorpgmaker.com, ce moteur m'a beaucoup aidé lorsque je viens de commencer. Le script est relativement simple et très amusant à travailler. Le code m'a appris tout ce que je devais savoir pour créer mon propre moteur / jeu 2D. Ce que vous ne devriez pas apprendre d'eux, c'est comment sécuriser votre serveur / client.
Nick

Réponses:

6

Tu es sur la bonne piste.

Considérez Minecraft. Minecraft ne charge que les zones (également appelées morceaux) entourant immédiatement les joueurs. C'est ainsi que le serveur peut fonctionner sans manquer de mémoire et pourquoi les clients ne sont pas enlisés dans le trafic réseau.

S'il s'agit d'une très faible quantité d'informations envoyées entre client / serveur, serait-il plus logique de simplement charger le monde entier lors de l'initialisation? Ou «Carte» si le monde est trop grand. Et puis après LOAD, envoyer uniquement les tuiles qui sont mises à jour?

C'est exactement ce que vous devez faire. N'envoyez que les données que vous devez envoyer.

  1. Lorsqu'un client se joint à lui, envoyez-lui un morceau de la carte de tuiles (ou tout si elle, si vous avez affaire à de petites zones)
  2. Lorsque le joueur essaie de modifier une tuile, envoyez ces données au serveur.
  3. Lorsqu'une vignette change d'état, envoyez un paquet contenant ces informations à tous les clients concernés.

Si vous envoyez simplement un tableau 2D d'ID de tuiles, la taille des données peut être très faible, surtout si vous avez moins de 256 types de tuiles différents. Dans ce cas, vous pouvez utiliser un seul octet (ou un caractère non signé). Donc, si vous envoyez des tuiles 100x100 au joueur, et chaque tuile se compose uniquement d'un seul octet ... Vous avez l'idée. Ce n'est pas beaucoup de données.

La communauté Minecraft a fait un excellent travail de documentation de son protocole: http://mc.kev009.com/Protocol

http://www.minecraftwiki.net/wiki/Classic_server_protocol

Nick Caplinger
la source
1
wow, merci beaucoup! C'est un gros regain de confiance que l'on m'a dit que j'étais sur la bonne voie, quand je sais si peu. Cela me dit que je comprends les choses correctement et que je fais de l'ingénierie du mieux que je peux. Je suis convaincu que si je continue à apprendre, j'en ferai suffisamment. C'est tellement satisfaisant d'entendre des conseils positifs, et non "vous vous trompez!" lol :)
Il m'a fallu beaucoup de temps avant de rassembler le culot de prendre des jeux multijoueurs et 3D. :)
Nick Caplinger
De plus, les conseils positifs sont ce sur quoi cette communauté prospère. J'encourage tout le monde à contribuer de toutes les manières possibles!
Nick Caplinger
3

C'est généralement une bonne idée d'envoyer uniquement les informations au client qui sont censées être montrées au joueur. Suivre ce principe réduit le trafic réseau et empêche la triche.

Mais gardez à l'esprit que lorsque le joueur déplace son personnage, vous voulez certainement commencer le mouvement côté client avant de recevoir la confirmation du serveur pour rendre le jeu moins lent et plus réactif. Cela signifie probablement que vous souhaitez également commencer à faire défiler l'écran vers une zone qui n'est pas encore chargée. Cela vous oblige à laisser cette partie de la carte vierge et à la remplacer par le monde réel lorsqu'elle a été chargée. Ce serait tout à fait un brise-immersion. Pour cette raison, vous devez précharger la zone dans un certain rayon autour de l'écran des joueurs.

La taille de la zone préchargée dépend de la vitesse à laquelle vos joueurs peuvent se déplacer et de la durée de leur latence moyenne.

Philipp
la source
-1

La quantité de données que vous envoyez du serveur au client peut être INCROYABLEMENT insignifiante. Si c'est tout ce que vous devez envoyer, je suggérerais avec véhémence de charger autant que possible sur Load, donc c'est encore moins de données requises. La quantité envoyée en charge sera suffisamment petite pour justifier le temps de chargement, l'utilisation de la mémoire sera presque inexistante à moins que votre monde ne soit ridiculement surdimensionné, et vous devrez mettre à jour presque aucune donnée du tout.

J'imagine que vous pourriez également faire quelques astuces pour optimiser la prédiction de décalage qui compense le retard moyen qu'un utilisateur subit, permettant un mouvement prévisible avec les personnages.

De plus, la priorité des données insignifiantes avec le mouvement du personnage et les actions / réactions du personnage ayant la priorité la plus élevée peut aider à s'assurer que même les joueurs retardataires ressentent très peu de décalage.


la source