Pinke Grafik, außer Kontrolle geratener Punktestand, XR-Absturz. Vier Bugs an einem Samstag.
Vier Bugs in vier Subsystemen, die alle ihre Unit-Tests bestehen – das ist der Fehlermodus, der kaputte Demos ausliefert. Ihn abzufangen ist die Disziplin, die aus einem Sample auf RakuAI etwas macht, das man tatsächlich ausführen kann.
Es gibt eine bestimmte Art von Samstag, die jeder kennt, der schon einmal eine Demo ausgeliefert hat. Die Demo funktionierte am Ende des letzten Wochenendes. Man nimmt sie sich diesen Samstagmorgen wieder vor. Jetzt ist sie auf vier verschiedene Arten kaputt, und keine der Arten hat mit den anderen zu tun.
Das war heute. Die Demo war das Shooter-Spiel, das wir als eines der kanonischen Samples ausliefern. Die Bugs warteten wie Partygäste, die niemand eingeladen hatte.
Was kaputt war
Die Demo bootete. Das war die gute Nachricht. Danach:
Die Grafik war pink. Jeder, der schon einmal in einem Echtzeit-Renderer gearbeitet hat, kennt das Pink des Untergangs. Es ist die Platzhalterfarbe für „fehlender Shader”, knalliges Pink, das einen anschreit, dass etwas in der Rendering-Pipeline den erwarteten Shader nicht finden konnte. Jedes prozedural generierte Objekt in der Demo rendete in dieser Farbe. Schiffe. Asteroiden. Partikel. Alles pink. Pink überall.
Der Punktestand geriet außer Kontrolle. Jeder Kill wurde doppelt registriert. Der Kill-Zähler stieg in Paaren. Zwanzig Gegner erledigt, „Punktestand: vierzig.” Vierzig Gegner erledigt, „Punktestand: achtzig.” Auf dem Papier sieht es aus, als wäre das Spiel großzügig, aber in der Praxis war das Leaderboard aufgeblasen, und die Highscore-Logik feuerte bei völlig falschen Schwellenwerten.
Der XR-Boot stürzte ab. Die Demo auf einem Flachbildschirm bootete sauber. In dem Moment, in dem ich ein Headset einsteckte und in den XR-Modus wechselte: harter Abbruch. Kein Backtrace tauchte über den Launcher auf. Der Renderer-Thread war verschwunden, bevor der Launcher ein Log abgreifen konnte.
Die Kamera rastete nicht auf das Schiff ein. Standard-Third-Person-Orbit-Kamera, die das Schiff im Bild halten soll. Beim Boot spawnte die Kamera am Weltursprung und blieb dort. Das Schiff war als kleiner Punkt in der Ferne über die Leere hinweg sichtbar.
Vier Bugs. Null Überlappung bei den Subsystemen. Die Art von Samstagmorgen, die darüber entscheidet, ob man den Workflow im Griff hat oder nicht.
Was jeden verursacht hat
Ich möchte jeden einzelnen durchgehen, weil jeder eine andere Lektion darüber lehrt, wie eine Codebasis in einem agentengetriebenen Workflow wächst und bricht.
Die pinke Grafik
Grundursache: Shader-Handles wurden bei jedem Render-Aufruf über den String-Namen nachgeschlagen, und ein Refactor über die Feiertage hatte die Initialisierung des Shader-Cache an einen anderen Punkt in der Boot-Sequenz verschoben. Die prozeduralen Generatoren renderten jetzt, bevor der Shader-Cache warmgelaufen war. Sie bekamen den Null-Handle-Fallback zurück, den der Renderer pflichtbewusst als knalliges Pink darstellte.
Der Fix bestand darin, ein explizites ShaderCache-Utility zu schaffen, das aufgelöste Shader-Referenzen bei erster Verwendung cacht und eine synchrone GetOrCreate-API bereitstellt, die die prozeduralen Generatoren aufrufen können, ohne sich um die Boot-Reihenfolge kümmern zu müssen. Jeder prozedurale Generator wurde darauf umgestellt. Pink verschwunden.
Die Lektion: Eine Annahme über die Init-Reihenfolge, die implizit in der Boot-Sequenz lebte, wurde durch ein Refactor gebrochen, das die Annahme nicht markierte. Implizite Reihenfolge ist zerbrechlich. Der neue Cache macht die Reihenfolge explizit und selbstheilend.
Der außer Kontrolle geratene Punktestand
Grundursache: Das GameplayHUD zählte Kills auf der UI-Seite, und der ScoreManager zählte Kills ebenfalls auf der Simulationsseite. Beide hörten auf dasselbe Kill-Event-Signal. Beide addierten zu einem gemeinsamen Punktestand-Feld. Der Punktestand wurde pro Kill zweimal erhöht.
Der Fix bestand darin, den kanonischen Eigentümer des Punktestands festzulegen. Der ScoreManager besitzt die Wahrheit. Das GameplayHUD liest vom ScoreManager und rendert. Die doppelte Erhöhung im HUD wurde entfernt.
Die Lektion: In einer eventgetriebenen Engine laufen beide Abonnenten desselben Events. Schreiben beide in denselben Zustand, wird der Zustand proportional dazu falsch, wie viele Abonnenten geschrieben haben. Der Fix besteht darin, eine klare Linie darüber zu ziehen, wem welcher Zustand gehört. Einmal gezogen, wird der Bug unmöglich.
Der XR-Boot-Absturz
Grundursache: Das XR-Subsystem versuchte zu initialisieren, bevor das zugrunde liegende Grafikgerät bereit war. Beim Flachbildschirm-Boot funktionierte die Reihenfolge zufällig, weil das Grafikgerät immer bereit war, bis der Nutzer „Start” drückte. Beim XR-Boot löste die Headset-Erkennung den XR-Init-Pfad aus, bevor das Grafikgerät als bereit bestätigt war. Das XR-Subsystem dereferenzierte ein Null-Gerätehandle. Absturz.
Der Fix war ein XRBootstrap, das XR am frühestmöglichen Punkt im Boot erkennt, die tatsächliche XR-Initialisierung verzögert, bis das Grafikgerät die Bereitschaft bestätigt, und sauber herunterfährt, wenn irgendetwas in der Kette einen Fehler meldet. Der Absturz wird jetzt zu einer sauberen Fehlermeldung, und der Nutzer fällt auf den Flachbildschirm zurück.
Die Lektion: Harte Abstürze sind die schlimmste Art von Fehler, weil sie das Logging töten, das einem gesagt hätte, was passiert ist. Den Fehler früher zu erkennen und sauber zu melden, lohnt die Engineering-Kosten.
Die Kamera, die sich nicht einklinkte
Grundursache: Die Orbit-Kamera versucht beim Boot, das Spielerschiff anzuvisieren. Das Schiff wird vom prozeduralen Generator asynchron erzeugt, einige Frames nachdem die Kamera initialisiert. Die Kamera suchte im allerersten Frame nach dem Schiff, fand nichts, und versuchte es danach nie wieder.
Der Fix bestand darin, der Orbit-Kamera einen Wiederholungsmechanismus zu geben. Sie sucht das Schiff über eine begrenzte Anzahl von Frames, bevor sie aufgibt, und sobald sie einrastet, bleibt sie eingerastet. Die Kamera spawnt jetzt kurz am Ursprung und springt dann innerhalb der ersten Sekunde des Gameplays zum Schiff.
Die Lektion: Race Conditions zwischen Systemen, die auf leicht unterschiedlichen Zeitplänen initialisieren, beißen einen. Der Fix ist eine kleine Wiederholung, begrenzt, damit sie nicht ewig läuft, mit einem expliziten Timeout, der einen nützlichen Fehler erzeugt, wenn die Wiederholung erschöpft ist.
Was ich speziell über die Shooter-Demo gelernt habe
Drei Dinge, alle unangenehm.
Jedes Subsystem funktionierte isoliert. Die Integration war kaputt. Der Renderer funktionierte. Das Punktestand-System funktionierte. Das XR-Subsystem funktionierte. Die Kamera funktionierte. Die Shooter-Demo als integrierte Erfahrung funktionierte nicht. Das ist die Art von Fehler, die Unit-Tests jedes Mal entgeht, weil Unit-Tests ihrer Natur nach Dinge isoliert prüfen.
Das Feiertags-Refactor über die Pause Ende Dezember war die unmittelbare Ursache für mindestens zwei dieser Bugs. Die Reorganisation des Shader-Cache und die Aufteilung des Kill-Event-Abonnements landeten beide im Zeitfenster des Feiertags-Sprints. Beide waren isoliert betrachtet korrekte PRs. Beide brachen die Demo auf nicht offensichtliche Weise. Die Lektion ist, die integrierten Demos als Teil der CI laufen zu lassen, nicht nur die Unit-Tests. Diese Arbeit landete heute Morgen als separater PR.
Der XR-Boot-Pfad brauchte seinen eigenen Boot-Guardian. Harte Abstürze sind inakzeptabel, weil sie die Diagnose töten. Jeder Boot-Pfad, der nicht-triviale Hardware berührt, braucht einen Guardian. Wir haben das jetzt für XR. Wir haben es nicht für räumliches Audio oder für die Wi-Fi-7-Verbindung. Beide hinzuzufügen steht für die nächsten zwei Samstage auf der Warteliste.
Was Partner und Entwickler daraus mitnehmen sollten
Wenn Sie etwas bauen, das mehrere Subsysteme mit Init-Reihenfolge-Abhängigkeiten integriert, ist die Lektion dieselbe, die die Shooter-Demo gerade gelernt hat. Machen Sie die Init-Reihenfolge explizit. Machen Sie die Fehlermodi robust. Lassen Sie die integrierte Demo in der CI laufen, nicht nur die Unit-Tests.
Wenn Sie ein Indie-Team sind, das überlegt, Raku einzusetzen: Die Shooter-Demo ist ein echtes Sample, das wir bei jedem Release testen. Wenn sie kaputtgeht, sehen Sie sie kaputtgehen. Das ist die Art von öffentlichem Disziplin-Signal, das mehr zählt als eine Feature-Liste.
Wenn Sie ein KI-Labor sind, das überlegt, Ihr Modell in eine AR-Erfahrung einzustecken: Der XR-Boot-Pfad hat jetzt einen vertretbaren Guardian. Ihr Modell wird auf dem Weg hinein keinen harten Absturz sehen. Sie bekommen sauberes Fehler-Reporting, wenn irgendetwas in der Kette scheitert. Die Infrastruktur ist vorhanden.
Vier Bugs. Ein Samstag. Die Demo baut jetzt sauber. Die Partygäste wurden hinausbegleitet.
Zurück zum Bauen.
Ausliefern auf einer Runtime, die ihre eigenen Samples ausführt
RakuAI testet seine Demos bei jedem Release mit Integrations-CI und robusten XR-Boot-Guardians. Das ist das öffentliche Disziplin-Signal, das mehr zählt als eine Feature-Liste. Fangen Sie an, darauf zu bauen.