Réseau : synchronisation dans un jeu

Réseau : synchronisation dans un jeu - Algo - Programmation

Marsh Posté le 10-08-2004 à 14:35:13    

J'aimerais mettre un terme à un petit jeu commencé il y a fort longtemps. C'est un jeu de type pong, multijoueur avec une baballe qu'il faut empécher de rentrer dans son camp tout en attaquant les autres avec des armes, bonus et autres effets divers sur la balle, sur les raquettes de ses adversaires etc ...
 
Pour le moment, le jeu est multijoueur, ordi + humains, mais sur une seule et meme machine. Autant dire que l'aspect réseau serait un enorme plus. Mais tout ce que j'ai fait jusqu'à présent fut ... merdique au niveau de la jouabilité.
 
Mon problème ne touche pas à l'ouverture de connexion réseau, ni a l'envoie de paquets aux autres machines, mais plutot à la stratégie à adopter pour que toutes les machines voient exactement le meme plateau de jeu au meme instant. Le jeu va assez vite et le moindre écrart (retard de réception de paquet par ex) a des conséquences sur le jeu.
 
Jusqu'a présent, je me suis contenté de désigner une machine serveur, et des clients. Les clients recoivent du serveur la position de tous les objets du jeu, balle y compris et n'effectuent aucun calcul. Ils se contentent d'afficher ce que leur envoie le serveur, et envoie les actions réalisés par le joueur local.
Cette stratégie est bien sur pourrie (mais j'ai essayé qd meme  :D ) : à cause de la différence de latence entre les différentes machines, les objets recus par les clients ne sont pas en phase à un meme instant t. Meme sur un réseau local on voit la différence.
 
J'ai essayé aussi de n'envoyer aux clients qu'une seule fois la position des objets, puis de les laisser calculer le reste jusqu'à la fin de la partie. Ca résoud pas mal de pb mais il y en a encore : imaginez que le joueur local bouge sa raquete et repousse la balle, le temps que l'information "bouge la raquette" atteigne les autres joueurs (client local -> serveur -> autres joueurs), le rebond aura eu lieu chez le client local et pas chez les autres ... => le jeu se désynchronise et ca devient trés amusant ("T'as perdu, t'as raté la balle !" "Non, je te l'ai renvoyé et toi t'as pas bougé, t'as perdu !!!" ...)
 
J'ai essayé d'autres trucs, qui sont plus de l'ordre de la bidouille, sans jamais arriver à un résultats satisfaisant.
 
bref, en gros, je ne sais pas comment résoudre ce pb. Vous avez des idéees ?
Vous connaissez un tutoriel qui traite de l'aspect synchronisation dans le jeux en réseau? J'ai déjà fait pas mal de recherche, mais c'est toujours trés obscur (j'ai lu beaucoup de choses sur des histoires de prédiction de position ... sans vraiment comprendre).

Reply

Marsh Posté le 10-08-2004 à 14:35:13   

Reply

Marsh Posté le 11-08-2004 à 17:28:54    

Un ptit up plein d'espoir.
 
Personne n'as jamais lu de docs sur les algo réseaux ?
Google me renvoie tout sauf ce que je cherche :sweat:

Reply

Marsh Posté le 11-08-2004 à 17:52:15    

euh idée con comme ça qui me traverse l'esprit...
si le serveur envoie une date et les directions+vitesses prises par chaque objet, les postes clients ne peuvent pas se démerder pour gérer tout ça?
ça te fait très peu d'info à renvoyer ça...

Reply

Marsh Posté le 11-08-2004 à 18:25:24    

moktar1er a écrit :

euh idée con comme ça qui me traverse l'esprit...
si le serveur envoie une date et les directions+vitesses prises par chaque objet, les postes clients ne peuvent pas se démerder pour gérer tout ça?
ça te fait très peu d'info à renvoyer ça...


 
Je vois à quoi tu penses : lorsqu'il recoit les infos, le client recalcule la position reelle des objs a l'instant présent.
 
Pb que je vois (comme ca) :  
ca fait pas mal de calcul pour le client si il doit recalculer la position des objets sur plusieurs cycles de jeu, à cause des nombreuses interactions entre ces objets : rebonds, effets divers (attraction de la balle par un objet par ex).
 
