Der lange Weg zu LuaHack

Ich bin mir ja immer noch nicht sicher, ob und wie ich Programmier-Topics auf diesem Blog behandeln soll.

Bislang habe ich diese Seite von mir in der Öffentlichkeit eher nicht so gezeigt¹, die Musik war (und ist btw immer noch) wesentlich wichtiger, und über das Programmieren muss ich dank Scrum & Co. eh schon mehr reden als mir eigentlich lieb ist.

Und selbst, wenn ich dazu übergehen sollte, hier über Programmierthemen zu fabulieren… in welcher Tiefe soll ich es tun? Eher generell, so dass es jeder versteht? Oder bis zur Zeitkomplexitäts-Analyse eines Shadow-Casting-Algorithmus? Wer liest hier überhaupt mit? Wer ist interessiert daran?

Trotzdem ist es natürlich eine wichtige Seite von mir, und ich programmiere durchaus nicht ’nur‘, um das Geld zum Musik machen zu verdienen, sondern auch zum Spaß. Gerade (bzw. seit längerer Zeit schon) bastle ich beispielsweise an einem Spiel, das in gleich zweifacher Hinsicht ein Novum sein dürfte.

Denn erstens handelt es sich um das meines Wissens erste rogue-like, das nativ für RISC OS entwickelt wird.

Und zweitens ist das Teil vollständig in Lua implementiert.

Wie es zu alledem – RISC OS, Lua und Roguelikes – kam, das ist eine recht interessante, lange und komplexe Geschichte, für die ich etwas weiter ausholen muss… tja, und ich denke, das mache ich einfach mal, und schaue, was die Reaktionen so sind, und dann schauen wir wie es weiter geht.

Thanks For The Memories

Den besten Brotjob² meines Lebens hatte ich nämlich 2012-2013.

Und zwar war ich zu dieser Zeit CTO bei einer feinen, kleinen Mobile-Spiele-Schmiede. Und weil wir sehr wenige Leute (sprich: sieben) waren, hatte ich gleichzeitig eine sehr aktive Rolle in der Entwicklung (sprich: sicher 80% unseres Codes kamen von mir, trotz des hochtrabenden Titels³).

Was daran so toll war?

Nun, zum einen durfte ich mir meine Zeit frei einteilen und von zuhause aus arbeiten. Und, ja, tatsächlich, das funktionierte, und zwar sehr gut.

Leider befindet sich Deutschland im Bereich Home Office noch immer im finstersten Mittelalter, und vielerorts herrscht mit gespenstischer Selbstverständlichkeit die Idee vor, wenn man nur genug Leute zusammen in ein lärmiges Büro sperrt und sie von morgens bis abends mit Meetings und Spielchen malträtiert, dann werden sie sich schon irgendwann ganz arg dolle zusammengehörig fühlen und mehr und bessere Arbeit machen als wenn man ihnen die individuelle Freiheit und Ruhe ließe, die sie als Geistesarbeiter eventuell benötigen könnten.

Mein damaliger Chef, dem ich bis in alle Ewigkeit dankbar sein werde, hatte die Weitsicht, das anders anzugehen, und das zahlte sich aus.

Obwohl 2012 ein Jahr der derben Schicksalsschläge war (mein Vater erlitt im August einen Schlaganfall und starb schließlich drei Monate später an den Folgen, während meine Mutter alles unternahm, um ihm schnell nachfolgen zu können), entstanden in dieser Zeit drei neue Spiele – zwei davon mit einer von Grund auf neu & selbst entwickelten Sprite-Engine, ein anderes unter einem mir bis dahin nicht bekannten Framework (Corona) mit einer mir bis dahin nicht bekannten Programmiersprache (Lua) –, sowie zwei Prototypen für ein weiteres Spiel und eine sehr hübsche Audio-App, ausserdem koordinierte ich unsere externen Mitarbeiter, unsere Praktikanten und alles was sonst noch so alles daran hing. Und das alles ohne Probleme, und ohne, dass jemals Dinge unerledigt liegen blieben.

Tja, und zum anderen entwickle ich eh gerne Spiele, einfach so, zum Spaß, und zur Entspannung. Tatsächlich hatte ich schon während meines vorherigen Brotjobs damit begonnen, nach Feierabend wild drauf los zu entwickeln, als Ausgleich für alles, was bei meinem damaligen Brötchengeber falsch lief (s.o.)

