Partage
  • Partager sur Facebook
  • Partager sur Twitter

Architecture clients-serveur dans un jeu

(dans la théorie)

    25 mars 2008 à 21:33:29

    Bonjour aux zéros,
    Après m'être rendu compte que c'est un probleme d'ordre théorique qui revient souvent, et à laquelle je suis confronté aujourd'hui, j'ai décidé d'ouvrir ce topic pour discuter de la meilleur facon de mettre en place une architecture client-serveur. Dans notre cas, ca sera dans le cadre d'un jeu, car c'est plus souvent dans ce cas là que le probleme se pose pour nous. L'objectif est de déterminer ce que doivent faire d'un coté le(s) client(s), et de l'autre le serveur, pour atteindre les meilleurs conditions de jeu possible, à savoir que les clients aient tous la même image du jeu, au même moment, et qu'une action d'un client de mette pas 15 secondes à se répercuter dans le jeu.
    J'aimerai que pour cette discussion se situe plus au niveau algorithmique, donc si vous avez des idées à expliquer, pas la peine de coder en C(++), ca sera amha plus simple et plus rapide d'expliquer par des actions simples en français, qui pourront éventuellement être facilement traduites en code si le besoin s'en fait sentir.

    J'ai déjà fait quelques recherches sur le sujet, et je dois avouer ne pas avoir trouver grand chose sur cette question précise, plus des documents sur des points de détails ou d'ordre trop général. Après quelques temps de réflexion, voici le systeme qui me semble le plus intéressant pour le moment, et qui pourra être le point de départ à la discussion: (copier/coller de ce que j'ai dit dans un autre topic)
    -le client:
    --envoie au serveur la (ou les) actions effectuées en local
    -le serveur:
    --centralise les actions de tous les clients
    --envoie à chacun des clients les actions effectuées, et les évènements ingame (spawn de monstres, déplacements d'élément, peu importe)
    -le client:
    --fait la résolution de l'instant en fonction des règles du jeu.

    Cependant, j'ai peur que ce système ait une lacune qui pose probleme : le délai entre l'action d'un joueur et sa réalisation effective à l'écran, dans la mesure où il y a un allez-retour de l'information entre le client et le serveur entre ces 2 moments.
    Je ne pense pas qu'on puisse pour chaque frame envoyer à tous les clients les informations sur chacun des objets du jeu, il faut donc trouver un moyen qui limite les échanges d'info et cependant fournit à chaque client une image précise de l'état du jeu...
    • Partager sur Facebook
    • Partager sur Twitter
      25 mars 2008 à 22:43:20

      Tu a tout a fait raison,le temps d'attente est le majeur probleme.
      Utilisées vous un moteur physique complexe ou "triviale"(predictifif ou pas?)?
      Sinon,un metre mot:input prediction.
      Je peu pas te donner plus d'info la je vai au pieu.
      Sinon voila une liste d'article qui peuvent etre interressants:
      http://www.ogre3d.org/wiki/index.php/External_Links#Articles
      • Partager sur Facebook
      • Partager sur Twitter
      Anonyme
        26 mars 2008 à 14:25:47

        tu peut aussi faire que les clients comunique directement entreux quand il sont sur la même map et que le serveur gére juste les pnj.
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          26 mars 2008 à 15:28:21

          Citation : Prsieux

          tu peut aussi faire que les clients comunique directement entreux quand il sont sur la même map et que le serveur gére juste les pnj.

          Laisser le serveur s'occuper des pnj est possible, mais faire que chaque client envois x fois la même info n'est pas bien (où x est le nombre de client).
          • Partager sur Facebook
          • Partager sur Twitter
            26 mars 2008 à 17:07:32

            a mon avis la premiere solution est la meilleure, mais tout depends du jeu bien sur. et il ne faut pas oublier qu'un serveur de jeu ne fait que ca. et j'ajouterais du coté du serveur une gestion Selecteur/Threads
            • Partager sur Facebook
            • Partager sur Twitter
              26 mars 2008 à 17:49:10

              Je pense que l'idéal serait que le client envoie les actions qu'il effectue au serveur, sans attendre de retour de celui-ci au sujet de l'action en question. Le client peux considérer qu'il n'a pas à attendre de retour du serveur si la situation dans laquelle il est, est la même que celle du serveur, et que le client appliquera les mêmes règles de résolution que le serveur.
              Ceci-dit, cette méthode laisse la porte-ouverte aux modifications côté client. On va dire que dans un premier temps, pour des jeux de l'envergure qui est la notre, ca ne devrait pas poser de probleme.
              D'autre part, le serveur devra calculer et envoyer aux clients les évènements qui ne dépendent pas d'une joueur, c'est-à-dire les PNJs et les évènements extérieurs (apparition/disparition d'éléments, changements de niveau...).
              Dans ce cadre, il serait peut-être judicieux pour le serveur de faire d'un côté un thread qui gère les clients (connexion/déconnexion de nouveau client et actions des clients) et de l'autre un thread qui s'occupe du reste (PNJs, évènements, ...), de facon à séparer dans le code 2 domaines qui sont relativements différents.

              Cependant, je me demande si un tel traitement en parallèle ne pourrait pas poser de probleme au niveau des threads (est-ce que l'envoie d'un paquet est une action qui pourrait etre interrompue? est-ce un probleme si lors d'une interruption d'un envoi, un autre envoi est effectué?).
              • Partager sur Facebook
              • Partager sur Twitter
                26 mars 2008 à 18:11:33

                deja je pense que tu devrais te renseigner sur le reseau (protocole, TCP, UDP, socket, probleme de endianness, ...)

                ensuite il faut que tu definisse tout le protocole de ton jeu

                puis, tu concois toute l'architecture de ton "reseau"
                • Partager sur Facebook
                • Partager sur Twitter
                  26 mars 2008 à 19:01:17

                  Salut.
                  Effectivement,le serveur ne doit pas trop s'occuper de savoir si le message est bien arriver ou est en retard.C'est au client de verifier,si le message est en retard,il doit essayer de "prédire" le message,et si la simulation entre le client et le serveur est trop décalé,le client doit demander au serveur de resyncroniser.
                  Pour ce qui est de modifications,si ton jeux est bien fait,une modif sur le client ne devrais pas pouvoir permetre au client de tricher en modifiant par exemple son inventaire.Ces(inventaire etc) requetes doivent etre traiter par le serveur sans se baser sur les données du client.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    26 mars 2008 à 19:15:09

                    Pour ce qui est des détails techniques, j'ai déjà testé les différents protocoles avec le module network de la SFML, l'aide que je recherche est surtout au niveau de la communication entre le serveur et les clients : quelles sont les données qui transitent et quelles sont les données instanciées chez les clients et chez le serveur.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      26 mars 2008 à 19:22:02

                      Citation : Chlab_lak

                      ensuite il faut que tu definisse tout le protocole de ton jeu

                      puis, tu concois toute l'architecture de ton "reseau"



                      c'est sur ca que tu dois te concentrer alors
                      • Partager sur Facebook
                      • Partager sur Twitter
                        27 mars 2008 à 15:17:47

                        Ben...C'était le but du topic... de discuter entre programmeurs intéressés par cette question, parce qu'elle est pas évidente, de trouver le moyen le plus efficace, à notre niveau, pour faire un systeme qui marche bien...
                        • Partager sur Facebook
                        • Partager sur Twitter
                          27 mars 2008 à 23:15:24

                          Bonsoir bonsoir !

                          Je me permet de faire un p'tit lien vers un (de mes) post très similaire a celui-ci...
                          Ici

                          Quelques idées, amenées par Inki et ledemonboiteux, étaient vraiment très intéressantes.
                          Bon, j'avoue ne pas avoir beaucoup plus poussé mes essais/recherches, mais je crois que certaines idées pourraient être exploitées.. Du moins, graines de reflexion, non ?

                          Quoi qu'il en soit, la gestion réseau (principalement dans un jeu) est souvent bien galère, et j'imagine que beaucoup de solutions "professionnelles" et/ou "commercialles" s'appuyent plutot sur une capacité de gestion/calcul(=> grappe de serveurs,...) que sur une réél optimisation du serveur et du client.

                          En tout cas, j'apprécie ce genre de post (et hop ! un favoris en plus ^^ ), et vous souhaite bonne reflexion !

                          Et surtout bonne nuit !
                          • Partager sur Facebook
                          • Partager sur Twitter
                            27 mars 2008 à 23:43:23

                            J'avais déjà suivit ton topic, mais il me semble qu'il est plus orienté sécurité alors que je souhaite m'intéresser plus au modèle à mettre en place pour avoir un systeme efficace sans implémenter de techniques compliquées d'optimisation/prediction...

                            Citation : Xan

                            Quoi qu'il en soit, la gestion réseau (principalement dans un jeu) est souvent bien galère, et j'imagine que beaucoup de solutions "professionnelles" et/ou "commercialles" s'appuyent plutot sur une capacité de gestion/calcul(=> grappe de serveurs,...) que sur une réél optimisation du serveur et du client.



                            Je n'en suis pas certain, dans la mesure où l'infrastructure coté client n'est pas extensible par le créateur du jeu. Alors il est sans doute possible de concvoir le systeme pour privilégié le travail du coté du serveur, mais il reste des constantes qui ne pourront pas bouger et qui limiteront les possibilités, qui sont la bande passante et le ping de la connexion du client. C'est pour ca que dans un projet conséquent, il est impératif d'utiliser des techniques pour réduire au maximum les échanges client-serveur.
                            • Partager sur Facebook
                            • Partager sur Twitter
                            Anonyme
                              28 mars 2008 à 0:57:53

                              Pour réduire les échanges je vais vous proposez le protocol utilisé par eve-online et world of wacraft.
                              Pour ne pas avoir a définir chaque joueur, les loot et tout le reste il y a une database internet au client qui elle est statique par exemple le serveur envoie le paquet :
                              1. 04 51 00 45 68 45 00 4A 10 05

                              Ce paquet doit être coupé en deux par le client au niveau du 00 qui est le caractère NULL. Le premier paquet est ce que l'on appel L'opcode il permet de dire au client ou au serveur cela dépend du sens dans lequel on l'envoie que directive est a effectué, cela permet aussi au client de prévoir ce qui va suivre. Dans notre cas nous dirons que cette opcode définit le drop d'un objet par un joueur. Il est donc logique de s'attendre a ce que l'id du joueur et l'id de l'objet suivent. Le client va donc récuperer l'id du client prendre la position tout ca et faire tomber l'objet avec l'if qui suit mais imaginer si a cgaque drop il fallait télécharger les données de l'objet...
                              Les dbc chez blizzard permettent de garder en mémoire les infos sur les objets donc moins de transfère.
                              • Partager sur Facebook
                              • Partager sur Twitter
                                28 mars 2008 à 22:50:07

                                Bonsoir !

                                Citation : alecool

                                J'avais déjà suivit ton topic, mais il me semble qu'il est plus orienté sécurité alors que je souhaite m'intéresser plus au modèle à mettre en place pour avoir un systeme efficace sans implémenter de techniques compliquées d'optimisation/prediction...



                                Tiens, c'est marrant, ce n'étais pas rééllement l'optique que j'avais en créant mon topic. Justement je cherchais un moyen de soulager le serveur, de mettre à profit les clients, de réduire les communications, et de gagner en vitesse. Bon, j'avoue qu'on a pu dériver vers la sécurité, car il me semble nécessaire d'y reflechir. A part un projet 'privée' (disons à communauté très réstreinte, et de 'confiance'), meme dans une petite communauté, il y a un risque qu'un petit malin cherche a détourner de son utilisation normal le programme, surtout s'il s'agit d'un jeu (c'est bien plus marrant de s'la peter a vaincre tout le monde que de pouvoir envoyer 1024 caractères au lieu de 512 dans un mini-chat... :lol: ).

                                Citation : alecool

                                Je n'en suis pas certain, dans la mesure où l'infrastructure coté client n'est pas extensible par le créateur du jeu. Alors il est sans doute possible de concvoir le systeme pour privilégié le travail du coté du serveur, mais il reste des constantes qui ne pourront pas bouger et qui limiteront les possibilités, qui sont la bande passante et le ping de la connexion du client. C'est pour ca que dans un projet conséquent, il est impératif d'utiliser des techniques pour réduire au maximum les échanges client-serveur.



                                Evidement, le client se doit d'etre plus léger que le serveur(d'ou ma nuance souligné sur le mot "réél"). Mais, malgré tout je pense que les serveurs sont plutot basé sur leur puissance que sur des algorithmes très efficaces.
                                Evidement, les échanges client-serveurs se doivent d'etre limité au strict minimum, je suis tout à fait d'accord sur ce point.

                                Citation : yamashi

                                Pour réduire les échanges je vais vous proposez le protocol utilisé par eve-online et world of wacraft.
                                Pour ne pas avoir a définir chaque joueur, les loot et tout le reste il y a une database internet au client qui elle est statique par exemple le serveur envoie le paquet :

                                1. 04 51 00 45 68 45 00 4A 10 05


                                Ce paquet doit être coupé en deux par le client au niveau du 00 qui est le caractère NULL. Le premier paquet est ce que l'on appel L'opcode il permet de dire au client ou au serveur cela dépend du sens dans lequel on l'envoie que directive est a effectué, cela permet aussi au client de prévoir ce qui va suivre. Dans notre cas nous dirons que cette opcode définit le drop d'un objet par un joueur. Il est donc logique de s'attendre a ce que l'id du joueur et l'id de l'objet suivent. Le client va donc récuperer l'id du client prendre la position tout ca et faire tomber l'objet avec l'if qui suit mais imaginer si a cgaque drop il fallait télécharger les données de l'objet...
                                Les dbc chez blizzard permettent de garder en mémoire les infos sur les objets donc moins de transfère.



                                Of course ! j'avais déjà lu plus d'un article sur cette méthode. Bon je ne l'ai jamais mis en oeuvre, mais ca ne semble pas particuliérement difficile a mettre en oeuvre.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  23 avril 2008 à 17:40:21

                                  Bonjour:


                                  1) statique vs dynamique.

                                  Tout d'abord tu dois défnir deux choses : ce qui est statique de ce qui est dynamique.
                                  Dans la partie statique tu va mettre les sprites, les caractéristiques des objets, le décors, le monde ... chaque client a une copie de la partie statique. Cette partie doit être identique pour chaque client. Si tu prévoie de la modifier, il te faut intégrer un gestionnaire de version, mais on n'est plus dans le sujet.

                                  Pour la partie dynamique, et ben ... et ben ca dépend.


                                  2) Qu'est ce qui se résoud en local
                                  La seconde question à se poser est de savoir s'il est utile de communiquer chaque changement (c'est à dire la partie dynamique) au serveur.
                                  En effet il y a peut être des parties dynamiques qui peuvent se résoudre en local : par exemple le client un barbare de niveau 8 boit sa prorpe potion de vie, il peut sans problème décider tout seul de retirer la potion de son inventaire et augmenter comme un grand son total de points de vie.
                                  Résoudre des choses en local est rapide, ne consomme pas de bande passante, ne casse pas les pieds au serveur, et quand le serveur rame ca ne ce voit pas. L'inconvéniant c'est que les petits malins peuvent tricher. En effet si je compte en local mon nombre de points de vie : je peux le fixer à 1 000 000, et si je possède min inventaire je peux décider que ma potion de vie se transforme en ultimate sword of the dead mamy mwarf!

                                  3) global vous avez dit global?
                                  Tout ce qui ne se résoud pas en local (car pas besoin de prévenir les autres joueurs de ce qu'il se passe) se résoud en global (il faut mettre au moins un joueur au courant de ce qu'il se passe). C'est là que le serveur intervient.

                                  Le principe consiste à prévenir le serveur, qui va traiter l'action et prévenir le/les joueurs impliqués.
                                  Pour ça le serveur possède une image de la partie dynamique de l'univers : chaque fois qu'un joueur lui dit qu'il fait une action, le serveur modifie cette image et préviens les joueurs concernés de ces modifications.


                                  Pour ca quelques astuces:
                                  - Séparer l'univers en Zones indépendantes
                                  - A chaque fois qu'un joueur arrive dans une zone, le serveur envoie un gros paquet qui contient toutes les infos dynamiques sur la zone. Ensuite en cours de partie il n'envoie aux joueurs que des informations sur les changements survenus. Les joueurs résolvent ces changements en local.
                                  - PENDANT LES TESTS Renvoyer de temps en temps toutes les infos de la zone aux joueurs, ils les comparent avec leurs informations et si il y a désacord : il faut produire un rapport de bug.
                                  - Autoriser les joueurs a communiquer directement entre eux. Par exemple le chat et le commerce peuvent être décentralisés du serveur. Le serveur se contacte de mettre les joueurs en relation et après ils se débrouillent. Là encore ils peuvent tricher.

                                  Penser qu'un serveur peut recevoir des requêtes contradictoires : exemple il y a un gros trésor.
                                  Le joueur Blurp indique au serveur qu'il ramasse le trésor.
                                  Le joueur Kiça indique au serveur qu'il ramasse le trésor.
                                  Le serveur doit se débrouiller pour qu'à la fin il n'y ai pas un trésor dans les mains de Blurp et un dans celles de Kiça. Par exemple il envoie a Blurp : "trésor" et a Kiça "dommage". Sur cet exemple c'est trivial, mais il faut absolument prendre en compte la possibilité dans tous les cas. Soit appliquer systématiquement : Joueur : demande d'action --> serveur : résultat d'action --> joueur mise a jour de son univers local.




                                  • Partager sur Facebook
                                  • Partager sur Twitter

                                  Architecture clients-serveur dans un jeu

                                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                  • Editeur
                                  • Markdown