7 Punkte von GN⁺ 2025-09-23 | 1 Kommentare | Auf WhatsApp teilen
  • Luau ist eine von Lua 5.1 abgeleitete eingebettete Skriptsprache, die schnell und sicher ist und schrittweise Typisierung unterstützt
  • Sie wurde weiterentwickelt, um komplexe Spiele und große Codebasen auf der Roblox-Plattform zu unterstützen, mit Verbesserungen bei Performance, Sprachwerkzeugen und Typsystem
  • Anders als Standard-Lua verfügt sie über Sandboxing-Funktionen und ist so entworfen, dass Code mit unterschiedlichen Berechtigungen parallel ausgeführt werden kann
  • Die Syntax ist mit Lua 5.1 kompatibel, bietet aber zusätzliche Syntax-Erweiterungen und Analysetools (Linter, Type Checker), um die Codequalität zu erhöhen
  • Mit Performance-Optimierungen, angepasstem Bytecode und JIT-Unterstützung zielt sie auf Ausführungsgeschwindigkeit auf LuaJIT-Niveau ab und hat auch jenseits von Roblox großes Potenzial in verschiedenen eingebetteten Umgebungen

Motivation (Hintergrund)

  • Um 2006 führte Roblox Lua 5.1 als Skriptsprache für Spiele ein
  • Mit der Zeit stiegen das Niveau der Spiele auf der Roblox-Plattform und die Teamgrößen, sodass Sprache und Implementierung umfassend verbessert wurden, um die Grenzen des bisherigen Lua zu überwinden
  • Mit dem Wachstum der Plattform wurde viel in Performance-Optimierung, Benutzerfreundlichkeit und die Entwicklung sprachbezogener Tools investiert
  • Insbesondere bei der Verwaltung großer Codebasen mit mehr als 1 Million Zeilen im Jahr 2020 wurde erkannt, dass die Einführung eines schrittweisen Typsystems unverzichtbar ist
  • Auf Basis dieser Anforderungen entwickelte Roblox mit Luau eine von Lua abgeleitete Sprache, die schnell, klein und sicher ist und zugleich Funktionen für die schrittweise Anwendung von Typen bietet
  • Eine ausführlichere Erklärung bietet das Dokument Why Luau

Überblick über Luau

  • Luau ist eine eingebettete Skriptsprache auf Basis von Lua 5.1
    • Sie bietet eine schnelle und leichtgewichtige Runtime
    • Sie unterstützt ein schrittweises Typsystem, sodass dynamische und statische Analyse parallel möglich sind
  • Sie ist in Roblox Studio integriert, und mit dem Flag --!strict kann der Strict Mode aktiviert werden
  • Entwickler können in den Luau Creator Docs die mit Roblox verknüpfte Dokumentation einsehen

Sandboxing (Sandbox-Funktionen)

  • Luau begrenzt die exponierte Standardbibliothek und bietet zusätzliche Sandboxing-Funktionen
  • Dadurch können nicht privilegierter Code, der von normalen Entwicklern geschrieben wurde, und privilegierter Code innerhalb der Plattform sicher parallel ausgeführt werden
  • Dadurch ergibt sich eine andere Ausführungsumgebung als bei Standard-Lua
  • Details finden sich in der Sandbox-Beschreibung

Compatibility (Kompatibilität)

  • Soweit möglich wird Abwärtskompatibilität mit Lua 5.1 gewahrt, zugleich werden teilweise auch Funktionen späterer Versionen übernommen
  • Luau übernimmt jedoch nicht alle Designentscheidungen von Lua, sondern spiegelt die spezifischen Anwendungsfälle und Einschränkungen von Roblox wider
  • Der Support-Status für Funktionen aus Versionen nach Lua 5.1 ist im Compatibility-Dokument beschrieben

Syntax (Syntax)

  • Sie ist vollständig kompatibel mit der Lua-5.1-Syntax
  • Zusätzlich bietet sie moderne und vertraute Syntax-Erweiterungen, die die Entwicklung erleichtern
  • Die vollständige Syntax ist im Syntax-Dokument zu finden

Analysis (Analysetools)

  • Zur Unterstützung beim Schreiben korrekten Codes werden Skript-Analysetools bereitgestellt

  • Bestandteile:

    • Linter: erkennt allgemeine Fehler
    • Type Checker: prüft Typen
  • Sie können mit dem CLI-Tool luau-analyze ausgeführt werden

  • Zu den Lint-Regeln siehe das Lint-Dokument, zur Typprüfung den Leitfaden Typecheck