Als mir also die Gelegenheit geboten wurde, das vollends zu meinem Beruf zu machen, griff ich ohne zu zögern zu.

Wolken am Horizont

Ich schreibe das alles in der Vergangenheit, weil es leider nicht hielt. Wir hatten uns und den Spielemarkt überschätzt… zwar hatten wir ein bis zwei kleine Hits gelandet, aber das reichte auf Dauer nicht, um uns über Wasser zu halten. Die Werbeeinnahmen brachen links und rechts ein, und als Gegenmaßnahme begingen wir den (auch heute noch überaus beliebten) Fehler, unsere Apps so derartig brutal mit Werbebannern und Interstitials zuzuscheißen, dass unsere User verärgert gingen und nie wieder kamen.

Herbst 2012 sah es schon relativ finster aus, und wir mussten uns überlegen, was wir tun konnten, um Kosten einzusparen und vielleicht doch noch das Ruder rumzureissen (was ein schöner Wortwitz ist, denn bis dahin hatten wir rundenbasierte Spiele mit Piraten-Thema entwickelt).

Die erste Stelle (und letzten Endes die einzige), an der wir den Rotstift ansetzten, war die native App-Entwicklung. Bis dahin hatte ich nativ für iOS entwickelt. Wir wollten aber den Android-Markt mitnehmen und wir mussten uns schnell bewegen… Wir könnten viel schneller und kostengünstiger sein, so unsere damalige Überlegung, wenn wir unsere Apps fortan mit einem hybriden Framework entwickeln würden.

Wir entschieden uns für Corona, ein Crossplatform-Framework für Android und iOS, um unsere bestehenden Spiele zu portieren und unser nächstes (und letztes) Spiel anzugehen.

Unglücklicherweise war uns da eine  ganz große und wichtige Wahrheit noch nicht bewusst, nämlich:

Crossplatform-Anwendungsentwicklung ist Unfug.

Bevor jetzt alle auf mich losgehen: Klar, man muss das einschränken. Es spricht überhaupt nichts dagegen, ein Spiel, das keinerlei speziellen Features und Eigenheiten der Zielplattform prominent verwendet, beispielsweise in Unity3D zu entwickeln.

Unser nächstes Spiel aber sollte eine rundenbasierte Foto-Rate-App werden, in der man ein Teil eines Gegenstandes mit der Handykamera aufnahm und zurechtschnitt und ein zufällig ausgewählter Mitspieler raten musste, worum es sich handelte. Eine Art Mischung aus Kreuzworträtsel, Instagram, Memory und Chatroulette… und als solches eine sehr nette Idee. Gleichzeitig konnte man noch mit seinen Mitspielern chatten und Extras kaufen und so weiter und so fort.

Nun haben sowohl Android-User als auch (vermutlich noch in stärkerem Maße) iOS-User gewisse Erwartungen daran, wie sich eine Software anzufühlen hat. Insbesondere wenn es um Dinge geht wie Fotos aufzunehmen und zurechtzuschneiden, zwischen verschiedenen Views hin- und her zu navigieren und mit andren Usern zu chatten, dann erwartet der Benutzer eine schon gelernte Art der Bedienung, und er erwartet (mit Fug und Recht, wie ich betonen möchte), ebendiese Bedienung in einer flüssigen und robusten UI tätigen zu können.

Und damit nahm das Unglück nahm seinen Lauf, denn bei Corona fühlte sich nichts flüssig und robust an, weder auf Anwender- noch auf Entwicklerseite. Um vernünftig mit großen Fotos hantieren zu können musste ich eine native Erweiterung schreiben, ebenso für alles an Client-Server-Kommunikation, was über das simple Senden von JSON-Daten hinausging (und der Google Blobstore erwartet nunmal multipart binaries, was ebenfalls sein gutes Recht ist). Im Endeffekt schrieb ich so viele native Erweiterungen von Corona, dass man die gesamte Sache auch gleich hätte nativ implementieren können.

Selbst wenn ich nicht nativ programmieren musste, dann war Corona auch für die einfachsten Dinge unglaublich unhandlich und gewöhnungsbedürftig. Ganz simples Beispiel: Pinch- und Rotate-Gesten sind unter iOS sehr beliebt, um Bilder zu rotieren und zu zoomen, oft und gerne wird auch beides zusammen verwendet. Um diese Gesten in einer nativen UIView zu erkennen und das Bild dementsprechend transformiert darzustellen, benötigt es im nativen UIKit ungefähr 5 Minuten Zeit und 10 Zeilen Programmcode. Unter Corona hingegen waren es zum Schluss 247 Zeilen, und zwar nach zwei Tagen Entwicklungsarbeit und etlichen grauen Haaren mehr auf meinem Haupte.

Und ganz von alledem abgesehen fühlte sich die App weder wie eine Android-App noch wie eine iOS-App an. Die Views ruckelten in  der Navigation unbeholfen herum (während nativ alles hardwarebeschleunigt und flüssig funktioniert hätte), es gab Blackouts und Blitzer wenn die Library mal wieder versuchte, irgendetwas nachzubilden, was nativ ganz anders aussah und normalerweise problemlos funktionierte, und ständig hing drohend über alledem der Memory Warning Crash, weil zig unnötige Megabytes an Code im Speicher gehalten wurden, die das Framework beherrbergten.

Damit wir uns nicht falsch verstehen: Corona ist vermutlich schon ganz ok, um ein einfaches 2D-Spiel zu schreiben, das nichts besonderes können muss. Für unseren Anwendungsfall (und tatsächlich war das Spiel in vielen seiner Funktionen näher an einer „Anwendung“ als an einem „Spiel“) jedoch war es falsch, falsch und nochmal falsch.

Doch auch wenn unser Crossplatform-Ausflug letzten Endes einer der fetteren Nägel in unserem Sarg war, so bin ich dennoch dankbar dafür, dass wir ihn unternommen haben. Denn erstens habe ich dabei viele Fehler gemacht, die ich in dieser Form garantiert nicht noch einmal machen werde (mein Crossplatform-Abwehrreflex ist gesund und jederzeit bereit zum Angriff).

Und zweitens lernte ich dabei Lua kennen.

Lua

Lua ist eine Programmiersprache, die 1993 von der Computer Graphics Technology Group der Päpstlichen Katholischen Universität von Rio de Janeiro in Brasilien entwickelt wurde.

In Brasilien gab es damals ein mehr oder weniger strenges Embargo für ausländische Hard- und Software. Das führte dazu, dass man das Rad öfter mal neu erfinden musste… und in einigen Fällen führte es dazu, dass man das Rad vor allen anderen erfand, und obendrein noch ein besseres und schöneres Rad als die anderen.

Denn TCL, die einzige vergleichbare damals schon existierende Skriptsprache, war im Vergleich zu Lua undurchsichtig, kompliziert, unflexibel und ganz allgemein eine ziemlich ekelerregende Angelegenheit.

PHP und JavaScript erschienen erst drei Jahre hinterher auf der Bildfläche und sind auch heute, 20 Jahre später, noch immer kein ausgesprochenes Paradebeispiel für Schönheit und Klarheit.

Als die Corona-Leute eben jene Crossplattform-Lösung ersannen, die uns schließlich (unter anderem) das Genick brach, da wählten sie Lua als Frontend-Programmiersprache. Aus relativ einleuchtenden Gründen, denn Lua ist leicht erlernbar, sehr effizient, lässt sich sehr gut in andere Programmiersprachen einbetten, und steht unter der MIT Lizenz, sprich, es ist für jedermann frei verfügbar und in eigene Projekte integrierbar.

Und so kam es, dass ich eines Tages vor der Aufgabe stand, Lua zu lernen. Und, oh Wunder, so sehr Corona selbst ein Krampf im Allerwertesten war, so sehr lernte ich Lua schätzen.

Denn erstens ist Lua konzeptionell wirklich sehr klar und einleuchtend. Zwar ist Lua selbst erstmal nicht objektorientiert, aber die vorhandenen Sprachkonstrukte wie metatables und Funktionen als First-Class-Objekte lassen Konzepte wie Objektorientierung und Vererbung sehr leicht verwirklichen.

Zweitens ist Lua für eine interpretierte Skriptsprache sehr schnell⁴. Ich hab keine Geschwindigkeitsvergleiche mit anderen Sprachen gemacht, aber andere Leute haben das getan, und das bestätigt meine Eindrücke.

