Jogo de Terminal

Em desenvolvimento

Andante

A torre que se sobe sozinha

RPG idle que roda no terminal e no navegador: o personagem sobe uma torre de cinco andares sozinho, luta, compra melhorias e continua progredindo mesmo com o jogo fechado.

ver detalhes técnicos
Página inicial com o painel do modo idle

O desafio

Jogos de terminal são divertidos, mas quase ninguém instala Python só para experimentar um. A ideia era um jogo idle que rodasse em qualquer computador sem instalar nada e que também pudesse ser jogado no navegador, com o mesmo código e o mesmo progresso.

O que foi feito

  • Jogo inteiro em um único arquivo Python, sem nenhuma dependência: roda em Linux e Windows com Python 3.8 ou mais novo
  • Modo idle de verdade: o personagem batalha, trabalha, compra melhorias na Forja e enfrenta os chefes sozinho, e ao voltar você recebe o que ele conquistou enquanto o jogo estava fechado (até 12 horas)
  • Cinco andares com chefe e condição para avançar; ao vencer o último, a torre recomeça mais difícil e mais generosa
  • Save em arquivo de texto legível, que dá para editar à mão
  • Site onde o mesmo arquivo do jogo roda dentro do navegador, sem cadastro, com o progresso salvo no próprio navegador
  • Uma versão gráfica em pixel art, ainda em protótipo, que usa o mesmo save do terminal

Resultado

O código do jogo está aberto no GitHub e o site está no ar em andante-site.vercel.app, com o terminal jogável e o botão para baixar o andante.py. O projeto continua em desenvolvimento: a versão gráfica ainda é um protótipo.

Telas do projeto

O andante.py rodando no navegador, já no modo idle
O andante.py rodando no navegador, já no modo idle
Os cinco andares da torre, com chefe, nível exigido e recompensa
Os cinco andares da torre, com chefe, nível exigido e recompensa
Como funciona: idle, loot, missões, habilidades, Forja e Altar
Como funciona: idle, loot, missões, habilidades, Forja e Altar
A página inicial no celular
A página inicial no celular
A torre em uma coluna no celular
A torre em uma coluna no celular

// por dentro

Como foi construído

O Andante é um único andante.py de cerca de 4.200 linhas, só com a biblioteca padrão do Python 3.8+. O modo idle é um laço de ticks com velocidade ajustável (de 2 s a 0,1 s por passo), leitura de tecla sem bloqueio (msvcrt no Windows, termios + select no Linux), autosave a cada 10 ticks e progresso offline calculado pelo tempo desde o último acesso, limitado a 12 horas e com 50% de eficiência. O site é Next.js 16 e roda esse mesmo arquivo, sem alterações, no Pyodide (Python em WebAssembly) dentro de um Web Worker, com a saída desenhada no xterm.js. Um adaptador em Python (web_runtime.py) troca stdout, input, time.sleep, tamanho do terminal e leitura de teclas por versões que conversam com a página, e cada save é copiado para o localStorage. A versão gráfica usa o andante.py como motor e só desenha por cima com Pyxel.

Jogo
Python 3.8+ só com a biblioteca padrãocores ANSIleitura de tecla com msvcrt/termios
Versão gráfica (protótipo)
Pyxel 2.9.9sprites 16×16 escritos no próprio códigofonte PixelMplus10empacotada em .pyxapp
Site
Next.js 16.4React 19.3Tailwind CSS 4shadcn/ui com Base UITypeScript 5
Terminal no navegador
Pyodide 0.27.2 (jsDelivr) em Web Workerxterm.js 5.5 com addons fit e unicode11SharedArrayBuffer + Atomics
Testes
script de regressão com um teste por bug já corrigido e smoke test de todas as telasrodando em pasta temporária sem tocar nos saves

Arquitetura

O mesmo arquivo no terminal e no navegador

O site baixa o andante.py original e roda no Pyodide. Em vez de manter uma versão web, o web_runtime.py substitui só o que depende de um terminal de verdade (stdout, input, sleep, clear e a leitura de teclas), então qualquer mudança no jogo chega ao site copiando um arquivo.

Performance

input() bloqueante dentro de um Web Worker

O Python fica parado em input() e sleep e não consegue receber postMessage. O teclado vai por um anel de 8 KB num SharedArrayBuffer, com contadores de leitura e escrita; o worker dorme com Atomics.wait e acorda com Atomics.notify quando chega tecla. A saída volta em lotes por postMessage.

Segurança

Isolamento de origem para liberar o SharedArrayBuffer

O SharedArrayBuffer só existe com a página isolada (crossOriginIsolated). O next.config.ts envia Cross-Origin-Opener-Policy same-origin e Cross-Origin-Embedder-Policy require-corp em todas as rotas, e serve o andante.py como text/plain.

Dados

Progresso offline com limite e eficiência

Ao abrir o jogo, progresso_offline() calcula XP, ouro, níveis e compras a partir do tempo desde o último acesso, com teto de 12 horas e 50% do rendimento do jogo aberto. Um bônus do Altar aumenta esse teto.

UX

Save em texto que o jogador pode editar

O save é um .txt com campos legíveis, flags em checklist e inventário em lista. O mesmo formato é usado no terminal, no navegador (localStorage) e na versão gráfica, então o progresso passa de um para o outro.

Testes

Regressão por bug corrigido

Cada bug corrigido vira um teste no regressao.py, que importa o jogo numa pasta temporária, simula as teclas e confere o resultado. Um dos testes deixa o idle rodar 6.000 ticks sozinho e exige que ele não trave e vença os cinco chefes da torre.

Quer um projeto como este?

Conte o que você precisa e receba uma proposta sem compromisso.

Pedir orçamento