Performance (Performance)

  • Es werden ein angepasstes Frontend mit Parser, Linter und Type Checker sowie optimierter Bytecode, Interpreter und Compiler bereitgestellt
  • Je nach Fall ist eine Performance möglich, die mit dem LuaJIT-Interpreter konkurrieren kann
  • Auf x64- und ARM64-Plattformen wird ein manueller JIT-Compiler unterstützt, der die Performance bestimmter Programme deutlich verbessern kann
  • Die Runtime wird fortlaufend optimiert und teilweise neu geschrieben, um die Effizienz zu steigern
  • Detaillierte Performance-Eigenschaften sind im Performance-Dokument beschrieben

Libraries (Bibliotheken)

  • Die Sprache selbst ist eine vollständige Obermenge von Lua 5.1
  • In der Standardbibliothek wurden einige Funktionen entfernt und einige neue hinzugefügt
  • Bei der Einbettung in eine Anwendung ist auch der Zugriff auf anwendungsspezifische Erweiterungsbibliotheken möglich
  • Die vollständige Bibliotheksdokumentation ist im Library-Dokument verfügbar

1 Kommentare

 
GN⁺ 2025-09-23
Hacker-News-Kommentare
  • Jemand hat im Lumix Engine erst Lua und LuaJIT verwendet und ist dann wegen des Typsystems zu Luau gewechselt. Allerdings stellte sich heraus, dass es außerhalb von Roblox schwer einzusetzen ist: Die Dokumentation ist schwach, die Community praktisch nicht vorhanden, sodass sie bei Problemen überhaupt nicht hilft. Gegenüber Lua oder LuaJIT ist es größer, wodurch das Kompilieren siebenmal langsamer wird. Auch die asynchrone Verarbeitung der API ist faktisch synchron blockiert, und es gibt viele Unannehmlichkeiten wie die Nutzung der STL. Außerdem treten häufig Bugs bei Analyse und LSP auf. Deshalb wird überlegt, nach Alternativen zu suchen.
    • Das Roblox-Team legt künftig den Schwerpunkt darauf, Luau auch außerhalb von Roblox leichter nutzbar zu machen. Es wird bereits erfolgreich an vielen Orten eingesetzt, darunter Remedy Entertainment (Alan Wake 2), Digital Extremes (Warframe) und GIANTS Software (Farming Simulator 25). Bisher konzentrierten sich Investitionen und Support intern auf Roblox, doch nun wird mit Lute eine allgemeine, unabhängige Runtime für allgemeine Einsatzzwecke entwickelt. Außerdem sollen verschiedene Luau-basierte Entwicklerwerkzeuge entstehen, um das Ökosystem auszubauen. Es ist noch früh, aber es wird aktiv in externe Nutzung und unterschiedliche Anwendungsfälle investiert. Man ist überzeugt, dass es für gesundes Wachstum von Luau wichtig ist, mehr Nutzer und Einsatzszenarien zu gewinnen.
    • Jemand nutzt Luau für den gesamten Gameplay-Code eines Unity-Spiels (über 60.000 Zeilen). Gewünscht wird vor allem bessere Dokumentation, insbesondere zur benutzerdefinierten Integration. Auch das neue Typsystem und das LSP wirken noch nicht besonders gut aufeinander abgestimmt. Seit zeux das Team verlassen hat, gibt es etwas Sorge um die langfristige Richtung. Die eigentliche Entwicklungserfahrung gefällt aber sehr: Luau-Code wird selbst während des laufenden Spiels fast sofort hot-reloaded, und auch C++-Projekte lassen sich schnell kompilieren. Positiv ist zudem die Sandbox-Umgebung für Modding-Support. Auch die offizielle Discord-Community ist einigermaßen aktiv.
    • Es wurde gesagt, das Kompilieren sei langsam, aber bei einer Skriptsprache müsse man Code doch eigentlich gar nicht kompilieren. Gefragt wird, ob vielleicht das Kompilieren der Luau-VM selbst gemeint ist.
  • Sehr interessant ist, dass Roblox an einer Node.js-artigen Luau-Runtime für den Desktop arbeitet: https://github.com/luau-lang/lute
    • Es gibt bereits die weiter ausgereifte Luau-Runtime Lune. Sie wird für Build-Skripte und die Automatisierung von Roblox-place-Dateien genutzt und funktioniert für den eigenen Einsatzzweck vollkommen zufriedenstellend.
    • Als weitere eigenständige Luau-Runtime existiert ebenfalls Lune.
  • Luau wirkt deutlich komplexer als Lua. Nach Codeumfang betrachtet hat Luau 120.000 Zeilen C++, während Lua 5.1 auf 14.000 Zeilen C kommt. Wenn ein schrittweises oder statisches Typsystem hinzukommt, ist diese zusätzliche Komplexität wohl unvermeidlich. Mit einem einigermaßen vollständigen Typsystem wird es am Ende zwangsläufig größer als eine dynamische Skriptsprache.
    • Lua (und bis zu einem gewissen Grad auch Luau) ist nicht gemessen an der Zeilenzahl klein, sondern beim Erlernen der Sprache selbst. Die zur Ausführung benötigte Runtime hängt nicht vollständig von der Analysis ab. In Analysis stecken zwei vollständige Typsysteme. In den letzten drei Jahren wurde ein neues Typsystem entwickelt, um grundlegende Einschränkungen zu lösen, und das alte soll bald entfernt werden. Dadurch könnten rund 30.000 Zeilen Code wegfallen.
    • Ich halte weder Lua noch Luau für kleine oder einfache Sprachen, und vielleicht ist diese Komplexität auch gar nicht nötig. Es wird an einer einfacheren, aber ausdrucksstarken Sprache namens Bau gearbeitet, ebenso an einer Lua-artigen VM. Solche kleinen Sprachen sind auch auf Reddit gelegentlich Thema: Bau, Bau VM, r/ProgrammingLanguages
    • Statisches oder graduelles Typing erhöht die Komplexität zwar, aber der Zuwachs ist kleiner, als man vielleicht denkt. Mitunter sind dynamische Skriptsprachen sogar komplexer. Ein Hindley–Milner-Typchecker lässt sich auf einer einzigen Code-Seite implementieren; die hier diskutierte Komplexität im Umfang von 2.000 Seiten wirkt überzogen. H–M ist vollständig und erlaubt vollständige Inferenz, auch ohne Higher-Order Functions, Generics (parametrischen Polymorphismus) oder Null-Pointer zu behandeln. Es lässt sich erweitern und ist schon in der Grundform deutlich mächtiger als die Typsysteme von C oder Java 1.7.
    • Ich habe selbst einen Typechecker für Lua geschrieben und viel Quellcode gelesen; die 14.000 Zeilen von Lua sind sehr dicht geschriebener Code. In einem durchschnittlichen Stil wären das eher 30.000 bis 40.000 Zeilen. Lua ist also nicht von Natur aus klein, sondern extrem kompakt implementiert.
    • Wenn man die mit tokei analysierten Zeilenzahlen detaillierter aufschlüsselt, hat das Analysis-Verzeichnis 62.000 Zeilen C++, 9.200 Zeilen C-Header, Ast 8.400 Zeilen C++, CodeGen 21.000 Zeilen C++ usw. Lua 5.1 hat im gesamten src-Verzeichnis 11.000 Zeilen C-Code und 1.900 Zeilen Header.
  • Jemand fragt nach dem Unterschied zwischen Teal und Luau. Beide werden als „statisch getypte Lua-Dialekte“ vorgestellt, daher möchte man sie vergleichen: https://teal-language.org/
    • Teal kompiliert Teal-Dateien zu Lua, daher gelten dieselben Vor- und Nachteile wie bei JS und TS. Luau hat dagegen eine eigene Runtime, die zu Lua aufwärtskompatibel ist, und verbessert nicht nur das Typsystem, sondern die gesamte Developer Experience. Deshalb sind beide ziemlich unterschiedlich. Teal hat den Vorteil, dass Lua überall genutzt werden kann. Luau läuft dagegen nur auf einer Luau-spezifischen Runtime, bietet aber aus Entwicklersicht bessere Nutzbarkeit, weil kein separater Kompilierungsschritt nötig ist. Außerdem bleibt Typinformation erhalten und kann weiter genutzt werden.
    • Teal wird nach Lua transpiliert, während Luau ein Fork von Lua ist. Dadurch sind weitreichende Änderungen möglich, etwa bei Interpreter-Performance, Sicherheit und Erweiterbarkeit der Syntax. Roblox ist mit einer Marktkapitalisierung von 100 Milliarden Dollar sehr groß und beschäftigt mehrere dedizierte Entwickler dafür.
    • Luau ist nicht einfach nur „Lua mit Typen“, sondern investiert viel in ein graduelles Typsystem und Typinferenz und verbessert zugleich die Sprache selbst schrittweise weiter. Es ist auf Developer Experience und Tooling-Support ausgerichtet. Auf Dinge wie Binärgröße wird geachtet, aber strikte Einfachheit wie bei Lua hat keine höchste Priorität. Der Fokus liegt weniger darauf, große C-Projekte an Lua anzubinden, sondern stärker darauf, dass Entwickler in der Sprache selbst eine gute Erfahrung haben.
  • Es ist schade, dass sich Lua nicht stärker weiterentwickelt hat, ohne die Kompatibilität zur Vergangenheit zu verlieren. Ende der 2000er haben Roblox und viele andere Projekte Lua 5.1 übernommen; inzwischen ist Lua bei 5.4, aber die Rückwärtskompatibilität wurde nicht gut bewahrt. LuaJIT unterstützt zum Beispiel nur 5.1. Das erinnert an die Situation bei Python 2.x/3.x, nur dass die Lua-Community überwiegend weiter bei 5.1 bleibt.
    • Tatsächlich ist es sogar noch schlimmer: luau und luaJIT haben sich ebenso wie das offizielle lua-Projekt jeweils in unterschiedliche Richtungen entwickelt und sind nun subtil inkompatibel zueinander. Alle sind zwar von Lua 5.1 ausgegangen, aber inzwischen fühlt es sich an, als gäbe es keinen offiziellen Standard mehr.
    • Der große Unterschied ist, dass die Lua-Community fehlende Rückwärtskompatibilität nicht öffentlich anprangert, weshalb es relativ leicht ist, Code für verschiedene Versionen zu schreiben.
    • Offizielle Statistiken sind schwer zu bekommen, aber gefühlt gibt es mehr Nutzer von 5.1 und 5.2 als von 5.4, und 5.3 scheint 5.4 ebenfalls nicht übertroffen zu haben. LuaJIT genießt viel Aufmerksamkeit, taucht in der Praxis aber nicht so häufig auf.
    • LuaJIT enthält auch einige Features neuerer Lua-Versionen (5.2, 5.3) und noch weitere Erweiterungen: https://luajit.org/extensions.html
  • Am interessantesten fand jemand, dass der Luau-Interpreter in manchen Fällen mit LuaJIT mithalten kann. Auf der Performance-Seite gibt es dazu eine gute Erklärung, an der man die Engineering-Stärke von Roblox erkennt: https://luau.org/performance
  • Jemand hat Luau kennengelernt, weil das 13-jährige Kind Interesse an Roblox Studio zeigte, und auch luau.org besucht. Das Engineering von Roblox ist wirklich beeindruckend.
    • Arseny Kapoulkine ist ein hervorragender Engineer. Es lohnt sich, seinen Blog oder seine Social-Media-Kanäle zu verfolgen. Neben luau und der Rendering-Engine von Roblox hat er meshoptimizer entwickelt, eine in der Grafikbranche nahezu unvermeidliche Bibliothek, und volk ist sogar im Vulkan SDK enthalten.
  • Second Life ist gerade dabei, von der bestehenden Linden Scripting Language auf Luau umzusteigen. Bisher basierte das Kompilieren auf Mono, doch da Mono nicht mehr gepflegt wird, war eine neue Sprache nötig. Es wurde nicht nur Luau-Unterstützung ergänzt, sondern auch der bestehende LSL-Compiler so angepasst, dass er die Luau-Ausführungsengine als Ziel hat. Die Performance wurde ebenfalls leicht verbessert. Second Life ist eine ungewöhnliche Umgebung, in der Hunderttausende ereignisbasierte Skripte auf dem Server laufen, weshalb Ressourcenmanagement nicht einfach ist. Wenn ein inaktives Programm pro Frame 1 Mikrosekunde verbraucht, kann sich das schnell zu einem großen Problem aufsummieren.
    • Als die Luau-Beta geöffnet wurde, hat jemand sie selbst ausprobiert und deutlich bessere Performance als im bisherigen Mono-System gespürt. Vor allem die Skriptprüfung beim Speichern wurde von 10 Sekunden auf praktisch sofort verkürzt, was die Entwicklungseffizienz stark verbessert. Noch besser wären allerdings Hilfsfunktionen wie CreateThread(fn), Wait(ms) und Await/Promises wie in FiveM, um Coroutines bequemer zu handhaben (Luau Promise-Implementierung). In FiveM erleichtern solche Wrapper sowohl die Skriptoptimierung als auch das Coroutine-Management: Beispiel für den Lua-Scheduler von FiveM
    • Nach dem Wechsel der VM fällt sofort auf, dass ein großer Teil des bisherigen Overheads auf Scheduling, Context Switching und die Implementierung von Bibliotheksfunktionen entfiel. Luau unterstützt präemptives Scheduling konzeptionell auf natürliche Weise, wodurch sich einfache Glue-Code-Orchestrierung viel leichter umsetzen lässt. Das in der VM zu behandeln ist deutlich billiger und einfacher als Zustandsmaschinen auf AST- oder Bytecode-Ebene zu transformieren. Auch der Overhead im Mikrosekundenbereich bei Idle-Programmen ist letztlich etwas, das der Scheduler optimieren muss.
  • Der minimale Reiz von Lua wurde durch type inference teilweise beschädigt; dafür bekommt man Typsicherheit, also gibt es Vor- und Nachteile. Verwirrend war aber, dass nach einer Deklaration mit --!strict selbst bei offensichtlichen Typverstößen weder Fehler noch Warnungen auftraten und der Code einfach lief. Das entsprach nicht der Erwartung.
    • Das Typsystem von Luau ist derzeit nicht „erzwingend (strict)“. Code kann auch ohne Typprüfung ausgeführt werden, und wenn man ihn direkt in der Demo oder über die ausführbare Datei luau startet, wird keine Typprüfung angewandt. Wenn in einer eingebetteten Umgebung jedoch erzwungen wird, dass sämtlicher Code vor dem Kompilieren typgeprüft werden muss, dann erhält man das erwartete Verhalten mit abgefangenen Typfehlern. Diese Entscheidung war unvermeidlich, weil auf einen Schlag Millionen Zeilen Lua-5.1-Code in Luau überführt wurden.
  • Man wollte schon immer Typed Lua, aber es war ziemlich schwierig, für dynamische Sprachen einen vollständigen Typechecker und ein vollständiges LSP zu implementieren. Jede dynamische Sprache hat ähnliche Probleme mit strukturellem Typing, ähnlich wie bei TypeScript. Es wird gefragt, ob man nicht die TypeScript-Engine wiederverwenden könnte, indem Luau-Code teilweise nach TypeScript übersetzt, mit tsc geprüft und die Fehler bzw. Ergebnisse dann wieder auf Luau zurückgemappt werden. So ließe sich vielleicht schnell ein Typechecker für verschiedene dynamische Sprachen bauen.
    • So wie LLVM ein gemeinsames IR für Compiler ist, könnte man vielleicht auch das TypeScript-Typsystem als gemeinsames Backend bzw. als „Zwischensprache“ für Typsysteme verwenden. Dynamische Sprachen sind zwar nicht die eigene Präferenz, aber mit Type-Checking und Tooling auf TypeScript-Niveau würde das Interesse deutlich steigen. Was nicht funktioniert, kann man aufgeben; genau das ist ja das Wesen graduellen Typings. Wenn das TypeScript-Typsystem in einer Lua-Runtime stecken würde, wäre es auf jeden Fall interessant. Auch die Entwicklung von Luau wird mit großem Interesse verfolgt.
    • Für Luau gibt es bereits einen hervorragenden Luau Language Server, der in vscode, nvim, zed usw. starke Diagnosen, Autocomplete und strikte Typprüfung bietet. Die Developer Experience ist viel besser als das, was man in Ruby oder Python erlebt hat. Jemand nutzt Luau sowohl für Shell-Skripting als auch für allgemeine Programmierung und hat auch eine eigene Node-ähnliche Runtime namens seal gebaut. Roblox-Entwickler nutzen für CI/CD und Testing offenbar häufiger das populärere Lune.
    • Um die letzten Ecken und Kanten dynamischer Sprachen mit TypeScript zu typisieren, würde das System zu komplex werden. Deshalb wäre es wohl besser, wie Rescript oder Gleam dem Zielsprachmodell einige Einschränkungen aufzuerlegen und stattdessen auf ein Hindley–Milner-Typsystem zu setzen. HM-Typsysteme sind dank langer Erfahrung und Theorie robust und praktisch. Es ist überraschend, dass es offenbar kein kleines ML-artiges Sprachprojekt gibt, das nach lua ausgibt. Wenn Gleam Lua als Backend unterstützen würde, würde das hervorragend passen.
    • Ein solches Projekt existiert bereits: TypeScriptToLua. Jemand hat damit in Love2D ziemlich gute Erfahrungen gemacht.