
Écrits · 21 févr. 2018
Mettre à jour Snake '97
Les défis du développement d'un jeu ultra populaire
Il y a quelques années, mon frère a renversé une bière sur mon iPhone dans un bar d'Amsterdam. Le pauvre n'a pas aimé la bière néerlandaise autant que moi : il est mort. En attendant un nouveau téléphone, j'ai utilisé un vieux modèle qui ne savait faire qu'envoyer des SMS, téléphoner et... jouer à Snake ! L'idée de Snake '97 était née, et ce mois-ci, il était temps de mettre à jour ce jeu ultra populaire.

Snake '97
À l'origine, j'ai programmé le jeu Snake en 2011 pour iOS. Il m'a fallu environ deux semaines pour créer un prototype fonctionnel qui ressemblait et se jouait comme le vrai classique des années 90. Mon autre frère m'a aidé pour les graphismes en prenant de superbes photos en gros plan de mon vieux téléphone (c'est toujours bizarre de penser que tant d'entre vous ont une copie de mon téléphone dans leur poche).

Quelques gros blogs en ont parlé, et Snake '97 s'est retrouvé en tête des classements partout dans le monde. Aujourd'hui, on y joue aux quatre coins de la planète, il est traduit en 53 langues et disponible sur iOS, Android, Windows, ChromeOS et macOS.

Une mise à jour s'impose
En 2011, il n'existait qu'un seul iPhone, l'iPhone 4. En tant que développeur, tu pouvais ignorer Android sans risque, et Windows Phone n'était même pas encore inventé. La vie était aussi belle qu'un développeur (paresseux) pouvait la rêver : une seule taille d'écran.

Avance rapide jusqu'à aujourd'hui : Apple vend actuellement 8 iPhone et il existe des millions et des millions d'appareils Android, tous avec des tailles d'écran, des processeurs, des mémoires et des versions de logiciel différents. Dire que c'est un défi serait un euphémisme...
Pour que Snake '97 reste aussi fun, je devais mettre à jour le moteur du jeu en profondeur. D'une manière ou d'une autre, je devais adapter les graphismes à chaque écran du monde et tenir compte des différences de puissance de calcul et de mémoire....

Un seul moteur de jeu pour les gouverner tous
Les premières versions du jeu avaient chacune leur propre moteur. Un pour iOS, un pour Android, un pour Windows, etc. Quand j'ai lancé Snake 2k (la variante Snake II), j'ai tout simplement ajouté une nouvelle série de moteurs. Au total, j'ai programmé 6 moteurs Snake différents en Objective-C (iOS), Java (Android) et C# (Windows). Faire tourner ces moteurs sur de nouveaux appareils, avec d'autres tailles d'écran, d'autres processeurs et d'autres configurations de mémoire, devenait de plus en plus difficile.
Mais ce mois-ci, j'ai serré les dents, et pas qu'un peu. J'ai conçu et construit un autre moteur Snake. Mais celui-ci devait remplacer tous les précédents. Il devait tourner sur iOS, Android et Windows. Je voulais un moteur prêt pour l'avenir, pour n'importe quel écran et n'importe quel type de commande (clavier, tactile, stylet, manette, joystick, ce que tu veux).

HTML5 Rocks
Le web a rattrapé la technologie des applis natives. De nombreuses nouvelles API ont fait leur apparition et permettent des expériences riches et interactives sur beaucoup d'appareils différents. Je me suis demandé s'il serait très difficile de faire fonctionner Snake '97 avec les technologies du web. Il n'y avait qu'une façon de le savoir, alors je m'y suis mis.
Des graphismes adaptatifs
J'ai commencé par construire le moteur graphique à partir du canvas HTML5 et d'un système d'échelle adaptatif que j'avais conçu pour la version Android de Snake '97. En gros, le moteur mesure la taille de l'écran disponible, l'orientation et la densité de pixels. Il adapte automatiquement du matériel photo haute résolution à ton écran précis.

Le nouveau moteur graphique gère même des trucs bizarres comme l'encoche de l'iPhone X. Tout cela se passe en une fraction de seconde. J'ai aussi conçu le moteur pour qu'il réagisse aux changements de taille d'écran. On peut maintenant jouer en mode portrait ou paysage, dans une fenêtre ou en plein écran (ou en écran partagé si tu es sur iPad).


Des puissances de calcul différentes
Tu crois qu'un jeu simple n'a pas à se soucier de la puissance de calcul ? Faux ! Dans un jeu comme Snake, le timing est essentiel. Les gens jouent avec leur « mémoire musculaire », en répétant leurs tapotements sur l'écran tactile sans penser aux mouvements individuels.
Le moteur de jeu doit être prévisible, il doit tourner à vitesse constante. Mais surtout, l'expérience doit être la même, que tu aies un vieil appareil Android ou une bête de course à 6 cœurs comme l'iPhone X.

J'ai utilisé la caméra vidéo haute vitesse de l'iPad Pro pour filmer des parties de Snake au ralenti. Grâce à la vidéo, j'ai pu repérer les différences de vitesse image par image. Cela a donné un système interne de benchmark (avec des minuteurs, qui comptent les millisecondes) qui ajuste automatiquement la vitesse du jeu, réglée avec précision pour ton appareil.
Les commandes : tactile, clavier, stylet, manette
Les joueurs contrôlent le serpent avec les commandes rétro (le clavier de l'ancien téléphone). La version iOS d'origine utilisait des UIButton transparents fixes que j'avais placés sur les photos de l'ancien téléphone. Un début simple et efficace.
Malheureusement, les boutons fournis par iOS avaient un certain retard (ce qui causait des délais imprévisibles) et ne s'adaptaient évidemment pas aux différentes tailles d'écran. J'ai littéralement codé en dur de nouvelles coordonnées pour chaque nouvel iPhone sorti ces dernières années.... pas un boulot marrant.
Le nouveau moteur utilise une astuce que j'avais mise au point pour la version Android : des boutons virtuels positionnés dynamiquement. Avec les informations d'échelle calculées par le moteur graphique, je maintiens dynamiquement une matrice de coordonnées X et Y correspondant aux boutons virtuels. Quand un joueur touche l'écran, le moteur calcule le bouton le plus proche avec des maths, le théorème de Pythagore.

Ça marche comme un charme et ça transforme tout l'écran en bouton. Le jeu est bien plus agréable à jouer comme ça. En plus du tactile, j'ai ajouté la prise en charge du clavier pour que les gens sans écran tactile puissent jouer à Snake eux aussi.
Pendant que je travaillais sur les commandes, j'ai découvert une autre merveille de HTML5, l'API GamePad. Elle permet à des programmeurs comme moi de gérer les manettes, les joysticks et d'autres périphériques de commande connectés en USB ou en Bluetooth.

Gérer des manettes différentes est un défi, mais c'est quand même amusant. J'ai sûrement perdu une journée entière à « tester »... enfin, à perfectionner mes talents avec la formidable manette SNES et le superbe stick analogique de la manette DualShock. (« Désolé chérie, je travaille ici... »)

Internationalisation
Si tu lis ceci, tu comprends probablement l'anglais. Mais une grande partie du public de Snake '97 ne le parle pas. Il y a même des joueurs dans plus de 30 langues différentes. De l'espagnol au russe, de l'arabe à l'hébreu, de l'allemand au japonais. Dis une langue, Snake l'a.
Concevoir une interface qui repose sur du texte est difficile quand on veut servir le monde entier. Les icônes ne sont pas parfaites non plus (une image peut avoir un autre sens ailleurs). En tant que designer UX, il faut trouver des concepts utilisés partout dans le monde. Pour Snake, j'ai choisi des icônes d'horloge, de compteur de vitesse, de haut-parleur et de trophée. Ces icônes sont courantes dans le monde entier et je les ai choisies précisément pour cette raison.

La description de l'appli est un texte que j'ai fait traduire par un service de traduction professionnel. D'autres éditeurs se fient à Google Translate, mais je sais que cela donne des résultats lamentables.
Classement mondial
Dans les années 90, tu gagnais du respect dans la rue si tu avais fait un beau score à Snake. Dans les versions d'origine de Snake '97, tu n'avais que ton propre meilleur score à battre, et sur iOS, tu pouvais envoyer ton score à GameCenter.
Pour la nouvelle version, je voulais une portée plus mondiale, avec un « classement mondial ». C'est le nouveau classement intégré, qui place instantanément ta partie dans la hiérarchie en comparant les scores de joueurs du monde entier. Il y a trois classements : de tous les temps, des 24 dernières heures et de la dernière heure.

Les meilleurs scores sont traités par un incroyable serveur Intel XEON à 48 cœurs avec une quantité folle de mémoire. Il tourne sous Debian GNU/Linux, avec MariaDB, NGINX et NodeJS. Aux heures de pointe, il traite plus de 10 scores par seconde. La configuration du serveur mérite un article de blog à part que j'écrirai plus tard, alors garde un œil sur ce blog si les big data te passionnent.

Télécharge-le maintenant
Il n'y a qu'une façon de savoir si mon travail est réussi : l'essayer toi-même.
N'hésite pas à me signaler les bugs que tu rencontres, tu trouveras mes coordonnées ici.
