Protocole réseau et broker Rust pour le jeux vidéo

page GitHub du projet

Contexte

         Le protocole RekT (Rapid Encrypted Knot Transfer) a été développé dans le cadre du cours de projet de la session d’hiver 2023 dispensé à l’UQAC (université du Québec à Chicoutimi) par Valère Plantevin. Le projet consistait à créer une simulation de plusieurs centaines de joueurs sur une seule carte de jeu en utilisant Unreal Engine. Le cours a été suivi par un groupe de 8 étudiants qui souhaitaient approfondir leurs connaissances en développement de jeux vidéo multijoueur en ligne. Le cours a adopté un format « recherche », ce qui signifie que nous étions laissés à nous-mêmes pour faire face à nos difficultés et apprendre à mieux comprendre de manière autonome les nouvelles technologies et concepts. Néanmoins, nous avions un rapport de progression hebdomadaire pour nous assurer que le projet avançait correctement.

Le groupe a été divisée en deux équipes. Une équipe « moteur de jeu » (5 personnes), était chargée de comprendre le fonctionnement de l’ECS (Entity Component System) Flecs afin de gérer les actions de tous les joueurs côté client. Ils devaient également remplacer la réplication d’Unreal Engine 5 pour prendre en charge le protocole développé par la deuxième équipe. Composée de trois personnes, la deuxième équipe « réseau », était chargée d’écrire un protocole pub/sub et de coder un broker (serveur) pour prendre en charge autant de connexions que possible avec une consommation minimale.

Dans ce projet j’ai pris part à la deuxième équipe et c’est pourquoi la suite de cette article présentera en détail la partie réseau du projet. 

Un travail en deux temps

         Pour notre équipe, le travail s’est déroulé en deux périodes. Il y a d’abord eu une phase de réflexion et de conception dans laquelle nous avons appris le fonctionnement des protocoles pub/sub et établie une liste des besoins d’un protocole réseau dans le jeux vidéo afin de pouvoir rédiger notre propre protocole dont vous pouvez retrouver la RFC ici. En suite, une deuxième phase est venue dans laquelle nous avons codé un broker qui utilise notre protocole afin de permettre à l’équipe « moteur de jeu » de réaliser des simulations de connexion jusqu’à atteindre les 300 joueurs et plus !

En bref, notre objectif c’est de chercher toujours plus de performance et d’optimisation !

Le protocole RekT

            Le protocole RekT (Rapid encrypted knot transfert) est un protocole réseau basé sur UDP, conçu pour répondre aux besoins de vitesse et d’optimisation des jeux vidéo multijoueurs avec un grand nombre de joueurs. Le protocole RekT s’inspire du protocole Tachyon et se concentre principalement sur la rapidité de transmission des données. Conscient des exigences spécifiques des jeux vidéo multijoueurs avec une grande quantité de joueurs (300+), RekT vise à minimiser les latences et à optimiser les performances du réseau.

          Lors de la connexion initiale, RekT utilise un système de handcheck pour s’assurer de l’authenticité des clients et les enregistré en tant que connexion valide sur le server. Une fois la connexion établie, le protocole fonctionne selon un modèle pub/sub (publication/abonnement) avec l’utilisation de topics (sujets) et d’objets (ensembles de topics). Cela permet aux clients de s’abonner aux sujets pertinents pour recevoir les données qui les intéressent.

        Pour simplifier la mise en œuvre du protocole, RekT ne prend pas en charge actuellement les systèmes d’autorité ou de chiffrement. Cependant, nous sommes conscient que la sécurité des données doit être prise en compte. Cella pourrait être ajoutée dans des versions ultérieures du protocole.

       Afin de maintenir une connexion active avec le serveur, les clients doivent envoyer périodiquement des requêtes ou des « heartbeat » (signe de vie) pour maintenir le contact lorsque aucune autre requête n’est nécessaire. Si un client ne maintient pas cette connexion, il sera déconnecté par le serveur.T

