Projet Cartylion
Partageons notre passion Communauté
Catégorie :
Date : 14 janvier 2022

Un stage autour de Conseil de Guerre en ligne

Je m’appelle Lucas et je suis actuellement étudiant en troisième année à l’ICAN.
J’ai pu participer au développement de Conseil de Guerre en ligne dans le cadre de mon stage avec Mathieu (le lead développer) qui s’est terminé en ce début janvier.

Objectif du stage : la mise en réseau

Ce stage a pour but de continuer le travail fait sur le prototype en place, notamment sur les effets des cartes encore manquants mais surtout d’aborder la mise en réseau. En effet, Conseil de Guerre pourrait se jouer en solo (contre une Intelligence Artificielle) mais c’est beaucoup plus dur à mettre en place qu’un mode joueur contre joueur (comme l’avait expliqué Mathieu dans son précédent article). Le réseau est la partie centrale de mon stage, et nous avons fait beaucoup de travail de R&D (recherche et développement) avec Mathieu afin de bien comprendre et appréhender le réseau sur un moteur de jeu comme Unity. Pour ma part, c’était plutôt compliqué car je n’avais jamais fait de pratique réseau auparavant et ça a été un gros morceau à digérer pour bien tout assimiler. Bien que je ne souhaite pas continuer à travailler dans le réseau car c’est un domaine de compétences très vaste et que je ne suis pas formé à ça, j’ai pu voir qu’un stage de deux mois était très loin d’être suffisant pour former quelqu’un à ce domaine. Ça reste toutefois une expérience très enrichissante et qui m’a permis d’élargir mes connaissances.

Quelques éléments pour commencer la mise en réseau

Une bibliothèque de code


La bibliothèque de code que nous avons retenue pour travailler sur le projet est Mirror. Une bibliothèque est un ensemble de fonctionnalités déjà codées que l’on peut ajouter à n’importe quel projet, en respectant les conditions d’utilisation de la bibliothèque en question.
Mirror est une bibliothèque qui dérive de UNet, l’ancienne principale bibliothèque de réseau de Unity. Mirror est une surcouche de la bibliothèque UNet, c’est-à-dire qu’elle a été créée par-dessus le code de UNet. Ainsi, la majorité des ressources valables pour cette dernière peuvent aussi l’être pour Mirror, ce qui en fait la bibliothèque la plus documentée par rapport aux autres que nous avons pu tester (MLAPI et Photon). Aussi, contrairement à d’autres, Mirror ne pose pas de limite payante au nombre d’utilisateurs simultanés ce qui est un avantage.


Un serveur, des clients : des indispensables pour comprendre le réseau


Avant toute chose, il est nécessaire d’expliquer les concepts de serveur et de clients. Un serveur est une entité qui a une vision d’ensemble du programme et va commander (à la manière d’un chef d’orchestre) aux autres entités. Les autres entités quant à elles sont les clients qui réalisent leur rôle de leur côté en suivant les indications du serveur (les concertistes).

Mirror fonctionne de manière simple : il y a un serveur et des clients, chacun possédant ses propres objets (un deck de cartes par exemple) et chacun pouvant avoir l’autorité (ou le contrôle) sur un objet.

Lorsqu’un client se connecte au serveur, il devient un clone de ce dernier. Si on souhaite, par la suite, faire apparaître le même objet sur le serveur et les clients, on peut utiliser une méthode, ou fonctionnalité, qui initialise automatiquement l’objet sur le serveur et le clone sur les clients. On peut alors préciser quel client a l’autorité sur cet objet.

Image représentant un serveur servant des clients sur une table
Un serveur, des clients, on est dans un ordi ou au resto ?

Nous avons ainsi un serveur et des clients qui sont des clones, mais comment faire pour effectuer des actions à la fois sur le serveur et sur les clients ?

