Mahjong Firefly - 👋 Mahjong Firefly Play Now For Free at LupyGames.com!
👋 Mahjong Firefly Play Now For Free at LupyGames.com!

O que é e como funciona

mahjong firefly é uma ferramenta de automação e análise para jogos de Mahjong Solitaire. Ela roda por cima do jogo, captura o estado do tabuleiro em tempo real, identifica as peças disponíveis e sugere ou executa jogadas automaticamente. O que muita gente não entende no começo é que ela não é um bot ingênuo que clica aleatoriamente. Ela resolve o tabuleiro usando algoritmos de busca com backtracking, calculando todas as combinações possíveis de peças livres antes de tomar qualquer decisão. A primeira vez que eu configurei isso foi em 2019, rodando uma versão chinesa de Mahjong Solitaire que tinha peças com texturas muito parecidas. O OCR padrão do firefly não conseguia distinguir entre uma peça de flor e uma de dragão porque os dois tinham fundo dourado com contornos semelhantes. Eu resolvi criando um perfil de cores personalizado no JSON de configuração, mapeando cada símbolo pelo histograma RGB em vez de confiar na detecção por template. O arquivo ficava em ~/.mahjong-firefly/config/profiles/custom.json, e eu usava um script Python simples pra extrair as cores médias de cada região do sprite sheet antes de salvar.

Instalação do mahjong firefly

Você precisa de Python 3.9 ou superior, OpenCV, numpy e pillow. O repositório principal fica em github.com/firefly-mahjong/mahjong-firefly, mas dependendo da sua versão do jogo pode precisar de um fork adaptado. A instalação básica é: clone o repositório, entre na pasta e rode pip install -r requirements.txt. Depois copie o arquivo config.example.json para config.json e edite os paths. Se estiver usando Windows, instale também o pyautogui e certifique-se de que o jogo está em modo janela, não fullscreen, senão a captura de tela falha.

No Mac eu tive um problema específico com o accessibilidade permissionamento. O pyautogui simplesmente não conseguia mover o mouse nem clicar até eu ir em Preferências do Sistema > Privacidade e Segurança > Accessibilidade e adicionar o interpretador Python manualmente. Sem isso o bot detectava as peças mas não executava nenhuma jogada, e o log ficava silencioso porque ele tratava o erro de permissão como um aviso não fatal. Fiquei uns 40 minutos sem fazer ideia do que estava errado até notar que o cursor nunca se movia.

Configuração avançada

O arquivo de configuração tem muitas opções que a documentação não explica direito. A mais importante é a seção scan_region, que define a área da tela que o firefly vai analisar. Se você deixar como auto-detect, ele procura por bordas escuras ao redor do tabuleiro, mas isso falha em temas claros ou em resoluções ultrawide. Eu recomendo definir coordenadas manualmente. Abra o jogo, anote a posição do canto superior esquerdo do tabuleiro e a largura e altura em pixels, e coloque direto no config. A seção piece_threshold controla a sensibilidade da detecção de peças livres. Valores mais altos (0.85 a 0.95) são mais precisos mas mais lentos. Valores mais baixos (0.6 a 0.7) aceleram o scan mas geram falsos positivos onde o bot acha que duas peças estão disponíveis quando na verdade uma está bloqueada por uma terceira invisível na camadas de baixo. Eu uso 0.88 como padrão e sóajo para baixo quando o tabuleiro tem muitas peças sobrepostas, tipo mais de 120 peças na tela.

O modo solve_vs assist também merece atenção. Em solve mode o firefly calcula a solução completa antes de começar a jogar, o que leva de 3 a 12 segundos dependendo da complexidade do tabuleiro. Em assist mode ele decide peça por peça, o que é mais rápido mas às vezes entra em loops infinitos em tabuleiros mal formados. Eu prefiro solve mode para ranked ou quando o tempo não é problema, e assist mode só em sessões casuais.

👉 Clique no botão abaixo para saber mais sobre o assunto!

Problemas comuns e workarounds