Drittens ist Lua schlank und unauffällig. Ein ausgewachsener Lua-Interpreter kommt in ca. 180kb ARM-Code unter.

Und viertens mag ich Lua einfach. Das ist bei Programmiersprachen so ein persönliches Ding, das sich schwer begründen lässt. Manche mag man, andere nicht so sehr. Als ich beispielsweise anno 1998 Objective-C kennenlernte, da war quasi sofort klar, dass das eine große Liebe werden würde. Swift hingegen (was viel bessererer weil moderner ist) reisst mich nicht im geringsten vom Hocker… und das liegt nicht daran, dass ich nicht gerne neue Dinge lerne (siehe: Lua).

Auf jeden Fall: Das alles führte dazu, dass ich auch noch lange nach dem Niedergang unserer Spiele-Company gerne den Lua-Interpreter auspackte und das eine oder andere Stück Spiel programmierte… was auch mit dem Auftauchen einer wirklich sehr genialen neuen Hardwareplattform zusammenhing, und der damit verbundenen Wiederauferstehung eines schlanken und schnellen Betriebssystems aus den späten 80er Jahren.

Aber das ist dann das Thema des nächsten Postings in dieser Reihe.


¹ Das gilt natürlich nicht für die Brotjob-Kollegen. Vor denen bleiben meine Musiker- und Fotografen-Personae ebenso gut versteckt, wie ich bisher meine Eigenschaft als Programmierer vor meinem Musik- und Fotopublikum versteckt habe. Komisch, ich mache das andersrum garantiert nicht freiwillig, aber es scheint mir ein ungeschriebenes Gesetz zu sein, dass diese Welten getrennt sein müssen.

² Danke, sleeksorrow, für das Wort

³ Wobei es mir jetzt auf dieses ‚CTO‘ gar nicht so sehr ankommt… ich frage mich eh immer wieder, warum Softwareentwickler nicht einfach Softwareentwickler bleiben dürfen, sondern mit der Zeit zu irgendwas hochtrabendem anderen mutieren müssen. Was ist so schlimm daran, ein Entwickler zu sein? Es gibt doch ein Leben lang etwas zu lernen und sich weiterzuentwickeln…

⁴ Zumindest war das damals so. Inzwischen läuft Javascript vermutlich nativ auf irgendwelchen GPU-Kernen, die nebenbei alle 10 Sekunden einen komprimierten Framebuffer-Dump an die NSA schicken. It’s a brave new world.


Kommentare

2 Antworten zu „Der lange Weg zu LuaHack“

  1. Avatar von Daniel
    Daniel

    Nun weiß ich zwar nicht, ob das für Dich als Code/Spiel Inspirationsquelle interessant ist oder nicht, aber ein schönes Spiel, das meines Wissens nach (ganz? teilweise?) in Lua geschrieben wurde, ist Aquaria von Bit Blot.

    Der Sourcecode wurde nach einer Weile freigegeben und ist unter https://hg.icculus.org/icculus/aquaria zu finden. Da dort keine Aktivität zu erkennen war, wurde das Ding natürlich schneller geforked, als man „Mama, Papa, auf Wiedersehen“ sagen kann. Das findet sich dann hier: https://github.com/AquariaOSE/Aquaria

    Erstaunlich fand ich auch, dass einer meiner wichtigsten Serverdienste in Lua geschrieben ist, nämlich der XMPP (vulgo: Jabber) Server Prosody.

    1. Avatar von Stephan
      Stephan

      Ui, super, das klingt sehr interessant. Ich hab mal grob drüber geschaut, das ist anscheinend C++ mit Lua, sehr klassisch und eine der coolen Seiten von Lua, dass man es problemlos an andere Programmiersprachen angebunden kriegt. Den zeitkritischen maschinennahen Teil macht man dann in C und den Rest in Lua… gleich mal dieses Wochenende nähr anschauen 🙂

      Tatsächlich geht mit Lua mehr als man annehmen mag… beispielsweise sind grosse Teile des Frontends von Adobe Lightroom in Lua geschrieben…

      Und ich hab’s mir für mein roguelike zum Ziel gesetzt, es tatsächlich vollständig in (Risc-)Lua zu schreiben. Ein bisschen wahnsinnig, aber man braucht ab und zu ein bisschen Wahnsinn. 😉

Schreibe einen Kommentar zu Daniel Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert