Wenn Sie jemals an der Programmierung beteiligt waren, sind Sie mit dem Konzept der Fehler vertraut. Wenn sie uns nicht stören würden, würde der Entwicklungsprozess viel schneller und angenehmer werden. Aber diese Fehler warten nur auf den Moment, um unseren Code, unseren Arbeitsplan und unseren kreativen Fluss zu ruinieren. Glücklicherweise gibt es viele Tools und Strategien, um Fehler zu beseitigen, selbst im Code von Retro-Game-Programmierern.
Debugging-Tools
Eine der besten Möglichkeiten zum Debuggen von Code ist die Verwendung eines Debuggers. Einige Versionen der FCEUX- und Mesen-Emulatoren verfügen über einen integrierten Debugger, mit dem Sie das Programm jederzeit unterbrechen können, um den Zustand des Codes zu überprüfen.
FCEUX-Emulator-DebuggerEs ist erwähnenswert, dass diese Methode besser für fortgeschrittene Programmierer geeignet ist, die mit Assemblersprache arbeiten. Aber wir sind neu, also werden wir in C (cc65) schreiben. Natürlich wird der Compiler nach seinen eigenen Regeln spielen, und es wird für uns schwierig sein, mit aus C-Code kompiliertem Maschinencode umzugehen.
Hex-Editor FCEUX
Nehmen wir an, wir müssen eine Art Variable oder Array beobachten. Fügen Sie den Linkeroptionen (ld65) die folgende Zeile hinzu:
-Ln labels.txt
Nach dem Kompilieren des Projekts wird die Datei
labels.txt
in ihrem Ordner
labels.txt
. Öffnen Sie es einfach in einem beliebigen Programm zum Anzeigen von Texten und suchen Sie nach dem Namen der Variablen, die wir beobachten möchten.
(
Hinweis: Wenn Sie eine statische Variable deklariert haben, wird diese nicht in diese Liste aufgenommen. Verwenden Sie daher anstelle des static unsigned char playerX
den unsigned char playerX
)
Jetzt kennen wir die Adresse der gewünschten Variablen, nicht schlecht. Lassen Sie es uns im Debugger finden. Führen Sie die ROM-Spiele im FCEUX-Emulator aus. Wählen Sie im Menü Debug das Element Hex Editor aus. Drücken Sie im folgenden Fenster Strg + G und geben Sie die Adresse unserer Variablen ein:
Drücken Sie OK, und der Cursor bewegt sich zu der Adresse, an der sich die Variable befindet. Werfen wir einen Blick darauf:
Dies kann nützlich sein, um zu überprüfen, ob das Array korrekt gefüllt ist, oder um Änderungen an bestimmten Variablen zu verfolgen. Außerdem können Sie sich wie ein großer Bruder fühlen und Ihren Code genau beobachten.
Weitere nützliche Debug-Menü-Tools für den FCEUX-Emulator wie PPU Viewer, Name Table Viewer usw.
Vereinfachen Sie den Debugging-Prozess
Und wenn wir nicht jedes Mal einen Debugger ausführen möchten, um eine Variable zu beobachten? Eine fortgeschrittenere Methode besteht darin, eine Prozedur zu schreiben, die den Wert auf dem Bildschirm anzeigt. Versuchen wir, anhand der Punktzahl in der Benutzeroberfläche die Position des Spielers auf der Y-Achse anzuzeigen:
Es funktioniert perfekt!
Doug Fraker,
Inhaber eines Retro-Codierers und
Nesdoug-Blogs, hat eine ähnliche Methode für die Verwendung von Bildschirmvisualisierungen für Debugging-Zwecke entwickelt. Das unten gezeigte Verfahren erzeugt eine graue Linie auf dem Bildschirm, die den Grad der CPU-Auslastung deutlich anzeigt:
Sie können diese Prozedur einfach in Ihren Code kopieren oder die Bibliothek nesdoug.h in das Projekt aufnehmen. Die Prozedur muss nach Abschluss des Spielzyklus aufgerufen werden, dann wird ein grauer Balken auf dem Bildschirm angezeigt.
Es hat funktioniert, aber es sieht so aus, als hätte ich noch einen Fehler! Wir werden ihn später loswerden. In der Zwischenzeit gehen wir weiter.
Die Kraft der Makros
Makros können auch ein nützliches Debugging-Tool sein. Sie ermöglichen es Ihnen, einen Platz im Code zu finden, der zur Quelle des Fehlers geworden ist.
Lassen Sie uns eine Art Makro erstellen, das uns zum richtigen Zeitpunkt Signale gibt, z. B. einen Sound abspielen oder eine Nullpalette mit dem erforderlichen Wert auswählen. Wir haben mehrere Makros, die die Nullpalette in rote, blaue und zufällige Farben ändern und Ton wiedergeben:
Wie funktioniert es Angenommen, Sie haben ein Projekt erfolgreich kompiliert, starten den Emulator mit Ihrem Spiel, klicken auf die Schaltfläche Start und ...
Es scheint nichts als einen weißen Bildschirm zu geben. Darüber hinaus melden einige Emulatoren möglicherweise "CPU-Stau!" In der Statusleiste. Was ist als nächstes zu tun?
Zunächst müssen Sie den Code lokalisieren, in dem der Fehler auftritt. Und hier kommt mein Klangmakro ins Spiel.
Wir wissen sicher, dass das Hauptmenü funktioniert. Mal sehen, was danach passiert:
playMainMenu(); player.lives = 9; points = 0; gameFlags = 0; while(current_level<7 && player.lives>0) { set_world(current_world); debugSound; playCurrentLevel(); }
Ich habe den Verdacht, dass das Spiel abstürzt, wenn die
set_world
Prozedur
set_world
. Lassen Sie uns diese Vermutung überprüfen. Ich gebe einfach den Makronamen in die nächste Zeile ein, nachdem die Prozedur überprüft wurde.
Wir starten das Projekt und ... ich höre einen Ton! Das heißt, dieses Verfahren war erfolgreich und wir müssen Folgendes überprüfen:
playCurrentLevel
. Verschieben wir das Debug-Makro unten:
while(current_level<7 && player.lives>0) { set_world(); playCurrentLevel(): debugSound; }
Ich starte das Projekt erneut, kann jedoch keinen Ton hören. Dies bedeutet, dass der Vorgang nicht abgeschlossen ist und ein Fehler darin auftritt.
In solchen Fällen sollten Sie den Prozedurcode öffnen und diese Technik weiter anwenden, bis Sie Ihre Suche nach einem möglichen Fehlerort eingrenzen können.
Ein Makro zum Ändern der Palette kann auch zum Überprüfen der Bedingungen hilfreich sein. Zum Beispiel führt unser Code einen komplexen Test mehrerer Bedingungen durch:
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); }
Wenn wir hier die Farbe der Palette ändern, werden wir sehen, ob die Bedingung erfüllt ist:
Dieses Huhn scheint in Ordnung zu sein. Wenn das Flag jedoch nicht funktioniert, ist eine der Bedingungen nicht erfüllt. In diesem Fall müssen Sie alle separat überprüfen, und dann finden Sie möglicherweise einen weiteren Fehler.
Nukleare Option
Ich habe kürzlich entdeckt, dass einer der Geister in meinem Spiel verdächtiges Verhalten zeigt. Von Zeit zu Zeit weigerte er sich, den Spieler anzugreifen.
Schauen Sie sich diesen Geist an, der von einem Fehler getroffen wurde - er greift nur an, wenn sich der Charakter in der Nähe der Bildschirmmitte befindet:
Egal wie intensiv ich den Code dieses Verfahrens studiert habe, ich konnte nicht herausfinden, wo der Fehler versteckt war, und entschied mich daher, extreme Maßnahmen zu ergreifen und die Arbeit dieses Codes in einer modernen Entwicklungsumgebung zu testen.
Ich nahm alles, was ich brauchte: eine Bildschirmzuordnung, ein Array mit Metadateiattributen, einen Prozedurcode und fügte sie einfach in Visual Studio 2017 ein:
Auf dem PC funktionierte der Code genauso. Wie sich herausstellte, versteckte sich der Fehler in einer Prozedur, die den Cache füllte, um Hindernisse zwischen dem Spieler und dem Feind zu finden. Das Array wurde falsch gefüllt. Ich bin sicher, es sollte 0 statt 0x80 geben.
Daher werde ich versuchen, den Code Schritt für Schritt zu debuggen, um herauszufinden, warum dies geschieht.
Es ist lustig, aber es sieht so aus, als hätte ich die Aktionen in der falschen Reihenfolge ausgeführt. Lassen Sie es uns beheben und das Array erneut überprüfen!
Es scheint, dass das Array jetzt korrekt gefüllt ist. Das heißt, ich muss nur den cc65-Code korrigieren und das NES-Projekt erneut kompilieren.
Moderne Entwicklungstools können also beim Debuggen von Algorithmen und beim Beheben von Fehlern helfen.
Befreien Sie sich ruhig von Insekten
Fehler sind ärgerlich, ebenso wie Code ärgerlich. Bleiben Sie einfach ruhig, verlieren Sie nicht die Kontrolle und nutzen Sie die gesamte Palette der verfügbaren Werkzeuge, um diese Schädlinge zu suchen und zu zerstören. Die Qualität Ihres Codes und die Sicherheit werden erheblich verbessert.
Möchten Sie Tipps direkt von Retro-Design-Profis erhalten? Willkommen zu unserer Zwietracht!
Unser Spiel The Meating gibt es hier !