Jeux Vidéo en Réseau : Technologies, Relation avec les Systèmes Intelligents Distribués - Projet Bibliographique
←
→
Transcription du contenu de la page
Si votre navigateur ne rend pas la page correctement, lisez s'il vous plaît le contenu de la page ci-dessous
GALLIOT Nicolas année 2004/2005 RASPILAIRE David Projet Bibliographique Jeux Vidéo en Réseau : Technologies, Relation avec les Systèmes Intelligents Distribués 1 1
Master Professionnel Systèmes Informatiques et Réseaux TABLE DES MATIERES INTRODUCTION................................................................................................................................................... 3 1. L’ARCHITECTURE DU JEU EN RÉSEAU .................................................................................................. 4 1.1. LE PEER-TO-PEER.............................................................................................................................................. 4 1.1.1. Définition ..............................................................................................................................................4 1.1.2. Avantages et inconvénients................................................................................................................... 5 1.1.3. Un exemple............................................................................................................................................5 1.2. L’ARCHITECTURE CLIENT-SERVEUR........................................................................................................................6 1.2.1. Définition ..............................................................................................................................................6 1.2.2. Avantages et inconvénients................................................................................................................... 7 1.2.3. Une architecture client-serveur avancée : Unreal............................................................................... 9 1.2.4. Un exemple............................................................................................................................................9 2. LES SYSTÈMES DISTRIBUÉS & LEUR APPLICATION ........................................................................11 2.1. PRÉSENTATION DES DIFFÉRENTES TOPOLOGIES EXISTANTES...................................................................................... 11 2.1.1. La topologie centralisée...................................................................................................................... 11 2.1.2. La topologie en anneau.......................................................................................................................12 2.1.3. La structure hiérarchique....................................................................................................................12 2.1.4. La topologie décentralisée.................................................................................................................. 13 2.2. LE «JEU DISTRIBUÉ»......................................................................................................................................... 13 2.2.1. Définition des dispositifs nécessaires..................................................................................................14 2.2.2. Exemple de mise en place d'un tel système......................................................................................... 15 3. UN EXEMPLE D'API ..................................................................................................................................... 18 3.1. PRÉSENTATION DE DIRECTX..............................................................................................................................18 3.1.1. Pourquoi Direct X ?............................................................................................................................ 18 3.1.2. Les services rendus par DirectX......................................................................................................... 19 3.2. L'INTERFACE DIRECTPLAY................................................................................................................................ 19 3.2.1. Les services fournis............................................................................................................................. 19 3.2.2. Fonctionnement de DirectPlay........................................................................................................... 20 JOUEURS DANS DIRECTPLAY.....................................................................................................................................20 MESSAGES DANS DIRECTPLAY..................................................................................................................................21 3.3 EXEMPLE D'IMPLÉMENTATION.............................................................................................................................. 21 CONCLUSION......................................................................................................................................................22 BIBLIOGRAPHIE................................................................................................................................................ 23 ANNEXE A............................................................................................................................................................ 24 2 2
Introduction L'explosion de l'Internet dans les années 90 et la chute considérable de la valeur du matériel hardware ont poussés les studios de création de jeux vidéo à prendre en considération l'aspect multijoueur dans le développement de leurs jeux. Et pour cause, d'après un article du Journal du Net, plus de 20 millions de joueurs génèrent plus de 1,8 milliards de dollars par an. Ce phénomène encore réservé aux ordinateurs s'est aujourd'hui répandu au monde des consoles (Xbox, PS2, GameCube...). Si quinze ans auparavant la durée de vie d'un jeu se limitait à l’exécution de son déroulement linéaire et variait proportionnellement à son niveau de difficulté, l'ajout d'une dimension multijoueur en ligne a permis d'augmenter considérablement cette durée de vie. Nous avons voulu nous intéresser plus profondément à ce phénomène, de sa naissance jusqu'à aujourd'hui et comprendre son principe de fonctionnement, en prenant l'exemple d'une API largement répandue pour le développement de jeux: Direct X. 3 3
1. L’architecture du jeu en réseau La sortie de Doom en 1993 marque l’avènement du jeu vidéo en réseau. Pour la première fois il est possible de jouer à plusieurs sur sa propre machine, à un jeu d’une durée de vie supérieure à celle de pong ou de frog. Trois années plus tard, en 1996, sort le mythique Duke Nukem 3D basé sur le même moteur que Doom et reprenant la possibilité de jouer à plusieurs en simultané. Ces deux jeux utilisent la même architecture pour le multijoueur, le Peer-to-Peer. Par la suite, le développement incessant des jeux en ligne conduit finalement à la naissance de Quake, qui bouleverse le monde du jeu multijoueur en proposant une architecture en client/serveur et non plus en peer-to-peer. Grâce à cette nouvelle architecture, les joueurs ne sont plus limités à un réseau local, mais peuvent jouer à travers le Net. Enfin, en 1999 sort Unreal Tournament qui révolutionne l’industrie toujours montante du jeu vidéo en réseau en améliorant considérablement l’architecture client-serveur. De nos jours, c’est cette architecture qui est utilisée dans le développement du module réseau des jeux multijoueurs. 1.1. Le Peer-to-peer 1.1.1. Définition Peer-to-peer: adj. Modèle de communication dans lequel chaque partie dispose des mêmes capacités et peut initialiser une session de communication, contrairement aux modèles dit "client / serveur". On peut établir une communication peer-to-peer en donnant à chaque utilisateur, dans un même protocole de communication, les capacités d'être client et serveur simultanément, directement ou au travers de réseaux comme Internet. Les premiers jeux multijoueurs, comme Doom ou Duke Nukem, se basent sur une architecture peer-to-peer pour la gestion du mode multijoueur, dans laquelle chaque machine est l’égale des autres. 4 4
Dans ce type d’architecture, deux ou plusieurs machines dialoguent ensemble, chacune exécutant le jeu dans son intégralité et échangeant uniquement des données en entrée. Ainsi, chaque machine synchronise ses entrées et son timing avec les autres, et envoie la même logique de jeu. Dans ce système complètement déterministe, chaque joueur perçoit la même réalité sur son écran. 1.1.2. Avantages et inconvénients L’architecture peer-to-peer réduit le trafic sur le réseau à son strict minimum, mais comporte un certain nombre d’inconvénients. En priorité il faut savoir faire face à la perte de paquets, détail dont l’importance augmente proportionnellement au nombre de joueur. Une donnée perdue entraîne une vue différente du jeu entre deux machines, et la synchronisation se perd. Par exemple, une machine n’a pas reçu l’information indiquant que l’ennemi A était détruit et quelques secondes plus tard, le joueur se fait tuer par A. Cet inconvénient impose un nombre limité de joueurs afin de ne pas perturber le déroulement de la partie (généralement 8 joueurs maximum). Les anciens joueurs de Doom se rappelleront les freezes du jeu pendant une partie multijoueur. Par ailleurs cette architecture manque de persistance, car tous les joueurs doivent démarrer le jeu ensemble, et aucun ne peut s’y ajouter par la suite. Enfin, le jeu s’exécutant intégralement sur chaque machine, tous les joueurs tournent à la même framerate interne, qui varie selon la puissance des machines. Une machine trop lente ralentira donc tous les autres joueurs. 1.1.3. Un exemple A titre d’exemple nous prendrons le jeu Starcraft, édité par Blizzard en 1998, qui utilise l’architecture peer-to-peer pour la gestion du mode multijoueur. En résumé, Starcraft est un jeu de stratégie dans lequel 3 races s’affrontent pour le contrôle d’une planète (à la manière du populaire Age of Empires). Dans une partie confrontant plusieurs joueurs, chaque client contrôle une race et envoie périodiquement ses actions aux autres joueurs qui mettent à jour leurs propres données du jeu. L’utilisation du peer-to-peer permet de limiter l’encombrement du réseau en envoyant un minimum de données. Le schéma suivant synthétise la bande passante utilisée en fonction du temps et du nombre de joueurs. 5 5
1.2. L’architecture client-serveur 1.2.1. Définition Client-serveur: nm. Modèle d'interaction entre systèmes distribués où les échanges sont de type question-réponse. Dans le monde TCP/IP, ces applications utilisent le protocole RPC. Un logiciel serveur est un programme qui offre un service sur le réseau. Le serveur accepte des requêtes, les traite et renvoie le résultat au demandeur. Le terme serveur s'applique à la machine sur laquelle le logiciel serveur s'exécute (de manière permanente). Un logiciel client est un programme qui utilise le service offert par un serveur. Le 6 6
client envoie une requête et reçoit une réponse. Le client peut être connecté de manière temporaire. Après le succès phénoménal de Doom et Duke Nukem, le développement des jeux en réseau conduit à l’éclosion de plusieurs « Doom-like », notamment Heretic, Hexen, et bien évidemment Doom II. Le 4 mai 1996, le monde assiste à la naissance de Quake et à la première architecture en client-serveur pour un jeu en réseau. Peu de temps après, Origin Systems s’inspire de ce système pour développer son mythique MMORPG Ultima Online. Dans une architecture client-serveur, une machine est désignée comme « serveur » et est responsable de toutes les décisions du jeu. C’est le serveur qui détermine l’état courant du jeu et qui décide de ce que chaque client doit, ou non, afficher. Les autres machines « clientes » agissent comme des simples terminaux de rendu, qui envoient les impulsions des touches au serveur, puis en reçoivent une liste d’objets à rendre. Le client reçoit également des informations sur la trajectoire de ces objets afin d’en prévoir les mouvements futurs. Cette nouvelle architecture a permis d’étendre le multijoueur au réseau Internet mondial, notamment grâce à l’éclosion simultanée de plusieurs serveurs de jeux (Zonejeux.com, Goa, etc.). Elle a été agrandie par la suite dans les extensions QuakeWorld et Quake 2, bénéficiant d’une nouvelle logique de simulation et de prédilection à chaque client, dans le but d’améliorer les détails visuels tout en réduisant l’occupation de bande passante. 1.2.2. Avantages et inconvénients Le principal avantage de l’architecture client-serveur est que chaque machine possède exactement la même vision du jeu, puisque le « traitement » de celui-ci ne s’effectue qu’à un seul endroit (sur le serveur). Ce procédé résout le problème de synchronisation du peer-to-peer où deux personnes peuvent avoir une vision différente du jeu. Mais, comme pour le peer-to-peer, malgré les avantages indéniables du modèle client-serveur, il comporte plusieurs inconvénients. En premier lieu, il est nécessaire d’avoir une machine serveur suffisamment puissante pour gérer le traitement de chacun des clients connectés, ainsi qu’une connexion réseau assez rapide pour que chaque client reçoive ses nouvelles données dans le délai imparti. De plus, cette architecture manque d’ouverture car quand un utilisateur crée un nouveau type d’objet (via l’éditeur approprié), une nouvelle logique doit être écrite afin d’en spécifier la simulation et la prédiction des mouvements (ou/et du comportement). Enfin, dans ce modèle le code du jeu et du réseau appartiennent à des modules différents, mais doivent connaître la syntaxe exacte de l’implémentation de l’autre, pour conserver la synchronisation du jeu. 7 7
1.2.3. Une architecture client-serveur avancée : Unreal L’arrivée de jeu Unreal Tournament en 1999 introduit une nouvelle approche du jeu en réseau et détrône le modèle client-serveur classique. Dans ce nouveau modèle, le serveur prend toujours en charge l’évolution de l’état du jeu mais le client va cette fois conserver une sélection pertinente des données du jeu afin de prévoir l’avancement de celui-ci en exécutant le même code que le serveur, sur approximativement les mêmes données, minimisant ainsi le nombre d’échanges entre les deux machines. Cet « état du jeu » est décrit par un langage orienté objet extensible qui démarque intégralement le code réseau du jeu. Le code réseau est généralisé de façon à pouvoir se coordonner avec n’importe quel autre jeu basé sur le même langage. Les possibilités d'extension d'un objet sont considérablement augmentées par cette méthode, puisque la structure de celui-ci le décrit intégralement, sans introduire de dépendances sur d’autres parties de codes reliées pour connaître l’implémentation interne de cet objet. 1.2.4. Un exemple Pour illustrer ce mode client-serveur, nous nous baserons sur le fameux Counter-Strike. Ici, les clients envoient leurs données uniquement au serveur qui maintient l’état courant du jeu et envoie des mises à jour régulières à toutes les machines connectées. Les schémas ci-dessous décrivent respectivement la bande passante utilisée par un client, puis par le serveur. 8 8
9 9
2. Les systèmes distribués & leur application Cette partie traite du concept de «jeu distribué» (Distributed Game en anglais). Le jeu distribué permet la spécification des niveaux d'applications de ressources dans une conception de jeu. Ces ressources sont distribuées à travers un réseau de stations où celles-ci peuvent servir des ressources identiques. Par un rapport de confiance, ces stations peuvent en localiser dynamiquement une autre et déterminer individuellement les meilleures ressources fournies par leur propre vue du réseau. Ceci permet un degré élevé de scalabilité, flexible et spécifique à chaque ressource. De ce fait, le jeu distribué permet l'utilisation de toute la largeur de la bande passante sur le réseau. Le but de cette partie sera donc de montrer en quoi l'utilisation de la distribution fait progresser nettement les jeux intensifs de réseau. Pour cela, nous allons tout d'abord définir les différentes topologies de réseaux distribués que l'on peut mettre en place, puis dans une deuxième partie nous présenterons la configuration d'un jeu distribué proprement dit. 2.1. Présentation des différentes topologies existantes 2.1.1. La topologie centralisée La topologie la plus commune que nous voyons sur Internet est centralisée. Cette conception est étroitement associée au modèle "Client/Serveur", où un serveur centralisé contrôle toutes les ressources disponibles pour la consommation de clients. La plupart des applications de bases de données et de jeux en ligne emploient un tel modèle. Il permet en effet de mettre en place une administration simplifiée, il présente une certaine facilité d'entretien et également une facilité de localisation des ressources. En revanche, cette topologie reste difficile à évaluer correctement et son coût est élevé. De plus il n'y a pas ou peu de redondance dans ce type de structure. 10 10
2.1.2. La topologie en anneau Dans une topologie typique d'anneau, plusieurs serveurs identiques sont reliés ensemble dans une boucle. Ceci permet un très bon degré de scalabilité et permet une certaine souplesse des taux de transfert, s'adaptant facilement à la demande croissante des clients. Pour faciliter cela, des serveurs mettant en application des topologies d'anneau sont placés sur un pied d’égalité pour la fiabilité. Cette topologie présente une certaine redondance et un équilibrage des charges assez simple. Elle dispose aussi d'un bon degré de scalabilité, bien que celle-ci soit limitée au niveau matériel. Les inconvénients principaux de cette structure demeurent d'une part le coût plus élevé de propriété par rapport au modèle centralisé, d'autre part une difficulté particulière à ajouter plus de ressources. 2.1.3. La structure hiérarchique Les topologies hiérarchiques possèdent une structure arborescente où l'importance est indiquée par la profondeur à laquelle un noeud ou une "feuille" est placé. Le noeud le plus important (donc qui «domine»), appelé la "racine", est situé au dessus de l'arbre. Les noeuds plus bas prennent généralement l'instruction des noeuds de plus haut niveau, donnant une forme très structurée de communication et de commande. Cette structure possède donc l'avantage de posséder des flots de communications structurés. De plus, les ressources peuvent être localisées rapidement et peuvent se trouver dans des endroits disparates. La disponibilité des informations peut parfois être limitée. La propagation de données erronées peut se produire et il reste difficile de prolonger et d'ajouter de nouvelles ressources, à l'instar de la topologie en anneau. 11 11
2.1.4. La topologie décentralisée Dans une topologie décentralisée, toutes les unités sont égales. Elles reproduisent le plus souvent les mêmes ressources avec des raccordements entre les unités non structurés et dynamiques. Les applications décentralisées sont aisément extensibles, mais sont les plus difficiles à contrôler. D'autre part cette topologie est très tolérante aux erreurs et permet d'ajouter dynamiquement de nouvelles ressources. Toutefois, les frais généraux de scalabilité peuvent être grands, il est difficile de synchroniser les données et l'état du système et il est également très difficile de contrôler toutes les ressources. La plupart des applications réparties modernes adoptent une approche hybride qui vise à utiliser les principaux avantages des topologies combinées tout en limitant les difficultés. 2.2. Le «jeu distribué» Les premiers jeux en réseau ont adopté une approche topologique centralisée. Il s'agissait du choix le plus évident vu la conception courante de jeu qu'on souhaitait rendre disponible sur le réseau. Le modèle "Client/Serveur" était bien connu dans d'autres applications de logiciels et ses méthodes pour combattre la latence et le scalabilité restait l’achat de nouvelles ressources … Pour de petits jeux de réseau, un modèle client serveur reste toujours un choix populaire. Cependant, il devient rapidement difficile à manier en essayant de partager et de faire cohabiter des milliers d'utilisateurs concourants. Des goulots d'étranglement évidents se produisent et la jouabilité globale s'en trouve dégradée. Il est intéressant de noter que le jeu en ligne peut apprendre beaucoup des enseignements tirés du développement du commerce en ligne (appelé également e-commerce), ce dernier possédant plusieurs caractéristiques communes au jeu en ligne. Si nous parlons de l'état d'information de produit dans un système de commerce en ligne ou de l'état de l'environnement (ou plutôt de l'univers) dans un jeu en ligne, les questions de la scalabilité, de la fiabilité et de la disponibilité demeurent identiques. 12 12
Tirant des services d'enchaînement et de la gestion de réseau de stations, nous pouvons envisager un modèle pour le jeu en ligne avec les dispositifs suivants: • Ressources redondantes spécifiques au jeu. • Un mécanisme pour la découverte de ces ressources. • La capacité de commuter dynamiquement entre les ressources qui fournissent le même service ou informations. • Un rapport de confiance entre les ressources et la métrique mesurant la confiance. 2.2.1. Définition des dispositifs nécessaires Pour faciliter ces dispositifs, nous définissons ce qui suit: La Ressource: L'encapsulation d'une source spécifique de détail de l'information ou de service à un jeu. Toute l'ampleur d'une application de jeu est l'addition de toutes les ressources uniques. Toutes les ressources partagent ces spécificités: • Uniquement identifiable. • Localisable. • Capacité de communiquer avec d'autres ressources. • Capacité de synchroniser l'état interne avec d'autres ressources semblables. Le Fournisseur: Un poste qui fournit une ressource unique aux consommateurs. Le Consommateur: Un poste qui cherche le service ou l'information d'un autre poste qu'il considère "digne de confiance" à un certain degré (mesurable). Un consommateur peut être n'importe quel poste dans le réseau, y compris ceux qui sont également des fournisseurs. Le poste de confiance: Un fournisseur qui, avec le temps, a fourni un degré d'information ou de service conforme de sorte qu'il soit considéré relativement "digne de confiance" par un consommateur spécifique. La confiance est mesurée par une combinaison de la métrique (qui représente la fiabilité) et la disponibilité d'information ou de service que le poste de confiance fournit au consommateur. En tant que telle, cette métrique est calculée du point de vue du consommateur mais peut être partagée avec d'autres consommateurs pour établir un "réseau de confiance" parmi tous les consommateurs cherchant la même ressource. Le Registre: Un type spécifique de fournisseur qui contrôle la découverte et la localisation de tous les types de ressources. Il est exigé de tous les fournisseurs qu’ils donnent des informations à un registre qui les identifie uniquement dans le 13 13
réseau et qu’ils décrivent le type d'information ou de service qu'ils fournissent. Les registres maintiennent une carte des ressources disponibles; ainsi les registres ont des moyens de connaître les ressources spécifiques nécessaires et les fournisseurs disponibles. Le Réseau De Jeu: Un réseau des ressources qui représentent toutes les fonctionnalité, services et informations pour une application spécifique de jeu. L'état du jeu est l'état collectif des différentes ressources à n'importe quel instant. Les ressources multiples existent, reproduisant la même information ou le même service. Les ressources peuvent découvrir et en localiser une autre grâce au registre (cf. ci-dessus). Elles peuvent alors activement communiquer entre elles et dynamiquement déterminer les plus disponibles et les plus fiables du point de vue unique du réseau (basé sur un rapport mesurable de confiance). La scalabilité est dynamiquement augmentée lorsque des ressources plus redondantes sont présentées au réseau, sont découvertes par d'autres consommateurs, et augmentent leur degré de confiance. De même, le réseau de jeu voit ses fonctionnalités étendues par l'introduction de nouveaux types de ressources. Le Jeu: Une application qui se compose d'une collection dynamique de ressources uniques fournies par le réseau de jeu. Les ressources spécifiques qui permettent la mise en place du jeu au niveau de l'utilisateur peuvent changer à tout moment mais doivent toujours fournir les services et informations les plus fiables et pour la plupart les plus disponibles. La commutation des ressources doit être transparente à l'utilisateur. À tout moment la vue et l'utilisation du jeu par l'utilisateur doivent être constantes et non interrompues par la commutation des ressources. 2.2.2. Exemple de mise en place d'un tel système Supposons que nous avons une structure de jeu multijoueur, en ligne, et un jeu de rôle typique (MMORPG). Nous pouvons définir les dispositifs et la fonctionnalité de ce jeu comme ensemble de ressources uniques (Diagramme1): • Map System: Le monde dans lequel on évolue. • Events System: Le système qui gère ce qui est fonction du temps, tels que le temps ou ce qui évolue dans l'environnement. • Player System: La gestion du joueur et de ses informations. • NPC System: La gestion des personnages non commandés par l'utilisateur (les «Non Player Characters»). • Time System: L'horloge globale. Une simple ressource pour synchroniser le temps pour toutes les ressources. Avec ces quelques ressources, nous avons une représentation de la majorité des MMORPG que l'on peut trouver aujourd'hui. Pour qu'un joueur intègre le jeu, il doit localiser les fournisseurs de ces 5 ressources (ce qui nécessite bien sûr, un 14 14
registre de ressources, comme décrit précédemment). Dans de nombreux MMORPG, on réalise rapidement que l'on doit gérer des milliers d'utilisateurs, parfois même plus. De ce fait, le jeu en réseau doit inclure plus de ressources redondantes dans le système de jeu. Quand un des joueurs se connecte, le système de jeu va localiser une ressource disponible à partir du registre. Le partage du réseau pour permettre la cohabitation d'encore plus de joueurs requiert simplement l'ajout de nouveaux fournisseurs. De la même façon, les autres ressources peuvent évoluer si la demande augmente. Cependant, pour les ressources simples et fournisseurs qui peuvent également en servir d’autres, des ressources plus complexes peuvent contrôler ceci. Le système d'horloge en est un bon exemple. Toutes les ressources, même le système de jeu qui représente les joueurs eux-mêmes, peuvent être les fournisseurs de l'horloge globale. Ceci permet la synchronisation de toutes les ressources entre elles. Quand le joueur interagit avec l'application correspondant au jeu, le système doit s'adapter en confiant à l'utilisateur une vue unique du réseau à un moment précis. En effet, le jeu lui-même doit pouvoir ajouter de nouvelles fonctionnalités au fur et à mesure de la progression du joueur dans la partie. Ceci représente peut-être la plus grande performance des jeux distribués: la possibilité de partager et d'évoluer simultanément sans pour autant perturber le jeu et la partie. Plus il y a de ressources introduites dans le jeu, meilleur sera le jeu. 15 15
Diagramme 1: Le réseau entier pour notre exemple de jeu MMORPG consiste en six systèmes distincts qui contiennent des ressources redondantes. 16 16
3. Un exemple d'API DirectX est le moyen rêvé pour la conception de jeux. Aujourd'hui le matériel ne cesse d'évoluer ; aucun secteur de l'informatique n'a connu de croissance aussi importante que celle de la carte vidéo. Parallèlement d'autres secteurs multimédias comme le son, les vidéos, les périphériques E/S (entrée / sortie) ou même le Web sont aussi en plein essor. Il faut donc une API capable de s'adapter facilement à cette dynamique tout en restant simple et efficace : c'est la définition même de DirectX. On trouve actuellement une multitude de kits de développements et d'outils permettant le développement d'un ou plusieurs de ces domaines. Pourtant aucun n'égale DirectX. DirectX fournit un jeu de composant permettant le développement d'applications comportant des données 2D, 3D, sonores, Web, vidéos, musicales, réseaux, ... 3.1. Présentation de DirectX 3.1.1. Pourquoi Direct X ? A l'origine, DirectX (qui fut nommé initialement Game SDK) répond au problème de la diversité des configurations matérielles existant chez les utilisateurs de PC. Grâce à son API, Microsoft permet aux développeurs de s'affranchir totalement du travail qui consiste à rendre leurs programmes compatibles avec tous les types de configuration. Avant DirectX, le développeur était confronté directement au matériel (hardware). L'utilisation de cette API permet de développer sans prendre en compte la configuration matérielle qui sera utilisée puisque c'est elle qui gère le dialogue entre l'application et le matériel : c'est le principe de la portabilité. Aussi, c'est avec l'arrivée de Windows 95 que s'est fait ressentir le besoin d'une API générique. Avant cela, la plupart des jeux étaient développés pour DOS. Avec l'expansion du nouveau système d'exploitation, les développeurs ont dû se pencher sur le problème de la programmation sous Windows, mais se sont heurtés à un problème : comment créer des applications rapides (en plein écran, avec des sons en temps réel, ...) connaissant le nombre important de "couches" entre Windows et le matériel (contrairement au DOS) ? DirectX est la réponse de Microsoft à ce problème. Etant données la position dominante de Microsoft dans l'univers de l'informatique et l'utilisation extrêmement répandue de son OS, il était indispensable pour les fabricants de matériels de suivre le mouvement imposé par la "toute-puissante" société, et de développer des drivers (pilotes) pour leurs matériels. La version actuelle de DirectX (9.0c) est basée sur l'architecture COM et se présente sous la forme d'interfaces. 17 17
3.1.2. Les services rendus par DirectX Direct3D est un moteur de rendu 3D fournissant des services élémentaires afin de faciliter le travail des applications dans la création de scènes 3D. Un format de fichier Direct3D permet de stocker les éléments d'une scène, les descriptions de mouvement et de rendu. Les développeurs disposent d'outils leur permettant de convertir des fichiers 3DS ou Autocad vers le format Direct3D. DirectSound fournit des sons stéréo et 3D à faible temps de latence avec mixage au niveau matériel, ainsi que la gestion mémoire pour la carte son. Ce module virtualise la carte son et ses attributs (buffers, mixage) afin de permettre à une application de gérer n'importe quelle carte de la même manière. Les services fournis permettent de charger des buffers avec des sons, de les jouer, de les mixer et de les synchroniser ensemble. Un son volumineux est automatiquement découpé par le système en morceaux compatibles avec la taille du buffer. Enfin, une extension DirectSound3D permet la restitution de sons spatialement localisés avec seulement deux enceintes, afin d'obtenir des effets spéciaux plus percutants. DirectPlay offre une interface homogène pour synchroniser les jeux entre plusieurs joueurs connectés par modem, par liaison série, sur un réseau local ou sur Internet (support des protocoles point à point et TCP/IP). Des fonctions permettent de déclarer un joueur dans une session et de reporter son activité auprès des autres joueurs. Cette interface étant responsable de la connectivité en réseau, nous allons nous y intéresser plus particulièrement. 3.2. L'interface DirectPlay DirectPlay est une couche au-dessus des protocoles réseaux normaux (IPX, TCP/IP, etc..). Une fois que le rapport est établi, il est possible d'envoyer des messages sans forcément savoir à quoi l'utilisateur se relie. 3.2.1. Les services fournis Les fournisseurs de services sont à la base de la communication en mode multijoueur. Ils régulent les données en passant par les modules de Windows tel que WinSock (pour TCP/IP), ou TAPI (modem à modem). DirectPlay propose en standard 4 fournisseurs de services (service providers) - Connexion Internet TCP/IP: nombre de joueurs illimité en théorie (en pratique 8 joueurs représente déjà beaucoup, mais cela dépend de la "bande passante" du serveur). Quand un utilisateur rejoint une session, il doit donner l'adresse IP 18 18
de l'ordinateur qui a créé la partie. - Connexion Modem-à-Modem: relie deux utilisateurs par une communication téléphonique. Pour rejoindre une session, l'utilisateur doit donner le numéro de téléphone de l'utilisateur de l'ordinateur qui a créé la partie. - Connexion Série : relie deux ordinateurs avec un câble. L'utilisateur doit donner des informations sur la connexion telles que la vitesse en bauds, le protocole (Xon, Xoff...). - Connexion IPX : relie des ordinateurs qui sont en réseaux. 3.2.2. Fonctionnement de DirectPlay Sessions dans DirectPlay Une session de DirectPlay est une voie de transmission entre plusieurs ordinateurs. Une application doit faire partie d'une session avant qu'elle ne puisse communiquer avec d'autres machines. Une application peut joindre une session existante ou créer une nouvelle session et attendre des personnes pour la joindre. Chaque session a un et seulement un serveur central, qui est l'application qui la crée. Seul le serveur central peut changer les propriétés de session. Le mode par défaut des sessions est peer-to-peer, l'autre mode est client/server. Joueurs dans DirectPlay Une application doit créer un joueur pour envoyer et recevoir le message. Des messages sont toujours dirigés vers un joueur et non vers l'ordinateur. Chaque message envoyé est dirigé vers un joueur spécifique et chaque message reçu est dirigé vers un joueur local spécifique (à l’exception des messages système). Des joueurs sont identifiés seulement en tant que locaux ou extérieur. On peut également grouper des joueurs dans une même session, ainsi n'importe quel message envoyé sera dirigé automatiquement vers le groupe. Cette technique est très utile pour des jeux où il est possible de s'allier avec d'autres et où l'on veut envoyer des messages seulement à ses alliés. 19 19
Messages dans DirectPlay Une fois la session et le joueur créés, il est possible de commencer à envoyer des messages. Chaque message envoyé est marqué pour un joueur local spécifique et peut être envoyé à n'importe quel joueur. Chaque message reçu est placé dans une file d'attente pour ce joueur local. Puisqu'un seul joueur est créé, tous les messages appartiennent à ce joueur. L'application peut choisir la file d'attente de réception pour les messages ou employer une file séparée pour chaque événement. Il existe deux types de messages: joueur et système. Les messages de joueur ont un expéditeur et un récepteur. Des messages système sont envoyés à chaque joueur et sont marqués « envoyés à partir du système » (DPID_sysmsg). Le DP représente DirectPlay, identificateur pour l'identification. Des messages système sont produits quand l'état de session est changé, c'est à dire quand un nouveau joueur joint la session. Des dispositifs de sécurité peuvent être implémentés en utilisant l'interface de fournisseur de soutien de sécurité (SSPI) sur des fenêtres. Ces messages sont chiffrés. 3.3 Exemple d'implémentation A titre indicatif, nous nous sommes penchés sur l'élaboration d'un petit programme en utilisant DirectPlay, basé sur des ressources que nous avons trouvé sur l’Internet. Une partie de ces sources est disponible en annexe A. 20 20
Conclusion Ces recherches nous ont permis de mieux comprendre le rôle prépondérant que joue le développement des nouvelles technologies de l'Internet dans l'évolution des jeux vidéo. Etroitement liée au progrès des composants hardware, l'API développée par Microsoft DirectX paraît répondre aux problèmes de compatibilité qui se posent lors de la création de nouveaux jeux. Après une étude approfondie des différentes topologies client-serveur utilisées actuellement, celles-ci nous semblent propices à d’autres types d’applications. Par exemple, le moteur Unreal partage l’exécution du jeu entre les différents clients, réduisant considérablement l’utilisation de ses ressources mémoires. 21 21
Bibliographie DirectX – L. Deruelle, Micro Application Ressources en ligne http://www.francedev.com/cours/directx_1.asp http://perso.club-internet.fr/galban/ http://prografix.games-creators.org/document/48 http://castelain.developpez.com/articles/DirectX9/ http://www.microsoft.com/france/msdn/technologies/technos/directx http://www.gamedev.com/ http://www.loonygames.com/content/2.10/feat/ http://www.extremetech.com/article2/0,1558,482,00.asp http://clootie.narod.ru/delphi/download_custom.html http://www.zoneprog.com/directx/index.php http://www.programmationworld.com/site/Cours.asp?Action=cours&Numero=60 http://portal.acm.org/citation.cfm?id=566506 http://forum.clubic.com/forum1.php?config=clubic.inc&cat=20 http://www.cs.wpi.edu/~claypool/papers/net-game/ http://maxblumberg.typepad.com/dailymusings/networking/ 22 22
Annexe A Création de la connexion TCP int Create_TCP_Connection(char *IP_address) { LPDIRECTPLAYLOBBYA old_lpdplobbyA = NULL; DPCOMPOUNDADDRESSELEMENT Address[2]; DWORD AddressSize = 0; LPVOID lpConnection= NULL; CoInitialize(NULL); if ( CoCreateInstance(CLSID_DirectPlay, NULL, CLSCTX_INPROC_SERVER, IID_IDirectPlay3A,(LPVOID*)&lpdp ) != S_OK) { CoUninitialize(); return(0); } DirectPlayLobbyCreate(NULL, &old_lpdplobbyA, NULL, NULL, 0); old_lpdplobbyA->QueryInterface(IID_IDirectPlayLobby2A, (LPVOID *)&lp- dplobby)); old_lpdplobbyA->Release(); Address[0].guidDataType = DPAID_ServiceProvider; Address[0].dwDataSize = sizeof(GUID); Address[0].lpData = (LPVOID)&DPSPGUID_TCPIP; Address[1].guidDataType = DPAID_INet; Address[1].dwDataSize = lstrlen(IP_address)+1; Address[1].lpData = IP_address; lpdplobby->CreateCompoundAddress(Address, 2, NULL, &Address_Size); lpConnection = GlobalAllocPtr(GHND, AddressSize); lpdplobby->CreateCompoundAddress(Address, 2, lpConnection, &Address_Size); lpdp->InitializeConnection(lpConnection, 0); GlobalFreePtr(lpConnection); return(1); } Création de Session BOOL FAR PASCAL EnumSessionsCallback(LPCDPSESSIONDESC2 lpThisSD, LPDWORD lpdwTimeOut, DWORD dwFlags, LPVOID lpContext) { HWND hwnd; if (dwFlags & DPESC_TIMEOUT) return(FALSE); hwnd = (HWND) lpContext; return(TRUE); } 23 23
int EnumSessions(HWND hwnd, GUID app_guid, DWORD dwFlags) { DPSESSIONDESC2 session_desc; ZeroMemory(..); lpdp->EnumSessions(&session_desc, 0, EnumSessionsCallback, hwnd, dw- Flags); return(1); } Envoi de messages const DWORD DP_MSG_CHATSTRING = 0; typedef struct DP_STRING_MSG_TYP { DWORD dwType; char szMsg[1]; } DP_STRING_MSG. *DP_STRING_MSG_PTR; int DP_Send_String_Mesg(DWORD type, DPID idTo, LPSTR lpstr) { DP_STRING_MSG_PTR lpStringMsg; DWORD dwMessageSize; dwMessageSize = sizeof(DP_STRING_MSG)+lstrlen(lpstr); lpStringMsg = (DP_STRING_MSG_PTR)GlobalAllocPtr(GHND, dwMessageSize); lpStringMsg->dwType = type; lstrcpy(lpStringMsg->szMsg, lpstr); lpdp->Send(local_player_id,idTo, DP_SEND_GUARANTEED, lpStringMsg, dwMessageSize); GlobalFreePtr(lpStringMsg); return(1); } Réception de Messages : void Receive_Mesg() { DPID idFrom, idTo; LPVOID lpvMsgBuffer = NULL; DWORD dwMsgBufferSize; HRESULT hr; DWORD count = 0; lpdp->GetMessageCount(local_player_id , &count); if (count == 0) return; do { do { idFrom = 0; idTo = 0; hr = lpdp->Receive(&idFrom, &idTo, 0, lpvMsgBuffer, &dwMsgBuf- ferSize); if (hr == DPERR_BUFFERTOOSMALL) { 24 24
if (lpvMsgBuffer) GlobalFreePtr(lpvMsgBuffer); lpvMsgBuffer = GlobalAllocPtr(GHND, dwMsgBufferSize); } } while(hr == DPERR_BUFFERTOOSMALL); if (SUCCEEDED(hr) && (dwMsgBufferSize >= sizeof(DPMSG_GENERIC) { if (idFrom == DPID_SYSMSG) Handle_System_Message((LPDPMSG_GENERIC)lpvMsgBuffer, dwMsgBuffersize, idFrom, idTo); else Handle_Appl_Message((LPDPMSG_GENERIC)lpvMsgBuffer, dwMsgBufferSize,idFrom,idTo); } } while (SUCCEEDED(hr)); if (lpvMsgBuffer) GlobalFreePtr(lpvMsgBuffer); } Gestion des Messages : int Handle_System_Message(LPDPMSG_GENERIC lpMsg, DWORD dwMsgSize, DPID idFrom, DPID idTo) { switch(lpMsg->dwType) { case DPSYS_SESSIONLOST: { } break; case DPSYS_HOST: { } break; case DPSYS_CREATEPLAYERORGROUP: { LPDPMSG_CREATEPLAYERORGROUP lp = (LPDPMSG_CREATEPLAYERORGROUP) lpMsg; } break; case DPSYS_DESTROYPLAYERORGROUP: // a lost player { LPDPMSG_DESTROYPLAYERORGROUP lp = (LPDPMSG_DESTROYPLAYERORGROUP) lpMsg; } break; default: } return(1); } int Handle_Appl_Message(LPDPMSG_GENERIC lpMsg, DWORD dwMsgSize, DPID idFrom, DPID idTo) { switch(lpMsg->dwType) { case DP_MSG_CHATSTRING: { DP_STRING_MSG_PTR lp = (DP_STRING_MGS_PTR)lpMsg; if (gameServer) 25 25
players { lpdp->Send(local_player_id,DPID_ALLPLAYERS, DPSEND_GUARANTEED, lp, dwMsgSize); } } break; default: } return(1); } Main if (gameServer) Create_TCP_Connection(""); else Create_TCP_Connection(tcp_address); if (gameServer) else { } if (gameServer) while(1) { if (PeekMessage(&msg,NULL,0,0,PM_REMOVE) { if (msg.message == WM_QUIT) break; } else { Receive_Mesg(); } } // end of while(1) DirectPlay_Shutdown(); 26 26
Vous pouvez aussi lire