1 Punkte von GN⁺ 2024-09-14 | 1 Kommentare | Auf WhatsApp teilen
  • Um die Trial-Game-Engine auf der Nintendo Switch auszuführen, wurde die Common-Lisp-Laufzeit SBCL über 2 Jahre portiert; inzwischen läuft das Projekt so weit, dass auf der Switch Lisp-Code kompiliert und ausgeführt sowie mit Shared Libraries interagiert werden kann
  • Die Switch bietet zwar eine Umgebung mit ARM64 Cortex-A57, 4 Kernen und 4 GB RAM, hat aber keine Shell, keine Kommandozeile, keinen Compiler und erlaubt auch keine Erzeugung ausführbarer Speicherseiten, weshalb das nicht zum üblichen SBCL-Bootstrap-Verfahren passt
  • Der Build kombiniert einen Linux-ARM64-Host mit dem Nintendo SDK und verwendet fasteval, immobile-code und elfination, um den Core in Code und Daten aufzuteilen und anschließend in ein finales Paket zu bündeln
  • Das Trial-REPL-Beispiel kann auf dem Switch-Devkit bereits OpenGL-Kontext, Eingabeverarbeitung und Shader-Zuweisung übernehmen, stürzt jedoch beim Ausführen des Garbage Collectors ab; Audio ist wegen Problemen mit C-Callbacks noch nicht möglich
  • Die wichtigsten verbleibenden Aufgaben sind die Stabilisierung von Safepoints für einen Multi-Thread-GC, die Wiederherstellung von C-Callbacks, das Vermeiden von CLOS-Laufzeitkompilierung, Performance-Optimierungen; aufgrund der Nintendo-NDA kann ein Teil des Codes nicht veröffentlicht werden

Wie weit SBCL auf der Switch bereits funktioniert

  • Um die Trial-Game-Engine auf der Nintendo Switch auszuführen, wurde in den vergangenen zwei Jahren gemeinsam mit Charles Zhang an einer Portierung von SBCL gearbeitet
  • Die zentrale Herausforderung bestand darin, die unter Trial laufende Common-Lisp-Laufzeit an die Switch-Plattform anzupassen
  • Was derzeit möglich ist:
    • Laufzeit und Compiler wurden portiert, sodass sich auf der Switch beliebiger Lisp-Code direkt kompilieren und ausführen lässt
    • Shared Libraries lassen sich anbinden
    • Mehrere Portabilitätsbibliotheken für Betriebssystemfunktionen, die Trial auf der Switch benötigt, wurden ebenfalls portiert
  • Das REPL-Beispiel von Trial läuft auf dem Switch-Devkit
    • Da die Switch selbst kein Terminal hat, erzeugt Trial einen OpenGL-Kontext, verwaltet Eingaben, weist Shader zu und zeigt Text auf dem Bildschirm an
  • Was noch blockiert:
    • Sobald SBCL versucht, den Garbage Collector auszuführen, stürzt es kurz darauf ab
    • Wegen spezieller Einschränkungen der Switch bleiben einige Punkte offen, die sich nicht einfach umgehen lassen
    • Der C-Callback-Mechanismus ist defekt, weshalb keine Audioausgabe möglich ist
    • Es könnte weitere bislang unentdeckte Probleme bei der Performance geben

Kosten und Nachhaltigkeit

  • Die Portierungsarbeit hat bisher etwa 17.000 US-Dollar gekostet, und Charles Zhang wurde monatlich dafür bezahlt
  • Die Einnahmen stammen aus Verkäufen von Kandria sowie Unterstützung über Patreon, GitHub Sponsors und Ko-Fi
    • In guten Monaten etwa 1.200 Dollar
    • In schlechten Monaten etwa 600 Dollar
  • In Zürich, Schweiz, ist es schwierig, allein von diesen Einnahmen zu leben; derzeit wird mit den Eltern zusammen gewohnt und durch reduzierte persönliche Ausgaben durchgehalten
  • Da fraglich ist, ob die Verkäufe von Kandria für die Switch die Portierungskosten wieder einspielen können, wird die Entscheidung schwierig, wofür die begrenzten Ressourcen eingesetzt werden sollen
  • Die Unterstützungseinnahmen sollen vorerst in die SBCL-Switch-Portierung und ein derzeit laufendes, noch nicht angekündigtes Spielprojekt fließen

Switch-Umgebung und Portierungsbedingungen

  • Öffentlich bekannte Eigenschaften der Switch-Umgebung:
    • Nutzercode läuft auf einem ARM64-Cortex-A57-Chip
    • Es stehen 4 Kerne und 4 GB RAM zur Verfügung
    • Das System läuft auf einem proprietären Mikrokernel-Betriebssystem, das ursprünglich für den Nintendo 3DS entwickelt wurde
  • Für SBCL existiert bereits ein ARM64-Linux-Port, sodass die Codegenerierung selbst bereits gelöst war
  • Kandria passt problemlos in 4 GB RAM, daher ist die Speicherkapazität an sich kein Problem
  • Die eigentliche Schwierigkeit liegt in der Interaktion mit dem proprietären Betriebssystem der Switch
    • Es gibt Einschränkungen, die typische PC-Betriebssysteme nicht haben
    • Für ein System wie Lisp ist das besonders problematisch
  • Die Switch ist die einzige Konsole, die das von Trial genutzte OpenGL-Rendering unterstützt
    • Xbox unterstützt nur DirectX, allerdings soll es eine von Microsoft entwickelte OpenGL-→-DirectX-Schicht geben, sodass eine Möglichkeit bestehen könnte
    • Playstation soll eine vollständig proprietäre Grafik-API haben, weshalb eine Portierung auf diese Plattform derzeit nicht in Betracht gezogen werden soll
  • Für die Entwicklung wurde über Nintendo of Europe Zugang erhalten und ein Devkit für etwa 400 Dollar gekauft
  • Devkit und SDK laufen nur unter Windows, was den Build-Prozess zusätzlich belastet

Der übliche SBCL-Build und der Konflikt mit der Switch

  • SBCL ist größtenteils in Lisp selbst geschrieben und enthält zusätzlich eine kleine C-Laufzeit
  • Die C-Laufzeit wird mit einem normalen C-Compiler gebaut, muss aber Informationen über die Ziel-Betriebssystemumgebung kennen
  • Da die Laufzeit selbst keinen Lisp-Compiler enthält, wird zum Bootstrappen von SBCL eine andere Lisp-Implementierung benötigt, idealerweise eine andere Version von SBCL
  • Fünf Build-Schritte auf dem PC

    • build-config
      • Sammelt Build-Konfigurationsoptionen für das Ziel und gibt sie in einem Format aus, das die späteren Build-Schritte lesen können
    • make-host-1
      • Baut mit einem Host-Lisp-Compiler einen Cross-Compiler
      • Erzeugt außerdem Header-Dateien, die das Speicherlayout von Lisp-Objekten als C-Strukturen beschreiben
    • make-target-1
      • Erzeugt mit dem Ziel-C-Compiler die C-Laufzeit
      • Die C-Laufzeit enthält den Garbage Collector und Glue-Code für die Interaktion mit der Betriebssystemumgebung
      • Außerdem werden aus den Betriebssystem-Headern Konstanten erzeugt, die Ziel-Lisp-Compiler und Laufzeit kennen müssen
    • make-host-2
      • Baut mit dem in make-host-1 erzeugten Lisp-Cross-Compiler das Ziel-Lisp-System, also Compiler und Standardbibliothek
      • Erzeugt einen Cold Core, in den die Laufzeit einspringen kann
    • make-target-2
      • Lädt den Cold Core in die Ziel-Laufzeit und schließt den Bootstrap ab
      • Nachdem das Lisp-System in den Speicher geladen wurde, wird es als Warm Core gedumpt
      • Danach lassen sich neuer Code laden und neue Images frei dumpen
  • Wo es auf der Switch problematisch wird

    • Im SBCL-Build gibt es einen Schritt, in dem Lisp-Code auf der Zielmaschine ausgeführt werden muss
    • Nutzer-Lisp-Code lässt sich nicht wie C nur per Batch kompilieren, sondern geht davon aus, zur Laufzeit in der Zielumgebung zu sein
    • Auch die Auslieferung einer Anwendung ähnelt make-target-2: Lisp-Code wird schrittweise kompiliert, dann wird ein Core mit angehängter Laufzeit gedumpt
    • Die SBCL-Laufzeit mappt beim Start einen Core-Blob in den Speicher, markiert Code-Seiten als ausführbar und springt dann in eine benutzerdefinierte Einstiegfunktion
    • Auf der Switch ist dieser gesamte Ablauf problematisch

