Si vous avez déjà été impliqué dans la programmation, vous connaissez le concept de bogues. S'ils ne nous dérangeaient pas, le processus de développement deviendrait beaucoup plus rapide et plus agréable. Mais ces bogues n'attendent que le moment pour ruiner notre code, notre horaire de travail et notre flux créatif. Heureusement, il existe de nombreux outils et stratégies pour éliminer les bogues, même dans le code des programmeurs de jeux rétro.
Outils de débogage
L'une des meilleures façons de déboguer du code est d'utiliser un débogueur. Certaines versions des émulateurs FCEUX et Mesen ont un débogueur intégré qui vous permet d'interrompre le programme à tout moment pour vérifier la santé du code.
Débogueur d'émulateur FCEUXIl convient de noter que cette méthode convient mieux aux programmeurs avancés travaillant avec le langage d'assemblage. Mais nous sommes nouveaux, nous allons donc écrire en C (cc65). Bien sûr, le compilateur jouera selon ses propres règles, et il nous sera difficile de traiter le code machine compilé à partir du code C.
Éditeur hexadécimal FCEUX
Disons que nous devons observer une sorte de variable ou de tableau. Ajoutez la ligne suivante aux options de l'éditeur de liens (ld65):
-Ln labels.txt
Après avoir compilé le projet, le fichier
labels.txt
apparaîtra dans son dossier. Il suffit de l'ouvrir dans n'importe quel programme pour visualiser des textes et de rechercher le nom de la variable que nous voulons observer.
(
Remarque: si vous avez déclaré une variable statique, elle ne sera pas incluse dans cette liste. Par conséquent, au lieu de static unsigned char playerX
utilisez unsigned char playerX
)
Maintenant, nous connaissons l'adresse de la variable souhaitée, pas mal. Trouvons-le dans le débogueur. Exécutez les jeux ROM dans l'émulateur FCEUX. Dans le menu Debug, sélectionnez l'élément Hex Editor, et dans la fenêtre qui s'ouvre, appuyez sur Ctrl + G et entrez l'adresse de notre variable:
Appuyez sur OK et le curseur se déplacera à l'adresse où se trouve la variable. Jetons un coup d'œil:
Cela peut être utile pour vérifier si le tableau est correctement rempli ou pour suivre les modifications de variables spécifiques. De plus, vous pouvez vous sentir comme un Big Brother, en regardant attentivement votre code.
Découvrez d'autres outils de menu de débogage de l'émulateur FCEUX utiles tels que PPU Viewer, Name table Viewer, etc.
Simplifiez le processus de débogage
Et si nous ne voulons pas exécuter un débogueur à chaque fois pour observer une variable? Une manière plus avancée consiste à écrire une procédure qui affiche la valeur à l'écran. Essayons d'utiliser le score dans l'interface pour afficher la position du joueur sur l'axe Y:
Cela fonctionne parfaitement!
Le codeur rétro et
propriétaire du blog de Nesdoug, Doug Fraker, a créé une méthode similaire pour utiliser des visualisations à l'écran à des fins de débogage. La procédure ci-dessous crée une ligne grise à l'écran qui montre clairement le degré de charge du processeur:
Vous pouvez simplement copier cette procédure dans votre code ou inclure la bibliothèque nesdoug.h dans le projet. La procédure doit être appelée après la fin du cycle de jeu, puis une barre grise s'affiche à l'écran.
Cela a fonctionné, mais il semble que j'ai encore un bug! Nous nous débarrasserons de lui plus tard. En attendant, passons à autre chose.
La puissance des macros
Les macros peuvent également être un outil de débogage utile. Ils vous permettront de trouver une place dans le code qui est devenue la source du bug.
Créons une sorte de macro qui nous donnera des signaux au bon moment, par exemple, jouer un son ou sélectionner une palette zéro avec la valeur nécessaire. Nous avons plusieurs macros qui changent la palette zéro en couleurs rouge, bleu et aléatoire, ainsi que la reproduction du son:
Comment ça marche? Supposons que vous ayez compilé avec succès un projet, vous démarrez l'émulateur avec votre jeu, cliquez sur le bouton Démarrer et ...
Il ne semble y avoir qu'un écran blanc. De plus, certains émulateurs peuvent signaler un «bourrage CPU!» Dans la barre d'état. Que faire ensuite?
Tout d'abord, vous devez localiser le code dans lequel l'erreur se produit. Et ici ma macro de son entre en jeu.
Nous savons avec certitude que le menu principal fonctionne. Voyons ce qui se passe après:
playMainMenu(); player.lives = 9; points = 0; gameFlags = 0; while(current_level<7 && player.lives>0) { set_world(current_world); debugSound; playCurrentLevel(); }
Je soupçonne que le jeu se bloque lorsque la procédure
set_world
est
set_world
. Vérifions cette intuition. J'entre simplement le nom de la macro dans la ligne suivante après la vérification de la procédure.
Nous commençons le projet et ... j'entends un son! Autrement dit, cette procédure a réussi et nous devons vérifier les éléments suivants:
playCurrentLevel
. Déplaçons la macro de débogage ci-dessous:
while(current_level<7 && player.lives>0) { set_world(); playCurrentLevel(): debugSound; }
Je redémarre le projet, mais je n'entends aucun son. Cela signifie que la procédure n'est pas terminée et qu'une défaillance se produit à l'intérieur.
Dans de tels cas, vous devez ouvrir le code de procédure et continuer à appliquer cette technique jusqu'à ce que vous puissiez affiner votre recherche d'un éventuel emplacement de bogue.
Une macro de changement de palette peut également être utile pour vérifier les conditions. Par exemple, notre code effectue un test complexe de plusieurs conditions:
if ( (getTile(objX, objY+16) || collide16() ) || (objsOX[i] && objY>objsOX[i])) { debugRed; objsSTATE[i]=THWOMP_SMASH; objY=objsY[i]-=4; objsFRM[i]=0; sfx_play(SFX_THWOMP_SLAM_DOWN,2); }
Si nous changeons la couleur de la palette ici, nous verrons si la condition est remplie:
Ce poulet semble aller bien. Mais si le drapeau ne fonctionne pas, alors l'une des conditions n'est pas remplie. Dans ce cas, vous devez tous les vérifier séparément, puis vous trouverez peut-être un autre bogue.
Option nucléaire
J'ai récemment découvert que l'un des fantômes de mon jeu présente une sorte de comportement suspect. De temps en temps, il refusait d'attaquer le joueur.
Jetez un œil à ce fantôme frappé par un bug - il n'attaque que lorsque le personnage est proche du centre de l'écran:
Peu importe la difficulté avec laquelle j'ai étudié le code de cette procédure, je ne pouvais pas comprendre où le bogue était caché, j'ai donc décidé de prendre des mesures extrêmes et de tester le travail de ce code dans un environnement de développement moderne.
J'ai pris tout ce dont j'avais besoin: une carte d'écran, un tableau avec des attributs de métafichier, un code de procédure et je les ai simplement insérés dans Visual Studio 2017:
Sur PC, le code fonctionnait exactement de la même manière. Il s'est avéré que le bug se cachait dans une procédure qui remplissait le cache pour trouver des obstacles entre le joueur et l'ennemi. Le tableau a été mal rempli. Je suis sûr qu'il devrait y avoir 0 au lieu de 0x80.
Donc, je vais essayer de déboguer étape par étape le code pour savoir pourquoi cela se produit.
C'est drôle, mais on dirait que je faisais les actions dans le mauvais ordre. Corrigeons-le et vérifions à nouveau le tableau!
Il semble maintenant que le tableau se remplisse correctement. Autrement dit, j'ai juste besoin de corriger le code cc65 et de recompiler le projet NES.
Ainsi, les outils de développement modernes peuvent aider au débogage des algorithmes et à la correction des bogues.
Débarrassez-vous des bugs calmement
Les bogues sont ennuyeux, tout comme le code ennuyeux. Restez calme, ne perdez pas le contrôle et utilisez toute la gamme d'outils disponibles pour rechercher et détruire ces ravageurs. La qualité de votre code et la tranquillité d'esprit augmenteront considérablement.
Vous souhaitez obtenir des conseils directement auprès de professionnels du rétro-design? Bienvenue dans notre Discord!
Notre jeu The Meating est disponible ici !