- une petite situation :
    instant t le serveur bouge la balle et envoie les infos au client
    instant t+x client recoit direction balle de l'instant t => commence les calculs pour se mettre à jour
    instant t+y calculs finis => la balle est placée à la position correcte pour l'instant t. On est en retard, encore plus qu'en renvoyant simplement la position des objets...
 
Ok, sur un réseau local, X vaut 10ms (on a 10 ms de ping en gros entre 2 pc sur mon petit reseau local). C'est pas enorme mais ca gène déjà bien.

Reply

Marsh Posté le 11-08-2004 à 18:39:10    

Autre chose, j'ai lu quelques explications sur le fonctionnement de Quake3 en reseau.
Déjà, les informations réseau sont envoyées à intervalles réguliers, genre toutes les 20 ms.
Ensuite quand on tire une rocket, l'info "tire la rocket" pars du client vers le serveur, lequel calcule la position de la rocket en tenant compte du délai de transission du paquet sur le réseau. De meme, il envoie la position de la rocket aux autres clients en tenant compte du ping (pas du ping exactement mais du nombre de cycles de rafraichissement du jeu necessaire a l'aller retour d'un paquet entre le serveur et le client).
 
C'est ce que j'en ai compris. Maintenant, ca m'a pas l'air con mais c compliqué, j'arrive pas à faire pareil.

Reply

Marsh Posté le 12-08-2004 à 07:18:35    

oliv5 a écrit :

J'aimerais mettre un terme à un petit jeu commencé il y a fort longtemps. C'est un jeu de type pong, multijoueur avec une baballe qu'il faut empécher de rentrer dans son camp tout en attaquant les autres avec des armes, bonus et autres effets divers sur la balle, sur les raquettes de ses adversaires etc ...


 
tu as un serveur maitre qui décide ce que les autres joueurs voient.
 
chaque client envoie le mouvement de la raquette au serveur qui décide si la balle est passée ou pas. Bien évidemment chaque info est étiquetée en fonction du temps d'émission pour que le serveur puisse s'y retrouver. Il traite les paquets dans l'ordre et ne traite le suivant que si le précédent a été traité. C'est pour ça que c'est bien d'envoyer les paquets à intervalles réguliers. Pour que le serveur sache qu'il a tout bien reçu. S'il lui en manque un il peut toujours demander à un client de lui renvoyer (en protocole UDP sinon ça n'a aucun sens) ou de se baser sur la condition précédente pour décider (si la connexion est vraiment pourrie..).
 
Tout ce que le serveur a a faire c'est à broadcaster la position que chaque joueur lui a envoyé (avec éventuellement une correction si il trouve que l'un des joueurs lui a envoyé une condition irréalisable). Et  
évidemment arbitrer du renvoi ou non de la balle.
 
Le client de son coté s'assure que le joueur ait une impression de fluidité malgré l'aller retour commande/arbitration/broadcast qui peut prendre du temps (quasiment pas en réseau local).
 
Il peut s'arranger pour rajouter un lag artificiel entre la reception de la commande depuis le clavier et l'affichage du truc à l'écran. La durée de ce lag dépendra des conditions réseau mais ne devrait pas exceder un 1/10e de secondes. Il y a des choses qui peuvent se faire immédiatement pour rajouter de la fluidité et d'autres qui sont un peu de la triche.
 
