1 pontos por GN⁺ 2025-04-19 | 1 comentários | Compartilhar no WhatsApp
  • The Backdooms é um jogo HTML compacto, autoextraível e com geração infinita, inspirado em DOOM 1993 e The Backrooms, que roda direto no navegador a partir de um código QR
  • A proposta é colocar todo o código do jogo na URL, permitindo jogar totalmente offline após o escaneamento, sem conexão com a internet
  • O fluxo de compressão comprime o HTML com Zlib, codifica em Base64, insere em um wrapper HTML com JavaScript e descompacta no navegador com a API DecompressionStream
  • A geração do QR usa qr.make(fit=True) para encontrar a menor versão possível do QR, e falha se não couber no limite padrão da versão 40 com nível de correção de erro L
  • O suporte móvel é limitado a navegadores móveis recentes com suporte à API DecompressionStream; o README cita Edge, Yandex e Opera como exemplos

O que o The Backdooms faz

  • The Backdooms é um jogo HTML que coloca o jogo inteiro dentro de um código QR e o executa no navegador
  • O jogo foi inspirado em DOOM 1993 e The Backrooms, e é estruturado como uma página web comprimida e autoextraível
  • Ao escanear o código QR, ele roda imediatamente no navegador, sem necessidade de download ou instalação separados
  • O README informa que é possível escanear e jogar
  • No GitHub Pages, também há uma versão um pouco menos comprimida

A técnica de compressão que leva o limite de armazenamento ao extremo

  • O objetivo do projeto é levar ao limite a capacidade de armazenamento de códigos QR e os limites de compressão, mostrando como hospedar aplicações web leves dentro de um código QR
  • O fluxo de compressão é composto pela seguinte sequência
    • Lê o HTML de entrada
    • Comprime o HTML com Zlib
    • Codifica os dados comprimidos em Base64
    • Insere em um wrapper HTML baseado em JavaScript
    • Converte o HTML completo em uma Data URI no formato data:text/html;base64,...
  • No navegador, a API DecompressionStream é usada para descompactar dinamicamente o conteúdo comprimido e executá-lo
  • O diagrama no README inclui DecompressionStream 'gzip' e a etapa Format Mismatch no processamento do navegador

Lógica de geração do código QR

  • A ferramenta de geração de QR fornece um fluxo para transformar um jogo de cerca de 2.5kb em um código QR
  • O exemplo de execução é o seguinte
python3 QRGEN.py <your-game.html> <output-qrcode.png>
python3 QRGEN.py EVEN-SMALLER-SLAMMER-BACKROOMS.html qrcode.png
  • O processo de geração primeiro tenta a menor versão de QR compatível com o tamanho do conteúdo usando qr.make(fit=True)
  • Se a versão necessária ultrapassar o limite padrão de 40 do código QR, ele força a versão 40 com fit=False
  • Para armazenar a quantidade máxima de dados, usa o nível mais baixo de correção de erro, L
  • Se os dados ainda forem grandes demais mesmo com versão 40 e nível L, a codificação do QR falha e retorna um erro

Execução e compatibilidade

  • Para jogar, basta ter um navegador web moderno
  • Após o escaneamento, como todo o código do jogo fica na URL, é possível jogar sem conexão com a internet
  • Em dispositivos móveis, é necessário um navegador recente com suporte à API DecompressionStream
    • O README cita Edge, Yandex e Opera como exemplos
  • Há uma implementação alternativa baseada em BigInt para QR codes menores em The BigInt Branch, mas a compatibilidade com navegadores móveis é limitada

Ambiente de geração e licença

  • Para gerar o código QR manualmente, são necessárias as seguintes dependências
    • Python 3.7+

      • biblioteca qrcode
      • pillow para processamento da imagem do código QR
      • O comando para instalar as dependências é o seguinte
pip install qrcode[pil]
- O processo de desenvolvimento está documentado no [MindDump](https://kuberwastaken.github.io/blog/Projects/How-I-Managed-To-Get-Doom-In-A-QR-Code)
- O projeto é publicado sob a **MIT License** e pode ser usado, modificado e compartilhado livremente

1 comentários

 
GN⁺ 2025-04-19
Comentários do Hacker News
  • Descobri o DecompressionStream pela primeira vez e refinei a parte de HTML para economizar mais alguns bytes
    Também abri um PR para quem tiver interesse em ver

    • Graças ao espaço liberado, consegui adicionar suporte a touchscreen, movimentação melhor, geração de inimigos e até tratamento de dano
      Muito obrigado de verdade; foi a melhor coisa do meu mês
  • Projeto realmente incrível
    Também aprendi sobre URLs data:; eu conhecia o esquema de URI data: e já tinha usado, mas não sabia que dava para usá-lo como uma URL completa
    Eu tinha pensado em fazer algo parecido que coubesse inteiro dentro de um QR code, mas deixei de lado porque achava, por engano, que precisaria de um link HTTP(s); este vídeo me inspirou bastante: Can you fit a whole game into a QR code?(https://www.youtube.com/watch?v=ExwqNreocpg)

    • Também vi esse vídeo por volta da época do lockdown e me inspirei; foi muito legal
      Mas fui na direção oposta, baseada em navegador, para ter compatibilidade mais ampla, e também dei os créditos no repositório
  • Sou iniciante em tecnologia, então pode ser uma pergunta boba, mas QR não é só dados codificados?
    Se o máximo de dados que um QR comporta é cerca de 3 KB, isso daria mais ou menos 3000 caracteres de texto simples; fico curioso se a conquista aqui é esse jogo estilo Doom funcionar como código executável desse tamanho

    • Códigos QR têm vários modos de codificação, como numérico, alfanumérico, 8 bits, kanji etc.; o mais comum é a codificação alfanumérica, e o mais denso é a codificação de 8 bits, que armazena dados binários diretamente
      No padrão QR, o significado e o propósito da codificação de 8 bits parecem um pouco ambíguos, mas a interpretação padrão é o conjunto de caracteres JIS8 e Shift JIS; em outros ECIs, ela representa diretamente valores de bytes de 8 bits
      De todo modo, é possível armazenar dados binários arbitrários em um QR code, e a ferramenta qrencode oferece suporte a isso por padrão
      Só que muitos decodificadores assumem que o QR contém texto, então o suporte é complicado; eu já enviei um patch de decodificação de QR binário por causa de um problema em que o zbar passava os dados pelo iconv e os corrompia
      Originalmente eu só queria imprimir uma chave privada RSA de 4096 bits como QR code, mas depois as pessoas começaram a codificar videogames em QR também, e isso é muito legal
      https://youtu.be/ExwqNreocpg
      https://news.ycombinator.com/item?id=24287347
  • Escaneei com o leitor de QR code padrão do iPhone e ele mostrou “nenhum dado utilizável encontrado”

    • Isso não é um problema de tamanho ou comprimento do QR code; é porque o scanner padrão do iPhone não dá suporte a URLs URI data:
      Por exemplo, uma página web autocontida Hi! pode ser codificada como data:text/html;base64,PGh0bWw+PGJvZHk+SGkhPC9ib2R5PjwvaHRtbD4=, e, se você colar isso no navegador, ele renderiza Hi!
      Mas, se você transformar isso em um QR code, nesse cenário não funciona
    • Obrigado por verificar
      A maioria dos celulares não lê bem QRs grandes, então é preciso algo como https://qrscanner.org/
      E provavelmente não funcionaria em celulares; por causa do limite de tamanho, não deu para incluir essa compatibilidade também
    • Fico até um pouco aliviado por não funcionar no iPhone
      Eu escaneio com frequência QR codes espalhados por aí para economizar tempo digitando URLs, e pensar que só escanear um QR code poderia permitir execução arbitrária de código é bem assustador
  • Se colocar image-rendering: pixelated no CSS do canvas, acho que ficaria com uma aparência de pixels nítidos, sem ficar borrado

    • Eu testei, mas gostei mais do visual atual; ficou mais divertido e com cara retrô
  • Espero que o próximo projeto seja um LLM em forma de QR code
    Relacionado: https://www.reddit.com/r/OpenAI/comments/138kbhs/someone_sho...

  • O link do trailer do jogo leva a um Shorts chamado “Fly me to the moon - 19 September 2024”
    Parece ter sido um engano

    • Agora deve estar corrigido
  • Gosto muito desses projetos de jogos minúsculos
    Me lembra .kkrieger
    https://en.wikipedia.org/wiki/.kkrieger

    • Alguém me contou sobre ele quando publiquei no LinkedIn; achei muito legal
  • Continue criando coisas incríveis, kuberwastaken

    • Vou dar o meu melhor
  • Já conversei com um amigo sobre uma ideia mais ou menos relacionada
    Eu me perguntava se daria para codificar um arquivo STL para impressão 3D inteiro em um QR code e colá-lo no objeto impresso, de modo que bastasse escanear o objeto para imprimi-lo de novo
    Pelo que pesquisei, parecia ser dados demais, e até cheguei a olhar QR codes multicoloridos, mas não sabia que era possível simplesmente fazer um QR code maior

    • Fiz algo parecido no passado como exploração de design para mesas
      Como mesas só exigem corte de chapas, codifiquei um arquivo 2D, mas mesmo assim precisei usar um algoritmo de compressão customizado para a prova de conceito
      https://johnkestner.com/rev/