alttpr-launcher: Rando auf Knopfdruck

ALTTPR? Rando? Was?

Einer der ersten auf dem Super Nintendo (SNES) erschienenen Titel war The Legend of Zelda: A Link to the Past (Japan: November 1991, EU: September 1992), dritter Teil der Zelda-Reihe. Die Kurzfassung für alle, die noch nie etwas davon gehört haben: man spielt den Helden Link, der durch das Königreich Hyrule streift, Monster platt haut, Gegenstände aus Dungeons und anderen Verstecken zerrt, um schlussendlich den fiesen Oberbösewicht Ganon zu besiegen und die namensgebende Prinzessin Zelda zu retten.

A Link to the Past (abgekürzt als ALttP) wird schon lange gespeedrunnt (laut Leaderboard-Historie erstmals 2008), üblicherweise die japanische Version 1.0. Die japanische Version, weil dort die Texte kürzer sind, was beim Wegdrücken der Dialoge Zeit spart. Version 1.0, weil dort manche Glitches möglich sind, die in späteren Versionen gepatcht wurden. Bei diesen NMG-Runs (No Major Glitches, also ohne Glitches die das Spiel komplett zerstören) ist der Ablauf immer gleich, bis auf wenige Situationen die vom Zufall bestimmt werden (man spricht von RNG, was strenggenommen erstmal nur für Random Number Generator steht). Dieser immer gleiche Ablauf erlaubt, dass Routen optimiert und ganze Räume quasi auswendig gelernt werden können, z.B. in welcher Reihenfolge man die Gegner ausschaltet um deren Bewegungsmuster nicht zu verändern und insgesamt möglichst schnell durch zu kommen. Dementsprechend dicht sind die aktuellen Bestzeiten beieinander: 1:23:00, 1:23:09, 1:23:28.

Dieser immer gleiche Ablauf ist zwar für Speedrunner essenziell, aber es gibt ja auch andere Zielgruppen und Interessen. So hat David Carroll aka. Dessyreqt 2014 mit der Entwicklung eines Item Randomizers begonnen, der 2016 erstmalig released wurde und seitdem von der ALttP-Community weiter entwickelt wird. Aktuell ist alttpr.com die zentrale Anlaufstelle, eine Webseite die gleichzeitig das Frontend für den Randomizer darstellt. Im Prinzip funktioniert es so, dass man die Original-ROM (Zelda no Densetsu: Kamigami no Triforce v1.0) hochlädt, die Parameter für seinen Seed festlegt, diesen rollen lässt (von engl. to roll [dice] = würfeln) und danach die gepatchte ROM-Datei wieder runterlädt. Diese kann dann in einem Emulator wie z.B. Snes9x oder RetroArch (vorzugsweise mit dem bsnes-mercury-Core) gespielt werden, oder auch auf echter Hardware mit einer SD-Karten-Cartridge (Stichworte SNES EverDrive, SD2SNES, FXPAK Pro) oder einer Super Nt.

Was in einem Rando-Seed alles anders ist, kann weitreichend beeinflusst werden. Im einfachsten Fall sind nur die Fundorte der diversen Gegenstände vertauscht (geshuffelt). Das klingt vielleicht trivial, führt jedoch zu völlig neuen Spielabläufen, weil manche Gegenden zum Beispiel nur bei Verfügbarkeit bestimmter Gegenstände bereist werden können. Um etwa die Zora River Ledge zu erreichen benötigt man die Flippers (Schwimmflossen), die im unveränderten Original-Spiel (der "Vanilla-ROM") gegen eine einmalige Zahlung von 500 Rupees von King Zora bezogen werden können -- in einem Rando-Seed aber vielleicht als Belohnung für den Sieg über Moldorm (den Dungeon-Boss in Tower of Hera) erhalten werden, den man jedoch nur erreichen kann, wenn man zuvor ((Handschuhe UND Lampe) ODER Flöte) UND (Spiegel ODER (Hookshot UND Hammer)) gefunden hat. Außerdem ist vom Key Layout (also in welchen Truhen innerhalb des Dungeons sich die verschiedenen Schlüssel für die Türen befinden) abhängig, ob zwingend eine Feuerquelle (Lampe oder Fire Rod) benötigt wird.

Ich habe die Gegenstände meiner ersten selbst gespielten Seeds manuell mit Papier und Bleistift getrackt und die Logik im Kopf verfolgt (nachdem ich zuvor dutzende Runs anderer Spieler angesehen hatte). Das ist kognitiv recht anspruchsvoll und entsprechend fehleranfällig, funktioniert aber hervorragend im Zusammenspiel mit alter Hardware und ohne zusätzliche Displays. Wenn man per Emulator spielt und eh einen PC laufen hat, dann empfiehlt sich der Einsatz eines Trackers wie dem Dunka-Tracker (offizielle Bezeichnung: ALTTP Randomizer Community Tracker). Mit geeignetem Setup erlaubt dies auch Auto Tracking, d.h. eingesammelte Gegenstände werden automatisch getrackt (mehr dazu später). Solche Tracker sind auch in den offiziellen Races erlaubt.

