L'architecture des MMORPGs

Concepts et Définitions

Nous allons maintenant nous intéresser aux mécanismes utilisés par les MMORPGs afin de pouvoir permettre aux joueurs d'interagir avec les serveurs de jeu. Les jeux multi-joueurs sont basés sur l'échanges de messages qu'on appellera évènements par la suite. Ces évènements peuvent contenir des informations sur les actions d'un joueur, d'un objet de l'IA, ou d'un changement d'état du monde. Lorsqu'un joueur ou une IA effectue une action, cette action ainsi que toutes les conséquences doivent êtres notifiées aux autres joueurs.

Mais notifier tous les joueurs sur le serveur serait un gaspillage de bande passantes, car en pratique tous les joueurs ne "verront" pas l'action, parcequ'un élément de décor les en empêche, ou parce qu'ils "regardent" ailleurs. On définit donc une zone d'intérêt , ou AoI (Area of Interest), autour de chaque joueur/IA. Le concept d'AoI permet de connaître quels sont les objets susceptibles de "voir" l'évènement. Ne seront notifiés que les joueurs présents dans l'AoI de l'auteur de l'évènement. Si l'évènement modifie de façon permanente l'état du monde, les clients qui n'ont pas été notifiés tout de suite le sont lorsqu'ils entrent dans la zone et que leur AoI entre en contact avec l'emplacement de l'élément du monde modifié. On réduit ainsi le pic de notifications lorsqu'un évènement est exécuté. Dans la suite de cet exposé, l'AoI des joueurs sera définie comme un cercle de rayon R centrée sur le joueur.


Communication Client-Serveur

Les échanges de messages entre les clients et les serveurs de jeu sont régis par un Design Pattern connu: Publish/Subscribe (voir figure ci-dessous). Dans ce pattern, les messages sont publiés par des publishers dans des topics différents suivant le contenu du message, son type, ou tout autre propriété comme son destinataire. Les Subscribers souscrivent à un ou plusieurs topics suivant leurs besoins. Un message publié par un publisher sera automatiquement délivrés à tous ses destinataires. Dans le contexte d'un MMORPG, les publishers seront les serveurse de jeu, et les subscribers seront les joueurs et les IA. Les topics seront ici des AoIs autour de chaque objet évoluant sur le serveur (IA ou joueur). Si un évènement implique un changement d'état d'une zone du monde du serveur, ce dernier notifiera tous les objets dont l'AoIs se superpose avec la zone d'effet de l'évènement.

Pattern Publiser / Subscriber

En pratique, ce sont les serveurs qui vont souscrire les clients pour leur AoIs. Comme on l'a vu dans la section précédente, lorsqu'un joueur va demander à son personnage de bouger, le module Inputs prend la commande, celle-ci est transformé en message par le composant View et le module Physique permet de prédire l'acceleration du personnage. Ces informations sont transmises au serveur qui peut alors modifier la subscription du client. Ce dernier n'a donc jamais à se soucier de ce problème vu que c'est le serveur qui s'en occupe. Cela permet d'éviter tout le trafic nécessaire pour transmettre les changements de souscriptions de tous les objets gérés par le serveur.

Mouvement objet

L'AoI d'un objet en mouvement comme sur le schéma ci-dessus suit donc les déplacements de son propriétaire. Que se passe-t-il aux frontières entre les serveurs? Comment un serveur peut-il savoir qu'un objet est entré sur sa zone? Le pattern Publish/Subscribe nous donne la solution. Tout comme nous avons définit une constante R pour les AoIs, on définit la zone contenant tous les points à une distance R de la frontière d'un serveur, qu'on appellera "zone la zone de frontière d'un serveur" par la suite. Sur le schéma ci-dessous, la zone orange représente la zone de frontière du serveur 1 et el bleu représente la zone de frontière du serveur 2.

Zone de frontière

Chaque serveur va souscrire auprès de ses voisins (serveurs se voyant attribués les zones du monde voisines de la sienne) pour sa zone de frontière. Ainsi dans l'exemple précédent, le Serveur 1 va souscrire auprès du Serveur 2 pour la zone orange, et vice et versa pour la zone en bleu. Ainsi les joueurs P1 et P2 représenter pourront "se voir" dans leur vue respective, car le serveur 1 sera notifié de la position de P2 par le serveur 2. De même le serveur 2 sera notifié de la position de P1 par le serveur 1. Ces deux serveurs sont donc en mesure de déterminer que les AoIs de P1 et P2 se superposent et de notifier chacun le joueur qu'ils hébergent de la présence de l'autre à l'extrémité de sa "vision".


Consistence

Supposant que les serveurs de jeux sont installés dans des datacenters et donc reliés par des connections à faibles latences, le temps de transmission inter-serveur Ls peut donc être négligé par rapport au temps de latence client - serveur Lc, car Lc >> Ls. A cause de cette latence imposée par les délais de transmissions réseaux, il se peut que l'ordre d'occurence de certains évènements vu par le serveur soit différent de l'ordre réel d'enchaînement de ces mêmes évènements. On se rend bien compte que l'ordre d'arrivée des évènements à un même serveur dépendent de la vitesse de transmission du client. C'est en fait aux frontières entre les serveurs que le problème se pose.

