1 Punkte von GN⁺ 2025-04-19 | 1 Kommentare | Auf WhatsApp teilen
  • The Backdooms ist ein komprimiertes, selbstentpackendes, unendlich generiertes HTML-Spiel, inspiriert von DOOM 1993 und The Backrooms, das direkt aus einem QR-Code im Browser läuft
  • Der gesamte Spielcode wird in der URL gespeichert; nach dem Scannen soll es als vollständig offline spielbare Struktur ohne Internetverbindung funktionieren
  • Der Kompressionsablauf besteht darin, HTML mit Zlib zu komprimieren, Base64-zu-kodieren, in einen JavaScript-HTML-Wrapper einzubetten und im Browser mit der DecompressionStream-API zu dekomprimieren und auszuführen
  • Die QR-Erzeugung sucht mit qr.make(fit=True) die kleinstmögliche QR-Version und schlägt fehl, wenn sie nicht innerhalb der Standardgrenze von Version 40 und Fehlerkorrekturstufe L bleibt
  • Mobile Unterstützung ist auf aktuelle mobile Browser beschränkt, die die DecompressionStream-API unterstützen; im README werden Edge, Yandex und Opera als Beispiele genannt

Was The Backdooms macht

  • The Backdooms ist ein HTML-Spiel, das das komplette Spiel in einem QR-Code enthält und im Webbrowser ausgeführt wird
  • Das Spiel ist von DOOM 1993 und The Backrooms inspiriert und als komprimierte, selbstentpackende Webseite aufgebaut
  • Nach dem Scannen des QR-Codes startet es direkt im Browser, ohne dass ein separater Download oder eine Installation nötig ist
  • Im README wird darauf hingewiesen, dass man es per Scannen spielen kann
  • Auf GitHub Pages gibt es außerdem eine etwas weniger komprimierte Version

Kompressionsansatz, der Speichergrenzen ausreizt

  • Das Ziel des Projekts ist es, die Speicherkapazität von QR-Codes und die Grenzen der Kompression auszureizen und zu zeigen, wie sich leichtgewichtige Webanwendungen in einem QR-Code hosten lassen
  • Der Kompressionsablauf ist in folgender Reihenfolge aufgebaut
    • Eingabe-HTML einlesen
    • HTML mit Zlib komprimieren
    • die komprimierten Daten mit Base64 kodieren
    • in einen JavaScript-basierten HTML-Wrapper einbetten
    • das gesamte HTML in eine Data-URI im Format data:text/html;base64,... umwandeln
  • Im Browser wird die DecompressionStream-API verwendet, um die komprimierten Inhalte dynamisch zu entpacken und auszuführen
  • Im Diagramm des README sind in der Browser-Verarbeitung die Schritte DecompressionStream 'gzip' und Format Mismatch enthalten

Logik zur QR-Code-Erzeugung

  • Das Tool zur QR-Code-Erzeugung bietet einen Ablauf, um ein etwa 2.5kb großes Spiel als QR-Code zu erzeugen
  • Ein Ausführungsbeispiel sieht wie folgt aus
python3 QRGEN.py <your-game.html> <output-qrcode.png>
python3 QRGEN.py EVEN-SMALLER-SLAMMER-BACKROOMS.html qrcode.png
  • Im Erzeugungsprozess wird mit qr.make(fit=True) zunächst die kleinstmögliche QR-Version für die Inhaltslänge versucht
  • Wenn die benötigte Version die Standardgrenze von 40 überschreitet, wird mit fit=False Version 40 erzwungen
  • Um die maximale Datenmenge unterzubringen, wird die niedrigste Fehlerkorrekturstufe L verwendet
  • Wenn die Daten selbst mit Version 40 und Stufe L zu groß sind, schlägt die QR-Kodierung fehl und gibt einen Fehler zurück

Ausführung und Kompatibilität

  • Zum Spielen selbst wird nur ein aktueller Webbrowser benötigt
  • Nach dem Scannen kann ohne Internetverbindung gespielt werden, da sich der komplette Spielcode in der URL befindet
  • Auf Mobilgeräten ist ein aktueller Browser erforderlich, der die DecompressionStream-API unterstützt
    • Im README werden Edge, Yandex und Opera als Beispiele genannt
  • Eine BigInt-basierte Alternative für kleinere QR-Codes gibt es im The BigInt Branch, allerdings ist die Kompatibilität mit mobilen Browsern eingeschränkt

Erstellungsumgebung und Lizenz

  • Um QR-Codes selbst zu erzeugen, werden die folgenden Abhängigkeiten benötigt
    • Python 3.7+

      • die Bibliothek qrcode
      • pillow für die Verarbeitung von QR-Code-Bildern
      • Der Befehl zur Installation der Abhängigkeiten lautet wie folgt
pip install qrcode[pil]
- Der Entwicklungsprozess ist im [MindDump](https://kuberwastaken.github.io/blog/Projects/How-I-Managed-To-Get-Doom-In-A-QR-Code) dokumentiert
- Das Projekt wird unter der **MIT License** veröffentlicht und kann frei verwendet, verändert und geteilt werden

1 Kommentare

 
GN⁺ 2025-04-19
Hacker-News-Kommentare
  • Habe DecompressionStream zum ersten Mal kennengelernt und den HTML-Teil überarbeitet, um noch ein paar Bytes einzusparen.
    Ich habe auch einen PR erstellt, falls es jemanden interessiert.

    • Dank des gewonnenen Platzes konnte ich Touchscreen-Unterstützung, bessere Bewegung, Gegner-Spawning und Schadensbehandlung hinzufügen.
      Wirklich vielen Dank, das war das Beste in diesem Monat.
  • Wirklich ein großartiges Projekt.
    Ich habe auch data:-URLs neu kennengelernt; das data:-URI-Schema kannte und hatte ich schon benutzt, aber ich wusste nicht, dass man es als vollständige URL verwenden kann.
    Ich hatte darüber nachgedacht, etwas Ähnliches zu bauen, das komplett in einen QR-Code passt, habe es aber aufgeschoben, weil ich fälschlicherweise dachte, man bräuchte einen HTTP(s)-Link. Dieses Video hat mich sehr inspiriert: Can you fit a whole game into a QR code?(https://www.youtube.com/watch?v=ExwqNreocpg)

    • Dieses Video habe ich auch ungefähr während des Lockdowns gesehen, es hat mich inspiriert und war wirklich toll.
      Ich bin allerdings in die entgegengesetzte Richtung gegangen, nämlich browserbasiert für breitere Kompatibilität, und habe die Quelle auch im Repository vermerkt.
  • Das ist vielleicht eine dumme Frage, weil ich technisch noch Anfänger bin, aber kodiert QR nicht einfach nur Daten?
    Wenn die maximale Datenmenge, die ein QR-Code aufnehmen kann, etwa 3 KB beträgt, entspräche das rund 3000 Klartextzeichen. Bedeutet die Leistung hier also, dass dieses Doom-ähnliche Spiel als ausführbarer Code in dieser Größenordnung funktioniert?

    • QR-Codes haben mehrere Kodierungsmodi, etwa numerisch, alphanumerisch, 8-Bit und Kanji. Am gebräuchlichsten ist die alphanumerische Kodierung, am dichtesten ist die 8-Bit-Kodierung, die Binärdaten direkt speichert.
      Bedeutung und Zweck der 8-Bit-Kodierung im QR-Standard wirken etwas unklar, aber die Grundinterpretation sind die Zeichensätze JIS8 und Shift JIS; andere ECIs stellen 8-Bit-Bytewerte direkt dar.
      Jedenfalls ist es möglich, beliebige Binärdaten in einem QR-Code zu speichern, und das Tool qrencode unterstützt das standardmäßig.
      Allerdings gehen Decoder oft davon aus, dass ein QR-Code Text enthält, wodurch die Unterstützung schwierig ist; ich habe einmal einen Patch für binäres QR-Decoding eingereicht, weil zbar die Daten durch iconv schickte und dabei beschädigte.
      Ursprünglich wollte ich lediglich einen 4096-Bit-RSA-Private-Key als QR-Code ausgeben, aber danach fingen Leute an, auch Videospiele als QR zu kodieren, und das ist wirklich großartig.
      https://youtu.be/ExwqNreocpg
      https://news.ycombinator.com/item?id=24287347
  • Ich habe ihn mit dem Standard-QR-Code-Scanner des iPhone gescannt, und es kam „Keine nutzbaren Daten gefunden“.

    • Das liegt nicht an der Größe oder Länge des QR-Codes, sondern daran, dass der Standard-Scanner des iPhone keine data:-URI-URLs unterstützt.
      Eine eigenständige Webseite Hi! kann man zum Beispiel als data:text/html;base64,PGh0bWw+PGJvZHk+SGkhPC9ib2R5PjwvaHRtbD4= kodieren; wenn man das in den Browser einfügt, wird Hi! gerendert.
      Wenn man daraus aber einen QR-Code macht, funktioniert es in dieser Situation nicht.
    • Danke fürs Überprüfen.
      Die meisten Smartphones können große QR-Codes nicht gut lesen, daher braucht man etwas wie https://qrscanner.org/.
      Und auf dem Handy wird es ohnehin nicht laufen; wegen der Größenbeschränkung konnte ich diese Kompatibilität nicht auch noch einbauen.
    • Dass es auf dem iPhone nicht funktioniert, beruhigt mich eher ein wenig.
      Ich scanne häufig QR-Codes, die irgendwo angebracht sind, um mir das Eintippen von URLs zu sparen; die Vorstellung, dass allein durch das Scannen eines QR-Codes beliebige Codeausführung möglich wäre, ist ziemlich beängstigend.
  • Wenn man dem Canvas-CSS image-rendering: pixelated hinzufügt, dürfte es nicht verschwommen wirken, sondern einen scharfen Pixel-Look bekommen.

    • Habe ich ausprobiert, aber mir gefiel es so wie jetzt besser, weil es lustiger und retrohafter wirkt.
  • Das nächste Projekt sollte ein LLM als QR-Code sein.
    Dazu passend: https://www.reddit.com/r/OpenAI/comments/138kbhs/someone_sho...

  • Der Link zum Game-Trailer führt zu einem Short namens „Fly me to the moon - 19 September 2024“.
    Sieht nach einem Versehen aus.

    • Sollte jetzt behoben sein.
  • Ich liebe solche ultrakleinen Spieleprojekte wirklich.
    Erinnert mich an .kkrieger.
    https://en.wikipedia.org/wiki/.kkrieger

    • Als ich es auf LinkedIn gepostet habe, hat mich jemand darauf hingewiesen; das war wirklich beeindruckend.
  • Bitte mach weiter so coole Sachen, kuberwastaken.

    • Ich werde mein Bestes geben.
  • Ich habe einmal mit einem Freund über eine einigermaßen verwandte Idee gesprochen.
    Wir fragten uns, ob man eine STL-Datei für den 3D-Druck komplett in einen QR-Code kodieren und auf das tatsächliche Objekt kleben könnte, sodass man das hergestellte Ding einfach scannen und erneut drucken kann.
    Beim Nachforschen sah es nach zu vielen Daten aus, und ich habe sogar mehrfarbige QR-Codes gefunden, wusste aber nicht, dass man einfach größere QR-Codes erstellen kann.

    • Ich habe früher im Rahmen einer Design-Exploration für Tische etwas Ähnliches gemacht.
      Bei Tischen muss man nur Plattenmaterial zuschneiden, deshalb habe ich eine 2D-Datei kodiert, aber selbst dafür brauchte ich für den Proof of Concept einen eigenen Kompressionsalgorithmus.
      https://johnkestner.com/rev/