Obwohl die Zeiten verschiedener Rando-Runs naturbedingt schlecht vergleichbar sind, ist es natürlich ohne weiteres möglich, einen identischen Seed kompetitiv zu runnen -- und das wird gemacht. Sogar im großen Stil: es gibt regelmäßige Turniere mit über hundert Teilnehmern; und das nach einem harten Qualifying, bei dem noch mal so viele Spieler ausgesiebt wurden. Die hauptsächlichen Plattformen sind Twitch und Discord, weshalb man im "durchsuchbaren" Teil des World Wide Webs vergleichsweise wenig darüber findet. Auch wenn das etwas elitär und nach "nur für Mitglieder" klingt: ich habe die Rando-Community bisher als sehr freundlich, offen und einladend erlebt.

Für alle, denen das zu kompliziert war und die sich einfach nur berieseln lassen möchten: schaut mal in den Stream von Teto rein; der Rest kommt dann von selbst.

Rando unter Linux

Es gibt etliche Anleitungen zur Konfiguration eines Rando-Setups unter Windows, bebildert, kleinteilig, präzise und anfängerfreundlich. Wenn es aber um Linux geht, dann wird es schon etwas dünner und ich hatte ein halbes Wochenende damit zugebracht, bis alles lief. Linux war eine Voraussetzung für mich, weil das Ganze auf einem Raspberry Pi laufen sollte, der am großen Wohnzimmer-Fernseher hängen kann. Inzwischen hängt es am Fernseher, ist aber ein richtiger PC geworden, weil ich keinen passenden Pi bekommen habe und sich die Emulation als überraschend rechenintensiv herausgestellt hatte. Ich denke ein 5er-Pi müsste es am Ende schon sein, habe diesen Ansatz aber nicht weiter verfolgt.

Als Emulator verwende ich RetroArch. Hier lauert der erste Fallstrick: es wird eine ausreichend aktuelle Version benötigt, damit das Auto-Tracking funktioniert. Wäre ich gleich der offiziellen Anleitung gefolgt, anstatt das Paket aus dem Ubuntu-Repository zu benutzen, hätte ich mir ein paar Stunden Fehlersuche sparen können. RetroArch unterstützt verschiedene Cores, die alle erdenklichen Konsolen emulieren. Für das Super Nintendo Entertainment System gibt es verschiedene Cores, ich verwende bsnes-mercury in der Balanced-Variante (Paket libretro-bsnes-mercury-balanced). Etwas fummelig ist die Einrichtung eines Gamepads; wenn es nicht out-of-the-box funktioniert, muss man sich durch googeln (keine Angst, es gibt viele detaillierte Anleitungen).

Wenn man nur spielen will, dann war das alles. Um das Auto-Tracking zum Laufen zu bekommen, muss in RetroArch die Unterstützung für "Network Commands" aktiviert werden. Außerdem wird noch das Programm QUsb2Snes benötigt. Dieses ist eine Art Gateway zwischen dem Websocket-Protokoll, das der Dunka-Tracker spricht, und dem RetroArch-Core (und anderen Emulatoren). Das Auto-Tracking an sich beinhaltet viel Low-Level-Magie. QUsb2Snes ist völlig egal, welches Spiel da läuft, es fragt nur nach Speicherinhalten, die per Adresse und Länge spezifiziert werden. Der Dunka-Tracker weiß, welches Bit im Arbeitsspeicher des SNES für welchen Gegenstand im Spiel steht und zerpopelt den Byte-Brei entsprechend. QUsb2Snes muss man selbst aus den Quellen übersetzen. Das klingt schlimmer als es ist, man benötigt nur eine Reihe von Abhängigkeiten, die aus der Paketverwaltung installiert werden können (aktuell: qtbase5-dev, libqt5websockets5-dev, libqt5serialport5-dev, g++ und make). Mehr Details sind in der Datei COMPILING.adoc enthalten, war insgesamt aber relativ schmerzfrei. Repository mit --recurse-submodules klonen!

Nachdem RetroArch und QUsb2Snes gestartet wurden kann der Dunka-Tracker geöffnet werden. Hier im unteren Bereich unter "Display Settings" die Option "Autotracking" auf "Yes" stellen; Portnummer 8080 passt normalerweise. Damit der Tracker so richtig Spaß macht, muss er zuvor wissen, welche Parameter beim Rollen des Seeds benutzt wurden. Dies kann entweder manuell eingestellt werden, oder man lässt den Tracker die Einstellungen importieren ("Import Flags"). Beim Importieren muss die Seed-URL (Download-Link beim Rollen über alttpr.com) angegeben werden; Vorsicht: bei manchen abgefahrenen Modi muss noch von Hand nachgeholfen werden. Ein nachträglich gestarteter Tracker erkennt normalerweise bereits erledigte Checks sowie eingesammelte Gegenstände (was auch für Start-Items funktioniert).