Build-Strategie für die Switch

  • Die Switch ist keine PC-Umgebung und bietet weder Shell noch Kommandozeile noch Compiler-Toolchain
  • Da das Betriebssystem die Erzeugung ausführbarer Speicherseiten nicht erlaubt, ist selbst bei ausführbaren Build-Schritten direkt auf der Switch die übliche inkrementelle Lisp-Kompilierung nicht möglich
  • Der Großteil des Codes ist plattformunabhängig und kann für ARM64 kompiliert werden
  • Nur die Teile, die mit der Betriebssystemumgebung interagieren, müssen wissen, dass das Ziel die Switch ist; deren Umsetzung kann in einer anderen ARM64-Umgebung wie Linux erfolgen
  • Build-Schritte für die Switch

    • build-config
      • Läuft auf dem Host-System und verwendet spezielle Flags, die einen Switch-Build markieren
      • Aktiviert das fasteval-Contrib
      • Da auf der Switch keine Laufzeitkompilierung möglich ist, ersetzt fasteval die Stellen, an denen sonst ein Compileraufruf nötig wäre
    • make-host-1
      • Keine großen Änderungen, erzeugt aber Header zur Vorbereitung der Switch-Plattform
    • make-target-1
      • Cross-kompiliert die C-Laufzeit für die Switch mit dem vom Nintendo SDK bereitgestellten C-Compiler
      • Da das Switch-Betriebssystem nicht POSIX-kompatibel ist, wurde in SBCL ein eigenes Laufzeitziel geschaffen; Unterschiede wie dynamisches Linken oder Page Mapping werden per Stub oder Wrapper behandelt
    • Zweites build-config, make-host-1, make-target-1
      • Erzeugt ein normales ARM64-Linux-System mit demselben Funktionsumfang wie die Switch
      • Einige Lisp-Prozesse erhalten spezielle Flags, damit sie wissen, dass das endgültige Ziel die Switch ist
    • make-host-2, make-target-2
      • Liefern einen leicht spezialisierten SBCL-Build für Linux ARM64, mit dem anschließend Nutzercode kompiliert wird
    • Kompilierung des Nutzercodes
      • *features* wird angepasst, damit das System glaubt, auf der Switch statt unter Linux zu laufen
      • Enthält :nx, aber nicht :linux, :unix oder :posix
      • Danach wird ASDF deaktiviert und ein Programm wie Trial annähernd auf normalem Weg kompiliert, bevor ein neuer Core gedumpt wird

Core-Paketierung mit immobile-code und elfination

  • Da sich auf der Switch die übliche Strategie zum Mapping eines Core nicht verwenden lässt, funktioniert es nicht, dem Laufzeitsystem einfach einen neuen Core anzuhängen
  • Als Lösung werden die weniger bekannten SBCL-Funktionen immobile-code und elfination eingesetzt
  • Normales SBCL legt zur Laufzeit kompilierten Code auf beliebige Seiten und markiert diese als ausführbar
    • Wenn der Code später nicht mehr benötigt wird, kann er vom Garbage Collector eingesammelt werden
    • Speicherplatz lässt sich zurückgewinnen und verbleibender Code verdichten
  • immobile-code verwendet eine andere Strategie
    • Code wird in speziell reservierte Code-Seiten gelegt und dort belassen
    • Dieser Code kann nicht Garbage-Collected werden
    • Dafür lässt sich die traditionelle Unterstützung von Betriebssystemen für ausführbare Dateien nutzen
    • Ausführbare Dateien besitzen vorab markierte Sektionen, die das Betriebssystem als Code erkennt und beim Programmstart entsprechend mappt
  • Der Elfination-Schritt wandelt den Core in getrennte Code- und Datensektionen um, wie sie eine normale ausführbare Datei benötigt
    • Der Elfinator analysiert den Core
    • Er schreibt Assembler so um, dass positionsunabhängiger Code für Address Space Layout Randomization entsteht
    • Danach trennt er in eine reine Code-Assemblerdatei und eine reine Daten-Payload-Datei
  • Abschließende Schritte:
    • Erzeugen der Assemblerdatei mit dem Elfinator
    • Linken des finalen Binärprogramms
    • Bündeln von Metadaten, Shared Libraries, Assets und Anwendungs-Binärdatei mit den Authoring-Tools des Nintendo SDK zu einem finalen Paket

Build-Infrastruktur und was offengelegt werden kann

  • Für den Build wird mindestens eine ARM64-Linux-Maschine benötigt, die den Großteil des Builds übernimmt
  • Um Compiler und Authoring-Tools des Nintendo SDK auszuführen, wird entweder eine AMD64-Windows-Maschine oder eine AMD64-Linux-Maschine mit Wine benötigt
  • Die reale Konfiguration kommt damit fast auf drei Maschinen hinaus
    • AMD64-„Driver“
    • ARM64-Build-Host
    • Windows-VM für die Kommunikation mit dem Devkit
  • Zur Automatisierung wurde ein spezielles Build-System mit Caching und Synchronisationslogik zwischen den Maschinen geschrieben
    • Es musste auch in einer MSYS2/Windows-Umgebung laufen, was Probleme bei der Pfadumwandlung verursachte
  • Zusätzlich wurden Elfinator und immobile-code für ARM64 lauffähig gemacht sowie unterstützende Bibliotheken wie pathname-utils, libmixed und cl-gamepad portiert
  • Wegen der Nintendo-NDA können viele Details nicht veröffentlicht werden
  • Alles, was veröffentlicht werden kann, wurde upstream eingebracht; für die Lisp-Bibliotheken gibt es keine privaten Forks
  • Um nicht direkt an das Nintendo SDK zu koppeln, wurde eine separate C-Bibliothek gebaut; die Lisp-Bibliotheken greifen über dieses benutzerdefinierte Interface auf Betriebssystemfunktionen zu
    • So kann die Lisp-Seite öffentlich bleiben, während nur die kleine C-Bibliothek privat bleiben muss

Absolute Pointer und Relokation beim Laden

  • Elfination war ursprünglich nicht dafür gedacht, positionsunabhängigen ausführbaren Lisp-Code direkt zu erzeugen
  • Lisp-Code enthält normalerweise viele absolute Pointer
  • Deshalb waren Arbeiten an SBCL-Compiler und Laufzeit nötig, um die Relokation absoluter Pointer beim Laden zu unterstützen
  • Code-Objekte enthalten normalerweise Code-Konstanten, die dann keine absoluten Pointer mehr enthalten dürfen
    • Der GC kann ausführbare Sektionen nicht verändern
    • Auch der OS-Loader kann für die Relokation absoluter Pointer keine ausführbaren Sektionen verändern
  • Der Lösungsweg:
    • Absolute Pointer wie Code-Konstanten werden in beschreibbaren Speicher außerhalb des Text-Bereichs verschoben
    • Konstantenreferenzen im Code werden so umgeschrieben, dass sie aus diesem beschreibbaren Speicher laden
    • Loader und bewegender GC können die Pointer in diesem Bereich anpassen

Probleme mit Garbage Collector und Safepoints

  • Der Standard-GC von SBCL ist gencgc, also ein generationaler Garbage Collector
  • gencgc trennt Objektgenerationen, scannt sie mit unterschiedlicher Häufigkeit und kopiert Objekte zur Speicherverdichtung in andere Generationsbereiche
  • Diese Struktur ist auf der Switch an sich nicht das Problem, wohl aber Multi-Threading
  • Bei mehreren Threads kann ein Thread gerade auf ein Objekt zugreifen, sodass es nicht beliebig verschoben werden kann
  • Die einfachste Lösung ist, vor dem Start des GC alle Threads anzuhalten
  • Unterschiede zwischen Unix und der Switch

    • Auf Unix-Systemen kann über den Signal-Mechanismus anderen Threads ein Signal geschickt werden, damit sie sich parken
    • Die Switch hat keinen Signal-Mechanismus und Threads können auch nicht unterbrochen werden
    • Jeder Thread muss also selbst bemerken, dass er sich parken soll; die übliche Strategie dafür sind Safepoints
    • Bei Safepoints fügt der Compiler zusätzlichen Code ein, der prüft, ob ein Thread geparkt werden soll
    • Da diese Prüfungen Kosten verursachen, sollten sie möglichst sparsam eingesetzt werden
    • Erfolgen sie zu selten, kann der GC nicht starten, bis alle Threads geparkt sind, wodurch andere Threads blockieren
    • Benötigen die Checks zu viele Instruktionen, stören sie CPU-Cache-Lines und Pipeline-Optimierungen
  • Grenzen des bisherigen SBCL-Safepoint-Systems

    • Das aktuelle Safepoint-System von SBCL wurde für Windows geschrieben
    • Auch Windows hat keine Signal-Handler zwischen Prozessen, aber im Unterschied zur Switch Signal-Handling für den aktuellen Thread
    • Das bisherige Verfahren:
      • Jeder Thread hält eine Seite, auf die der Safepoint ein Wort schreibt
      • Sobald GC startet, wird diese Seite als schreibgeschützt markiert
      • Erreicht ein anderer Thread den Safepoint und versucht, auf die Seite zu schreiben, entsteht ein Segmentation Fault und der Thread parkt sich
      • Dadurch ist nur eine einzige Schreibinstruktion nötig, was sehr effizient ist
    • Auf der Switch funktioniert auch diese Technik nicht, daher müssen komplexere Checks eingefügt werden
    • Da Safepoints außerhalb von Windows bislang nicht nötig waren, wurde dieser Teil anderswo nicht getestet und ist unabhängig von den Switch-Anpassungen instabil
    • Möglicherweise braucht dieser Bereich des Codebestands eine größere Bereinigung, hoffentlich aber keine vollständige Neuschreibung

Vermeidung von CLOS-Laufzeitkompilierung

  • CLOS verschiebt die Kompilierung der für Method Dispatch nötigen discriminating function normalerweise bis zum ersten Aufruf einer Generic Function
  • CLOS ist sehr dynamisch, und Methoden können fast jederzeit hinzugefügt oder entfernt werden, weshalb schwer feststellbar ist, wann das System „fertig“ ist
  • Auf der Switch kann kein Compiler aufgerufen werden, daher lässt sich dieses Modell der verzögerten Kompilierung nicht unverändert übernehmen
  • Die derzeitige Strategie stützt sich auf den Fast Evaluator
    • Die Funktion compile wird per Stub ersetzt
    • Statt echter Kompilierung wird eine Lambda erzeugt, die den Code im Evaluator ausführt
    • Das funktioniert auch für Nutzercode, der auf compile angewiesen ist
    • Die Ausführung ist jedoch deutlich langsamer als echte Kompilierung

Verbleibende Aufgaben und Performance-Risiken

  • Der fasteval-Ansatz ist vor allem ein Fallback
  • Unmittelbar vor dem Dump des finalen Images soll möglichst viel CLOS-Zustand eingefroren und möglichst viel Code vorab kompiliert werden
  • Auch der von Charles vor einigen Jahren wiederhergestellte Block-Compilation-Modus soll weiter untersucht werden
  • Wegen des relativ schwachen Prozessors der Switch könnten zusätzliche Optimierungen nötig sein
    • Auf Seiten der Trial-Engine
    • Im Kandria-Code
  • Bisher waren Optimierungen weniger dringlich, weil selbst Computer von vor 10 Jahren die Anforderungen des Spiels gut erfüllen konnten
  • Aufgaben mit hoher Priorität:
    • Den Garbage Collector vollständig funktionsfähig machen
      • Aktuell gelingt der Boot bis in die Trial-Hauptschleife
      • Beim Multi-Generation-Compaction-Schritt scheitert das System
    • Callbacks aus C wieder zum Laufen bringen
      • Dieser Teil der SBCL-Codebasis enthält viele handgeschriebene Assembler-Routinen
      • Sie müssen möglicherweise an immobile-code und Elfination angepasst werden
      • Trial benötigt Callbacks nur für die Soundwiedergabe über libmixed
    • Weitere Portabilitätsarbeit, bis die Selftest-Suite von Trial auf der Switch vollständig durchläuft

Durch NDA begrenzter Offenlegungsrahmen

  • Die gesamte Portierungsarbeit würde gerne veröffentlicht werden, kann wegen der Nintendo-NDA aber nicht offengelegt werden
  • Was offengelegt werden kann, wird upstream eingebracht oder öffentlich gemacht
  • Einige Codebestandteile mit direkter Anbindung an das Nintendo SDK dürfen nicht mit Personen geteilt werden, die die NDA nicht unterzeichnet haben
  • Wer Common-Lisp-Spiele für die Nintendo Switch veröffentlichen möchte, könnte nach Unterzeichnung der NDA Zugang zur Portierungsarbeit erhalten
  • In den monatlichen Updates für Patrons sollen Fortschritte detaillierter geteilt werden

1 Kommentare

 
GN⁺ 2024-09-14
Hacker-News-Meinungen
  • In den letzten Wochen habe ich Trial(https://github.com/Shirakumo/trial) ausprobiert, um mit Spieleentwicklung in Common Lisp zu experimentieren, und es hat mir großen Spaß gemacht.
    Dass man fast alles ändern kann, während das Spiel läuft, ist wirklich ein großer Vorteil; ich hoffe daher, dass diese Portierung gelingt.

    • Sprachen aus der Lisp-Familie scheinen gut zur Spieleentwicklung zu passen. Dass man Code interaktiv auswerten kann, ohne neu zu kompilieren, macht bei Feature-Entwicklung, inkrementeller Entwicklung und Bugfixes einen großen Unterschied.
      Auch dass man den Anwendungszustand zwischen Codeänderungen beibehalten kann, wirkt sehr nützlich, und Common Lisp scheint eine deutlich schnellere Sprache zu sein, als ich vage angenommen hatte.
      Persönlich sehe ich nicht nur bei der Spieleentwicklung, sondern generell die Nutzung von Datenstrukturen, insbesondere den Umgang mit Maps, als größten Nachteil, weil sie etwas ungelenk ist; dieser Kompromiss scheint aber akzeptabel.
  • Das ist wirklich cool. SBCL ist eine hervorragende Sprachimplementierung, und ich wollte schon immer Common-Lisp-Entwicklung auf einer „echten“ Spielkonsole ausprobieren.
    Dass Shinmera diese Arbeit macht, überrascht mich im positiven Sinne. Ich habe sie früher ein paar Mal in #lispgames und im Lisp-Discord gesehen, wusste aber nicht, dass sie auch Interesse an so Low-Level-Entwicklung hat.
    Es wirkt umso beeindruckender, weil ich einmal kurz in die Interna von SBCL hineingeschaut habe und eingeschüchtert wieder zurückgewichen bin. Ich frage mich auch, ob die Kombination aus SBCL mit Threading und SDL2 inzwischen auf dem Raspberry Pi läuft.

    • Die Arbeit an SBCL mache nicht ich; das ist alles die Arbeit von Charles, der dafür beauftragt wurde. Mein Teil ist die Portabilität, damit Trial in verschiedenen Umgebungen läuft, die gesamte Build-Struktur und die anfänglichen Runtime-Stubs.
      Und wie schon gesagt: *her :)
    • Müsste es nicht „her“ heißen?
  • Danke an den Autor für den interessanten und detaillierten Beitrag. Details zu offiziellen Konsolenportierungen auf diesem Niveau kommen einem normalerweise erst Jahre nach dem Ende der Lebenszeit einer Konsole zu Gesicht.
    Wenn ich solche tiefgehende Arbeit lese, denke ich an meinen eigenen Job, in dem ich den ganzen Tag repetitive Software benutze, und werde ein wenig neidisch.

    • Nach meiner Erfahrung waren auch solche offiziellen Tools meist ziemlich provisorisch zusammengestückelt, und abgesehen von Debugging-Unterstützung waren moderne Homebrew-Toolchains für ältere Plattformen oft besser.
      Devkits hatten zwar meist bessere Hooks, zugleich hatte es aber auch Vorteile, den GDB-zentrierten Ablauf zu vermeiden. Nachdem ich beides erlebt habe, bin ich mir nicht sicher, ob das wirklich eine Welt ist, auf die man so neidisch sein sollte.
    • Ich war gerade dabei, wieder einen weiteren Tag mit Ruby on Rails zu beginnen, und habe darüber nachgedacht, welche Hobbys oder Open-Source-Projekte später meine Aufmerksamkeit verdienen könnten.
      Vielleicht geht es nicht um ein Projekt, das meine Aufmerksamkeit braucht, sondern um ein Projekt, das meine Aufmerksamkeit später brauchen wird :D
  • Bei der Stelle „Ich würde gern alles offenlegen, kann es aber wegen der NDA nicht“ frage ich mich, warum das offizielle SDK statt eines uneingeschränkten Homebrew-SDKs(https://switchbrew.org/wiki/Setting_up_Development_Environment) verwendet wurde.
    Rein spekulativ könnte es daran liegen, dass Nintendo keine offiziellen Releases von Spielen erlaubt, die mit einem Drittanbieter-SDK gebaut wurden.

    • Mit Homebrew erstellte Spiele kann man nicht veröffentlichen; man muss zwingend das offizielle SDK verwenden. Außerdem besitzen nur sehr wenige Leute eine jailbroken Switch, sodass es außer über Emulatoren sehr schwierig wird, das Spiel überhaupt auszuführen.
  • Dazu passt https://opengoal.dev.
    Zum Hintergrund: Naughty Dog verwendete bei der Entwicklung der Jak-&-Daxter-Reihe für die PS2 eine eigene Lisp-ähnliche Sprache namens GOAL. Weil genügend Debugging-Informationen übrig geblieben waren, war Reverse Engineering möglich, und das OpenGOAL-Projekt hat das geschafft.
    Heute lassen sich diese Spiele auf allen Plattformen ausführen, auf die der GOAL-Compiler portiert wurde. Soweit ich weiß, ist das derzeit etwa x86; eine Portierung auf die Switch wäre cool.

  • Ich habe Kandria gerade gekauft. Ich spiele nicht besonders viel und werde es wahrscheinlich nicht ausgiebig spielen, aber Shinmera erweitert eindeutig die Grenzen der Lisp-Welt, und das ist unterstützenswert.

  • Ihre Arbeit ist wirklich großartig. Als jemand, der gelegentlich Common Lisp verwendet, freut mich so etwas sehr.

  • Ich wünschte, Firmen wie Nintendo oder Sony würden solche Bemühungen direkt unterstützen. Letztlich ist es eine weitere Möglichkeit, Spiele für Konsolen zu entwickeln, also IP zu schaffen; ich weiß nicht, welche Nachteile es hätte, wenn die Plattformen so etwas wie einen Github Accelerator starten würden.

    • Es ist bereits bekannt, dass Spieleentwickler jedes vom Plattformbetreiber verlangte Verfahren auf eigene Kosten durchlaufen. Entwickler haben kaum Verhandlungsmacht, um bei der Entscheidung, für welche Plattform sie veröffentlichen, wegen technischer Details wählerisch zu sein.
      Nintendo muss keinen neuen Anreiz schaffen, um Switch-Releases zu fördern. Den größten Anreiz gibt es bereits: über 140 Millionen verkaufte Geräte und eine hohe Kaufquote bei Spielen.
      Trotzdem gibt es nicht mehr so viele Verfahren wie früher. Die heutigen Systeme sind größtenteils auf allgemeine CPU- und GPU-Architekturen konvergiert, und selbst wenn es Unterschiede gibt, sind sie oft nur kleine Verzierungen.
    • Früher gab es solche Unterstützung, aber was die Leute damit gemacht haben, war hauptsächlich, MAME und andere Emulatoren zu portieren oder Spiele aus der 8- und 16-Bit-Ära nachzubauen.
      Deshalb wird es schwierig, Gutes zu bekommen.
  • Wegen solcher Beiträge komme ich zu HN. Applaus an den ursprünglichen Autor und seinen Kollegen. Ich weiß, dass es unmöglich ist, aber es wäre wirklich ein Segen, wenn Nintendo seine Systeme nur ein bisschen offener behandeln würde.

  • Weil es nirgendwo erklärt wird: SBCL steht für „Steel Bank Common Lisp“.
    „Steel Bank Common Lisp(SBCL) ist ein Hochleistungs-Common-Lisp-Compiler. Es ist Open-Source-/freie Software unter einer großzügigen Lizenz und bietet neben einem Compiler und Runtime-System für ANSI Common Lisp auch eine interaktive Umgebung mit Debugger, statistischem Profiler, Code-Coverage-Tool und mehreren Erweiterungen.“
    https://www.sbcl.org/