Et bien, comme je vous l’ai dit, ce sont des clones, ils ont donc les mêmes méthodes sur les mêmes objets. Une méthode qui s’exécute à chaque centaine de milliseconde s’exécutera indépendamment sur le serveur et sur les clients, mais une méthode qu’un client effectue (par un appui sur un bouton par exemple) ne s’effectuera que sur ce même client. Enfin, c’est le cas sauf si on utilise deux outils très puissants : les commands et les RPCs (pour Remote Procedure Call). Ces deux outils sont similaires et permettent depuis un des côtés (serveur ou client) de demander à l’autre côté de faire quelque chose.

Ainsi, quand le client veut faire une action et le serveur doit le savoir : on effectue l’action puis grâce à une command on envoie les informations au serveur. À l’inverse, quand le serveur doit envoyer des informations aux clients : on crée un RPC pour envoyer ces informations. Ce sont en quelque sorte des méthodes qui permettent de faire communiquer entre eux le serveur et les clients.


Un exemple pour mieux comprendre


Prenons l’exemple d’un jeu au tour par tour, il y a plusieurs joueurs et un serveur. Chacun a connaissance de l’état actuel du jeu.


Le joueur actif souhaite terminer son tour de jeu. Pour cela, il clique sur un bouton qui active la méthode TourSuivant() qui change le joueur actif. Dans ce cas, ni le serveur, ni les autres clients ne seront informés de ce changement.
Créons alors une nouvelle méthode mais que l’on marque comme une command (avec une balise avant son nom et Cmd dans son nom), cette nouvelle méthode CmdTourSuivant() va être appelée par notre client qui souhaite mettre fin à son tour à la place de TourSuivant(), et tout ce qu’elle fait se fait alors sur le serveur. Une command peut se traduire par “le client demande au serveur d’effectuer une action”.
Dans CmdTourSuivant(), nous voulons que le serveur passe au joueur suivant, on va donc y mettre TourSuivant() (rappelez-vous, ce sont des clones, la méthode existe donc aussi sur le serveur).
Maintenant nous n’avons plus un client qui passe son tour avec les autres clients et le serveur qui ne sont pas au courant mais le serveur qui passe le tour sans que les clients ne soient au courant : il faut donc les informer. Et c’est là qu’arrive le RPC, nous allons donc créer une nouvelle méthode RPC de la même manière que nous avons créé la command, elle s’appellera RpcTourSuivant() et elle effectuera l’action TourSuivant(). Il faut maintenant l’appeler sur le serveur pour qu’elle s’effectue sur chacun des clients. Le meilleur moyen pour ça est de l’appeler dans la command CmdTourSuivant().

Image de corps en codage
Exemple de corps de deux méthodes

Nous obtenons ainsi une sorte de boucle : le client souhaite finir son tour, il demande au serveur de le faire CmdTourSuivant(), le serveur passe alors au tour suivant TourSuivant() puis informe tous les clients de le faire RpcTourSuivant() qui à leur tour passent au tour suivant TourSuivant().



Nous avons donc un serveur et des clients qui peuvent communiquer entre eux ainsi qu’un prototype fonctionnel. Mais il reste encore beaucoup de travail à faire pour arriver à un système en ligne viable, notamment dans le fait de créer des salons qui regroupent les joueurs et un matchmaking pour permettre aux différents joueurs de pouvoir se connecter et de jouer les uns contre les autres.
Ce sera certainement pour l’article suivant !

Lucas
 
Lucas est un stagiaire en développement. Il a travaillé avec Matthieu sur le projet de Conseil de Guerre en ligne.
 

1 reply on “Un stage autour de Conseil de Guerre en ligne”

    1. Stage programmation interfaçage Unity site web – Blog Projet CarTylion

      […] Les essais m’ont permis d’apprendre beaucoup sur la programmation réseau (Rpc, command expliqué dans l’article de Lucas), j’ai également pu améliorer ma conception en architecture logicielle […]
      – Article Stage programmation interfaçage Unity site web

      0 j'aime

Laisser un commentaire

Cette section n'est pas encore disponible.

Mot de passe oublié ?

Vous n'avez pas encore de compte ?

Créer un compte

Pour rester informé-e des évolutions du site, laissez-nous votre email.

À bientôt !