Der Tracker kennt nicht nur die Bit-Positionen der diversen Gegenstände, sondern auch die Voraussetzungen um die verschiedenen Gegenden zu erreichen. So wird beispielsweise bei Vorhandensein von Flöte, dem zweiten Paar Handschuhen und dem Spiegel die Checkerboard Cave grün dargestellt, auch wenn keine Moon Pearl vorliegt -- denn man kann trotz fehlender Moon Pearl im Bunny State durch die Dark World laufen und zur Checkboard Cave spiegeln, auch wenn man sonst nichts in der Dark World tun kann und entsprechend alles andere rot ist. Gerade während eines Races kann man solche Details gerne vergessen, und wenn die Moon Pearl dann ausgerechnet dort liegt, hat man ziemlich schlechte Chancen das Race noch zu gewinnen (man spricht vom last locaten, wenn der gesuchte Gegenstand erst auf dem letzten möglichen Check auftaucht). Diese Funktion des Trackers ist übrigens unabhängig vom Auto-Tracking und kann auch manuell bedient werden.

SahasrahBot und pyz3r

Wer auf alttpr.com etwas herumgestöbert hat, der hat neben dem Punkt "Generate Randomized Game" (Randomizer) vielleicht auch den Punkt "Create Custom Game" (Customizer) entdeckt. Der Customizer erlaubt eine viel stärkere Einflussnahme auf den Seed, wie z.B. die Vorgabe von Start-Items, diverse Map/Key/Compass-Shuffles, erforderliche Glitches und vieles mehr. Diese erhöhte Flexibilität kommt allerdings auch mit einer erheblichen Komplexität bei der Konfiguration.

Thomas Prescott aka. Synack verdanken wir den wunderbaren SahasrahBot, einem via Discord ansprechbaren Bot der Rando-Seeds rollt und über ihren Download-Link verfügbar macht. Dabei bietet SahasrahBot eine Menge von Presets an, die besonders beliebte Kombinationen in Form eines YAML-Dokuments spezifiziert, wie z.B. "Casual Boots" (ein Standard-Seed mit Start-Boots und Start-Schwert auf dem Onkel). Das YAML-Dokument beschreibt dabei ziemlich genau das JSON-Dokument, das zum Generieren des Seeds an den Radomizer- bzw. Customizer-Endpunkt des Randomizer-Backends gesendet werden muss (abhängig von dem Attribut customizer).

Hinten raus nutzt SahasrahBot die Bibliothek pyz3r (ich habe mir das als "python zelda 3 randomizer" zusammengereimt), und ist gleichzeitig auch die beste Form der Dokumentation, die ich finden konnte. Diese Bibliothek vereinfacht die Nutzung der alttpr.com-API ganz erheblich und übernimmt auch as Patchen der Vanilla-ROM sowie das anschließende Feintuning wie z.B. die Sprite-Auswahl, Wahl der Herzchen-Farbe und ganz wichtig: die Aktivierung des Quickswaps.

Mit pyz3r ist es nicht mehr so schwer, einen eigenen Client zu schreiben, der das Rollen und Starten eines Seeds automatisiert. Und genau das habe ich gemacht.

Jetzt noch automatisch

Mein Programm alttpr-launcher wird komplett über die Kommandozeile sowie eine Konfigurations-Datei im YAML-Format gesteuert:

usage: main.py [-h] (--roll-seed path | --get-seed hash | --list-layouts) [--config path] [--layout name]

Bei der Funktion --roll-seed wird ein Preset-Dokument angegeben (gleiches Format wie bei den SahasrahBot-Presets) und darauf basierend ein neuer Seed erzeugt. Mit der Funktion --get-seed wird ein bereits existierender, per Hash-Code spezifizierter Seed heruntergeladen. Mit diesem Seed wird die hinterlegte Vanilla-ROM gepatcht und das Ergebnis daraus entsprechend der Einstellungen aus der Konfigurations-Datei abgestimmt und abgelegt.

Danach werden die diversen Programme (Emulator, QUsb2Snes und Webbrowser für den Tracker) gestartet und gemäß eines vorab definierten Screen-Layouts positioniert (unter Verwendung von wmctrl). Das im Download-Paket hinterlegte Layout passt genau zu meinem Full-HD-Fernseher (1920 x 1080), kann aber leicht in config.yaml angepasst werden. Die Einstellungen aus dem Seed werden per URL-Parameter an den Dunka-Tracker weitergegeben, sodass im Idealfall das Setup direkt spielbereit ist. Der Tracker ist per iframe in eine HTML-Seite eingebettet, die zusätzlich noch einen einfachen Timer mit Start/Stop/Reset beinhaltet.

Das Ubuntu auf meinem Media-PC habe ich so eingerichtet, dass es direkt ohne Login zum Desktop durch startet, auf dem diverse Verknüpfungen liegen, die jeweils einen per Preset definierten Seed rollen und starten. An diesem PC habe ich einen drahtlosen Trackball hängen, mit dem ich vom Sofa aus bequem den Tracker steuern kann. Somit muss nur noch der PC gestartet und ein Icon doppelgeklickt werden, schon kann's losgehen.

Downloads

Version Datum Datei Beschreibung
1.0 2023-12-28 alttpr-launcher-1.0.tar.gz Erstes Release

Zurück zur Hauptseite