Le symptôme

En testant le jeu avec le boss actif, un détail a accroché l'oeil. Toutes les secondes, le scroll hoquetait très légèrement. Pas un ralentissement, pas un flash, juste un saut. Comme si l'image restait figée une fraction de seconde avant de reprendre sa course. Immobile, on ne voit rien. Mais dès que la caméra bouge, ça se voit, parce qu'un scroll fluide rend visible le moindre bug.

Sur l'Atari ST, il n'y a pas d'outil de mesure tout fait. Une machine de 1989, un émulateur, et mes yeux. Voici l'enquête d'une soirée, une sacrée soirée ;)

Première piste : la peste qui calcule trop

Le suspect évident, c'était la peste. Elle se propage une fois par seconde, et à ce moment-là elle inspecte beaucoup de cases d'un coup pour décider lesquelles vont contaminer leurs voisines. J'ai d'abord traqué un calcul coûteux qu'elle refaisait sans cesse, et je l'ai remplacé par une simple valeur préparée une fois pour toutes. Sur le papier, un beau gain.

Résultat : le saut est toujours là. Même fréquence, même amplitude. Bravo mais non ...

Deuxième piste : trop de cases redessinées d'un coup

Deuxième réflexe. Quand la peste se propage, chaque case qui change d'état doit être redessinée à l'image suivante. Si beaucoup de cases basculent en même temps, ça fait soudain une grosse pile de dessins à rattraper. J'ai donc limité le nombre de basculements autorisés par seconde, le surplus attendant son tour.

Résultat : le saut est toujours là.

À ce stade de la soirée, je commence à douter de mes hypothèses. Il me faut voir ce qui se passe, pas deviner.

Voir le temps, enfin

Il existe une vieille astuce de l'Atari ST, utilisée par les demo makers, pour visualiser où part le temps de calcul. On change la couleur de fond de l'écran à chaque étape du travail d'une image. Résultat : des bandes de couleur apparaissent, et l'épaisseur de chaque bande dit en un coup d'oeil combien de temps cette étape a coûté. Pas de chiffres, pas de tableau, juste une image qui se lit instantanément.

J'ai donc coloré chaque grande phase de la boucle de jeu, et relancé. La plupart des images se ressemblaient, bien équilibrées, avec une large marge de temps libre en bas, signe que tout va bien.

Et puis, pile toutes les secondes, une image radicalement différente. La phase de la peste dévorait la moitié supérieure de l'écran. Tout le reste était écrasé contre le bas, et la marge avait quasiment disparu. Le diagnostic était enfin clair et sans ambiguïté : faire tout le travail de propagation de la peste en une seule fois dépassait le temps disponible pour une image, et l'émulateur sautait alors cette image. Ni le calcul coûteux ni la pile de dessins n'étaient les vrais coupables. C'était simplement le volume total fait d'un seul coup.

La bonne idée : étaler le travail

Puisque tout faire d'un coup pose problème, autant répartir ce travail sur les cinquante images d'une seconde. À chaque image, la peste ne traite qu'une petite tranche. Au bout d'une seconde, toutes les tranches réunies couvrent un cycle complet. Le rythme global est conservé, mais le pic disparaît.

J'implémente, je teste. Scroll parfaitement fluide, plus aucun saut. Victoire. Je commence à savourer.

Puis j'entre dans la salle du boss, et tout vire au rouge en trois secondes. La peste avait déferlé sur toute la carte.

Le piège caché

J'ai tout de suite vu l'erreur. J'avais décidé de traiter un nombre fixe de cases par image. Quand la peste est très étendue, ce nombre fixe ne couvre qu'une petite part de la population à chaque image, et tout va bien. Mais en début de partie, quand il n'y a qu'une poignée de cases actives, ce même nombre fixe les englobe toutes, à chaque image. Du coup, chaque case tentait de contaminer un voisin cinquante fois plus vite que prévu. La peste explosait.

La vraie solution, c'est de raisonner en proportion plutôt qu'en quantité fixe. Au lieu de promettre un nombre de cases par image, je garantis que chaque case sera traitée une fois par seconde, quelle que soit la taille de la population. Quand il y a peu de cases, on en fait peu par image. Quand il y en a beaucoup, on en fait plus. Le rythme reste juste dans tous les cas, du tout début paisible jusqu'à la salle du boss saturée.

Nouveau test, salle du boss, scroll fluide et propagation de la peste au bon rythme. Fin de l'histoire.

Ce que j'en retire

Deux leçons que je garde.

La première : optimiser sans diagnostic, c'est perdre son temps. Mes deux premières corrections étaient des améliorations honnêtes, mais aucune ne s'attaquait au vrai coût. La visualisation par bandes de couleur aurait dû être ma première étape, pas la troisième. C'est un cadeau de l'histoire Atari ST : aucun outil moderne ne te donne ce rendu aussi immédiat, parce que sur cette machine la frontière entre calcul et image est très mince.

La seconde : étaler un travail périodique avec une quantité fixe par image est un piège dès que la population varie. Raisonner en proportion garantit le bon rythme dans tous les cas. Une évidence après coup, beaucoup moins sur le moment.

Le dispositif de visualisation reste dispo dans le code, désactivé. Au prochain à-coup, je le rallume et on remet ça.

Le .prg actuel est disponible au téléchargement. Flèches pour bouger, fire pour la lanterne, P pour pause, Esc pour quitter. Teste le scroll dans la salle du boss, c'est la zone où l'optimisation se voit le mieux.