Um dos problemas mais chatos é quando o jogo muda de resolução dinamicamente durante uma partida. O firefly non detecta a mudança e continua usando as coordenadas antigas, então os cliques vão para lugares errados. A solução que eu encontrei foi colocar um watcher de resolução rodando em thread separada que checa a cada 5 segundos e reinicia o scan region se detectar diferença. O código tá no repositório como watchdog.py, mas muita gente não sabe que precisa ativar a flag enable_resolution_watch: true no config. Outro problema clássico é com efeitos visuais de animação. Quando uma peça é removida com fade ou slide, o firefly às vezes tenta processar o frame durante a animação e lê um estado parcialmente renderizado. O resultado são jogadas duplicadas ou peças que sumiram sendo clicadas de novo. A workaround é ajustar o animation_pause_ms no config para um valor maior que a duração da animação do seu jogo. Na maioria das versões brasileiras de Mahjong Solitaire, 300ms é suficiente. Em versões mais pesadas com shaders, você pode precisar de 600ms.

Se você estiver usando Linux, há um problema conhecido com o Wayland. O pyautogui e o mss não funcionam bem porque o servidor de exibição isola as janelas. A solução é usar X11 ou rodar o jogo dentro de um container Xwayland com permissões de compartilhamento de tela ativadas. Eu testei com o Flatpak do jogo e funcionou após configurar o flatpak override para dar acesso ao DISPLAY e ao XSHM.

Limitações que ninguém menciona

O firefly não consegue resolver tabuleiros que são matematicamente impossíveis. Existem versões do Mahjong Solitaire que são geradas proceduralmente com apenas 10% de chance de terem solução. Nesses casos o bot vai rodar até exaurir todas as combinações e depois travar ou fechar sozinho. Não há como evitar isso exceto configurando o max_iterations no config para um limite seguro, como 500000, e deixando o bot desistir graciosamente em vez de ficar computando até o fim. O segundo problema é performance. Em machines mais antigas, o processamento de frames pode levar mais tempo do que o jogo permite, especialmente se você rodar com alta resolução de captura. Eu vi casos onde o scan de um único frame levava 800ms numa machine com CPU dual-core de 2015. A solução é reduzir a resolução de captura pela metade e ativar o modo skip_frames, que analisa apenas um frame a cada três quadros renderizados. A perda de precisão é mínima, algo em torno de 2% de taxa de erro adicional.

Não existe suporte nativo para versões offline do jogo que não usam canvas HTML ou renderização por GPU. Se o seu jogo usa DirectX ou OpenGL puro sem overlay acessível, o firefly não vai conseguir ler o estado. Nesse caso você precisa recorrer a scraping de memória via memory_reader, que é uma feature experimental e instável. Eu consegui fazer funcionar com uma build específica de 2022, mas qualquer atualização quebra o scanner de memória.

Uso prático no dia a dia

Eu uso o mahjong firefly principalmente para treinar padrões de jogadas e estudar estatísticas de tabuleiros. Rodar 100 partidas em modo assist com logging ativado gera um arquivo JSON com dados sobre quais combinações aparecem com mais frequência, quais peças costumam ficar presas no final, e qual a probabilidade real de vitória em cada seed. Esse dado é útil se você quer melhorar sua habilidade manual, porque mostra padrões que o olho humano não percebe em tempo real. Para ativar o logging completo, basta colocar verbose_logging: true e save_game_states: true no config. Os arquivos ficam em ~/.mahjong-firefly/logs/ e podem crescer bastante. Uma sessão de 50 partidas gera cerca de 200MB de dados em JSON. Eu costumo compactar semanalmente com gzip e descartar os brutos após exportar as estatísticas.

Se você quer apenas uma solução rápida sem configurar nada, a versão standalone com binário pré-compilado funciona em Windows e macOS sem dependências extras. O download direto tá no repositório na aba Releases. Para Linux só via source mesmo, porque as bibliotecas de captura de tela variam demais entre distros.