La consistence du jeux est réalisée si on remplit deux conditions. Il faut premièrement que, pour tous les évènements affectant un objet quelconque du jeu, l'ordre d'occurrence de ces évènements soient le même pour tous les clients dont la vue doit en retranscrire les états. La deuxième exigences est que l'ordre d'occurrence des évènements relatif à un objet doit être cohérent avec l'ordre d'occurrence de tous les évènements du jeu. Si un entier était attribué à chaque évènement dans un ordre croissant, les numéros des évènements affectant un objet particuler soient croissants de façon monotone.

Afin d'assurer la consistence dans la résolution des évènements du jeu, on utilisera des verrous. Il y aura deux types de verrous. Tout d'abord les verrous de région. Un verrou de région permet d'exclure mutuellement les serveurs voulant exécuter des évènements sur une région donnée. Lorsqu'on se trouve près des frontières entre 2 serveurs, les verrous de régions ne suffisent plus, car un serveur demandant un lock sur une région à cheval sur les 2 serveurs devra transmettre la notification au serveur qui gère la zone au delà de sa frontière. Celui-ci dans l'intervalle peut faire de même et on se retrouve avec un deadlock.

Prenons le cas de 3 joueurs P1, P2, et P3 dans la zone de frontière aux coins de 3 serveurs S1, S2, et S3 comme le montre le schéma ci-dessous.

Consistence Evènements

Le joueur P2 effectue une action sur le serveur S2. Comme plusieurs objets se situent dans l'AOI de P2, mais sur d'autres serveurs, il faut utiliser des verrous pour s'assurer qu'aucune action de P1 ou P3 ne vienne perturber l'exécution de l'action de P2. S2 demande donc un verrou pour la zone couverte par l'AOI de P2 sur chaque serveur. Chaque serveur lui retourne un verrou sur la région contenant les verrous sur tous les objets présents susceptibles d'être affectés par l'action de P2. Afin d'éviter un deadlock, à chaque fois qu'un serveur à besoin de verrous pour exécuter un évènement, il demande aux serveur voisins dans le même ordre. Chaque serveur a un ID. Un serveur ayant besoin d'un verrou demandera aux serveurs dans l'ordre décroissant. C'est pour ça qu'ici S2 demande un verrou à S3 en premier. En suite il essaye d'acquérir les verrous sur les objets dans sa zone, puis il termine en demandant les verrous à S1.

Echanges Consistence Evènements

Si des verrous sont déjà pris, cela veut dire qu'un autre serveur essaye d'exécuter un évènement et la procédure est annulée et on réessaye du début. Une fois que S2 possède tous les verrous nécessaires, il exécute l'évènement. Et publie la notification dans le même ordre que la prise des verrous. Le serveur 3 est donc notifié en premier. Ce dernier publiera la notification aux objets qu'il administre. Ensuite S2 notifie les objets qu'il possède, et enfin, il publie la notification à S1 qui se charge de notifié P1. Une fois notifié, chaque objet mettra à jour sa vue locale. L'exécution de l'action de P2 est terminée et S2 relâche tous les verrous. Par ce processus, on assure la consistence des données à tout instant sur les serveurs de jeu.


Nous allons maintenant voir comment le transfert d'un objet entre deux serveurs de jeu. Cet évènement arrive assez souvent et le cas le plus complexe est lorsque l'objet transferé est un joueur. Il faut alors que les évènements qui surviennent pendant le transfert de l'objet entre les deux serveurs soient exécutés sans que le gameplay en soit significativement affecté.

Changement de serveur

Nous avons un joueur P qui va passer d'un serveur S1 au serveur S2 qui administre la zone du monde contigue à celle administrée par S1. Le diagramme ci-dessous montre les étapes pour assurer la continuité de service et la consistence des données du jeu pendant le transfert de l'état de P de S1 à S2. Pour commencer, S1 demande les verrous sur la région dans laquelle P va évoluer lors du changement de serveur auprès de S2 et demande un verrou sur tous les objets situés dans l'AoI de P.

Avant de démarrer le transfert des données de P, S1 va envoyer l'ID de sa dernière action pour que S2 puisse juger si les évènements qu'il reçoit de S1, puis il initie le transfert de l'état de P. Si P exécute un évènement pendant le temps du transfert, S1 le transfert également à S2 qui le stocke dans une liste d'attente car S2 a souscrit à S1 pour la région autour de ses frontière. Une fois le transfert terminé, S1 relâche tous les verrous acquis au début de la transaction. Enfin, il notifie le joueur P que son nouveau serveur de jeu est le serveur 2.

Echanges Changement de serveur

Alors un échange de connexion entre le joueur P et le serveur 2 a lieu. P souscrit auprès de S2 pour recevoir les évènements. S2 devient à ce moment opérationnel. Il commence par exécuter tous les évènements mis en attente pendant le temps de transfert des données de P et à publier les résultats à tous les objets dans la zone. Au final, le gameplay n'est presque pas impacté. De plus, en pratique les concepteurs font tout ce qu'ils peuvent pour limiter au maximum ces zones d'échanges.