Pour la deuxième phase du projet nous avons tous les trois du découvrir et apprendre le langage de programmation Rust pour coder le broker. Ce défi de plus était optionnel mais fortement conseillé au vue des performances du langage et de ses aptitudes à optimiser la mémoire et l'asynchrone. Cela explique pourquoi le serveur a eu plusieurs versions ;)y
C'est ma petite tête sur cette photo
- Lucas
Le broker

        Le développement de la partie codage du serveur RekT a été réalisé de manière progressive, en surmontant le défi de maîtriser le langage de programmation Rust, avec lequel nous n’étions pas familier du tout au départ. Il se trouve que notre travail a pris la forme d’un projet avec 3 versions majeurs que je vais survoler plus bas. Vous pouvez consulter le dépôt GitHub pour voir le code.

Version 1 – Découverte du langage : Dans le dossier « GYM » du projet, nous nous sommes consacrée à la découverte du langage Rust. Cette étape était cruciale pour acquérir les connaissances de base, comprendre la syntaxe et assimiler les bonnes pratiques de programmation spécifiques à Rust. Dans cette version nous avons réussi a faire communiquer deux client entre eux sans le système de signe de vie (vérification du maintien de la connexion) ni le système de calcule du ping. En effet le broker étant synchrone cela nous empêché de faire plusieurs tâche en même temps. C’est pourquoi nous sommes passé à l’étape supérieur avec la version 2.

Version 2 – Premier broker asynchrone avec Tokio : Le dossier « Async_broker » a été dédié à la création de la première version fonctionnelle du broker en utilisant la bibliothèque Tokio pour la programmation asynchrone. Bien que toute les fonctionnalités étaient présente, cette version n’a pas su répondre aux attentes en termes de performances et de rapidité requises pour le protocole RekT. Notre manière d’utiliser les tâches asynchrone de Tokio ne nous a pas épargné sur la manière de partager les ressources entre elles ce qui a causé de nombreuse duplication de mémoire et surtout la création excessive de tache asynchrone simultané. Cela a mené à une génération exponentiel de la consommation de mémoire RAM et un usage du CPU disproportionné. 

Version 3 – Quête d’optimisation et patron de conception message : Le sous-dossier « Async_broker_message » a été consacré à la recherche d’optimisations supplémentaires pour le broker et à la correction des mauvais usage du langage. Nous avons adopté le patron de conception message pour améliorer la gestion des tâches asynchrones concurrentes ce qui nous a permis de diviser drastiquement le nombre de tâche simultané mais aussi de mieux gérer la propagation de variable entre tâches. Nous avons également revue les structures de donné commune à toutes les tâches pour éviter les clones et passer le plus possible par référence. Cette phase d’optimisation a été essentielle pour augmenter la capacité de traitement du broker et atteindre les performances requises par le protocole RekT et le projet de manière générale.

Le résultat du projet

          Afin de tester le travail des deux équipes, l’équipe « moteur de jeu » a crée un jeu très simple jouable par une IA qui consiste en un simple labyrinthe qui comporte des portes de couleur. Pour traverser ces portes vous devrez vous parer de la couleur de cette dernière grâce à une touche pour passer du d’une couleur à l’autre.

             Ce projeta été un succès pour nous car nous avons su mettre en place toutes les mesures nécessaires pour apprendre en autonomie les connaissance suffisante pour satisfaire les besoins du projet. Notre professeur a reconnu les efforts fourni et a salué le résultat fini qui est très satisfaisant !

Dans le gif ci-dessus on voit 300 IA répliqué qui jouent au jeux tout en étant synchronisé sur le réseau. On remarque que les mouvements sont fluide et cohérent malgré la latence et les possible lag du réseau.

Dans le gif ci-dessous on observe de plus prêt le comportement des IA au abord d’une porte rouge.

Merci d'avoir lu l'article

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *