Voir la version complète : la programmation du reseau dans un jeu
Bonjour.
Comment programme ton le reseau dans un jeu. C'est à dire dans un jeu comme CS quelles sont les informations envoyées du client vers le serveur et du serveur vers le client. Par exemple: On envoie les actions avancer, reculer, tourner, tirer ou bien les nouvelles coordonnées du joueur quand on avance. Le serveur envoie les coordonnées de tous les joueurs a chaque messages ou bien il calcule les joueurs qui seraient interressant de transmettre.
Comment est géré la perte de paquet car dans les jeux c'est le protocole UDP qui est utilisé pour plus de rapidité, ce qui n'accuse pas reception du paquet et son ordonnacement. Comment on fait si on perd des messages ou bien que les messages n'arrivent pas dans le bon ordre.
Comment on empêche la tricherie dans le cas d'un logiciel open source ou commercial si par exemple le serveur transmet a chaque message la position du tous les personnages on peut modifier l'application pour que tous les personnages soit afficher sur une minicarte par exemple ( je sais pas si c'est faisable pour CS mais la questions est pour le principe).
merci d'avance de vos réponses.
NB: j'espère que Game Creators Network saura répondre à ces questions.
Niveau protocole, TCP/IP (connexion point à point)
L'UDP est plus particulièrement utilisé pour le broadcast .On émet à tout le monde.
L'objectif d'un jeu est de réduire au minimum l'envoi de paquets réseau. Donc le client doit envoyer un minimum d'infos que possible.
Donc l'envoi des coordonnées du perso toutes les x millisecondes = à proscrire.
Si le personnage avance tout droit à une vitesse fixe, alors pourkoi envoyer la position toutes les secondes ? il suffit d'envoyer une seule fois l'info au serveur disant que le perso avance ds telle direction.
Donc envoyer une info a chq changement d'action, de mode de déplacement, chgt de direction suffit.
Pour ce qui est des messages perdus... ca arrive que quelques uns se perdent...mais c'est rare. Pourkoi ? protocole TCP/IP oblige : quand tu envoies une info a ta carte réseau...ta carte réseau va transmettre l'info un certain nombre de fois le paquet jusqu'a ce que le destinataire l'a reçu.
C'est un ensemble d'optimisations de ce genre qui va réduit le tube d'infos à envoyer au serveur qui va faire que le jeu est viable (pas de lag dû au réseau).
Pour ce qui est de la triche, tu peux par exemple encrypter les données envoyées mais ca comporte deux inconvénients :
- ca rallonge la taille du paquet donc le temps d'envoi par réseau
- à long terme, c'est inefficace contre les pirates
Une méthode sûre : Mettre le décisionnel au nivo du serveur. De ce fait, hacker le client ne sert plus à rien. Mais c'est relatif ;)
Joker-eph
26/04/2005, 20h50
Niveau protocole, TCP/IP (connexion point à point)
L'UDP est plus particulièrement utilisé pour le broadcast .On émet à tout le monde.
l'udp est utilisé pour le temps réel également. si on choisit de transmettre des positions, qu'inporte qu'il y ait des pertes, la donnée est obsolète on ne la retransmet pas on transmet la nouvelle.
Donc envoyer une info a chq changement d'action, de mode de déplacement, chgt de direction suffit.
Comment gère tu le retard ? exemple je dis le personnage avance, tant qu'on ne reçoit pas stop, il continue d'avancer, et si le stop n'arrive pas en même temps sur chaque client, les positions seront décalées.
Joker-eph
26/04/2005, 20h53
Ce sujet tombe bien parceque j'allais poser les même questions, j'en arrive au même stade dans mon jeu et j'ai pas mal de flou encore.
Est-ce qu'il y a de la doc en ligne ? des tutos comme ceux qu'on trouve pour les lib graphiques ?
il faut bien sur envoyer de temps en temps la position du/des joueurs mais de façon cyclique. C'est à dire qu'il faut l'envoyer par exemple toutes les <x> ms si aucun message n'a été envoyé depuis un certain temps ( notion de signal de vie pour ceux qui ont déja fait du distribué) ou bien on envoie les données de position à la fin d'un message à envoyer...si on message doit etre émit.
Je ne sais pas si je suis bien clair sur ce point mais je veux bien essayer de développer d'avantage ma réponse si tu le souhaites.
L'objectif n'est pas de ne JAMAIS envoyer les coordonnées de positionnement d'un personnage, mais d'éviter d'envoyer toutes les 3 ms une nouvelle position. Un moyen d'y remédier est d'envoyer plutot des commandes (des ordres) de type : je marche...je m'arrete. Dans tous les cas, il faudra de temps en temps (par signaux de vie par exemple) recadrer les positionnements pour gommer les erreurs dues à la latence réseau.
La complexité du réseau est de gérer cette latence. Par Internet, la difficulté étant plus grande à cause du débit maximum d'émission qui est très restreint comparé aux réseaux de terrain de type LAN. D'ou la Nécessité de réduire au MAXIMUM le nombre de paquets réseaux à emettre. Le 'tube' d'une connexion réseau est limitateur en soit.
Joker-eph
27/04/2005, 14h02
Merci je comprend plus ou moins ce que tu veux faire je pense.
-Rien ne bouge, au bout d'un certain temps on renvois les positions.
-Mouvement, on envoi un vecteur de direction avec les positions, ainsi les autres client pendant le temps d'attente de la nouvelle position peuvent extrapoler la trajectoire initiée par le mouvement.
Merci je comprend plus ou moins ce que tu veux faire je pense.
LOL...je recommence :)
On peut envoyer la position quand :
- à chaque nouvelle commande. (Je marche tout droit,Je m'arrete, Je m'accroupi, Je saute, etc.)
- au bout d'un certain temps <x> quand aucune commande n'a été envoyé depuis longtemps.
Je prends un exemple concret :
Imagine un personage en plein milieu du desert sur un sol plat. On lui ordonne d'avancer droit devant.
- Premier paquet réseau à envoyer: Commande <AVANCER tout droit> + position
Ensuite...plus besoin de renvoyer la position...Le serveur sait que le perso avance toujours ds la meme direction. Il est DONC capable de calculer tout seul la nouvelle position du joueur sans que celui-ci ne lui est envoyé sa position. Mais certains effets epsilon de déplacement peut subsister entre le client et le serveur (lié à l'imprecision des calculs ou de la latence réseau lors de l'envoi de la première commande)-> d'ou la nécessité d'envoyer de temps en temps la position( c'est un fait).
Reste à définir ce temps en temps...Certains penseront alors à un timer qui enverrait un paquet réseau contenant la position du joueur toutes les 500 ms par exemple :) Mais là encore, ca serait une erreur :p
Ca serai inutile d'envoyer une information de positionnement si 10ms avant, une commande aurait été envoyée au serveur sachant qu'une commande est toujours accompagnée de la position. D'ou le signal de vie.
L'idée est d'utiliser pour cela un timer. Il s'agit d'envoyer la position du joueur au serveur quand un certain temps s'est écoulé sans aucune activitée sur le réseau du client. Techniquement parlant, il suffit d'envoyer la position au réseau à chaque expiration d'un timer réglé sur 500ms à 1s (à la louche agricole). Ce timer doit pouvoir etre réinitialisé si une commande doit être envoyé.
Ceci permet d'optimiser (minimiser) le traffic réseau. Quand on a un serveur de MMORPG, on imagine très bien pourquoi coté serveur, il faut absolument lui envoyer le stricte minimum de paquets réseaux.
Joker-eph
27/04/2005, 15h51
Ouais c'est plus clair pour tous le monde mais c'est pareil que ce que j'ai noté en 2 lignes nan ?
Ouais c'est plus clair pour tous le monde mais c'est pareil que ce que j'ai noté en 2 lignes nan ?
oui et non... :)
En fait, ce qui est important, ce n'est pas d'être en mouvement ou non. c'est le fait de changer de mouvement qui importe le plus. Si tu marches pendant un quart d'heure ds la même direction, tu es d'accord que tu ne vas envoyer qu'une seule commande ? Et dans ce cas, tu devras alors envoyer grace au signe de vie ta position pour palier l'effet de bord de la lattence.
Pour ce qui est de la position : je suis assis ou je suis mort... le signe de vie n'est pas vraiment nécessaire... à moins que le cadavre n'est la particularité de se déplacer tout seul :) Sait-on jamais :)
Joker-eph
27/04/2005, 16h34
Oui en fait ce que je désignais par "rien ne bouge" c'etait "pas d'action à transmettre"
Joker-eph
27/04/2005, 16h35
Pour ce qui est de la position : je suis assis ou je suis mort... le signe de vie n'est pas vraiment nécessaire...
Hum ça va pas être évident à gérer.
si ce n'est la gestion du signe de vie qui te gène qd le perso est immobile, il suffit juste de désactiver le timer.
Avant de coder, il faut surtout garder un certain niveau d'abstraction. (Nécessite une vision objet). Tu peux aisément coder ce mécanisme du signe de vie en suivant le modèle OSI des couches réseaux : tout simplement en faisant un protocole par dessus TCP/IP(ou UDP).
Mais je rapelle qu'il s'agit que d'une solution parmi d'autres :) Il existe pleins de mécanismes lourds (orientés DCOM , CORBA, etc) pour gérer les applications distribuées mais plus ou moins adaptés au temps réel exigé par les jeux vidéos orientés multi-joueurs.
blu3dr4g0n
27/04/2005, 17h06
pour avoir des tutoriaux poussés (mais anglais), veuillez consulter le site gamedev (http://www.gamedev.net/reference/list.asp?categoryid=30) :
http://www.gamedev.net/reference/articles/article1948.asp
http://www.gamedev.net/reference/articles/article1138.asp
et sur gamasutra (inscription gratuite requise)
http://www.gamasutra.com/features/19970905/ng_01.htm
http://www.gamasutra.com/features/19970919/aronson_01.htm
vous pouvez aussi vous impregner des API comme
http://www.gillius.org/gne/index.htm (http://www.rit.edu/%7Ejpw9607/gne/)
http://www.planetunreal.com/gamebots/docapi.html
Joker-eph
27/04/2005, 19h08
Pas le temps de regarder ça tout de usite mais merci !!
gamedev est vraiment bien avance tout de meme et c'est tres complet.
(mais la barriere de la langue reste majeur ...)
Atréides
30/06/2005, 19h16
Je la qualifierais de majeure si c'était en italien, allemand, romahche, gaélique ou russe. En anglais, elle est mineure voire inexistante.
Ca pourrait être intéressant d'essayer de définir à plusieurs un protocole viable et extensible de communication client/serveur pour jeux en ligne. Quelques chose qui puisse être réutilisé facilement.
TERMINABEN
08/07/2005, 19h05
Bonjour,
j'ai programmé des jeux en réseau et la meilleur technique (à mes yeux) est la suivante:
Le serveur envoit tous les X ms un paquet à tous les clients.
Les clients répondent en envoyant des paquets indiquant au serveur s'ils désirent avancer, se stopper tourner, tirer etc ...
Le serveur recoit ces paquets et déplace le joueurs.
Une fois le déplacement effectué, le serveur envoit à tous les joueurs leur position et celles de tous ses concurrents.
Il en résulte que le mouvement est uniquement calculé par le serveur et la synchronisation est parfaite, chaque client verra la meme chose.
L'autre avantage est que si un client n'a pas répondu depuis un certain temps, on peu signaler aux autres joueurs que l'individu en question a des problemes de connexion, par cette meme technique on peut calculer le ping du joueur.
J'utilise ce systeme depuis longtemps avec tous mes jeux réseau.
Le seul probleme notable, c'est que le client verra ses mouvements légerement sacadés en raison des X ms qui rafraichissent sa position, apres il suffit de lisser le mouvement avec la technique de ton choix.
Voila cette technique fonctionne pas trop mal et n'est pas trop dur à mettre en oeuvre.
Je suis justement en train d'étudier la question pour un jeu ,
j'ai un gros probleme pour les colisions, par ce que je veut les gérer sur les clients, et si un client détecte une collision avec un autre ( pour un jeu d'auto-tamponneuses) et l'autre non parce qu'il n'a pas exactement les memes coordonnées ça peut etre très génant.
>terminaben:
je vois pas concretement coment on fait un lissage
>newbiz:
une librairie comme raknet, sans utiliser l'orienté objet rempli apparement ce role,
mais si quelqu'un pouvait m'aider a comprendre comment mettre en oeuvre les principes si bien expliqué ici. Parce que la là je me perd carrément dans la doc
TERMINABEN
10/07/2005, 13h25
Pour faire un lissage il faut que le client ait une boucle de retard par rapport au server, autrement dit un retard de seulement X ms par rapport a sa possition réelle, tous les clients ayant ce retard imperceptibles, la synchronisation reste nickel.
Etant donné que le client se trouve à T-1 (temps du serveur avec une boucle de retard) lorsque le client recoit sa position à T tu peus alors, grace à T-1 et T tracer une droite de T-1 à T qui sera décomposée en X parties correspondant au fps du clients.
Avec cette technique, que j'utilise, le mouvement est lissé et parait plus fluide.
Une autre technique existe je te l'expliquerai dans un prochain post la je vais manger ! :00000023:
TERMINABEN
13/07/2005, 21h00
Oui donc, l'autre solution est de déplacer le client normalement, c'est à dire que le client calcule lui meme son propre déplacement, et de replacer sa position tous les X ms par rapport à son déplacement réel sur le serveur, en théorie les mouvements doivent etre quasi similaires chez le client et sur le serveur, cette technique est pas mal mais moins efficace que la précédente.
Voili voilou !
vBulletin® v.3.6.5, Copyright ©2000-2009, Jelsoft Enterprises Ltd. Tous droits réservés - Version française vbulletin-fr.org