- The Backdooms est un jeu HTML compressé, auto-extractible et généré à l’infini, inspiré de DOOM 1993 et de The Backrooms, qui s’exécute directement dans le navigateur depuis un QR code
- Il place tout le code du jeu dans une URL et vise une architecture entièrement hors ligne, jouable sans connexion Internet après le scan
- Le flux de compression consiste à compresser le HTML avec Zlib, à l’encoder en Base64, puis à l’insérer dans un wrapper HTML JavaScript ; le navigateur le décompresse ensuite avec l’API
DecompressionStream pour l’exécuter
- La génération du QR code utilise
qr.make(fit=True) pour trouver la plus petite version possible du QR code, et échoue si le contenu ne tient pas dans la limite standard de la version 40 avec le niveau de correction d’erreurs L
- La prise en charge mobile se limite aux navigateurs mobiles récents compatibles avec l’API
DecompressionStream ; le README cite Edge, Yandex et Opera comme exemples
Ce que fait The Backdooms
- The Backdooms est un jeu HTML qui contient l’intégralité du jeu dans un QR code et s’exécute dans un navigateur web
- Le jeu s’inspire de DOOM 1993 et de The Backrooms, et prend la forme d’une page web compressée auto-extractible
- En scannant le QR code, il se lance directement dans le navigateur, sans téléchargement ni installation supplémentaires
- Le README indique qu’il est possible de scanner pour jouer
- GitHub Pages propose aussi une version un peu moins compressée
Une méthode de compression qui pousse les limites du stockage
- L’objectif du projet est de repousser les limites de la capacité de stockage d’un QR code et de la compression, tout en montrant comment héberger une application web légère dans un QR code
- Le flux de compression suit les étapes suivantes
- Lecture du HTML d’entrée
- Compression du HTML avec Zlib
- Encodage des données compressées en Base64
- Insertion dans un wrapper HTML basé sur JavaScript
- Conversion de l’ensemble du HTML en Data URI au format
data:text/html;base64,...
- Dans le navigateur, l’API
DecompressionStream est utilisée pour décompresser dynamiquement le contenu compressé et l’exécuter
- Le diagramme du README inclut, côté navigateur, une étape
DecompressionStream 'gzip' ainsi qu’une étape Format Mismatch
Logique de génération du QR code
- L’outil de génération de QR code fournit un flux pour transformer un jeu d’environ 2,5 ko en QR code
- Exemples d’exécution
python3 QRGEN.py <your-game.html> <output-qrcode.png>
python3 QRGEN.py EVEN-SMALLER-SLAMMER-BACKROOMS.html qrcode.png
- Le processus de génération commence par essayer
qr.make(fit=True) afin de trouver la plus petite version de QR adaptée à la longueur du contenu
- Si la version nécessaire dépasse la limite standard des QR codes, à savoir 40, il force la version 40 avec
fit=False
- Pour contenir le maximum de données, il utilise le niveau de correction d’erreurs le plus bas, L
- Si les données restent trop volumineuses même avec la version 40 et le niveau L, l’encodage du QR code échoue et renvoie une erreur
Exécution et compatibilité
- Le jeu lui-même ne nécessite qu’un navigateur web récent
- Après le scan, comme tout le code du jeu se trouve dans l’URL, il est possible d’y jouer sans connexion Internet
- Sur mobile, il faut un navigateur récent prenant en charge l’API
DecompressionStream
- Le README cite Edge, Yandex et Opera comme exemples
- Une implémentation alternative basée sur BigInt pour obtenir un QR code plus petit se trouve dans The BigInt Branch, mais sa compatibilité avec les navigateurs mobiles est limitée
Environnement de génération et licence
- Pour générer soi-même le QR code, les dépendances suivantes sont nécessaires
-
Python 3.7+
- La bibliothèque
qrcode
pillow pour le traitement des images de QR code
- La commande d’installation des dépendances est la suivante
pip install qrcode[pil]
- Le processus de développement est décrit dans [MindDump](https://kuberwastaken.github.io/blog/Projects/How-I-Managed-To-Get-Doom-In-A-QR-Code)
- Le projet est publié sous **MIT License**, ce qui permet de l’utiliser, le modifier et le partager librement
1 commentaires
Avis sur Hacker News
J’ai découvert DecompressionStream et j’ai retouché la partie HTML pour gagner quelques octets de plus
J’ai aussi ouvert une PR si ça t’intéresse
Un immense merci, c’est ce qui m’est arrivé de mieux ce mois-ci
Projet vraiment génial
J’ai aussi découvert les URL
data:: je connaissais le schéma d’URIdata:et je l’avais déjà utilisé, mais je ne savais pas qu’on pouvait l’utiliser comme URL complèteJ’avais pensé à faire quelque chose de similaire qui tiendrait entièrement dans un QR code, mais j’avais remis ça à plus tard en pensant à tort qu’il fallait un lien HTTP(s). Cette vidéo m’a beaucoup inspiré : Can you fit a whole game into a QR code?(https://www.youtube.com/watch?v=ExwqNreocpg)
Mais je suis parti dans la direction opposée, avec une approche basée sur le navigateur pour une compatibilité plus large, et j’ai aussi indiqué la source dans le dépôt
Question peut-être idiote de débutant en technique, mais un QR code ne fait-il pas qu’encoder des données ?
Si la quantité maximale de données qu’un QR peut contenir est d’environ 3 Ko, cela correspondrait à quelque 3 000 caractères en texte brut ; la prouesse ici, c’est donc que ce jeu façon Doom fonctionne avec un code exécutable de cette taille ?
Dans la norme QR, le sens et l’objectif de l’encodage 8 bits semblent un peu ambigus, mais l’interprétation par défaut correspond aux jeux de caractères JIS8 et Shift JIS ; avec d’autres ECI, il représente directement des valeurs d’octets 8 bits
Quoi qu’il en soit, il est possible de stocker des données binaires arbitraires dans un QR code, et l’outil
qrencodele prend en charge par défautCela dit, beaucoup de décodeurs partent du principe que le QR contient du texte, ce qui rend la prise en charge délicate ; j’ai déjà envoyé un patch de décodage de QR binaires à cause d’un problème où zbar faisait passer les données par
iconvet les corrompaitÀ l’origine, je voulais seulement imprimer une clé privée RSA 4096 bits sous forme de QR code, puis des gens se sont mis à encoder aussi des jeux vidéo en QR, et c’est vraiment génial
https://youtu.be/ExwqNreocpg
https://news.ycombinator.com/item?id=24287347
Je l’ai scanné avec le scanner QR par défaut de l’iPhone et il affiche « Aucune donnée utilisable trouvée »
data:Par exemple, une page web autonome
Hi!peut être encodée endata:text/html;base64,PGh0bWw+PGJvZHk+SGkhPC9ib2R5PjwvaHRtbD4=, et si on la colle dans un navigateur,Hi!s’afficheMais si on en fait un QR code, cela ne fonctionne pas dans ce cas
La plupart des téléphones lisent mal les grands QR codes, donc il faut quelque chose comme https://qrscanner.org/
Et ça ne fonctionnera probablement pas sur téléphone ; à cause de la limite de taille, je n’ai pas pu ajouter cette compatibilité
Je scanne souvent des QR codes un peu partout pour éviter de saisir des URL, et l’idée qu’un simple scan de QR code puisse permettre l’exécution de code arbitraire fait assez peur
Si on ajoutait
image-rendering: pixelatedau CSS du canvas, le rendu aurait sans doute un aspect pixel net au lieu d’être flouLe prochain projet devrait être un LLM en QR code
À ce sujet : https://www.reddit.com/r/OpenAI/comments/138kbhs/someone_sho...
Ce n’est pas un LLM, mais c’est quand même un chatbot assez chouette
https://github.com/Kuberwastaken/MiniLMs/tree/main/SYNEVA
Le lien vers la bande-annonce du jeu mène vers un Short intitulé « Fly me to the moon - 19 September 2024 »
Ça ressemble à une erreur
J’adore ce genre de projets de jeux minuscules
Ça me fait penser à .kkrieger
https://en.wikipedia.org/wiki/.kkrieger
Continue à créer des choses géniales, kuberwastaken
J’avais déjà discuté d’une idée assez proche avec un ami
On se demandait si l’on pouvait encoder entièrement un fichier STL pour impression 3D dans un QR code et le coller sur l’objet physique, afin de pouvoir simplement scanner l’objet fabriqué pour le réimprimer
En creusant, il semblait y avoir beaucoup trop de données, et j’avais même regardé les QR codes multicolores, mais je ne savais pas qu’on pouvait simplement faire des QR codes plus grands
Comme une table ne nécessite que de découper des panneaux, j’encodais un fichier 2D, mais même pour une preuve de concept, il avait fallu utiliser un algorithme de compression personnalisé
https://johnkestner.com/rev/