OPTIMISATION DU MOTEUR DE BULLET

OK, un post technique. Désolé !
Mon code pour les bullets était horrible : je l’ai écris il y a très longtemps sans aucune optimisation en tête. Ça marchait et j’étais déja bien content comme ça.
Et puis j’y ai repensé, j’ai mal dormi, j’ai fait des cauchemars et finalement j’ai décidé de faire quelquechose et d’écrire un vrai moteur de bullets plus rapide et plus propre.
Tout ça sans être un vrai programmeur : je suis un artiste technique / programmeur, alors ne rigolez pas si j’ai choisi une approche un peu naive :)

GESTION des BULLETS
Je savais que créer et détruire beaucoup d’objets (au sens programmation, pas bullet hell) était mal, alors j’avais quand même dès le début créé un pool d’objets bullets lors du lancement du SHMUP Creator. Déja ça.
Ce qui n’était pas top, c’était la manière de gérer efficacement les bullets actives. Par exemple, je devais itterer toutes les bullets pour en trouver une libre (inactive) avant de la spawner, j’iterrai toutes les bullets pour les updater etc.
Avec la puissance des CPUs en 2017, ça va, mais pas super pour gérer 6000 bullets.
Alors j’ai écrit un vrai gestionnaire de bullets qui s’occupe de tout ça. Je crée toujours le pool d’objets bullets mais aussi deux listes : une qui liste les IDs des bullets libres (inactives) et une qui liste toutes les bullets actives (que l’on voit sur l’écran). Les IDs étant des références qui pointent vers les bullets du pool.
Quand je veux spawner une bullet, je récupère le dernier ID de la liste « bullets libres » et je mets en « active » la bullet du pool qui correspond à cet ID. Je supprime cet ID de la liste des bullets libres et je l’ajoute à la liste des bullets actives.
Cette liste de bullets actives me permet de n’updater que les bullets que l’on voit sur l’écran et aussi de maintenir un ordre d’affichage dont j’ai besoin pour le rendu (voir plus bas)
Quand une bullet est morte, je mets son état à « DEAD » et je supprime son ID de la liste des bullets active et je le rajoute à la liste des bullets libres.

DESSINER les BULLETS et les DRAW CALLS
La pire des choses que je faisais c’etait de dessiner chaque bullet individuellement. Sur mon portable ça marchait, donc pas de problème. Mais avec 6000 bullets le jeu commençais quand même à ralentir. En plus, avoir un rendu de bullets dans le bon ordre est très important, et ça ralentissait d’autant plus l’affichage.
Donc, j’ai écrit un Bullet Renderer. Pour chaque type de bullets affiché à l’écran je crée une liste de polygones qui utilisent la position, rotation et échelle de chaque bullet et qui est dessinée en une seule fois avec son propre materiau.
Grâce à la fameuse liste ordonnée de bullets actives, je peux dessiner ces bullets dans le bon ordre, avec en plus des prioritées : les bullets des ennemis toujours par dessus tout, puis celles du joueur etc.
Au final, je n’ai plus qu’un draw call par type de bullets au lieu de 3000 pour 3000 bullets. C’est mieux !

ON PEUT FAIRE MIEUX !
Le nouveau gestionnaire de bullets est loin d’être optimal et parfait, mais c’est déja un grand progrès. Peut-être qu’un jour je m’y remettrai, mais pas tout de suite :)
Et pour l’instant, il est beaucoup plus rapide, et c’est bien :)

La suite des aventures très bientôt !

bullets

No Comments