Ce qui est de la triche c'est de ne pas attendre le retour du broadcast pour afficher la position des autres joueurs ou la sienne propre. Bien évidemment le client doit extrapoler la position future à partir des broadcast précédents et des commandes de son joueur. Et surtout il ne doit pas brutalement changer la position quand il se rend compte que sa simulation a affiché les joueurs à une mauvaise place (sinon téléportation). L'idéal ce serait d'influencer le mouvement général pour les ramener à leur position réélle à partir de la trajectoire supposée.
(un peu d'integration/derivation ?). Les mouvements du joueur sur son propre client eux, peuvent se faire à pleine précision avec des corrections uniquement en cas de collision/ou autre mécanisme de jeu décidé par le serveur.
 
Bon il y a plein d'autres trucs. Ce n'est pas un problème simple à résoudre surtout lorsque tu prononces le mot "internet" ou pire "modem".
 
LeGreg

Reply

Marsh Posté le 12-08-2004 à 10:17:52    

[:blueflag]

Reply

Marsh Posté le 12-08-2004 à 10:19:16    

j'ai lu avec intéret tes idées. Certaines choses me semblent évidentes, mais d'autres pas.
 

Citation :

Les mouvements du joueur sur son propre client eux, peuvent se faire à pleine précision avec des corrections uniquement en cas de collision/ou autre mécanisme de jeu décidé par le serveur.


 
C'est le joueur client qui m'ennuie : tu sembles dire qu'il faut afficher immédiatement les mouvements du joueur sur son propre client, meme si ces mouvements n'ont pas encore été pris en compte par le serveur.
Dans ce cas, que se passe-t-il ? Le joeur bouge et rentre en collision avec la balle => rebond. Ce rebond va etre calculé par le serveur et renvoyé aux clients. Mais que fait le joueur qui a causé le rebond ? il affiche le rebond sur son propre client en avance (avant d'avoir recu l'info "rebond" du serveur en retour), quitte à devoir se corriger plus tard ou il attend l'info du serveur.
 
Dans ce dernier cas, que fait-il en attendant ? la balle doit-elle continuer son chemin (on ignore le rebond ?) ?
 
Quand les clients ne bougent pas, je n'ai pas de pb de synchro actuellement. Mais des qu'ils bougent, le jeu se désynchronise et j'ai immédiatement des "sauts" pour la balle (elle revient brutalement en place), comme tu le disais. J'ai essayé d'interpoler la position mais ca introduit encore plus de retard : sur le serveur la balle continue sa vie tandis que les clients tentent de rattraper leur retard en interpolant ... J'ai essayé d'accélérer la balle aussi pendant l'interpolation mais je n'ai pas été bien loin car il me semblait que ce n'était pas une bonne approche.

Reply

Marsh Posté le 12-08-2004 à 10:54:07    

Reply

Marsh Posté le 12-08-2004 à 11:26:46    

oliv5 a écrit :

Dans ce dernier cas, que fait-il en attendant ? la balle doit-elle continuer son chemin (on ignore le rebond ?) ?


 
Je n'ai pas dit que c'était un probleme simple. Et je n'ai jamais eu à le résoudre non plus.
 
A mon avis le probleme de la balle est faisable à partir du moment ou un seul joueur peut affecter le déplacement de la balle à un moment donné et que la balle à un mouvement déterministe en dehors de la collision avec les joueurs (ce qui permet de prédire son déplacement sans erreur à partir de la position de départ et sa vélocité).
 
Pour ce qui est de répercuter immédiatement les mouvements de ton joueur. Il y a plusieurs choses à prendre en compte:
les mouvements propres du joueur. Il n'y a aucune raison de ne pas les répercuter immédiatement. Ceux-ci seront enregistrés par ton client avec leur time tag propre. C'est ce time tag qui sera communiqué au serveur et qui sera ensuite broadcasté. On peut donc dire que ton client a une connaissance parfaite de ta position à un moment donné. Ce que n'ont pas les autres joueurs mais comme eux ne sont pas à ta place, ils n'ont pas besoin d'avoir le sentiment de précision dont toi tu as besoin pour tes déplacements. Ils ont juste une idée suffisamment précise (suivant la qualité de la connexion) de ta trajectoire et si le temps envoi+arbitrage+broadcast est inférieure au lag fixé arbitrairement alors la précision sera parfaite.
 
Pour les collisions avec le décor (s'il y en a), la encore l'arbitrage final doit se faire sur le serveur mais il n'y a pas de raison que ton client et le serveur soit en désaccord s'ils partagent les memes données sur la position du décor donc ton client peut répercuter directement les collisions avec les mouvements communs du décor.
 
Reste les collisions avec les autres joueurs. Si les interactions avec les autres joueurs sont limitées il n'y en a pas besoin. S'il y a besoin, un peu de finesse sera nécessaire sans doute...
 
Pour l'arbitrage avec la balle voir plus haut.

Reply

Marsh Posté le 12-08-2004 à 11:26:46   

Reply

Marsh Posté le 12-08-2004 à 11:50:36    


 
héhé, déjà parcouru, c'est là que j'ai lu les trucs sur quake3 :)
Mais une petite relecture de certains chapitres interessants ne fera pas de mal.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed