J'ai pensé à un jeu RTS multi-joueurs. La partie que je n'arrive pas à contourner est de garder le mouvement de l'unité synchronisé. Si je déplace l'unité A pour repérer XY, je dois la communiquer au serveur qui relaie à l'autre client.
Je suis curieux de voir à quoi ressembleraient les communications. Pourriez-vous simplement communiquer au serveur que je déplace l'unité A vers XY de JZ? Peut-être que vous devez plutôt communiquer le mouvement coord par coord? Quelle est la méthodologie la plus efficace pour communiquer le mouvement des unités d'un client à l'autre?
ÉDITER
Il s'agit d'une question republiée par stackoverflow . J'ai trouvé que ce site était probablement un meilleur endroit pour la question.
L'une des meilleures réponses de ce post:
Je suppose que vous avez l'intention d'utiliser le paradigme de mise en réseau client-serveur? Dans ce cas, vous ne pouvez pas faire confiance aux clients pour gérer le positionnement réel des unités, vous devez déléguer cette tâche au serveur. Vous prenez ensuite la liste de commandes de chaque client par tick, et calculez le mouvement de chaque unité, une fois celle-ci terminée, vous cochez ensuite la position de chaque unité pertinente pour chaque client (soit sur une carte entière, soit par vue) et recommencez le processus.
Réponses:
Vous ne voulez pas synchroniser les positions de toutes les unités du serveur à chaque client; cela prendra beaucoup plus de bande passante que vous n'en avez besoin. Vous auriez également à faire face à l'interpolation / extrapolation des positions des unités, etc. Presque aucun client / serveur professionnel RTS n'utilise!
Au lieu de cela, vous souhaitez envoyer uniquement les commandes des joueurs. Plutôt que de déplacer les unités immédiatement lorsque le joueur clique, vous allez mettre en file d'attente la commande de déplacement à effectuer à un moment donné dans le futur - généralement seulement quelques images. Tout le monde envoie ses commandes à tout le monde. Quelques images plus tard, tout le monde exécute toutes les commandes, et parce que le jeu est déterministe, ils voient tous le même résultat.
L'inconvénient est que chaque joueur est aussi lent que le joueur le plus lent - si quelqu'un prend du retard dans l'envoi de commandes, tout le monde doit ralentir et attendre qu'il rattrape (dans Starcraft 2, c'est le "XXX ralentit le jeu") " dialogue).
En fait, il y a encore une chose qui se fait habituellement: éliminer complètement le serveur . Demandez à chaque client d'envoyer ses commandes à tous les autres clients. Cela réduit le décalage (au lieu d'une commande allant de vous -> serveur -> adversaire, cela vient juste de vous -> adversaire) et facilite le codage, car vous n'avez plus besoin de coder un serveur séparé. Ce type d'architecture est appelé peer-to-peer (P2P).
L'inconvénient est que vous avez maintenant besoin d'un moyen de résoudre les conflits, mais comme les commandes des joueurs sont indépendantes les unes des autres dans la plupart des RTS, ce n'est généralement pas un gros problème. De plus, cela ne se modifie pas bien - chaque fois que vous ajoutez un nouveau joueur, chaque joueur doit lui envoyer ses commandes. Vous n'allez pas créer un MMO RTS en utilisant le P2P.
Cette configuration (envoi de commandes uniquement à l'aide de P2P) est le fonctionnement de la plupart des RTS, y compris Starcraft, C&C et AoE, et c'est la seule façon dont AoE pourrait éventuellement prendre en charge 1500 unités sur une connexion à 28,8 kbps .
Voici quelques conseils supplémentaires pour écrire un RTS P2P:
rand()
,cos()
etc., mais presque toutes les mathématiques à virgule flottante sont hors de question (voir ici , ici et ici ) ! Dans ce cas, il vaut mieux utiliser client-serveur.la source
J'ai créé un RTS en réseau TCP, dans lequel j'ai passé les commandes elles-mêmes, plutôt que les résultats des commandes . Par exemple, un joueur donne un ordre de déplacement. Si l'ordre de déplacement est valide selon ce client, il est envoyé au serveur. Le serveur le renvoie ensuite à tous les clients, qui le valident et l'exécutent.
Ainsi, toutes les machines clientes exécutent le jeu elles-mêmes, le code serveur accepte les messages et les renvoie à tous les clients. Si un client donne un ordre de déplacement, il ne commencera à l'exécuter qu'après avoir été reçu du serveur.
Le serveur envoie également un numéro de «tick» auquel exécuter la commande, qui est quelques ticks avant le tick «actuel». De cette façon, toutes les commandes peuvent être exécutées en même temps sur toutes les machines.
Un avantage de cette méthode est qu'elle ne dépend d'aucune machine cliente individuelle pour valider la commande. Si je réussissais les résultats du déplacement, je pourrais peut-être le pirater pour déplacer mes unités plus rapidement. Tous les clients doivent exécuter la même commande et si une machine l'exécute différemment, ce sera évident.
La validation de la commande côté client avant de l'envoyer au serveur n'est pas nécessaire, mais en théorie, elle économise le trafic réseau. J'ai utilisé le même code de validation pour dire à l'interface utilisateur que le déplacement était possible, donc il n'a pas fallu écrire de code supplémentaire.
Quant à ce à quoi les messages pourraient ressembler. Je n'étais pas préoccupé par l'ultra efficacité car c'était mon premier jeu en réseau. J'ai passé des commandes sous forme de chaînes. Les commandes seraient formatées comme ceci:
"<player_id>:<command>:<parameters>"
Pour un exemple artificiel, une commande de mouvement pourrait ressembler à ceci:
"3:move:522:100:200"
. Cela signifie que le joueur3
veutmove
s'unir522
à (100
,200
).Le serveur passe la commande à tous les clients, y compris celui qui l'a envoyé, avec un numéro de tick attaché comme ceci:
"153238:3:move:522:100:200"
.Ensuite, les clients exécuteraient tous cette commande lorsque tick 153238 est exécuté.
la source