IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement 2D, 3D et Jeux Discussion :

Compensation de lag


Sujet :

Développement 2D, 3D et Jeux

  1. #1
    screetch
    Invité(e)
    Par défaut Compensation de lag
    fork de la discussion sur la game loop multi threadée

    il y a de nombreuses possibilités mais ce que disait deadalnix :
    il stocke les positions des objets dans des tableaux, 8, espacés de 10ms
    théoriquement il peut donc remonter le temps de 70ms (de 0ms a 70ms)

    ensuite il y a la difficulté de savoir corriger

    il y a de nombreux "temps" différent; pour ne pas se tromper, voila en gros comment ca marche

    - il y a le présent du client
    - il y a le présent du serveur; toujours en décalage avec le présent du client (lag)
    - le futur du client (qui est le présent du serveur)
    - le passé du serveur (qui est le présent du client)

    celui qui a raison doit toujours être le serveur pour éviter le piratage, et aussi pour que tous les gens connectés partagent la même représentation du monde.

    On a donc : le présent du serveur qui domine, mais le présent du client qui est ce que le joueur voit (et il ne faut pas attendre entre le moment ou tu appuies sur la touche et le moment ou tu vois ce qui se passe)

    c'est très important que lorsque le client voit quelque chose, il puisse lui tirer dessus dans un FPS, sans compenser lui même le lag.

    pour cela, le client utilise en général la "prédiction" et la "correction". la prédiction consiste a dire que l'on est en avance par rapport au serveur, mais que l'on peut déjà calculer avec pas mal de précision la position des ennemis puisque ceux-ci ont des vitesses et positions connues.
    Mais qu'en faisant ca on est en "avance" par rapport au temps serveur, et que donc on prédit peut être quelque chose qui va changer

    alors donc, si l'on suit bien, le client doit toujours être au top du top de la réactivité, mais le serveur lagge un peu derriere. Donc le client prédit ce qui se passe, puis lorsque le serveur répond, le client corrige ce qui a été mal prédit.

    De plus, lorsque je tire, j'envoie au serveur mon ordre de tir (puis je prédis le tir sur le client)
    le serveur va recevoir l'ordre de tir mais sait que cela c'est produit en fait dans le passé, car le temps que transite l'information toussa toussa

    le serveur va donc recevoir l'ordre de tir et regarder dans son passé ce qui se passait a ce moment, va etre capable de dire si le joueur est effectivement touché ou pas et va renvoyé le statut du tir, qui sera recu plus tard par le client et qui ALORS affichera l'information que le tir a touché ou pas.

    Le serveur peut (mais pas doit) appliquer une correction au passé mais c'est costaud; en cas de lag, on risque plutot de voir un delai entre le fait qu'un joueur est touché ou pas, c'est a dire que tu feras trois pas vivant avant de savoir que l'on t'a tué.


    Le serveur a donc la notion de passé
    le client en général ne connait pas le passé, il prédit le futur de manière a l'afficher avant qu'il n'arrive.

    (C'est seulement un des designs possibles)
    Dernière modification par TanEk ; 16/02/2009 à 18h47. Motif: Correction du titre pour le rendre moins provocateur

  2. #2
    screetch
    Invité(e)
    Par défaut
    par l'exemple

    Sur le client, je vois un ennemi, je tire

    Au moment ou je tire, le joueur est a la position P sur le client (prédite,car on a pas recu l'info du serveur)
    Je continue a prédire, je pense avoir touché mais je ne suis pas certain...
    J'envoie mon info de tir
    50ms plus tard, le serveur recoit l'info du tir
    il va regarder dans sa table du passé me dire ce qui s'est produit il y a 50ms si il ajoute un projectile ; a t'il touché ou pas ? oui, car le lcient a bien prédit la position P
    il envoie l'info "touché", et applique a son présent (ou a son passé) l'info touché, il retire des ponts de vie au joueur touché etc etc

    50ms plus tard, le client recoit l'info : touché. donc, 100ms après avoir tiré il saura si c'est touché ou pas.


    Il arrive parfois que le joueur s'arrête au mauvais moment, juste au moment de tirer; dans ce cas

    Au moment ou je tire, le joueur est a la position P sur le client (prédite,car on a pas recu l'info du serveur)
    Je continue a prédire, je pense avoir touché mais je ne suis pas certain...
    J'envoie mon info de tir
    10ms plus tard je recois la nouvelle position de l'autre joueur; j'applique la correction sur ce que je sais du joueur et reprédit sa nouvelle position : mince, manqué, je prédis que je le manque maintenant

    90ms plus tard je recois la confirmation du serveur : manqué
    durant 10ms j'ai pensé que c'etait touché a cause du lag; au pire, on peut se tromper pendant presque 50ms avec un lag de 50ms.

  3. #3
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    salut,

    un post très intéressant que je vais compléter par un lien que quelqu'un du forum m'avait déjà donné il me semble (IrmatDen ?) : networked physics (en Anglais). A noter que la dicussion qui s'engage dans les commentaires à la suite de l'article est également à lire
    Autre mine d'informations de 1er choix: le site de Valve qui détaille les mécanismes mis en oeuvre dans leur moteur réseau du moteur de jeu qu'ils commercialisent (celui d'Half Life 2 et de Counter Strike Source): ici et (en Anglais, toujours).

    Pour revenir au lag compensation, tout dépend également du type de jeu et du degré de réactivité qu'il nécessite (le FPS étant le plus contraignant): j'ai pu constater avec quelques tests que pour un jeu de petites voitures par exemple, on peut tout à fait imposer du lag ... artificiel !

    Prenons l'exemple d'un petit jeu de voitures arcade genre micromachines. L'idée de base est que lorsque je commande ma propre petite voiture en local, les actions que je fais au temps T (appui de la touche pour tourner, accélérer) ne seront réellement prises en compte qu'au moment T + x millisecondes. Concrètement:

    - au temps T, le joueur A appuie sur la flèche gauche pour tourner à ... gauche

    - un paquet réseau "joueur A tournera à gauche au temps T+ x msec" va être immédiatement (ie. au temps T) émis vers le serveur qui va le faire suivre aux autres clients.

    - en local, la voiture ne tourne pas tout de suite, mais commencera seulement à tourner à T+ x msec ; idem sur les clients distants: le joueur A ne commencera à tourner qu'à T+ x msec.

    L'avantage est qu'avec cette méthode on laisse d'autant plus de 'mou' aux problèmes de latence.

    Le cas idéal est celui ou tous les joueurs ont un ping inférieur à x msec. Dans ce cas, chacun recevra les intentions des autres joueurs avant même d'avoir à les mettre en oeuvre dans le jeu. En d'autres termes, les mécanismes de prédiction ne seront plus utilisés du tout.

    Sinon, si les joueurs (ou certains joueurs) ont un ping supérieur à x msec, ça réduira d'autant (x msec) la durée de prédiction donc le risque d'erreur et l'ampleur des corrections à appliquer (pas toujours funky pour la 'user experience').

    Après, tout dépend du type de jeu. Il faut faire des tests avec différentes valeurs et voir ce qui convient le mieux, genre "à proscrire pour un FPS", "150msec pour un RTS".

    Perso, mes petits tests m'ont montré qu'avec 60 millisecondes dans un petit jeu de voitures 'arcade', ça donne juste un (tout petit) peu d'inertie à la voiture qu'on conduit, mais ce n'est au final absolument pas handicapant pour le gameplay et quasi indétectable par l'utilisateur.
    Au pire, il sentira que la voiture a une légère inertie et adaptera instinctivement son pilotage.
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  4. #4
    Membre averti Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Points : 417
    Points
    417
    Par défaut
    Bon je vais jeter plusieurs questions qui me passe par la tête...
    Répondez à votre rythme :p

    -> Supposons que l'on veuille compenser les lags de tous les clients.
    Le serveur doit donc garder le passé pendant un temps T.
    Ce temps T étant défini par le client qui lag le plus. Si on veut que l'on puisse complètement compenser, il faut que ce temps T soit au moins supérieur à deux fois le ping du client le plus lent.
    Comment ça se passe "en vrai" ?
    -> Es-ce qu'on calcul en permanence le client le plus lent afin de sauvegarder les états passés nécessaires, ou bien es-ce un temps fixé à l'avance ?
    -> La durée de compensation est dynamique ou statique ?
    -> Que ce passe-t-il dans un FPS, par exemple, si un client à un temps de lag plus long que le temps de compensation du serveur ?
    -> Le serveur doit garder des états, de combien ces états doivent être espacé dans le temps ?
    -> Encore une fois dynamique ou statique ?

    Je sais que Deadalnix a fait le choix de pouvoir stocker 8 états qui sont séparés chacun de 10 ms, ce qui permet d'obtenir une compensation de 80ms.
    Es-ce que d'autre personnes qui ont développé un peu sur ce sujet, peuvent partager leur expérience ?

    Je pense personnellement que le lag compensation ne doit pas être intégré au moteur physique, car ce dernier ne doit pas être dépendant du réseau. Je pense donc que le lag compensation (et entre autre la gestion des états) doit être effectué par du code qui utilise le moteur, mais non par le moteur, qu'en pensez vous ?

    Je souffle un peu et je vous laisse répondre....
    Première grosse démo en construction :
    http://bitbucket.org/rafy/exo2/

  5. #5
    screetch
    Invité(e)
    Par défaut
    Il y a plusieurs facons de faire, mais voila en gros mes réponses a tes questions :

    on peut ajuster dynamiquement le serveur sur le client le plus lent jusqu'a une certaine limite

    si un client lague trop, le problème principal sera que la prédiction sur les autres clients sera toujours mauvaise car le serveur informera les autres clients trop tard
    donc si le client lague trop, on peut juste ignorer ce qu'il fait : si un paquet d'input arrive trop tard, on ne le valide pas, on fait comme si le client n'avait pas appuyé sur la touche.
    cela permet aussi d'empecher les gens de tricher en "faisant" du lag sur leur machine

    Le serveur doit conserver des états au rythme qui lui convient; si par exemple les états sont espacés de 50ms, tu peux interpoler les états après 25ms (gain de mémoire mais perte de temps CPU, en gros) ce qui t'autorise a garder pour 2 fois plus de temps. Tu peux garder des états séparés a différent intervalles, par exemple :
    5ms
    10ms
    15ms
    30ms
    45ms
    60ms
    90ms

  6. #6
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2005
    Messages
    249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Mars 2005
    Messages : 249
    Points : 349
    Points
    349
    Par défaut
    Citation Envoyé par screetch Voir le message
    le serveur va donc recevoir l'ordre de tir et regarder dans son passé ce qui se passait a ce moment, va etre capable de dire si le joueur est effectivement touché ou pas et va renvoyé le statut du tir, qui sera recu plus tard par le client et qui ALORS affichera l'information que le tir a touché ou pas.
    Imaginons que le joueur est touché, et meurt. Ca se passe donc dans le passé du serveur. Devrait-il alors y avoir un mécanisme d'annulation des actions effectués par ce joueur entre cet instant et le présent? Ou bien est-ce qu'on élude la question, en considérant que ce laps de temps est négligeable (après tout, les actions effectuées quelques ms après la mort peuvent être vues comme des réflexes post-mortem).

    De plus, il me semble que le serveur ne devrait pas regarder dans son passé (= présent client au moment du tir), mais dans son présent à lui au moment du tir client, c'est-à-dire avec une correction d'un demi ping et non d'un ping (ping = aller+retour de l'information)

  7. #7
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Citation Envoyé par Rafy Voir le message
    Je sais que Deadalnix a fait le choix de pouvoir stocker 8 états qui sont séparés chacun de 10 ms, ce qui permet d'obtenir une compensation de 80ms.
    Es-ce que d'autre personnes qui ont développé un peu sur ce sujet, peuvent partager leur expérience ?
    Personellement, je suis parti sur l'idée que pour chaque client on a la date de la dernière mise à jour qu'il a envoyée, donc qu'on peut connaître la date Tlast la plus récente pour laquelle on a les mises à jour de tous les autres clients (et qui permet de caractériser l'ensemble du 'monde' de façon complète et certaine, ie. sans prédiction).

    A chaque fois que Tlast évolue, on peut alors éliminer tous les événements antérieurs à Tlast de notre historique interne (les 80ms de buffer de Deadalnix).

    Exemple concret avec trois joueurs:
    - heure actuelle: Th= 1680ms.
    - J1, dernière mise à jour reçue à T = 1600 ms.
    - J2, dernière mise à jour reçue à T = 1520 ms.
    - J3, dernière mise à jour reçue à T = 1630 ms.

    Dans ce cas, on connaît de façon certaine l'état du jeu à Tlast=1520ms. Donc on peut supprimer de notre historique tous les événements datant d'avant 1520ms.



    Ensuite on reçoit un paquet (à Th= 1690ms) provenant de J1 pour T=1610ms. On refait le calcul ; Tlast est toujours égal à 1520ms. Rien ne bouge.

    Ensuite on reçoit un paquet (à Th=1695ms) provenant de J2 pour T=1530ms. On refait le calcul ; Tlast vaut maintenant 1530ms donc on peut supprimer de l'historique tous les événements antérieurs à T=1530ms.

    donc si le client laggue trop, on peut juste ignorer ce qu'il fait [...] cela permet aussi d'empecher les gens de tricher en "faisant" du lag sur leur machine
    C'est également à prendre en compte.
    Mais là tout dépend de la façon dont tu veux gérer ça dans ton propre jeu: les réponses peuvent varier: d'ignorer le paquet jusqu'à décider que le ping du joueur étant trop grand tu le fais brutalement quitter la partie.

    Devrait-il alors y avoir un mécanisme d'annulation des actions effectués par ce joueur entre cet instant et le présent?
    A mon humble avis, ton programme passe son temps à recalculer plusieurs fois la logique du jeu pour une même période à partir du dernier état 'certain' (Tlast), au fur et à mesure qu'il engrange des nouvelles infos sur cette période.
    L'idée n'est donc pas d'annuler les actions postérieures, mais de calculer à nouveau, en recommençant à partir de Tlast une nouvelle fois la même période.

    En reprenant mon exemple du dessus:

    à Th = 1680ms, on n'avait des informations certaines que jusqu'à Tlast = 1520ms. Cela veut dire que tout ce qui a été calculé depuis cet instant là est de la prédiction.

    Lorsqu'on reçoit le premier paquet à Th= 1690ms pour l'état de J1 à 1610ms, on va refaire l'ensemble des calculs entre 1610ms et 1680ms plus les nouveaux calculs pour la période 1680ms -> 1690ms.
    Lorsqu'on reçoit le second paquet à Th = 1695ms pour l'état de J2 à 1530ms, on va à nouveau refaire les calculs pour l'ensemble du jeu entre 1530ms et 1695ms, etc...

    A noter que tous les calculs ne sont pas forcément à refaire. Par exemple lorsqu'on reçoit des nouvelles de J1 à 1610ms, si J3 est géographiquement à l'autre bout du jeu, et qu'il n'y a aucune chance qu'ils aient pu interagir, rien ne sert de recommencer les calculs pour J3.
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  8. #8
    screetch
    Invité(e)
    Par défaut
    Citation Envoyé par kremvax Voir le message
    De plus, il me semble que le serveur ne devrait pas regarder dans son passé (= présent client au moment du tir), mais dans son présent à lui au moment du tir client, c'est-à-dire avec une correction d'un demi ping et non d'un ping (ping = aller+retour de l'information)
    Il faut regarder ce qui se passait lorsque le client a tiré, pas lorsque le serveur recoit l'info
    il y a donc un demi-ping de décalage sur le serveur
    il doit donc regarder ce qui se passait sur le client il y a un demi-ping

  9. #9
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Citation Envoyé par screetch Voir le message
    il doit donc regarder ce qui se passait sur le client il y a un demi-ping
    Effectivement, ça peut faire pas mal de différence: il faut que le serveur fasse le test (d'impact du tir par exemple) en fonction de ce que le client qui a tiré voyait à ce moment là. Le second lien sur le moteur Source engine de Valve, paragraphe 'lag compensation' explicite tout ça en détail.
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  10. #10
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2005
    Messages
    249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Mars 2005
    Messages : 249
    Points : 349
    Points
    349
    Par défaut
    Donc si je comprends bien, le mécanisme de compensation revient à l'instant du tir en temps CLIENT, faisant en sorte donc que ce que voit le client qui prévaut sur la "réalité" du serveur - ce qui est logique pour le confort et la précision des inputs du client. C'est ce que je comprends de ce que vous dites et de la formule Command Execution Time = Current Server Time - Packet Round-Trip-Time - Client View Interpolation. Mais du coup, ça peut créer des situations absurdes non?

    Par exemple, le joueur A tue le joueur B. Pendant le lag de A, le joueur B tue le joueur C. Supposons que le lag est relativement gros à cet instant pour A, mais faible pour B et C. Pendant 1 seconde, B et C verront que B a tué C. Puis le tir de A est traité, et donc C revient à la vie. Un peu bizarre, non?

  11. #11
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Citation Envoyé par kremvax Voir le message
    Mais du coup, ça peut créer des situations absurdes non?
    Effectivement, mais dans ce domaine on ne peut pas faire mieux.
    Comme expliqué dans l'article de Valve, il peut par exemple arriver qu'un joueur A soit considéré comme touché par un autre joueur B car au moment du tir, A était dans la ligne de mire de B. Or entre temps, A a eu le temps de se cacher derrière un mur. A se fait donc toucher alors que B n'est plus visible.

    Ce n'est evidemment pas parfait, mais de deux maux, mieux vaut choisir le moindre: cette solution est plus acceptable pour le gameplay qu'un client qui -de son point de vue- tirerait pile poil sur un adversaire et qui ne le toucherait pas.
    Ca a également l'avantage de ne pas favoriser à outrance les joueurs ayant les pings les plus bas (par exemple le joueur qui héberge la partie et a donc un ping proche de zéro).

    De plus, il faut relativiser: un ping moyen pour un jeu comme un FPS se situe aux alentours de 60ms et les joueurs au dessus de 100ms sont rarement acceptés.
    De plus, il n'y a pas de miracles: si un joueur a un ping de 200ms, quelles que soient les techniques que tu utiliseras, ça ne pourra jamais donner un gameplay acceptable pour un FPS.

    Pendant 1 seconde, B et C verront que B a tué C. Puis le tir de A est traité, et donc C revient à la vie. Un peu bizarre, non?
    Non: pour les 'phases critiques' d'un jeu (par exemple le fait de tuer quelqu'un dans un FPS), le client n'utilisera jamais la prédiction et attendra une confirmation du serveur.
    Si tu testes counter strike sur internet, tu pourras d'ailleurs constater que quand quelqu'un te tire dessus, tes points de vie ne sont pas réduits dans l'instant, mais il y a un petit décalage: le temps d'attendre la confirmation du serveur.
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  12. #12
    Expert confirmé
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 519
    Points : 5 168
    Points
    5 168
    Par défaut
    juste une question en passant
    est-ce qu'il faut mesurer le décalage (ping) entre le client et le serveur afin de synchroniser au mieux les prédictions ?
    si le client mesure son ping et en informe le serveur ça permet de caler les prédictions sur un temps de réponse mesuré et non arbitraire
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  13. #13
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Citation Envoyé par shenron666 Voir le message
    est-ce qu'il faut mesurer le décalage (ping) entre le client et le serveur afin de synchroniser au mieux les prédictions ?
    Ca me paraît indispensable afin que tout le monde évolue dans le jeu au même instant, et donc pour "synchroniser les montres".

    si le client mesure son ping et en informe le serveur
    Je dirais plutôt qu'il faut en priorité que ce soit le serveur qui mesure le ping vers son client (ie. : paradigme du "ne jamais faire confiance au client").
    Mais ça n'empêche pas non plus que le client mesure lui aussi son ping. Après tout,ce n'est pas grand chose à faire

    A noter que la latence ne doit pas être estimée une seule fois pour toutes, mais au contraire tout au long de la partie, car elle peut beaucoup varier d'un instant à l'autre (on appelle ça la gigue).

    Pour estimer le 'temps universel', plus on a de mesures régulières, plus on peut en déduire une estimation fine.
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  14. #14
    Expert confirmé
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 519
    Points : 5 168
    Points
    5 168
    Par défaut
    tu confirmes ce à quoi je pensais, je suis content d'avoir compris les principes abordés ici

    Citation Envoyé par nouknouk Voir le message
    Je dirais plutôt qu'il faut en priorité que ce soit le serveur qui mesure le ping vers son client (ie. : paradigme du "ne jamais faire confiance au client").
    c'est pas faux, toujours garder ce paradigme évite les risques de "triche", à graver dans le marbre

    merci pour ces précisions nouknouk
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  15. #15
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Citation Envoyé par shenron666 Voir le message
    tu confirmes ce à quoi je pensais
    A noter que je ne suis pas vraiment une référence absolue en la matière.
    Tout juste un amateur un minimum éclairé qui s'est intéressé récemment à ce sujet fort pointu (une formation d'ingé télécom aidant à connaître les bases des technos réseau).

    Donc ce serait encore plus parfait si quelqu'un de réellement expérimenté dans le domaine pouvait corroborer ou infirmer mes allégations

    toujours garder ce paradigme évite les risques de "triche", à graver dans le marbre
    Oui, mais ... non
    J'ai justement j'ai en tête une petite idée pour éviter les problèmes de montée en charge que ce paradigme implique dans le cas de serveurs centralisés. Faut juste que je trouve le temps d'écrire un pavé indigeste pour détailler ma ptite idée à deux sous et la soumettre au regard critique des forumeurs
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  16. #16
    Membre averti Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Points : 417
    Points
    417
    Par défaut
    Citation Envoyé par nouknouk Voir le message
    (...)
    Tout juste un amateur un minimum éclairé
    (...)
    Ben ouais regarde sous ton pseudo : membre éclairé
    (C'était juste pour être peut-être cité dans la taverne ça)
    On parlait de mesurer le ping des clients afin de savoir lequel était le plus lent. OK, mais il faut le faire tous les combien de temps ? Je suppose qu'il ne faut pas le faire à chaque frame, sinon ça va pas le faire, si on le fait à chaque fois que le serveur envoie ou reçoit un paquet ça va faire un peu longuet.
    Bon sinon j'ai un question pourrie encore, qui va tout fouttre en l'air
    Quand le serveur envoie des infos vers un client, il n'envoie pas le dernier état dans lequel était le moteur, il envoie juste des données qui modifient l'état précédent afin de ne pas saturer la bande passante avec des infos que connait déjà le client. Bon certains ont peut-être déjà vu la question qui va tomber :
    Tout au début on parlait d'un TLast, le dernier temps de mise à jour du client le plus lent. Ce TLast doit donc tenir compte des informations qui sont envoyées. je veux dire par la que c'est pas parce qu'un client répond et reçoit vite les paquet qu'il a les dernières mise à jour et surtout qu'il a le même état que le serveur !!! Le plus rapide peut ne pas être à jour du tout et qu'il faille qu'il reçoivent plein d'info pour se mettre à jour alors que le plus lent seulement la position de certains objets... Si le serveur compense, il faut que les client partent du même état.. Il n'y a pas un soucis la ?
    Première grosse démo en construction :
    http://bitbucket.org/rafy/exo2/

  17. #17
    Membre émérite
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 537
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 537
    Points : 2 548
    Points
    2 548
    Par défaut
    Tant qu'on y est voici comment je procède de mon coté.

    Tout d'abord, je ne prédit pas le futur coté client.

    Coté serveur, j'ai le passé en mémoire. Je maintient un ping associé a chaque joueur que je met a jour de temps en temps.

    Quand le serveur reçoit une action d'un joueur, il regarde son ping, et applique cette action dans le passé. Dans la limite de 80ms.

    Une liste d'objets impactés est tenue. Tous les objets impactés par l'action du joueur sont mis dans cette liste. leur nouveau comportement physique est recalculé sur le temps du lag.

    Si ces objets venaient a interagir avec d'autres objets, ceux-ci seront aussi ajouté dans la liste, comme s'ils étaient « contaminés ».

    La physique est totalement asynchrone. Il y a 10ms entre chaque étape. tant que le moteur physique est en retard, il mouline, s'il est en avance, il fait des pauses. cela permet de rattraper le retard qui est pris sur une grosse charge.

    le retard pris par le serveur est très peu perceptible par les joueurs tant que celui-ci ne dépasse pas le ping, ce qui laisse une bonne marge de manœuvre. En effet, le lag compensation fera que leur action s'exécutent au moment opportun grâce au lag compensation.

  18. #18
    Membre averti Avatar de Rafy
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 415
    Points : 417
    Points
    417
    Par défaut
    Bon voici apres synthèse et recherche d'info sur le sujet.
    Dans des jeux comme UT, HL², Le client date ses paquets. Ainsi il envoie des informations au serveur du genre : à telle date j'ai commencé à avancer.
    Le serveur recoit ce paquet du client, remonte dans le passé (jusqu'a 2 secondes pour HL) applique les modifications que la paquet du client entraine. Puis il envoie les mises à jour à tout le monde.
    Il saute alors deux choses au yeux : C'est cool que le client envoie une date dans le paquet, mais quelle date ? Il faut qu'il envoie une date que le serveur puisse utiliser. Il faut donc synchroniser les clients en temps, avec le serveur. Pour que leur référence en temps soit la plus proche possible du serveur.
    Personnellement j'ai utilisé l'algorithme qui est expliqué ici.
    J'obtient un écrat entre le serveur et le client de l'ordre de 10 15 ms (même avec un grand ping > 500).
    Je l'ai adapté pour que ça ne soit pas le client, mais le serveur qui effectue ce calcul (rappelez vous : "never trust the client").
    Mais tout ceci pose un petit problème : Si le client date ses paquets, ben il peut mettre n'importe qu'elle date !!! Ben ouais, c'est pour ça qu'il existe des hackers C'est un problème qui n'est pas soluble. On peut détecter tout de même si le client envoie des timestamp éroné en comparant avec le ping.
    Il faut savoir que le fait de dater les paquet et d'avoir une synchronisation est plus précis que d'interpoler la valeur du ping. en effet si le ping varie beaucoup, la valeur du ping calculée peut être très différente de la vrai valeur. et l'interpolation augmente encore l'erreur. C'est egallement plus rapide car le serveur n'a pas besoin de faire un allé retour de paquet pour connaitre le délai.
    Ce problème est bien connu, mais inévitable. (speedhacking).
    De toutes façons même si le client ne datait pas ses paquets, alors le client pourrait tout de même tricher et fakant son ping. En effet, il est "facile" pour lui de faire croire au serveur qu'il a un ping élevé. (il suffit de retarder l'envoie des paquets qui servent à calculer le ping). Et puis pour tricher, envoyer les paquet normalement. Le serveur va remonter dans le passé en croyant que le client à un grand ping, mais comme c'est faux, le client va commencer à bouger sur le serveur avant même que le client ai envoyé l'info. Il est donc ainsi possible d'augmenter sa vitesse de déplacement artificiellement dans un jeu....

    Pour conclure, la synchronisation en temps entre le serveur et le client apporte des problèmes de "sécurité", mais elle apporte des avantages important pour la compensation du lag que ça soit sur le plan de la rapidité ou de la précision. Il faut donc être conscient des dangers et tenter de les éviter.
    Première grosse démo en construction :
    http://bitbucket.org/rafy/exo2/

  19. #19
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France, Sarthe (Pays de la Loire)

    Informations forums :
    Inscription : Avril 2007
    Messages : 113
    Points : 99
    Points
    99
    Par défaut
    Citation Envoyé par Rafy Voir le message
    Mais tout ceci pose un petit problème : Si le client date ses paquets, ben il peut mettre n'importe qu'elle date !!! Ben ouais, c'est pour ça qu'il existe des hackers C'est un problème qui n'est pas soluble.
    Y a tj la possibilité du cryptage et des signatures. le serveur refuse les paquets non ou mal signés (evite les pb de faux clients). le client crypte (clé double) pour empecher les modifs à la volée (évite les patchs pirate)
    En gros, si tu dates pas, tu t'en sors pas.

    Halo 2 aussi faisait du datage de paquet reseau : les grenade sont rigolotes, elle explose en "retard", cad une fois que tous le monde a recu l'information d'explosion de grenade. Ca permet de "tuer" sans erreur ni besoin de rollback.
    D'ailleurs, les données transferées ne correspondaient pas au deplacement pas a pas, mais aux évènements (je tourne, j'avance a x m/s, je tire, je me baisse etc...) ca permettaient de réduire drastiquement la quantité de données à transférer.
    Par voie de conséquence il faut non pas stocker les positions de objets sur les 8 dernieres frames, mais stocker les évènements qui ont eu lieu pour tous les objets en mouvement.

    Le lag compensation ne résould pas tout : comme la gestion du lag augmente arithmétiquement avec le nb de joueur, on se retrouve rapidement a bout de solution quand on a plus de 32 ou 64 joueurs.
    Les MMORPG ont trouvés des solutions radicales a ce pb, d'ailleurs, les joueurs en payent le prix en subissant un certain manque de Réalisme (Dans Wow, on passe a travers les monstres, les PNJ et les PJ)

  20. #20
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Citation Envoyé par Fraggy Voir le message
    Y a tj la possibilité du cryptage et des signatures. le serveur refuse les paquets non ou mal signés (evite les pb de faux clients). le client crypte (clé double) pour empecher les modifs à la volée (évite les patchs pirate)
    J'ai du mal à voir comment tu peux t'assurer de la non modification du client en cryptant. Tu peux détailler ?
    En gros, si tu dates pas, tu t'en sors pas.
    +1

    Halo 2 aussi faisait du datage de paquet reseau : les grenade sont rigolotes, elle explose en "retard", cad une fois que tous le monde a recu l'information d'explosion de grenade. Ca permet de "tuer" sans erreur ni besoin de rollback.
    C'est le principe évoqué plus haut du "pour les événements importants", on préfère attendre un confirmation du serveur (l'exemple avait été pris des pertes de points de vie dans Counter Strike).
    Par contre, je ne comprend pas pourquoi tu dis qu'elles explosaient 'en retard'. Parles-tu du feedback visuel dans le jeu (question ouverte: je ne connais pas le jeu) ?
    Parce que logiquement (si c'est une grenade à explosion à T+x secondes après l'avoir lancée, x constant) le client peut déterminer dès le lancer de la grenade à quelle date exacte l'explosion doit avoir lieu, et jouer l'animation d'explosion au bon moment, quitte a ne répercuter les 'morts' et pertes de points de vie qu'après. Ce que fait Counter Strike par exemple.

    D'ailleurs, les données transferées ne correspondaient pas au deplacement pas a pas, mais aux évènements (je tourne, j'avance a x m/s, je tire, je me baisse etc...) ca permettaient de réduire drastiquement la quantité de données à transférer.
    Par voie de conséquence il faut non pas stocker les positions de objets sur les 8 dernieres frames, mais stocker les évènements qui ont eu lieu pour tous les objets en mouvement.
    Tout dépend si ton stream réseau est fiable ou non: s'il n'est pas fiable (UDP), tu es obligé d'envoyer des valeurs absolues ; s'il est fiable (TCP), là tu peux te permettre de n'envoyer que des deltas.
    De toute façon, envoyer une trame de quelques vecteurs une vingtaine de fois par seconde reste largement en dessous des capacités des lignes actuelles. C'était surtout vrai du temps du modem RTC 56k.

    Le lag compensation ne résould pas tout : comme la gestion du lag augmente arithmétiquement avec le nb de joueur, on se retrouve rapidement a bout de solution quand on a plus de 32 ou 64 joueurs.
    Pas nécessairement le lag peut être introduit par deux facteurs:

    - le lag au niveau couche 'réseau' dépend de la capacité de ta connexion. Or les connexions sont largement dimensionnées maintenant pour supporter le streaming des infos de 100 utilisateurs en simultané.

    - le lag au niveau capacité de traitement du serveur: le traitement et le renvoi des données pour 100 utilisateurs peut prendre un temps infime (moins d'une ms) même pour un jeu avec 100 utilisateurs connectés, la différence de lag serait alors tout aussi négligeable pour 2 utilisateurs que pour 100. A ce niveau, tout dépend du jeu et de sa complexité.
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

Discussions similaires

  1. Fonctions LAG et LEAD
    Par Nounoursonne dans le forum Oracle
    Réponses: 8
    Dernier message: 16/10/2007, 11h49
  2. Lag dans les requêtes des répliques mais pas du maître
    Par Thomas JOUANNOT dans le forum Access
    Réponses: 3
    Dernier message: 16/03/2006, 10h17
  3. [hardware][hdd] probleme de lag dans les jeux
    Par graphicsxp dans le forum Composants
    Réponses: 3
    Dernier message: 21/02/2006, 01h51
  4. Les largeurs ne se compensent pas
    Par Anduriel dans le forum Balisage (X)HTML et validation W3C
    Réponses: 6
    Dernier message: 21/12/2005, 00h36
  5. fonction LAG et erreur PLS-00103. Oracle 8i
    Par henrirobert dans le forum Oracle
    Réponses: 7
    Dernier message: 26/05/2005, 17h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo