
Online Mode 2.0 en préparation pour Dragon Ball Devolution
Cette dernière année a été plutôt folle pour Dragon Ball Devolution avec l'ajout du mode Online, le passage à 60fps et surtout, sa survie à la disparition de Flash. Concernant le mode Online, c'est la première fois que je programmais un jeu en ligne et je n'avais pas la moindre idée de la façon dont j'allais synchroniser les deux joueurs à distance. Le problème était intéressant, et je pense maintenant avoir assez de recul pour améliorer tout ça.
Lire la suite de Online Mode 2.0 en préparation pour Dragon Ball Devolution
Synchronisation optimale des données ?
Actuellement, les données ne sont envoyées d'un joueur à l'autre que lorsqu'elles sont modifiées. Je me disais que ce serait mieux pour l'optimisation des transferts selon la formule magique :
MOINS DE TRANSFERTS = MOINS DE LAG
Le personnage est défini par ses coordonnées X, Y, ses points de HP, de KI, de POW et s'il appuie sur la touche ATK (attaque). En vrai, il y a plein d'autres paramètres, mais restons simple pour l'exemple.

[ X=10, Y=100, HP=100, KI=100, POW=0, ATK=0 ]
Tant qu'il ne se déplace pas, on n'envoie rien à l'adversaire.

[ X=30, Y=100, HP=100, KI=100, POW=0, ATK=0 ]
Quand le personnage se déplace, on envoie seulement la donnée qui a été modifiée.
Jusque-là, tout fonctionne parfaitement !
Quid des projectiles ?
Passons aux boules de feu. Je ne garde aucune trace de ces dernières dans un tableau, parce que je n'avais pas besoin de faire ça dans le jeu. Comme les boules de feu sont tirées automatiquement en direction de l'adversaire, et que la position de l'adversaire devrait normalement être à jour, l'angle de tir, et donc la position de la boule de feu devrait être identique sur les deux écrans...

[ X=30, Y=100, HP=100, KI=50, POW=50, ATK=1 ]
En appuyant sur la touche attaque, le personnage charge une boule de feu, le KI utilisé se transforme en POW.

[ X=30, Y=100, HP=100, KI=50, POW=0, ATK=0 ]
En relâchant la touche attaque, le personnage tire la boule de feu avec une valeur POW en direction de l'adversaire.
En théorie, ça fonctionne parfaitement. Mais en pratique, les joueurs ont des vitesses de connexion plutôt foireuses... Par exemple, il suffit d'un micro lag pour que le joueur qui prépare une boule de feu n'ai pas reçu les dernières coordonnées de son adversaire au moment du tir.

En exagérant, cela donne ça :
Le joueur 1 tire en direction de l'ancienne position du joueur 2. Alors, il arrive que le joueur 1 voit son adversaire se prendre une boule de feu de plein fouet, tandis que sur l'écran du joueur 2, ce dernier évite le projectile. Donc son HP n'est pas modifié et le joueur 1 ne comprend pas pourquoi son adversaire ne perd pas de vie.
À cause de ce problème, les deux joueurs finissent par se crêper le chignon sur le chat-box en se traitant de "cheater" et de "hacker". Et ça devient sérieusement pénible.
En plus, il existe plein d'autres cas spéciaux qui entrainent des problèmes, comme le pouvoir "Body-Change" du Captain Ginyu qui consiste à voler le corps de son adversaire. Dans ce cas-là, l'inversion des personnages est faite quasiment en même temps chez les deux joueurs, tout en envoyant leurs nouvelles données au joueur adverse au même moment. Ça donne de mauvaises surprises durant la partie...
Connection Timeout
Encore un souci : comment savoir que la connexion est perdue entre les deux joueurs parce qu'ils sont à 100m de leur wifi surbondé en plus de se trouver à une demi-planète de distance ? Il suffit de vérifier qu'aucune donnée n'a été envoyée durant un certain laps de temps. Mais si personne ne bouge volontairement, cela entraine aussi un timeout... Je suis donc obligé d'envoyer le temps qui s'écoule, en plus des données des personnages.
Finalement, est-ce qu'il ne faudrait pas tout envoyer ?
Mis bout à bout, je me rend compte que le "MOINS DE TRANSFERTS = MOINS DE LAG" n'était pas forcément une bonne idée. C'est parfait pour un jeu lent, au tour par tour, mais ça ne fonctionne pas pour un jeu d'action. En effet, il est extrêmement rare que les joueurs ne fassent rien. Il y a un transfert de donnée en permanence, en plus du timer pour vérifier la déconnexion.
Mon prochain gros chantier sur ce jeu consistera à stocker les boules de feu existantes dans deux tableaux, un par joueur, pour facilement retrouver leur position à l'écran. Puis envoyer en permanence toutes les données des deux joueurs et leurs tableaux respectifs. Comme ça, pas besoin de faire le tri dans les données, ni d'envoyer le timer de déconnexion.
En théorie ça devrait marcher...